mirror of
https://github.com/labring/FastGPT.git
synced 2025-10-15 15:41:05 +00:00
feat: more sub plan info;fix: emprt index (#4997)
* feat: more sub plan info * fix: emprt index * doc
This commit is contained in:
13
packages/global/support/wallet/sub/type.d.ts
vendored
13
packages/global/support/wallet/sub/type.d.ts
vendored
@@ -45,6 +45,9 @@ export type TeamSubSchema = {
|
||||
nextMode: `${SubModeEnum}`;
|
||||
currentSubLevel: StandardSubLevelEnum;
|
||||
nextSubLevel: StandardSubLevelEnum;
|
||||
maxTeamMember?: number;
|
||||
maxApp?: number;
|
||||
maxDataset?: number;
|
||||
|
||||
totalPoints: number;
|
||||
surplusPoints: number;
|
||||
@@ -52,7 +55,7 @@ export type TeamSubSchema = {
|
||||
currentExtraDatasetSize: number;
|
||||
};
|
||||
|
||||
export type FeTeamPlanStatusType = {
|
||||
export type TeamPlanStatusType = {
|
||||
[SubTypeEnum.standard]?: TeamSubSchema;
|
||||
standardConstants?: TeamStandardSubPlanItemType;
|
||||
|
||||
@@ -61,5 +64,11 @@ export type FeTeamPlanStatusType = {
|
||||
|
||||
// standard + extra
|
||||
datasetMaxSize: number;
|
||||
usedDatasetSize: number;
|
||||
};
|
||||
|
||||
export type ClientTeamPlanStatusType = TeamPlanStatusType & {
|
||||
usedMember: number;
|
||||
usedAppAmount: number;
|
||||
usedDatasetSize: number;
|
||||
usedDatasetIndexSize: number;
|
||||
};
|
||||
|
@@ -18,7 +18,7 @@ import { BucketNameEnum } from '@fastgpt/global/common/file/constants';
|
||||
import type { ClientSession } from '../../../common/mongo';
|
||||
import { createOrGetCollectionTags } from './utils';
|
||||
import { rawText2Chunks } from '../read';
|
||||
import { checkDatasetLimit } from '../../../support/permission/teamLimit';
|
||||
import { checkDatasetIndexLimit } from '../../../support/permission/teamLimit';
|
||||
import { predictDataLimitLength } from '../../../../global/core/dataset/utils';
|
||||
import { mongoSessionRun } from '../../../common/mongo/sessionRun';
|
||||
import { createTrainingUsage } from '../../../support/wallet/usage/controller';
|
||||
@@ -166,7 +166,7 @@ export const createCollectionAndInsertData = async ({
|
||||
})();
|
||||
|
||||
// 2. auth limit
|
||||
await checkDatasetLimit({
|
||||
await checkDatasetIndexLimit({
|
||||
teamId,
|
||||
insertLen: predictDataLimitLength(trainingMode, chunks)
|
||||
});
|
||||
|
@@ -199,7 +199,7 @@ export const rawText2Chunks = async ({
|
||||
.map((item) => ({
|
||||
q: item[0] || '',
|
||||
a: item[1] || '',
|
||||
indexes: item.slice(2),
|
||||
indexes: item.slice(2).filter((item) => item.trim()),
|
||||
imageIdList
|
||||
}))
|
||||
.filter((item) => item.q || item.a);
|
||||
|
@@ -83,8 +83,7 @@ const TrainingDataSchema = new Schema({
|
||||
enum: Object.values(DatasetDataIndexTypeEnum)
|
||||
},
|
||||
text: {
|
||||
type: String,
|
||||
required: true
|
||||
type: String
|
||||
}
|
||||
}
|
||||
],
|
||||
|
@@ -5,28 +5,9 @@ import { DatasetTypeEnum } from '@fastgpt/global/core/dataset/constants';
|
||||
import { TeamErrEnum } from '@fastgpt/global/common/error/code/team';
|
||||
import { SystemErrEnum } from '@fastgpt/global/common/error/code/system';
|
||||
import { AppTypeEnum } from '@fastgpt/global/core/app/constants';
|
||||
|
||||
export const checkDatasetLimit = async ({
|
||||
teamId,
|
||||
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;
|
||||
};
|
||||
import { MongoTeamMember } from '../user/team/teamMemberSchema';
|
||||
import { TeamMemberStatusEnum } from '@fastgpt/global/support/user/team/constant';
|
||||
import { getVectorCountByTeamId } from '../../common/vectorDB/controller';
|
||||
|
||||
export const checkTeamAIPoints = async (teamId: string) => {
|
||||
const { standardConstants, totalPoints, usedPoints } = await getTeamPlanStatus({
|
||||
@@ -45,6 +26,72 @@ export const checkTeamAIPoints = async (teamId: string) => {
|
||||
};
|
||||
};
|
||||
|
||||
export const checkTeamMemberLimit = async (teamId: string, newCount: number) => {
|
||||
const [{ standardConstants }, memberCount] = await Promise.all([
|
||||
getTeamStandPlan({
|
||||
teamId
|
||||
}),
|
||||
MongoTeamMember.countDocuments({
|
||||
teamId,
|
||||
status: { $ne: TeamMemberStatusEnum.leave }
|
||||
})
|
||||
]);
|
||||
|
||||
if (standardConstants && newCount + memberCount > standardConstants.maxTeamMember) {
|
||||
return Promise.reject(TeamErrEnum.teamOverSize);
|
||||
}
|
||||
};
|
||||
|
||||
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, 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);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
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 }),
|
||||
@@ -74,30 +121,12 @@ export const checkTeamDatasetLimit = async (teamId: string) => {
|
||||
}
|
||||
};
|
||||
|
||||
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, AppTypeEnum.tool]
|
||||
}
|
||||
})
|
||||
]);
|
||||
export const checkTeamWebSyncPermission = async (teamId: string) => {
|
||||
const { standardConstants } = await getTeamStandPlan({
|
||||
teamId
|
||||
});
|
||||
|
||||
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);
|
||||
}
|
||||
if (standardConstants && !standardConstants?.permissionWebsiteSync) {
|
||||
return Promise.reject(TeamErrEnum.websiteSyncNotEnough);
|
||||
}
|
||||
};
|
||||
|
@@ -52,6 +52,9 @@ const SubSchema = new Schema({
|
||||
type: String,
|
||||
enum: Object.values(StandardSubLevelEnum)
|
||||
},
|
||||
maxTeamMember: Number,
|
||||
maxApp: Number,
|
||||
maxDataset: Number,
|
||||
|
||||
// stand sub and extra points sub. Plan total points
|
||||
totalPoints: {
|
||||
|
@@ -6,10 +6,9 @@ import {
|
||||
} from '@fastgpt/global/support/wallet/sub/constants';
|
||||
import { MongoTeamSub } from './schema';
|
||||
import {
|
||||
type FeTeamPlanStatusType,
|
||||
type TeamPlanStatusType,
|
||||
type TeamSubSchema
|
||||
} from '@fastgpt/global/support/wallet/sub/type.d';
|
||||
import { getVectorCountByTeamId } from '../../../common/vectorDB/controller';
|
||||
import dayjs from 'dayjs';
|
||||
import { type ClientSession } from '../../../common/mongo';
|
||||
import { addMonths } from 'date-fns';
|
||||
@@ -44,12 +43,21 @@ export const getTeamStandPlan = async ({ teamId }: { teamId: string }) => {
|
||||
const standardPlans = global.subPlans?.standard;
|
||||
const standard = plans[0];
|
||||
|
||||
const standardConstants =
|
||||
standard?.currentSubLevel && standardPlans
|
||||
? standardPlans[standard.currentSubLevel]
|
||||
: undefined;
|
||||
|
||||
return {
|
||||
[SubTypeEnum.standard]: standard,
|
||||
standardConstants:
|
||||
standard?.currentSubLevel && standardPlans
|
||||
? standardPlans[standard.currentSubLevel]
|
||||
: undefined
|
||||
standardConstants: standardConstants
|
||||
? {
|
||||
...standardConstants,
|
||||
maxTeamMember: standard?.maxTeamMember || standardConstants.maxTeamMember,
|
||||
maxAppAmount: standard?.maxApp || standardConstants.maxAppAmount,
|
||||
maxDatasetAmount: standard?.maxDataset || standardConstants.maxDatasetAmount
|
||||
}
|
||||
: undefined
|
||||
};
|
||||
};
|
||||
|
||||
@@ -111,14 +119,11 @@ export const getTeamPlanStatus = async ({
|
||||
teamId
|
||||
}: {
|
||||
teamId: string;
|
||||
}): Promise<FeTeamPlanStatusType> => {
|
||||
}): Promise<TeamPlanStatusType> => {
|
||||
const standardPlans = global.subPlans?.standard;
|
||||
|
||||
/* Get all plans and datasetSize */
|
||||
const [plans, usedDatasetSize] = await Promise.all([
|
||||
MongoTeamSub.find({ teamId }).lean(),
|
||||
getVectorCountByTeamId(teamId)
|
||||
]);
|
||||
const plans = await MongoTeamSub.find({ teamId }).lean();
|
||||
|
||||
/* Get all standardPlans and active standardPlan */
|
||||
const teamStandardPlans = sortStandPlans(
|
||||
@@ -158,17 +163,25 @@ export const getTeamPlanStatus = async ({
|
||||
standardMaxDatasetSize +
|
||||
extraDatasetSize.reduce((acc, cur) => acc + (cur.currentExtraDatasetSize || 0), 0);
|
||||
|
||||
const standardConstants =
|
||||
standardPlan?.currentSubLevel && standardPlans
|
||||
? standardPlans[standardPlan.currentSubLevel]
|
||||
: undefined;
|
||||
|
||||
return {
|
||||
[SubTypeEnum.standard]: standardPlan,
|
||||
standardConstants:
|
||||
standardPlan?.currentSubLevel && standardPlans
|
||||
? standardPlans[standardPlan.currentSubLevel]
|
||||
: undefined,
|
||||
standardConstants: standardConstants
|
||||
? {
|
||||
...standardConstants,
|
||||
maxTeamMember: standardPlan?.maxTeamMember || standardConstants.maxTeamMember,
|
||||
maxAppAmount: standardPlan?.maxApp || standardConstants.maxAppAmount,
|
||||
maxDatasetAmount: standardPlan?.maxDataset || standardConstants.maxDatasetAmount
|
||||
}
|
||||
: undefined,
|
||||
|
||||
totalPoints,
|
||||
usedPoints: totalPoints - surplusPoints,
|
||||
|
||||
datasetMaxSize: totalDatasetSize,
|
||||
usedDatasetSize
|
||||
datasetMaxSize: totalDatasetSize
|
||||
};
|
||||
};
|
||||
|
@@ -14,7 +14,10 @@ export const getSafeEnv = () => {
|
||||
return {
|
||||
LOG_LEVEL: process.env.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 @@
|
||||
"ai_points_calculation_standard": "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.",
|
||||
"app_amount": "App amount",
|
||||
"avatar": "Avatar",
|
||||
"avatar_selection_exception": "Abnormal avatar selection",
|
||||
"balance": "balance",
|
||||
@@ -21,6 +22,7 @@
|
||||
"contact_us": "Contact us",
|
||||
"current_package": "Current plan",
|
||||
"current_token_price": "Current points price",
|
||||
"dataset_amount": "Dataset amount",
|
||||
"effective_time": "Effective time",
|
||||
"email_label": "Mail",
|
||||
"exchange": "Exchange",
|
||||
@@ -34,6 +36,7 @@
|
||||
"help_document": "Help documentation",
|
||||
"knowledge_base_capacity": "Dataset usages",
|
||||
"manage": "Manage",
|
||||
"member_amount": "Member amount",
|
||||
"member_name": "Name",
|
||||
"month": "moon",
|
||||
"new_password": "New Password",
|
||||
|
@@ -215,7 +215,6 @@
|
||||
"core.app.Interval timer run": "Scheduled Execution",
|
||||
"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.name": "name",
|
||||
"core.app.Name and avatar": "Avatar & Name",
|
||||
"core.app.Publish": "Publish",
|
||||
"core.app.Publish Confirm": "Confirm to Publish App? This Will Immediately Update the App Status on All Publishing Channels.",
|
||||
@@ -261,6 +260,7 @@
|
||||
"core.app.have_saved": "Saved",
|
||||
"core.app.logs.Source And Time": "Source & Time",
|
||||
"core.app.more": "View More",
|
||||
"core.app.name": "name",
|
||||
"core.app.no_app": "No Apps Yet, Create One Now!",
|
||||
"core.app.not_saved": "Not Saved",
|
||||
"core.app.outLink.Can Drag": "Icon Can Be Dragged",
|
||||
@@ -1145,10 +1145,10 @@
|
||||
"support.wallet.subscription.Upgrade plan": "Upgrade Package",
|
||||
"support.wallet.subscription.ai_model": "AI Language Model",
|
||||
"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 dataset": "{{amount}} Datasets",
|
||||
"support.wallet.subscription.function.Max app": "{{amount}} App limit",
|
||||
"support.wallet.subscription.function.Max dataset": "{{amount}} Dataset limit",
|
||||
"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.mode.Month": "Month",
|
||||
"support.wallet.subscription.mode.Period": "Subscription Period",
|
||||
|
@@ -6,6 +6,7 @@
|
||||
"ai_points_calculation_standard": "AI 积分",
|
||||
"ai_points_usage": "AI 积分使用量",
|
||||
"ai_points_usage_tip": "每次调用 AI 模型时,都会消耗一定的 AI 积分。具体的计算标准可参考上方的“计费标准”。",
|
||||
"app_amount": "应用数量",
|
||||
"avatar": "头像",
|
||||
"avatar_selection_exception": "头像选择异常",
|
||||
"balance": "余额",
|
||||
@@ -21,6 +22,7 @@
|
||||
"contact_us": "联系我们",
|
||||
"current_package": "当前套餐",
|
||||
"current_token_price": "当前积分价格",
|
||||
"dataset_amount": "知识库数量",
|
||||
"effective_time": "生效时间",
|
||||
"email_label": "邮箱",
|
||||
"exchange": "兑换",
|
||||
@@ -34,6 +36,7 @@
|
||||
"help_document": "帮助文档",
|
||||
"knowledge_base_capacity": "知识库容量",
|
||||
"manage": "管理",
|
||||
"member_amount": "成员数量",
|
||||
"member_name": "成员名",
|
||||
"month": "月",
|
||||
"new_password": "新密码",
|
||||
@@ -53,7 +56,9 @@
|
||||
"please_bind_contact": "请绑定联系方式",
|
||||
"please_bind_notification_receiving_path": "请先绑定通知接收途径",
|
||||
"purchase_extra_package": "购买额外套餐",
|
||||
"redeem_coupon": "兑换码",
|
||||
"reminder_create_bound_notification_account": "提醒创建者绑定通知账号",
|
||||
"reset_password": "重置密码",
|
||||
"resource_usage": "资源用量",
|
||||
"select_avatar": "点击选择头像",
|
||||
"standard_package_and_extra_resource_package": "包含标准套餐与额外资源包",
|
||||
@@ -65,7 +70,6 @@
|
||||
"type": "类型",
|
||||
"unlimited": "无限制",
|
||||
"update_password": "修改密码",
|
||||
"reset_password": "重置密码",
|
||||
"update_success_tip": "更新数据成功",
|
||||
"upgrade_package": "升级套餐",
|
||||
"usage_balance": "使用余额: 使用余额",
|
||||
@@ -74,6 +78,5 @@
|
||||
"user_team_team_name": "团队",
|
||||
"verification_code": "验证码",
|
||||
"you_can_convert": "您可以兑换",
|
||||
"yuan": "元",
|
||||
"redeem_coupon": "兑换码"
|
||||
"yuan": "元"
|
||||
}
|
||||
|
@@ -1145,10 +1145,10 @@
|
||||
"support.wallet.subscription.Upgrade plan": "升级套餐",
|
||||
"support.wallet.subscription.ai_model": "AI语言模型",
|
||||
"support.wallet.subscription.function.History store": "{{amount}} 天对话记录保留",
|
||||
"support.wallet.subscription.function.Max app": "{{amount}} 个应用&插件",
|
||||
"support.wallet.subscription.function.Max dataset": "{{amount}} 个知识库",
|
||||
"support.wallet.subscription.function.Max app": "{{amount}} 个应用上限",
|
||||
"support.wallet.subscription.function.Max dataset": "{{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.mode.Month": "按月",
|
||||
"support.wallet.subscription.mode.Period": "订阅周期",
|
||||
|
@@ -6,6 +6,7 @@
|
||||
"ai_points_calculation_standard": "AI 積分",
|
||||
"ai_points_usage": "AI 積分使用量",
|
||||
"ai_points_usage_tip": "每次呼叫 AI 模型時,都會消耗一定的 AI 積分。\n具體的計算標準可參考上方的「計費標準」。",
|
||||
"app_amount": "應用數量",
|
||||
"avatar": "頭像",
|
||||
"avatar_selection_exception": "頭像選擇異常",
|
||||
"balance": "餘額",
|
||||
@@ -21,6 +22,7 @@
|
||||
"contact_us": "聯絡我們",
|
||||
"current_package": "目前套餐",
|
||||
"current_token_price": "目前積分價格",
|
||||
"dataset_amount": "知識庫數量",
|
||||
"effective_time": "生效時間",
|
||||
"email_label": "信箱",
|
||||
"exchange": "兌換",
|
||||
@@ -34,6 +36,7 @@
|
||||
"help_document": "幫助文件",
|
||||
"knowledge_base_capacity": "知識庫容量",
|
||||
"manage": "管理",
|
||||
"member_amount": "成員數量",
|
||||
"member_name": "成員名",
|
||||
"month": "月",
|
||||
"new_password": "新密碼",
|
||||
|
@@ -215,7 +215,6 @@
|
||||
"core.app.Interval timer run": "排程執行",
|
||||
"core.app.Interval timer tip": "可排程執行應用程式",
|
||||
"core.app.Make a brief introduction of your app": "為您的 AI 應用程式寫一段介紹",
|
||||
"core.app.name": "名稱",
|
||||
"core.app.Name and avatar": "頭像與名稱",
|
||||
"core.app.Publish": "發布",
|
||||
"core.app.Publish Confirm": "確認發布應用程式?這將立即更新所有發布管道的應用程式狀態。",
|
||||
@@ -261,6 +260,7 @@
|
||||
"core.app.have_saved": "已儲存",
|
||||
"core.app.logs.Source And Time": "來源與時間",
|
||||
"core.app.more": "檢視更多",
|
||||
"core.app.name": "名稱",
|
||||
"core.app.no_app": "還沒有應用程式,快來建立一個吧!",
|
||||
"core.app.not_saved": "未儲存",
|
||||
"core.app.outLink.Can Drag": "圖示可拖曳",
|
||||
@@ -1145,8 +1145,8 @@
|
||||
"support.wallet.subscription.Upgrade plan": "升級方案",
|
||||
"support.wallet.subscription.ai_model": "AI 語言模型",
|
||||
"support.wallet.subscription.function.History store": "{{amount}} 天對話紀錄保留",
|
||||
"support.wallet.subscription.function.Max app": "{{amount}} 個應用程式與外掛程式",
|
||||
"support.wallet.subscription.function.Max dataset": "{{amount}} 個知識庫",
|
||||
"support.wallet.subscription.function.Max app": "{{amount}} 個應用上限",
|
||||
"support.wallet.subscription.function.Max dataset": "{{amount}} 個知識庫上限",
|
||||
"support.wallet.subscription.function.Max dataset size": "{{amount}} 組知識庫索引",
|
||||
"support.wallet.subscription.function.Max members": "{{amount}} 個團隊成員",
|
||||
"support.wallet.subscription.function.Points": "{{amount}} AI 點數",
|
||||
|
Reference in New Issue
Block a user