mirror of
https://github.com/labring/FastGPT.git
synced 2025-07-23 21:13:50 +00:00
@@ -1,8 +1,8 @@
|
||||
import { UsageSourceEnum } from '@fastgpt/global/support/wallet/usage/constants';
|
||||
import { MongoUsage } from './schema';
|
||||
import { BillSourceEnum } from '@fastgpt/global/support/wallet/bill/constants';
|
||||
import { MongoBill } from './schema';
|
||||
import { ClientSession } from '../../../common/mongo';
|
||||
|
||||
export const createTrainingUsage = async ({
|
||||
export const createTrainingBill = async ({
|
||||
teamId,
|
||||
tmbId,
|
||||
appName,
|
||||
@@ -14,33 +14,33 @@ export const createTrainingUsage = async ({
|
||||
teamId: string;
|
||||
tmbId: string;
|
||||
appName: string;
|
||||
billSource: `${UsageSourceEnum}`;
|
||||
billSource: `${BillSourceEnum}`;
|
||||
vectorModel: string;
|
||||
agentModel: string;
|
||||
session?: ClientSession;
|
||||
}) => {
|
||||
const [{ _id }] = await MongoUsage.create(
|
||||
const [{ _id }] = await MongoBill.create(
|
||||
[
|
||||
{
|
||||
teamId,
|
||||
tmbId,
|
||||
appName,
|
||||
source: billSource,
|
||||
totalPoints: 0,
|
||||
list: [
|
||||
{
|
||||
moduleName: 'support.wallet.moduleName.index',
|
||||
moduleName: 'wallet.moduleName.index',
|
||||
model: vectorModel,
|
||||
charsLength: 0,
|
||||
amount: 0
|
||||
},
|
||||
{
|
||||
moduleName: 'support.wallet.moduleName.qa',
|
||||
moduleName: 'wallet.moduleName.qa',
|
||||
model: agentModel,
|
||||
charsLength: 0,
|
||||
amount: 0
|
||||
}
|
||||
]
|
||||
],
|
||||
total: 0
|
||||
}
|
||||
],
|
||||
{ session }
|
@@ -1,15 +1,13 @@
|
||||
import { connectionMongo, type Model } from '../../../common/mongo';
|
||||
const { Schema, model, models } = connectionMongo;
|
||||
import { UsageSchemaType } from '@fastgpt/global/support/wallet/usage/type';
|
||||
import { UsageSourceMap } from '@fastgpt/global/support/wallet/usage/constants';
|
||||
import { BillSchema as BillType } from '@fastgpt/global/support/wallet/bill/type';
|
||||
import { BillSourceMap } from '@fastgpt/global/support/wallet/bill/constants';
|
||||
import {
|
||||
TeamCollectionName,
|
||||
TeamMemberCollectionName
|
||||
} from '@fastgpt/global/support/user/team/constant';
|
||||
|
||||
export const UsageCollectionName = 'usages';
|
||||
|
||||
const UsageSchema = new Schema({
|
||||
const BillSchema = new Schema({
|
||||
teamId: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: TeamCollectionName,
|
||||
@@ -20,11 +18,6 @@ const UsageSchema = new Schema({
|
||||
ref: TeamMemberCollectionName,
|
||||
required: true
|
||||
},
|
||||
source: {
|
||||
type: String,
|
||||
enum: Object.keys(UsageSourceMap),
|
||||
required: true
|
||||
},
|
||||
appName: {
|
||||
type: String,
|
||||
default: ''
|
||||
@@ -38,16 +31,16 @@ const UsageSchema = new Schema({
|
||||
type: Date,
|
||||
default: () => new Date()
|
||||
},
|
||||
totalPoints: {
|
||||
// total points
|
||||
total: {
|
||||
// 1 * PRICE_SCALE
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
// total: {
|
||||
// // total points
|
||||
// type: Number,
|
||||
// required: true
|
||||
// },
|
||||
source: {
|
||||
type: String,
|
||||
enum: Object.keys(BillSourceMap),
|
||||
required: true
|
||||
},
|
||||
list: {
|
||||
type: Array,
|
||||
default: []
|
||||
@@ -55,15 +48,11 @@ const UsageSchema = new Schema({
|
||||
});
|
||||
|
||||
try {
|
||||
UsageSchema.index({ teamId: 1, tmbId: 1, source: 1, time: -1 }, { background: true });
|
||||
// timer task. clear dead team
|
||||
UsageSchema.index({ teamId: 1, time: -1 }, { background: true });
|
||||
|
||||
UsageSchema.index({ time: 1 }, { expireAfterSeconds: 180 * 24 * 60 * 60 });
|
||||
BillSchema.index({ teamId: 1, tmbId: 1, source: 1, time: -1 }, { background: true });
|
||||
BillSchema.index({ time: 1 }, { expireAfterSeconds: 180 * 24 * 60 * 60 });
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
|
||||
export const MongoUsage: Model<UsageSchemaType> =
|
||||
models[UsageCollectionName] || model(UsageCollectionName, UsageSchema);
|
||||
MongoUsage.syncIndexes();
|
||||
export const MongoBill: Model<BillType> = models['bill'] || model('bill', BillSchema);
|
||||
MongoBill.syncIndexes();
|
@@ -1,8 +1,3 @@
|
||||
/*
|
||||
user sub plan
|
||||
1. type=standard: There will only be 1, and each team will have one
|
||||
2. type=extraDatasetSize/extraPoints: Can buy multiple
|
||||
*/
|
||||
import { connectionMongo, type Model } from '../../../common/mongo';
|
||||
const { Schema, model, models } = connectionMongo;
|
||||
import { TeamCollectionName } from '@fastgpt/global/support/user/team/constant';
|
||||
@@ -28,10 +23,25 @@ const SubSchema = new Schema({
|
||||
required: true
|
||||
},
|
||||
status: {
|
||||
// active: continue sub; canceled: canceled sub;
|
||||
type: String,
|
||||
enum: Object.keys(subStatusMap),
|
||||
required: true
|
||||
},
|
||||
mode: {
|
||||
type: String,
|
||||
enum: Object.keys(subModeMap)
|
||||
},
|
||||
currentMode: {
|
||||
type: String,
|
||||
enum: Object.keys(subModeMap),
|
||||
required: true
|
||||
},
|
||||
nextMode: {
|
||||
type: String,
|
||||
enum: Object.keys(subModeMap),
|
||||
required: true
|
||||
},
|
||||
startTime: {
|
||||
type: Date,
|
||||
default: () => new Date()
|
||||
@@ -45,16 +55,12 @@ const SubSchema = new Schema({
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
pointPrice: {
|
||||
// stand level point total price
|
||||
type: Number
|
||||
},
|
||||
|
||||
// standard sub
|
||||
currentMode: {
|
||||
type: String,
|
||||
enum: Object.keys(subModeMap)
|
||||
},
|
||||
nextMode: {
|
||||
type: String,
|
||||
enum: Object.keys(subModeMap)
|
||||
},
|
||||
// sub content
|
||||
currentSubLevel: {
|
||||
type: String,
|
||||
enum: Object.keys(standardSubLevelMap)
|
||||
@@ -63,34 +69,79 @@ const SubSchema = new Schema({
|
||||
type: String,
|
||||
enum: Object.keys(standardSubLevelMap)
|
||||
},
|
||||
|
||||
// stand sub and extra points sub. Plan total points
|
||||
totalPoints: {
|
||||
type: Number
|
||||
},
|
||||
pointPrice: {
|
||||
// stand level point total price
|
||||
|
||||
currentExtraDatasetSize: {
|
||||
type: Number
|
||||
},
|
||||
surplusPoints: {
|
||||
// plan surplus points
|
||||
nextExtraDatasetSize: {
|
||||
type: Number
|
||||
},
|
||||
|
||||
// extra dataset size
|
||||
currentExtraDatasetSize: {
|
||||
currentExtraPoints: {
|
||||
type: Number
|
||||
}
|
||||
},
|
||||
nextExtraPoints: {
|
||||
type: Number
|
||||
},
|
||||
|
||||
// standard sub limit
|
||||
// maxTeamMember: {
|
||||
// type: Number
|
||||
// },
|
||||
// maxAppAmount: {
|
||||
// type: Number
|
||||
// },
|
||||
// maxDatasetAmount: {
|
||||
// type: Number
|
||||
// },
|
||||
// chatHistoryStoreDuration: {
|
||||
// // n day
|
||||
// type: Number
|
||||
// },
|
||||
// maxDatasetSize: {
|
||||
// type: Number
|
||||
// },
|
||||
// trainingWeight: {
|
||||
// // 0 1 2 3
|
||||
// type: Number
|
||||
// },
|
||||
// customApiKey: {
|
||||
// type: Boolean
|
||||
// },
|
||||
// customCopyright: {
|
||||
// type: Boolean
|
||||
// },
|
||||
// websiteSyncInterval: {
|
||||
// // hours
|
||||
// type: Number
|
||||
// },
|
||||
// reRankWeight: {
|
||||
// // 0 1 2 3
|
||||
// type: Number
|
||||
// },
|
||||
// totalPoints: {
|
||||
// // record standard sub points
|
||||
// type: Number
|
||||
// },
|
||||
|
||||
surplusPoints: {
|
||||
// standard sub / extra points sub
|
||||
type: Number
|
||||
},
|
||||
|
||||
// abandon
|
||||
renew: Boolean, //决定是否续费
|
||||
datasetStoreAmount: Number
|
||||
});
|
||||
|
||||
try {
|
||||
// get team plan
|
||||
SubSchema.index({ teamId: 1, type: 1, expiredTime: -1 });
|
||||
|
||||
// timer task. check expired plan; update standard plan;
|
||||
SubSchema.index({ type: 1, expiredTime: -1 });
|
||||
// timer task. clear dead team
|
||||
SubSchema.index({ type: 1, currentSubLevel: 1, nextSubLevel: 1 });
|
||||
SubSchema.index({ teamId: 1 });
|
||||
SubSchema.index({ status: 1 });
|
||||
SubSchema.index({ type: 1 });
|
||||
SubSchema.index({ expiredTime: -1 });
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
|
@@ -1,70 +1,87 @@
|
||||
import { SubTypeEnum } from '@fastgpt/global/support/wallet/sub/constants';
|
||||
import { MongoTeamSub } from './schema';
|
||||
import {
|
||||
FeTeamPlanStatusType,
|
||||
StandSubPlanLevelMapType
|
||||
} from '@fastgpt/global/support/wallet/sub/type.d';
|
||||
import { addHours } from 'date-fns';
|
||||
import { FeTeamSubType, StandSubPlanLevelMapType } from '@fastgpt/global/support/wallet/sub/type.d';
|
||||
import { getVectorCountByTeamId } from '../../../common/vectorStore/controller';
|
||||
|
||||
export const getTeamSubPlans = async ({
|
||||
teamId,
|
||||
standardPlans
|
||||
}: {
|
||||
teamId: string;
|
||||
standardPlans?: StandSubPlanLevelMapType;
|
||||
}): Promise<FeTeamPlanStatusType> => {
|
||||
const [plans, usedDatasetSize] = await Promise.all([
|
||||
MongoTeamSub.find({ teamId }).lean(),
|
||||
getVectorCountByTeamId(teamId)
|
||||
]);
|
||||
|
||||
const standard = plans.find((plan) => plan.type === SubTypeEnum.standard);
|
||||
const extraDatasetSize = plans.filter((plan) => plan.type === SubTypeEnum.extraDatasetSize);
|
||||
const extraPoints = plans.filter((plan) => plan.type === SubTypeEnum.extraPoints);
|
||||
|
||||
const totalPoints =
|
||||
(standard?.totalPoints || 0) +
|
||||
extraPoints.reduce((acc, cur) => acc + (cur.totalPoints || 0), 0);
|
||||
const surplusPoints =
|
||||
(standard?.surplusPoints || 0) +
|
||||
extraPoints.reduce((acc, cur) => acc + (cur.surplusPoints || 0), 0);
|
||||
|
||||
const standardMaxDatasetSize =
|
||||
standard?.currentSubLevel && standardPlans
|
||||
? standardPlans[standard.currentSubLevel]?.maxDatasetSize || Infinity
|
||||
: Infinity;
|
||||
const totalDatasetSize =
|
||||
standardMaxDatasetSize +
|
||||
extraDatasetSize.reduce((acc, cur) => acc + (cur.currentExtraDatasetSize || 0), 0);
|
||||
|
||||
return {
|
||||
[SubTypeEnum.standard]: standard,
|
||||
standardConstants:
|
||||
standard?.currentSubLevel && standardPlans
|
||||
? standardPlans[standard.currentSubLevel]
|
||||
: undefined,
|
||||
|
||||
totalPoints,
|
||||
usedPoints: totalPoints - surplusPoints,
|
||||
|
||||
datasetMaxSize: totalDatasetSize,
|
||||
usedDatasetSize
|
||||
};
|
||||
};
|
||||
export const getTeamStandPlan = async ({
|
||||
/* get team dataset max size */
|
||||
export const getTeamDatasetMaxSize = async ({
|
||||
teamId,
|
||||
standardPlans
|
||||
}: {
|
||||
teamId: string;
|
||||
standardPlans?: StandSubPlanLevelMapType;
|
||||
}) => {
|
||||
const standard = await MongoTeamSub.findOne({ teamId, type: SubTypeEnum.standard }).lean();
|
||||
if (!standardPlans) {
|
||||
return {
|
||||
maxSize: Infinity,
|
||||
sub: null
|
||||
};
|
||||
}
|
||||
|
||||
const plans = await MongoTeamSub.find({
|
||||
teamId,
|
||||
expiredTime: { $gte: addHours(new Date(), -3) }
|
||||
}).lean();
|
||||
|
||||
const standard = plans.find((plan) => plan.type === SubTypeEnum.standard);
|
||||
const extraDatasetSize = plans.find((plan) => plan.type === SubTypeEnum.extraDatasetSize);
|
||||
|
||||
const standardMaxDatasetSize =
|
||||
standard?.currentSubLevel && standardPlans
|
||||
? standardPlans[standard.currentSubLevel]?.maxDatasetSize || Infinity
|
||||
: Infinity;
|
||||
const totalDatasetSize =
|
||||
standardMaxDatasetSize + (extraDatasetSize?.currentExtraDatasetSize || 0);
|
||||
|
||||
return {
|
||||
maxSize: totalDatasetSize,
|
||||
sub: extraDatasetSize
|
||||
};
|
||||
};
|
||||
|
||||
export const getTeamSubPlanStatus = async ({
|
||||
teamId,
|
||||
standardPlans
|
||||
}: {
|
||||
teamId: string;
|
||||
standardPlans?: StandSubPlanLevelMapType;
|
||||
}): Promise<FeTeamSubType> => {
|
||||
const [plans, usedDatasetSize] = await Promise.all([
|
||||
MongoTeamSub.find({ teamId }).lean(),
|
||||
getVectorCountByTeamId(teamId)
|
||||
]);
|
||||
|
||||
const standard = plans.find((plan) => plan.type === SubTypeEnum.standard);
|
||||
const extraDatasetSize = plans.find((plan) => plan.type === SubTypeEnum.extraDatasetSize);
|
||||
const extraPoints = plans.find((plan) => plan.type === SubTypeEnum.extraPoints);
|
||||
|
||||
const standardMaxDatasetSize =
|
||||
standard?.currentSubLevel && standardPlans
|
||||
? standardPlans[standard.currentSubLevel]?.maxDatasetSize || Infinity
|
||||
: Infinity;
|
||||
const totalDatasetSize =
|
||||
standardMaxDatasetSize + (extraDatasetSize?.currentExtraDatasetSize || 0);
|
||||
|
||||
const standardMaxPoints =
|
||||
standard?.currentSubLevel && standardPlans
|
||||
? standardPlans[standard.currentSubLevel]?.totalPoints || Infinity
|
||||
: Infinity;
|
||||
const totalPoints = standardMaxPoints + (extraPoints?.currentExtraPoints || 0);
|
||||
|
||||
const surplusPoints = (standard?.surplusPoints || 0) + (extraPoints?.surplusPoints || 0);
|
||||
|
||||
return {
|
||||
[SubTypeEnum.standard]: standard,
|
||||
standardConstants:
|
||||
standard?.currentSubLevel && standardPlans
|
||||
? standardPlans[standard.currentSubLevel]
|
||||
: undefined
|
||||
[SubTypeEnum.extraDatasetSize]: extraDatasetSize,
|
||||
[SubTypeEnum.extraPoints]: extraPoints,
|
||||
|
||||
standardMaxDatasetSize,
|
||||
datasetMaxSize: totalDatasetSize,
|
||||
usedDatasetSize,
|
||||
|
||||
standardMaxPoints,
|
||||
totalPoints,
|
||||
usedPoints: totalPoints - surplusPoints
|
||||
};
|
||||
};
|
||||
|
Reference in New Issue
Block a user