Commit a848c2e3 by Archer Committed by GitHub

feat: more sub plan info;fix: emprt index (#4997)

* feat: more sub plan info

* fix: emprt index

* doc
parent ccae96a9
--- ---
title: 'V4.9.11(进行中)' title: 'V4.9.12(进行中)'
description: 'FastGPT V4.9.12 更新说明' description: 'FastGPT V4.9.12 更新说明'
icon: 'upgrade' icon: 'upgrade'
draft: false draft: false
toc: true toc: true
weight: 789 weight: 788
--- ---
## 🚀 新增内容 ## 🚀 新增内容
...@@ -17,7 +17,9 @@ weight: 789 ...@@ -17,7 +17,9 @@ weight: 789
1. 密码校验时,增加更多的特殊字符 1. 密码校验时,增加更多的特殊字符
2. 后端全量计算知识库 chunk 参数,避免自动模式下部分参数未正确使用默认值。 2. 后端全量计算知识库 chunk 参数,避免自动模式下部分参数未正确使用默认值。
3. 将文本分块移至 worker 线程,避免阻塞。 3. 将文本分块移至 worker 线程,避免阻塞。
4. 展示更多套餐用量信息。
## 🐛 修复 ## 🐛 修复
1. 自定义问答提取提示词被覆盖。 1. 自定义问答提取提示词被覆盖。
\ No newline at end of file 2. 模板导入时,存在空 indexes 时,导致数据插入失败。
\ No newline at end of file
...@@ -45,6 +45,9 @@ export type TeamSubSchema = { ...@@ -45,6 +45,9 @@ export type TeamSubSchema = {
nextMode: `${SubModeEnum}`; nextMode: `${SubModeEnum}`;
currentSubLevel: StandardSubLevelEnum; currentSubLevel: StandardSubLevelEnum;
nextSubLevel: StandardSubLevelEnum; nextSubLevel: StandardSubLevelEnum;
maxTeamMember?: number;
maxApp?: number;
maxDataset?: number;
totalPoints: number; totalPoints: number;
surplusPoints: number; surplusPoints: number;
...@@ -52,7 +55,7 @@ export type TeamSubSchema = { ...@@ -52,7 +55,7 @@ export type TeamSubSchema = {
currentExtraDatasetSize: number; currentExtraDatasetSize: number;
}; };
export type FeTeamPlanStatusType = { export type TeamPlanStatusType = {
[SubTypeEnum.standard]?: TeamSubSchema; [SubTypeEnum.standard]?: TeamSubSchema;
standardConstants?: TeamStandardSubPlanItemType; standardConstants?: TeamStandardSubPlanItemType;
...@@ -61,5 +64,11 @@ export type FeTeamPlanStatusType = { ...@@ -61,5 +64,11 @@ export type FeTeamPlanStatusType = {
// standard + extra // standard + extra
datasetMaxSize: number; datasetMaxSize: number;
};
export type ClientTeamPlanStatusType = TeamPlanStatusType & {
usedMember: number;
usedAppAmount: number;
usedDatasetSize: number; usedDatasetSize: number;
usedDatasetIndexSize: number;
}; };
...@@ -18,7 +18,7 @@ import { BucketNameEnum } from '@fastgpt/global/common/file/constants'; ...@@ -18,7 +18,7 @@ import { BucketNameEnum } from '@fastgpt/global/common/file/constants';
import type { ClientSession } from '../../../common/mongo'; import type { ClientSession } from '../../../common/mongo';
import { createOrGetCollectionTags } from './utils'; import { createOrGetCollectionTags } from './utils';
import { rawText2Chunks } from '../read'; import { rawText2Chunks } from '../read';
import { checkDatasetLimit } from '../../../support/permission/teamLimit'; import { checkDatasetIndexLimit } from '../../../support/permission/teamLimit';
import { predictDataLimitLength } from '../../../../global/core/dataset/utils'; import { predictDataLimitLength } from '../../../../global/core/dataset/utils';
import { mongoSessionRun } from '../../../common/mongo/sessionRun'; import { mongoSessionRun } from '../../../common/mongo/sessionRun';
import { createTrainingUsage } from '../../../support/wallet/usage/controller'; import { createTrainingUsage } from '../../../support/wallet/usage/controller';
...@@ -166,7 +166,7 @@ export const createCollectionAndInsertData = async ({ ...@@ -166,7 +166,7 @@ export const createCollectionAndInsertData = async ({
})(); })();
// 2. auth limit // 2. auth limit
await checkDatasetLimit({ await checkDatasetIndexLimit({
teamId, teamId,
insertLen: predictDataLimitLength(trainingMode, chunks) insertLen: predictDataLimitLength(trainingMode, chunks)
}); });
......
...@@ -199,7 +199,7 @@ export const rawText2Chunks = async ({ ...@@ -199,7 +199,7 @@ export const rawText2Chunks = async ({
.map((item) => ({ .map((item) => ({
q: item[0] || '', q: item[0] || '',
a: item[1] || '', a: item[1] || '',
indexes: item.slice(2), indexes: item.slice(2).filter((item) => item.trim()),
imageIdList imageIdList
})) }))
.filter((item) => item.q || item.a); .filter((item) => item.q || item.a);
......
...@@ -83,8 +83,7 @@ const TrainingDataSchema = new Schema({ ...@@ -83,8 +83,7 @@ const TrainingDataSchema = new Schema({
enum: Object.values(DatasetDataIndexTypeEnum) enum: Object.values(DatasetDataIndexTypeEnum)
}, },
text: { text: {
type: String, type: String
required: true
} }
} }
], ],
......
...@@ -5,28 +5,9 @@ import { DatasetTypeEnum } from '@fastgpt/global/core/dataset/constants'; ...@@ -5,28 +5,9 @@ import { DatasetTypeEnum } from '@fastgpt/global/core/dataset/constants';
import { TeamErrEnum } from '@fastgpt/global/common/error/code/team'; import { TeamErrEnum } from '@fastgpt/global/common/error/code/team';
import { SystemErrEnum } from '@fastgpt/global/common/error/code/system'; import { SystemErrEnum } from '@fastgpt/global/common/error/code/system';
import { AppTypeEnum } from '@fastgpt/global/core/app/constants'; import { AppTypeEnum } from '@fastgpt/global/core/app/constants';
import { MongoTeamMember } from '../user/team/teamMemberSchema';
export const checkDatasetLimit = async ({ import { TeamMemberStatusEnum } from '@fastgpt/global/support/user/team/constant';
teamId, import { getVectorCountByTeamId } from '../../common/vectorDB/controller';
insertLen = 0
}: {
teamId: string;
insertLen?: number;
}) => {
const { standardConstants, totalPoints, usedPoints, datasetMaxSize, usedDatasetSize } =
await getTeamPlanStatus({ teamId });
if (!standardConstants) return;
if (usedDatasetSize + insertLen >= datasetMaxSize) {
return Promise.reject(TeamErrEnum.datasetSizeNotEnough);
}
if (usedPoints >= totalPoints) {
return Promise.reject(TeamErrEnum.aiPointsNotEnough);
}
return;
};
export const checkTeamAIPoints = async (teamId: string) => { export const checkTeamAIPoints = async (teamId: string) => {
const { standardConstants, totalPoints, usedPoints } = await getTeamPlanStatus({ const { standardConstants, totalPoints, usedPoints } = await getTeamPlanStatus({
...@@ -45,32 +26,19 @@ export const checkTeamAIPoints = async (teamId: string) => { ...@@ -45,32 +26,19 @@ export const checkTeamAIPoints = async (teamId: string) => {
}; };
}; };
export const checkTeamDatasetLimit = async (teamId: string) => { export const checkTeamMemberLimit = async (teamId: string, newCount: number) => {
const [{ standardConstants }, datasetCount] = await Promise.all([ const [{ standardConstants }, memberCount] = await Promise.all([
getTeamStandPlan({ teamId }), getTeamStandPlan({
MongoDataset.countDocuments({ teamId
}),
MongoTeamMember.countDocuments({
teamId, teamId,
type: { $ne: DatasetTypeEnum.folder } status: { $ne: TeamMemberStatusEnum.leave }
}) })
]); ]);
// User check if (standardConstants && newCount + memberCount > standardConstants.maxTeamMember) {
if (standardConstants && datasetCount >= standardConstants.maxDatasetAmount) { return Promise.reject(TeamErrEnum.teamOverSize);
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);
} }
}; };
...@@ -101,3 +69,64 @@ export const checkTeamAppLimit = async (teamId: string, amount = 1) => { ...@@ -101,3 +69,64 @@ export const checkTeamAppLimit = async (teamId: string, amount = 1) => {
} }
} }
}; };
export const checkDatasetIndexLimit = async ({
teamId,
insertLen = 0
}: {
teamId: string;
insertLen?: number;
}) => {
const [{ standardConstants, totalPoints, usedPoints, datasetMaxSize }, usedDatasetIndexSize] =
await Promise.all([getTeamPlanStatus({ teamId }), getVectorCountByTeamId(teamId)]);
if (!standardConstants) return;
if (usedDatasetIndexSize + insertLen >= datasetMaxSize) {
return Promise.reject(TeamErrEnum.datasetSizeNotEnough);
}
if (usedPoints >= totalPoints) {
return Promise.reject(TeamErrEnum.aiPointsNotEnough);
}
return;
};
export const checkTeamDatasetLimit = async (teamId: string) => {
const [{ standardConstants }, datasetCount] = await Promise.all([
getTeamStandPlan({ teamId }),
MongoDataset.countDocuments({
teamId,
type: { $ne: DatasetTypeEnum.folder }
})
]);
// 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 checkTeamWebSyncPermission = async (teamId: string) => {
const { standardConstants } = await getTeamStandPlan({
teamId
});
if (standardConstants && !standardConstants?.permissionWebsiteSync) {
return Promise.reject(TeamErrEnum.websiteSyncNotEnough);
}
};
...@@ -52,6 +52,9 @@ const SubSchema = new Schema({ ...@@ -52,6 +52,9 @@ const SubSchema = new Schema({
type: String, type: String,
enum: Object.values(StandardSubLevelEnum) enum: Object.values(StandardSubLevelEnum)
}, },
maxTeamMember: Number,
maxApp: Number,
maxDataset: Number,
// stand sub and extra points sub. Plan total points // stand sub and extra points sub. Plan total points
totalPoints: { totalPoints: {
......
...@@ -6,10 +6,9 @@ import { ...@@ -6,10 +6,9 @@ import {
} from '@fastgpt/global/support/wallet/sub/constants'; } from '@fastgpt/global/support/wallet/sub/constants';
import { MongoTeamSub } from './schema'; import { MongoTeamSub } from './schema';
import { import {
type FeTeamPlanStatusType, type TeamPlanStatusType,
type TeamSubSchema type TeamSubSchema
} from '@fastgpt/global/support/wallet/sub/type.d'; } from '@fastgpt/global/support/wallet/sub/type.d';
import { getVectorCountByTeamId } from '../../../common/vectorDB/controller';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import { type ClientSession } from '../../../common/mongo'; import { type ClientSession } from '../../../common/mongo';
import { addMonths } from 'date-fns'; import { addMonths } from 'date-fns';
...@@ -44,12 +43,21 @@ export const getTeamStandPlan = async ({ teamId }: { teamId: string }) => { ...@@ -44,12 +43,21 @@ export const getTeamStandPlan = async ({ teamId }: { teamId: string }) => {
const standardPlans = global.subPlans?.standard; const standardPlans = global.subPlans?.standard;
const standard = plans[0]; const standard = plans[0];
const standardConstants =
standard?.currentSubLevel && standardPlans
? standardPlans[standard.currentSubLevel]
: undefined;
return { return {
[SubTypeEnum.standard]: standard, [SubTypeEnum.standard]: standard,
standardConstants: standardConstants: standardConstants
standard?.currentSubLevel && standardPlans ? {
? standardPlans[standard.currentSubLevel] ...standardConstants,
: undefined maxTeamMember: standard?.maxTeamMember || standardConstants.maxTeamMember,
maxAppAmount: standard?.maxApp || standardConstants.maxAppAmount,
maxDatasetAmount: standard?.maxDataset || standardConstants.maxDatasetAmount
}
: undefined
}; };
}; };
...@@ -111,14 +119,11 @@ export const getTeamPlanStatus = async ({ ...@@ -111,14 +119,11 @@ export const getTeamPlanStatus = async ({
teamId teamId
}: { }: {
teamId: string; teamId: string;
}): Promise<FeTeamPlanStatusType> => { }): Promise<TeamPlanStatusType> => {
const standardPlans = global.subPlans?.standard; const standardPlans = global.subPlans?.standard;
/* Get all plans and datasetSize */ /* Get all plans and datasetSize */
const [plans, usedDatasetSize] = await Promise.all([ const plans = await MongoTeamSub.find({ teamId }).lean();
MongoTeamSub.find({ teamId }).lean(),
getVectorCountByTeamId(teamId)
]);
/* Get all standardPlans and active standardPlan */ /* Get all standardPlans and active standardPlan */
const teamStandardPlans = sortStandPlans( const teamStandardPlans = sortStandPlans(
...@@ -158,17 +163,25 @@ export const getTeamPlanStatus = async ({ ...@@ -158,17 +163,25 @@ export const getTeamPlanStatus = async ({
standardMaxDatasetSize + standardMaxDatasetSize +
extraDatasetSize.reduce((acc, cur) => acc + (cur.currentExtraDatasetSize || 0), 0); extraDatasetSize.reduce((acc, cur) => acc + (cur.currentExtraDatasetSize || 0), 0);
const standardConstants =
standardPlan?.currentSubLevel && standardPlans
? standardPlans[standardPlan.currentSubLevel]
: undefined;
return { return {
[SubTypeEnum.standard]: standardPlan, [SubTypeEnum.standard]: standardPlan,
standardConstants: standardConstants: standardConstants
standardPlan?.currentSubLevel && standardPlans ? {
? standardPlans[standardPlan.currentSubLevel] ...standardConstants,
: undefined, maxTeamMember: standardPlan?.maxTeamMember || standardConstants.maxTeamMember,
maxAppAmount: standardPlan?.maxApp || standardConstants.maxAppAmount,
maxDatasetAmount: standardPlan?.maxDataset || standardConstants.maxDatasetAmount
}
: undefined,
totalPoints, totalPoints,
usedPoints: totalPoints - surplusPoints, usedPoints: totalPoints - surplusPoints,
datasetMaxSize: totalDatasetSize, datasetMaxSize: totalDatasetSize
usedDatasetSize
}; };
}; };
...@@ -14,7 +14,10 @@ export const getSafeEnv = () => { ...@@ -14,7 +14,10 @@ export const getSafeEnv = () => {
return { return {
LOG_LEVEL: process.env.LOG_LEVEL, LOG_LEVEL: process.env.LOG_LEVEL,
STORE_LOG_LEVEL: process.env.STORE_LOG_LEVEL, STORE_LOG_LEVEL: process.env.STORE_LOG_LEVEL,
NODE_ENV: process.env.NODE_ENV NODE_ENV: process.env.NODE_ENV,
HTTP_PROXY: process.env.HTTP_PROXY,
HTTPS_PROXY: process.env.HTTPS_PROXY,
NO_PROXY: process.env.NO_PROXY
}; };
}; };
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
"ai_points_calculation_standard": "AI points", "ai_points_calculation_standard": "AI points",
"ai_points_usage": "AI points", "ai_points_usage": "AI points",
"ai_points_usage_tip": "Each time the AI ​​model is called, a certain amount of AI points will be consumed. \nFor specific calculation standards, please refer to the \"Billing Standards\" above.", "ai_points_usage_tip": "Each time the AI ​​model is called, a certain amount of AI points will be consumed. \nFor specific calculation standards, please refer to the \"Billing Standards\" above.",
"app_amount": "App amount",
"avatar": "Avatar", "avatar": "Avatar",
"avatar_selection_exception": "Abnormal avatar selection", "avatar_selection_exception": "Abnormal avatar selection",
"balance": "balance", "balance": "balance",
...@@ -21,6 +22,7 @@ ...@@ -21,6 +22,7 @@
"contact_us": "Contact us", "contact_us": "Contact us",
"current_package": "Current plan", "current_package": "Current plan",
"current_token_price": "Current points price", "current_token_price": "Current points price",
"dataset_amount": "Dataset amount",
"effective_time": "Effective time", "effective_time": "Effective time",
"email_label": "Mail", "email_label": "Mail",
"exchange": "Exchange", "exchange": "Exchange",
...@@ -34,6 +36,7 @@ ...@@ -34,6 +36,7 @@
"help_document": "Help documentation", "help_document": "Help documentation",
"knowledge_base_capacity": "Dataset usages", "knowledge_base_capacity": "Dataset usages",
"manage": "Manage", "manage": "Manage",
"member_amount": "Member amount",
"member_name": "Name", "member_name": "Name",
"month": "moon", "month": "moon",
"new_password": "New Password", "new_password": "New Password",
......
...@@ -215,7 +215,6 @@ ...@@ -215,7 +215,6 @@
"core.app.Interval timer run": "Scheduled Execution", "core.app.Interval timer run": "Scheduled Execution",
"core.app.Interval timer tip": "Can Execute App on Schedule", "core.app.Interval timer tip": "Can Execute App on Schedule",
"core.app.Make a brief introduction of your app": "Give Your AI App an Introduction", "core.app.Make a brief introduction of your app": "Give Your AI App an Introduction",
"core.app.name": "name",
"core.app.Name and avatar": "Avatar & Name", "core.app.Name and avatar": "Avatar & Name",
"core.app.Publish": "Publish", "core.app.Publish": "Publish",
"core.app.Publish Confirm": "Confirm to Publish App? This Will Immediately Update the App Status on All Publishing Channels.", "core.app.Publish Confirm": "Confirm to Publish App? This Will Immediately Update the App Status on All Publishing Channels.",
...@@ -261,6 +260,7 @@ ...@@ -261,6 +260,7 @@
"core.app.have_saved": "Saved", "core.app.have_saved": "Saved",
"core.app.logs.Source And Time": "Source & Time", "core.app.logs.Source And Time": "Source & Time",
"core.app.more": "View More", "core.app.more": "View More",
"core.app.name": "name",
"core.app.no_app": "No Apps Yet, Create One Now!", "core.app.no_app": "No Apps Yet, Create One Now!",
"core.app.not_saved": "Not Saved", "core.app.not_saved": "Not Saved",
"core.app.outLink.Can Drag": "Icon Can Be Dragged", "core.app.outLink.Can Drag": "Icon Can Be Dragged",
...@@ -1145,10 +1145,10 @@ ...@@ -1145,10 +1145,10 @@
"support.wallet.subscription.Upgrade plan": "Upgrade Package", "support.wallet.subscription.Upgrade plan": "Upgrade Package",
"support.wallet.subscription.ai_model": "AI Language Model", "support.wallet.subscription.ai_model": "AI Language Model",
"support.wallet.subscription.function.History store": "{{amount}} Days of Chat History Retention", "support.wallet.subscription.function.History store": "{{amount}} Days of Chat History Retention",
"support.wallet.subscription.function.Max app": "{{amount}} Apps & Plugins", "support.wallet.subscription.function.Max app": "{{amount}} App limit",
"support.wallet.subscription.function.Max dataset": "{{amount}} Datasets", "support.wallet.subscription.function.Max dataset": "{{amount}} Dataset limit",
"support.wallet.subscription.function.Max dataset size": "{{amount}} Dataset Indexes", "support.wallet.subscription.function.Max dataset size": "{{amount}} Dataset Indexes",
"support.wallet.subscription.function.Max members": "{{amount}} Team Members", "support.wallet.subscription.function.Max members": "{{amount}} Member limit",
"support.wallet.subscription.function.Points": "{{amount}} AI Points", "support.wallet.subscription.function.Points": "{{amount}} AI Points",
"support.wallet.subscription.mode.Month": "Month", "support.wallet.subscription.mode.Month": "Month",
"support.wallet.subscription.mode.Period": "Subscription Period", "support.wallet.subscription.mode.Period": "Subscription Period",
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
"ai_points_calculation_standard": "AI 积分", "ai_points_calculation_standard": "AI 积分",
"ai_points_usage": "AI 积分使用量", "ai_points_usage": "AI 积分使用量",
"ai_points_usage_tip": "每次调用 AI 模型时,都会消耗一定的 AI 积分。具体的计算标准可参考上方的“计费标准”。", "ai_points_usage_tip": "每次调用 AI 模型时,都会消耗一定的 AI 积分。具体的计算标准可参考上方的“计费标准”。",
"app_amount": "应用数量",
"avatar": "头像", "avatar": "头像",
"avatar_selection_exception": "头像选择异常", "avatar_selection_exception": "头像选择异常",
"balance": "余额", "balance": "余额",
...@@ -21,6 +22,7 @@ ...@@ -21,6 +22,7 @@
"contact_us": "联系我们", "contact_us": "联系我们",
"current_package": "当前套餐", "current_package": "当前套餐",
"current_token_price": "当前积分价格", "current_token_price": "当前积分价格",
"dataset_amount": "知识库数量",
"effective_time": "生效时间", "effective_time": "生效时间",
"email_label": "邮箱", "email_label": "邮箱",
"exchange": "兑换", "exchange": "兑换",
...@@ -34,6 +36,7 @@ ...@@ -34,6 +36,7 @@
"help_document": "帮助文档", "help_document": "帮助文档",
"knowledge_base_capacity": "知识库容量", "knowledge_base_capacity": "知识库容量",
"manage": "管理", "manage": "管理",
"member_amount": "成员数量",
"member_name": "成员名", "member_name": "成员名",
"month": "月", "month": "月",
"new_password": "新密码", "new_password": "新密码",
...@@ -53,7 +56,9 @@ ...@@ -53,7 +56,9 @@
"please_bind_contact": "请绑定联系方式", "please_bind_contact": "请绑定联系方式",
"please_bind_notification_receiving_path": "请先绑定通知接收途径", "please_bind_notification_receiving_path": "请先绑定通知接收途径",
"purchase_extra_package": "购买额外套餐", "purchase_extra_package": "购买额外套餐",
"redeem_coupon": "兑换码",
"reminder_create_bound_notification_account": "提醒创建者绑定通知账号", "reminder_create_bound_notification_account": "提醒创建者绑定通知账号",
"reset_password": "重置密码",
"resource_usage": "资源用量", "resource_usage": "资源用量",
"select_avatar": "点击选择头像", "select_avatar": "点击选择头像",
"standard_package_and_extra_resource_package": "包含标准套餐与额外资源包", "standard_package_and_extra_resource_package": "包含标准套餐与额外资源包",
...@@ -65,7 +70,6 @@ ...@@ -65,7 +70,6 @@
"type": "类型", "type": "类型",
"unlimited": "无限制", "unlimited": "无限制",
"update_password": "修改密码", "update_password": "修改密码",
"reset_password": "重置密码",
"update_success_tip": "更新数据成功", "update_success_tip": "更新数据成功",
"upgrade_package": "升级套餐", "upgrade_package": "升级套餐",
"usage_balance": "使用余额: 使用余额", "usage_balance": "使用余额: 使用余额",
...@@ -74,6 +78,5 @@ ...@@ -74,6 +78,5 @@
"user_team_team_name": "团队", "user_team_team_name": "团队",
"verification_code": "验证码", "verification_code": "验证码",
"you_can_convert": "您可以兑换", "you_can_convert": "您可以兑换",
"yuan": "元", "yuan": "元"
"redeem_coupon": "兑换码"
} }
...@@ -1145,10 +1145,10 @@ ...@@ -1145,10 +1145,10 @@
"support.wallet.subscription.Upgrade plan": "升级套餐", "support.wallet.subscription.Upgrade plan": "升级套餐",
"support.wallet.subscription.ai_model": "AI语言模型", "support.wallet.subscription.ai_model": "AI语言模型",
"support.wallet.subscription.function.History store": "{{amount}} 天对话记录保留", "support.wallet.subscription.function.History store": "{{amount}} 天对话记录保留",
"support.wallet.subscription.function.Max app": "{{amount}} 个应用&插件", "support.wallet.subscription.function.Max app": "{{amount}} 个应用上限",
"support.wallet.subscription.function.Max dataset": "{{amount}} 个知识库", "support.wallet.subscription.function.Max dataset": "{{amount}} 个知识库上限",
"support.wallet.subscription.function.Max dataset size": "{{amount}} 组知识库索引", "support.wallet.subscription.function.Max dataset size": "{{amount}} 组知识库索引",
"support.wallet.subscription.function.Max members": "{{amount}} 个团队成员", "support.wallet.subscription.function.Max members": "{{amount}} 个团队成员上限",
"support.wallet.subscription.function.Points": "{{amount}} AI 积分", "support.wallet.subscription.function.Points": "{{amount}} AI 积分",
"support.wallet.subscription.mode.Month": "按月", "support.wallet.subscription.mode.Month": "按月",
"support.wallet.subscription.mode.Period": "订阅周期", "support.wallet.subscription.mode.Period": "订阅周期",
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
"ai_points_calculation_standard": "AI 積分", "ai_points_calculation_standard": "AI 積分",
"ai_points_usage": "AI 積分使用量", "ai_points_usage": "AI 積分使用量",
"ai_points_usage_tip": "每次呼叫 AI 模型時,都會消耗一定的 AI 積分。\n具體的計算標準可參考上方的「計費標準」。", "ai_points_usage_tip": "每次呼叫 AI 模型時,都會消耗一定的 AI 積分。\n具體的計算標準可參考上方的「計費標準」。",
"app_amount": "應用數量",
"avatar": "頭像", "avatar": "頭像",
"avatar_selection_exception": "頭像選擇異常", "avatar_selection_exception": "頭像選擇異常",
"balance": "餘額", "balance": "餘額",
...@@ -21,6 +22,7 @@ ...@@ -21,6 +22,7 @@
"contact_us": "聯絡我們", "contact_us": "聯絡我們",
"current_package": "目前套餐", "current_package": "目前套餐",
"current_token_price": "目前積分價格", "current_token_price": "目前積分價格",
"dataset_amount": "知識庫數量",
"effective_time": "生效時間", "effective_time": "生效時間",
"email_label": "信箱", "email_label": "信箱",
"exchange": "兌換", "exchange": "兌換",
...@@ -34,6 +36,7 @@ ...@@ -34,6 +36,7 @@
"help_document": "幫助文件", "help_document": "幫助文件",
"knowledge_base_capacity": "知識庫容量", "knowledge_base_capacity": "知識庫容量",
"manage": "管理", "manage": "管理",
"member_amount": "成員數量",
"member_name": "成員名", "member_name": "成員名",
"month": "月", "month": "月",
"new_password": "新密碼", "new_password": "新密碼",
......
...@@ -215,7 +215,6 @@ ...@@ -215,7 +215,6 @@
"core.app.Interval timer run": "排程執行", "core.app.Interval timer run": "排程執行",
"core.app.Interval timer tip": "可排程執行應用程式", "core.app.Interval timer tip": "可排程執行應用程式",
"core.app.Make a brief introduction of your app": "為您的 AI 應用程式寫一段介紹", "core.app.Make a brief introduction of your app": "為您的 AI 應用程式寫一段介紹",
"core.app.name": "名稱",
"core.app.Name and avatar": "頭像與名稱", "core.app.Name and avatar": "頭像與名稱",
"core.app.Publish": "發布", "core.app.Publish": "發布",
"core.app.Publish Confirm": "確認發布應用程式?這將立即更新所有發布管道的應用程式狀態。", "core.app.Publish Confirm": "確認發布應用程式?這將立即更新所有發布管道的應用程式狀態。",
...@@ -261,6 +260,7 @@ ...@@ -261,6 +260,7 @@
"core.app.have_saved": "已儲存", "core.app.have_saved": "已儲存",
"core.app.logs.Source And Time": "來源與時間", "core.app.logs.Source And Time": "來源與時間",
"core.app.more": "檢視更多", "core.app.more": "檢視更多",
"core.app.name": "名稱",
"core.app.no_app": "還沒有應用程式,快來建立一個吧!", "core.app.no_app": "還沒有應用程式,快來建立一個吧!",
"core.app.not_saved": "未儲存", "core.app.not_saved": "未儲存",
"core.app.outLink.Can Drag": "圖示可拖曳", "core.app.outLink.Can Drag": "圖示可拖曳",
...@@ -1145,8 +1145,8 @@ ...@@ -1145,8 +1145,8 @@
"support.wallet.subscription.Upgrade plan": "升級方案", "support.wallet.subscription.Upgrade plan": "升級方案",
"support.wallet.subscription.ai_model": "AI 語言模型", "support.wallet.subscription.ai_model": "AI 語言模型",
"support.wallet.subscription.function.History store": "{{amount}} 天對話紀錄保留", "support.wallet.subscription.function.History store": "{{amount}} 天對話紀錄保留",
"support.wallet.subscription.function.Max app": "{{amount}} 個應用程式與外掛程式", "support.wallet.subscription.function.Max app": "{{amount}} 個應用上限",
"support.wallet.subscription.function.Max dataset": "{{amount}} 個知識庫", "support.wallet.subscription.function.Max dataset": "{{amount}} 個知識庫上限",
"support.wallet.subscription.function.Max dataset size": "{{amount}} 組知識庫索引", "support.wallet.subscription.function.Max dataset size": "{{amount}} 組知識庫索引",
"support.wallet.subscription.function.Max members": "{{amount}} 個團隊成員", "support.wallet.subscription.function.Max members": "{{amount}} 個團隊成員",
"support.wallet.subscription.function.Points": "{{amount}} AI 點數", "support.wallet.subscription.function.Points": "{{amount}} AI 點數",
......
...@@ -112,7 +112,7 @@ const RechargeModal = ({ ...@@ -112,7 +112,7 @@ const RechargeModal = ({
<Box>{`${t('common:support.user.team.Dataset usage')}:`}</Box> <Box>{`${t('common:support.user.team.Dataset usage')}:`}</Box>
<Box <Box
ml={2} ml={2}
>{`${teamPlanStatus?.usedDatasetSize} / ${teamPlanStatus?.datasetMaxSize || t('account_info:unlimited')}`}</Box> >{`${teamPlanStatus?.usedDatasetIndexSize} / ${teamPlanStatus?.datasetMaxSize || t('account_info:unlimited')}`}</Box>
<Box ml={5}>{`${t('common:support.wallet.subscription.AI points usage')}:`}</Box> <Box ml={5}>{`${t('common:support.wallet.subscription.AI points usage')}:`}</Box>
<Box <Box
ml={2} ml={2}
......
...@@ -8,6 +8,7 @@ import MyIcon from '@fastgpt/web/components/common/Icon'; ...@@ -8,6 +8,7 @@ import MyIcon from '@fastgpt/web/components/common/Icon';
import { useTranslation } from 'next-i18next'; import { useTranslation } from 'next-i18next';
import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip'; import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip';
import dynamic from 'next/dynamic'; import dynamic from 'next/dynamic';
import type { TeamSubSchema } from '@fastgpt/global/support/wallet/sub/type';
const ModelPriceModal = dynamic(() => const ModelPriceModal = dynamic(() =>
import('@/components/core/ai/ModelTable').then((mod) => mod.ModelPriceModal) import('@/components/core/ai/ModelTable').then((mod) => mod.ModelPriceModal)
...@@ -15,10 +16,12 @@ const ModelPriceModal = dynamic(() => ...@@ -15,10 +16,12 @@ const ModelPriceModal = dynamic(() =>
const StandardPlanContentList = ({ const StandardPlanContentList = ({
level, level,
mode mode,
standplan
}: { }: {
level: `${StandardSubLevelEnum}`; level: `${StandardSubLevelEnum}`;
mode: `${SubModeEnum}`; mode: `${SubModeEnum}`;
standplan?: TeamSubSchema;
}) => { }) => {
const { t } = useTranslation(); const { t } = useTranslation();
const { subPlans } = useSystemStore(); const { subPlans } = useSystemStore();
...@@ -31,9 +34,9 @@ const StandardPlanContentList = ({ ...@@ -31,9 +34,9 @@ const StandardPlanContentList = ({
price: plan.price * (mode === SubModeEnum.month ? 1 : 10), price: plan.price * (mode === SubModeEnum.month ? 1 : 10),
level: level as `${StandardSubLevelEnum}`, level: level as `${StandardSubLevelEnum}`,
...standardSubLevelMap[level as `${StandardSubLevelEnum}`], ...standardSubLevelMap[level as `${StandardSubLevelEnum}`],
maxTeamMember: plan.maxTeamMember, maxTeamMember: standplan?.maxTeamMember || plan.maxTeamMember,
maxAppAmount: plan.maxAppAmount, maxAppAmount: standplan?.maxApp || plan.maxAppAmount,
maxDatasetAmount: plan.maxDatasetAmount, maxDatasetAmount: standplan?.maxDataset || plan.maxDatasetAmount,
chatHistoryStoreDuration: plan.chatHistoryStoreDuration, chatHistoryStoreDuration: plan.chatHistoryStoreDuration,
maxDatasetSize: plan.maxDatasetSize, maxDatasetSize: plan.maxDatasetSize,
permissionCustomApiKey: plan.permissionCustomApiKey, permissionCustomApiKey: plan.permissionCustomApiKey,
...@@ -43,7 +46,14 @@ const StandardPlanContentList = ({ ...@@ -43,7 +46,14 @@ const StandardPlanContentList = ({
permissionWebsiteSync: plan.permissionWebsiteSync, permissionWebsiteSync: plan.permissionWebsiteSync,
permissionTeamOperationLog: plan.permissionTeamOperationLog permissionTeamOperationLog: plan.permissionTeamOperationLog
}; };
}, [subPlans?.standard, level, mode]); }, [
subPlans?.standard,
level,
mode,
standplan?.maxTeamMember,
standplan?.maxApp,
standplan?.maxDataset
]);
return planContent ? ( return planContent ? (
<Grid gap={4} fontSize={'sm'} fontWeight={500}> <Grid gap={4} fontSize={'sm'} fontWeight={500}>
......
'use client'; 'use client';
import React, { useCallback, useEffect, useMemo } from 'react'; import React, { useCallback, useMemo } from 'react';
import { import {
Box, Box,
Flex, Flex,
...@@ -70,10 +70,6 @@ const Info = () => { ...@@ -70,10 +70,6 @@ const Info = () => {
const standardPlan = teamPlanStatus?.standardConstants; const standardPlan = teamPlanStatus?.standardConstants;
const { isOpen: isOpenContact, onClose: onCloseContact, onOpen: onOpenContact } = useDisclosure(); const { isOpen: isOpenContact, onClose: onCloseContact, onOpen: onOpenContact } = useDisclosure();
useMount(() => {
initUserInfo();
});
return ( return (
<AccountContainer> <AccountContainer>
<Box py={[3, '28px']} px={[5, 10]} mx={'auto'}> <Box py={[3, '28px']} px={[5, 10]} mx={'auto'}>
...@@ -402,55 +398,77 @@ const PlanUsage = () => { ...@@ -402,55 +398,77 @@ const PlanUsage = () => {
} }
}); });
const datasetUsageMap = useMemo(() => { const valueColorSchema = useCallback((val: number) => {
if (val < 50) return 'green';
if (val < 80) return 'yellow';
return 'red';
}, []);
const datasetIndexUsageMap = useMemo(() => {
if (!teamPlanStatus) { if (!teamPlanStatus) {
return { return {
colorScheme: 'green',
value: 0, value: 0,
maxSize: t('account_info:unlimited'), max: t('account_info:unlimited'),
usedSize: 0 rate: 0
}; };
} }
const rate = teamPlanStatus.usedDatasetSize / teamPlanStatus.datasetMaxSize; const rate = teamPlanStatus.usedDatasetIndexSize / teamPlanStatus.datasetMaxSize;
const colorScheme = (() => {
if (rate < 0.5) return 'green';
if (rate < 0.8) return 'yellow';
return 'red';
})();
return { return {
colorScheme, value: teamPlanStatus.usedDatasetIndexSize,
value: rate * 100, rate: rate * 100,
maxSize: teamPlanStatus.datasetMaxSize || t('account_info:unlimited'), max: teamPlanStatus.datasetMaxSize || 1
usedSize: teamPlanStatus.usedDatasetSize
}; };
}, [teamPlanStatus, t]); }, [t, teamPlanStatus]);
const aiPointsUsageMap = useMemo(() => { const aiPointsUsageMap = useMemo(() => {
if (!teamPlanStatus) { if (!teamPlanStatus) {
return { return {
colorScheme: 'green',
value: 0, value: 0,
maxSize: t('account_info:unlimited'), max: t('account_info:unlimited'),
usedSize: 0 rate: 0
}; };
} }
const rate = teamPlanStatus.usedPoints / teamPlanStatus.totalPoints;
const colorScheme = (() => {
if (rate < 0.5) return 'green';
if (rate < 0.8) return 'yellow';
return 'red';
})();
return { return {
colorScheme, value: Math.round(teamPlanStatus.usedPoints),
value: rate * 100, max: teamPlanStatus.totalPoints,
max: teamPlanStatus.totalPoints ? teamPlanStatus.totalPoints : t('account_info:unlimited'), rate: (teamPlanStatus.usedPoints / teamPlanStatus.totalPoints) * 100
used: teamPlanStatus.usedPoints ? Math.round(teamPlanStatus.usedPoints) : 0
}; };
}, [teamPlanStatus, t]); }, [t, teamPlanStatus]);
const limitData = useMemo(() => {
if (!teamPlanStatus) {
return [];
}
return [
{
label: t('account_info:member_amount'),
value: teamPlanStatus.usedMember,
max: teamPlanStatus?.standardConstants?.maxTeamMember || t('account_info:unlimited'),
rate:
(teamPlanStatus.usedMember / (teamPlanStatus?.standardConstants?.maxTeamMember || 1)) *
100
},
{
label: t('account_info:app_amount'),
value: teamPlanStatus.usedAppAmount,
max: teamPlanStatus?.standardConstants?.maxAppAmount || t('account_info:unlimited'),
rate:
(teamPlanStatus.usedAppAmount / (teamPlanStatus?.standardConstants?.maxAppAmount || 1)) *
100
},
{
label: t('account_info:dataset_amount'),
value: teamPlanStatus.usedDatasetSize,
max: teamPlanStatus?.standardConstants?.maxDatasetAmount || t('account_info:unlimited'),
rate:
(teamPlanStatus.usedDatasetSize /
(teamPlanStatus?.standardConstants?.maxDatasetAmount || 1)) *
100
}
];
}, [t, teamPlanStatus]);
return standardPlan ? ( return standardPlan ? (
<Box mt={[6, 0]}> <Box mt={[6, 0]}>
...@@ -531,6 +549,7 @@ const PlanUsage = () => { ...@@ -531,6 +549,7 @@ const PlanUsage = () => {
<StandardPlanContentList <StandardPlanContentList
level={standardPlan?.currentSubLevel} level={standardPlan?.currentSubLevel}
mode={standardPlan.currentMode} mode={standardPlan.currentMode}
standplan={standardPlan}
/> />
</Box> </Box>
</Box> </Box>
...@@ -574,15 +593,15 @@ const PlanUsage = () => { ...@@ -574,15 +593,15 @@ const PlanUsage = () => {
{t('account_info:knowledge_base_capacity')} {t('account_info:knowledge_base_capacity')}
</Box> </Box>
<Box color={'myGray.600'} ml={2}> <Box color={'myGray.600'} ml={2}>
{datasetUsageMap.usedSize}/{datasetUsageMap.maxSize} {datasetIndexUsageMap.value}/{datasetIndexUsageMap.max}
</Box> </Box>
</Flex> </Flex>
</Flex> </Flex>
<Box mt={3}> <Box mt={1}>
<Progress <Progress
size={'sm'} size={'sm'}
value={datasetUsageMap.value} value={datasetIndexUsageMap.rate}
colorScheme={datasetUsageMap.colorScheme} colorScheme={valueColorSchema(datasetIndexUsageMap.rate)}
borderRadius={'md'} borderRadius={'md'}
isAnimated isAnimated
hasStripe hasStripe
...@@ -591,7 +610,7 @@ const PlanUsage = () => { ...@@ -591,7 +610,7 @@ const PlanUsage = () => {
/> />
</Box> </Box>
</Box> </Box>
<Box mt="9" width={'100%'} fontSize={'sm'}> <Box mt="6" width={'100%'} fontSize={'sm'}>
<Flex alignItems={'center'}> <Flex alignItems={'center'}>
<Flex alignItems={'center'}> <Flex alignItems={'center'}>
<Box fontWeight={'bold'} color={'myGray.900'}> <Box fontWeight={'bold'} color={'myGray.900'}>
...@@ -599,15 +618,15 @@ const PlanUsage = () => { ...@@ -599,15 +618,15 @@ const PlanUsage = () => {
</Box> </Box>
<QuestionTip ml={1} label={t('account_info:ai_points_usage_tip')}></QuestionTip> <QuestionTip ml={1} label={t('account_info:ai_points_usage_tip')}></QuestionTip>
<Box color={'myGray.600'} ml={2}> <Box color={'myGray.600'} ml={2}>
{aiPointsUsageMap.used}/{aiPointsUsageMap.max} {aiPointsUsageMap.value}/{aiPointsUsageMap.max}
</Box> </Box>
</Flex> </Flex>
</Flex> </Flex>
<Box mt={3}> <Box mt={1}>
<Progress <Progress
size={'sm'} size={'sm'}
value={aiPointsUsageMap.value} value={aiPointsUsageMap.rate}
colorScheme={aiPointsUsageMap.colorScheme} colorScheme={valueColorSchema(aiPointsUsageMap.rate)}
borderRadius={'md'} borderRadius={'md'}
isAnimated isAnimated
hasStripe hasStripe
...@@ -616,6 +635,42 @@ const PlanUsage = () => { ...@@ -616,6 +635,42 @@ const PlanUsage = () => {
/> />
</Box> </Box>
</Box> </Box>
<MyDivider />
{limitData.map((item) => {
return (
<Box
key={item.label}
_notFirst={{
mt: 4
}}
width={'100%'}
fontSize={'sm'}
>
<Flex alignItems={'center'}>
<Box fontWeight={'bold'} color={'myGray.900'}>
{item.label}
</Box>
<Box color={'myGray.600'} ml={2}>
{item.value}/{item.max}
</Box>
</Flex>
<Box mt={1}>
<Progress
size={'sm'}
value={item.rate}
colorScheme={valueColorSchema(item.rate)}
borderRadius={'md'}
isAnimated
hasStripe
borderWidth={'1px'}
borderColor={'borderColor.low'}
/>
</Box>
</Box>
);
})}
</Box> </Box>
{isOpenStandardModal && <StandDetailModal onClose={onCloseStandardModal} />} {isOpenStandardModal && <StandDetailModal onClose={onCloseStandardModal} />}
{isOpenRedeemCouponModal && ( {isOpenRedeemCouponModal && (
......
...@@ -12,7 +12,7 @@ import { getCollectionWithDataset } from '@fastgpt/service/core/dataset/controll ...@@ -12,7 +12,7 @@ import { getCollectionWithDataset } from '@fastgpt/service/core/dataset/controll
import { pushGenerateVectorUsage } from '@/service/support/wallet/usage/push'; import { pushGenerateVectorUsage } from '@/service/support/wallet/usage/push';
import type { InsertOneDatasetDataProps } from '@/global/core/dataset/api'; import type { InsertOneDatasetDataProps } from '@/global/core/dataset/api';
import { simpleText } from '@fastgpt/global/common/string/tools'; import { simpleText } from '@fastgpt/global/common/string/tools';
import { checkDatasetLimit } from '@fastgpt/service/support/permission/teamLimit'; import { checkDatasetIndexLimit } from '@fastgpt/service/support/permission/teamLimit';
import { NextAPI } from '@/service/middleware/entry'; import { NextAPI } from '@/service/middleware/entry';
import { WritePermissionVal } from '@fastgpt/global/support/permission/constant'; import { WritePermissionVal } from '@fastgpt/global/support/permission/constant';
import { CommonErrEnum } from '@fastgpt/global/common/error/code/common'; import { CommonErrEnum } from '@fastgpt/global/common/error/code/common';
...@@ -41,9 +41,9 @@ async function handler(req: NextApiRequest) { ...@@ -41,9 +41,9 @@ async function handler(req: NextApiRequest) {
per: WritePermissionVal per: WritePermissionVal
}); });
await checkDatasetLimit({ await checkDatasetIndexLimit({
teamId, teamId,
insertLen: 1 insertLen: 1 + (indexes?.length || 0)
}); });
const [ const [
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
import type { NextApiResponse } from 'next'; import type { NextApiResponse } from 'next';
import type { PushDatasetDataProps } from '@fastgpt/global/core/dataset/api.d'; import type { PushDatasetDataProps } from '@fastgpt/global/core/dataset/api.d';
import { authDatasetCollection } from '@fastgpt/service/support/permission/dataset/auth'; import { authDatasetCollection } from '@fastgpt/service/support/permission/dataset/auth';
import { checkDatasetLimit } from '@fastgpt/service/support/permission/teamLimit'; import { checkDatasetIndexLimit } from '@fastgpt/service/support/permission/teamLimit';
import { predictDataLimitLength } from '@fastgpt/global/core/dataset/utils'; import { predictDataLimitLength } from '@fastgpt/global/core/dataset/utils';
import { pushDataListToTrainingQueue } from '@fastgpt/service/core/dataset/training/controller'; import { pushDataListToTrainingQueue } from '@fastgpt/service/core/dataset/training/controller';
import { NextAPI } from '@/service/middleware/entry'; import { NextAPI } from '@/service/middleware/entry';
...@@ -35,7 +35,7 @@ async function handler(req: ApiRequestProps<PushDatasetDataProps>, res: NextApiR ...@@ -35,7 +35,7 @@ async function handler(req: ApiRequestProps<PushDatasetDataProps>, res: NextApiR
}); });
// auth dataset limit // auth dataset limit
await checkDatasetLimit({ await checkDatasetIndexLimit({
teamId, teamId,
insertLen: predictDataLimitLength(getTrainingModeByCollection(collection), data) insertLen: predictDataLimitLength(getTrainingModeByCollection(collection), data)
}); });
......
...@@ -2,7 +2,7 @@ import type { NextApiRequest, NextApiResponse } from 'next'; ...@@ -2,7 +2,7 @@ import type { NextApiRequest, NextApiResponse } from 'next';
import { jsonRes } from '@fastgpt/service/common/response'; import { jsonRes } from '@fastgpt/service/common/response';
import { authCert } from '@fastgpt/service/support/permission/auth/common'; import { authCert } from '@fastgpt/service/support/permission/auth/common';
import { checkDatasetLimit } from '@fastgpt/service/support/permission/teamLimit'; import { checkDatasetIndexLimit } from '@fastgpt/service/support/permission/teamLimit';
export default async function handler(req: NextApiRequest, res: NextApiResponse<any>) { export default async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
try { try {
...@@ -19,7 +19,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse< ...@@ -19,7 +19,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
const numberSize = Number(size); const numberSize = Number(size);
await checkDatasetLimit({ await checkDatasetIndexLimit({
teamId, teamId,
insertLen: numberSize insertLen: numberSize
}); });
......
...@@ -2,17 +2,53 @@ import type { NextApiRequest, NextApiResponse } from 'next'; ...@@ -2,17 +2,53 @@ import type { NextApiRequest, NextApiResponse } from 'next';
import { authCert } from '@fastgpt/service/support/permission/auth/common'; import { authCert } from '@fastgpt/service/support/permission/auth/common';
import { getTeamPlanStatus } from '@fastgpt/service/support/wallet/sub/utils'; import { getTeamPlanStatus } from '@fastgpt/service/support/wallet/sub/utils';
import { NextAPI } from '@/service/middleware/entry'; import { NextAPI } from '@/service/middleware/entry';
import type { ClientTeamPlanStatusType } from '@fastgpt/global/support/wallet/sub/type';
import { MongoApp } from '@fastgpt/service/core/app/schema';
import { AppTypeEnum } from '@fastgpt/global/core/app/constants';
import { MongoDataset } from '@fastgpt/service/core/dataset/schema';
import { DatasetTypeEnum } from '@fastgpt/global/core/dataset/constants';
import { getVectorCountByTeamId } from '@fastgpt/service/common/vectorDB/controller';
import { MongoTeamMember } from '@fastgpt/service/support/user/team/teamMemberSchema';
import { TeamMemberStatusEnum } from '@fastgpt/global/support/user/team/constant';
async function handler(req: NextApiRequest, res: NextApiResponse<any>) { async function handler(
req: NextApiRequest,
res: NextApiResponse<any>
): Promise<ClientTeamPlanStatusType | undefined> {
try { try {
const { teamId } = await authCert({ const { teamId } = await authCert({
req, req,
authToken: true authToken: true
}); });
return getTeamPlanStatus({ const [planStatus, usedMember, usedAppAmount, usedDatasetSize, usedDatasetIndexSize] =
teamId await Promise.all([
}); getTeamPlanStatus({
teamId
}),
MongoTeamMember.countDocuments({
teamId,
status: { $ne: TeamMemberStatusEnum.leave }
}),
MongoApp.countDocuments({
teamId,
type: {
$in: [AppTypeEnum.simple, AppTypeEnum.workflow, AppTypeEnum.plugin, AppTypeEnum.tool]
}
}),
MongoDataset.countDocuments({
type: { $ne: DatasetTypeEnum.folder }
}),
getVectorCountByTeamId(teamId)
]);
return {
...planStatus,
usedMember,
usedAppAmount,
usedDatasetSize,
usedDatasetIndexSize
};
} catch (error) {} } catch (error) {}
} }
......
...@@ -73,13 +73,11 @@ const formatIndexes = async ({ ...@@ -73,13 +73,11 @@ const formatIndexes = async ({
}; };
// If index not type, set it to custom // If index not type, set it to custom
indexes = indexes indexes = indexes.map((item) => ({
.map((item) => ({ text: typeof item.text === 'string' ? item.text : String(item.text),
text: typeof item.text === 'string' ? item.text : String(item.text), type: item.type || DatasetDataIndexTypeEnum.custom,
type: item.type || DatasetDataIndexTypeEnum.custom, dataId: item.dataId
dataId: item.dataId }));
}))
.filter((item) => !!item.text.trim());
// Recompute default indexes, Merge ids of the same index, reduce the number of rebuilds // Recompute default indexes, Merge ids of the same index, reduce the number of rebuilds
const defaultIndexes = await getDefaultIndex({ q, a, indexSize }); const defaultIndexes = await getDefaultIndex({ q, a, indexSize });
...@@ -134,7 +132,7 @@ const formatIndexes = async ({ ...@@ -134,7 +132,7 @@ const formatIndexes = async ({
) )
).flat(); ).flat();
return chekcIndexes; return chekcIndexes.filter((item) => !!item.text.trim());
}; };
/* insert data. /* insert data.
* 1. create data id * 1. create data id
......
...@@ -20,7 +20,7 @@ import { delay } from '@fastgpt/service/common/bullmq'; ...@@ -20,7 +20,7 @@ import { delay } from '@fastgpt/service/common/bullmq';
import { rawText2Chunks, readDatasetSourceRawText } from '@fastgpt/service/core/dataset/read'; import { rawText2Chunks, readDatasetSourceRawText } from '@fastgpt/service/core/dataset/read';
import { getLLMModel } from '@fastgpt/service/core/ai/model'; import { getLLMModel } from '@fastgpt/service/core/ai/model';
import { getLLMMaxChunkSize } from '@fastgpt/global/core/dataset/training/utils'; import { getLLMMaxChunkSize } from '@fastgpt/global/core/dataset/training/utils';
import { checkDatasetLimit } from '@fastgpt/service/support/permission/teamLimit'; import { checkDatasetIndexLimit } from '@fastgpt/service/support/permission/teamLimit';
import { predictDataLimitLength } from '@fastgpt/global/core/dataset/utils'; import { predictDataLimitLength } from '@fastgpt/global/core/dataset/utils';
import { getTrainingModeByCollection } from '@fastgpt/service/core/dataset/collection/utils'; import { getTrainingModeByCollection } from '@fastgpt/service/core/dataset/collection/utils';
import { pushDataListToTrainingQueue } from '@fastgpt/service/core/dataset/training/controller'; import { pushDataListToTrainingQueue } from '@fastgpt/service/core/dataset/training/controller';
...@@ -258,7 +258,7 @@ export const datasetParseQueue = async (): Promise<any> => { ...@@ -258,7 +258,7 @@ export const datasetParseQueue = async (): Promise<any> => {
// Check dataset limit // Check dataset limit
try { try {
await checkDatasetLimit({ await checkDatasetIndexLimit({
teamId: data.teamId, teamId: data.teamId,
insertLen: predictDataLimitLength(trainingMode, chunks) insertLen: predictDataLimitLength(trainingMode, chunks)
}); });
......
...@@ -15,7 +15,10 @@ import type { ...@@ -15,7 +15,10 @@ import type {
TeamMemberItemType, TeamMemberItemType,
TeamMemberSchema TeamMemberSchema
} from '@fastgpt/global/support/user/team/type.d'; } from '@fastgpt/global/support/user/team/type.d';
import type { FeTeamPlanStatusType, TeamSubSchema } from '@fastgpt/global/support/wallet/sub/type'; import type {
ClientTeamPlanStatusType,
TeamSubSchema
} from '@fastgpt/global/support/wallet/sub/type';
import type { TeamInvoiceHeaderType } from '@fastgpt/global/support/user/team/type'; import type { TeamInvoiceHeaderType } from '@fastgpt/global/support/user/team/type';
import type { PaginationProps, PaginationResponse } from '@fastgpt/web/common/fetch/type'; import type { PaginationProps, PaginationResponse } from '@fastgpt/web/common/fetch/type';
import type { import type {
...@@ -100,7 +103,7 @@ export const checkTeamDatasetSizeLimit = (size: number) => ...@@ -100,7 +103,7 @@ export const checkTeamDatasetSizeLimit = (size: number) =>
/* plans */ /* plans */
export const getTeamPlanStatus = () => export const getTeamPlanStatus = () =>
GET<FeTeamPlanStatusType>(`/support/user/team/plan/getTeamPlanStatus`, { maxQuantity: 1 }); GET<ClientTeamPlanStatusType>(`/support/user/team/plan/getTeamPlanStatus`, { maxQuantity: 1 });
export const getTeamPlans = () => export const getTeamPlans = () =>
GET<TeamSubSchema[]>(`/proApi/support/user/team/plan/getTeamPlans`); GET<TeamSubSchema[]>(`/proApi/support/user/team/plan/getTeamPlans`);
......
import { create, devtools, persist, immer } from '@fastgpt/web/common/zustand'; import { create, devtools, persist, immer } from '@fastgpt/web/common/zustand';
import type { UserUpdateParams } from '@/types/user'; import type { UserUpdateParams } from '@/types/user';
import { useSystemStore } from '@/web/common/system/useSystemStore';
import { getTokenLogin, putUserInfo } from '@/web/support/user/api'; import { getTokenLogin, putUserInfo } from '@/web/support/user/api';
import type { OrgType } from '@fastgpt/global/support/user/team/org/type'; import type { OrgType } from '@fastgpt/global/support/user/team/org/type';
import type { UserType } from '@fastgpt/global/support/user/type.d'; import type { UserType } from '@fastgpt/global/support/user/type.d';
import type { FeTeamPlanStatusType } from '@fastgpt/global/support/wallet/sub/type'; import type { ClientTeamPlanStatusType } from '@fastgpt/global/support/wallet/sub/type';
import { getTeamPlanStatus } from './team/api'; import { getTeamPlanStatus } from './team/api';
import { getGroupList } from './team/group/api';
type State = { type State = {
systemMsgReadId: string; systemMsgReadId: string;
...@@ -22,7 +20,7 @@ type State = { ...@@ -22,7 +20,7 @@ type State = {
setUserInfo: (user: UserType | null) => void; setUserInfo: (user: UserType | null) => void;
updateUserInfo: (user: UserUpdateParams) => Promise<void>; updateUserInfo: (user: UserUpdateParams) => Promise<void>;
teamPlanStatus: FeTeamPlanStatusType | null; teamPlanStatus: ClientTeamPlanStatusType | null;
initTeamPlanStatus: () => Promise<any>; initTeamPlanStatus: () => Promise<any>;
teamOrgs: OrgType[]; teamOrgs: OrgType[];
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment