mirror of
https://github.com/labring/FastGPT.git
synced 2025-08-02 20:58:12 +00:00
9
projects/app/src/service/support/permission/auth/bill.ts
Normal file
9
projects/app/src/service/support/permission/auth/bill.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { GET } from '@fastgpt/service/common/api/plusRequest';
|
||||
import { FastGPTProUrl } from '@fastgpt/service/common/system/constants';
|
||||
|
||||
export const authTeamBalance = async (teamId: string) => {
|
||||
if (FastGPTProUrl) {
|
||||
return GET('/support/permission/authBalance', { teamId });
|
||||
}
|
||||
return true;
|
||||
};
|
@@ -24,7 +24,6 @@ export async function authDatasetData({
|
||||
|
||||
const data: DatasetDataItemType = {
|
||||
id: String(datasetData._id),
|
||||
teamId: datasetData.teamId,
|
||||
q: datasetData.q,
|
||||
a: datasetData.a,
|
||||
chunkIndex: datasetData.chunkIndex,
|
||||
|
@@ -6,7 +6,7 @@ import type {
|
||||
AuthOutLinkResponse
|
||||
} from '@fastgpt/global/support/outLink/api.d';
|
||||
import { authOutLinkValid } from '@fastgpt/service/support/permission/auth/outLink';
|
||||
import { getUserChatInfoAndAuthTeamPoints } from '@/service/support/permission/auth/team';
|
||||
import { getUserAndAuthBalance } from '@fastgpt/service/support/user/controller';
|
||||
import { AuthUserTypeEnum } from '@fastgpt/global/support/permission/constant';
|
||||
import { OutLinkErrEnum } from '@fastgpt/global/common/error/code/outLink';
|
||||
import { OutLinkSchema } from '@fastgpt/global/support/outLink/type';
|
||||
@@ -58,15 +58,13 @@ export async function authOutLinkChatStart({
|
||||
// get outLink and app
|
||||
const { shareChat, appId } = await authOutLinkValid({ shareId });
|
||||
|
||||
// check ai points and chat limit
|
||||
const [{ user }, { uid }] = await Promise.all([
|
||||
getUserChatInfoAndAuthTeamPoints(shareChat.tmbId),
|
||||
// check balance and chat limit
|
||||
const [user, { uid }] = await Promise.all([
|
||||
getUserAndAuthBalance({ tmbId: shareChat.tmbId, minBalance: 0 }),
|
||||
authOutLinkChatLimit({ outLink: shareChat, ip, outLinkUid, question })
|
||||
]);
|
||||
|
||||
return {
|
||||
teamId: shareChat.teamId,
|
||||
tmbId: shareChat.tmbId,
|
||||
authType: AuthUserTypeEnum.token,
|
||||
responseDetail: shareChat.responseDetail,
|
||||
user,
|
||||
|
@@ -1,18 +0,0 @@
|
||||
import { UserErrEnum } from '@fastgpt/global/common/error/code/user';
|
||||
import { TeamMemberWithUserSchema } from '@fastgpt/global/support/user/team/type';
|
||||
import { MongoTeamMember } from '@fastgpt/service/support/user/team/teamMemberSchema';
|
||||
import { checkTeamAIPoints } from '../teamLimit';
|
||||
|
||||
export async function getUserChatInfoAndAuthTeamPoints(tmbId: string) {
|
||||
const tmb = (await MongoTeamMember.findById(tmbId, 'teamId userId').populate(
|
||||
'userId',
|
||||
'timezone openaiAccount'
|
||||
)) as TeamMemberWithUserSchema;
|
||||
if (!tmb) return Promise.reject(UserErrEnum.unAuthUser);
|
||||
|
||||
await checkTeamAIPoints(tmb.teamId);
|
||||
|
||||
return {
|
||||
user: tmb.userId
|
||||
};
|
||||
}
|
@@ -1,44 +0,0 @@
|
||||
import { POST } from '@fastgpt/service/common/api/plusRequest';
|
||||
import type {
|
||||
AuthOutLinkChatProps,
|
||||
AuthOutLinkLimitProps,
|
||||
AuthOutLinkInitProps,
|
||||
AuthOutLinkResponse
|
||||
} from '@fastgpt/global/support/outLink/api.d';
|
||||
import { getUserChatInfoAndAuthTeamPoints } from './team';
|
||||
import { MongoTeam } from '@fastgpt/service/support/user/team/teamSchema';
|
||||
import { MongoTeamMember } from '@fastgpt/service/support/user/team/teamMemberSchema';
|
||||
export function authOutLinkInit(data: AuthOutLinkInitProps): Promise<AuthOutLinkResponse> {
|
||||
if (!global.feConfigs?.isPlus) return Promise.resolve({ uid: data.outLinkUid });
|
||||
return POST<AuthOutLinkResponse>('/support/outLink/authInit', data);
|
||||
}
|
||||
export function authOutLinkChatLimit(data: AuthOutLinkLimitProps): Promise<AuthOutLinkResponse> {
|
||||
if (!global.feConfigs?.isPlus) return Promise.resolve({ uid: data.outLinkUid });
|
||||
return POST<AuthOutLinkResponse>('/support/outLink/authChatStart', data);
|
||||
}
|
||||
|
||||
export async function authTeamShareChatStart({
|
||||
teamId,
|
||||
ip,
|
||||
outLinkUid,
|
||||
question
|
||||
}: AuthOutLinkChatProps & {
|
||||
teamId: string;
|
||||
}) {
|
||||
// get outLink and app
|
||||
const res: any = await MongoTeam.findById(teamId);
|
||||
|
||||
// check balance and chat limit
|
||||
const tmb = await MongoTeamMember.findOne({ teamId, userId: String(res.ownerId) });
|
||||
|
||||
if (!tmb) {
|
||||
throw new Error('can not find it');
|
||||
}
|
||||
|
||||
const { user } = await getUserChatInfoAndAuthTeamPoints(String(tmb._id));
|
||||
|
||||
return {
|
||||
user,
|
||||
uid: outLinkUid
|
||||
};
|
||||
}
|
@@ -1,102 +0,0 @@
|
||||
import { getVectorCountByTeamId } from '@fastgpt/service/common/vectorStore/controller';
|
||||
import { getTeamSubPlans, getTeamStandPlan } from '@fastgpt/service/support/wallet/sub/utils';
|
||||
import { getStandardSubPlan } from '../wallet/sub/utils';
|
||||
import { MongoApp } from '@fastgpt/service/core/app/schema';
|
||||
import { MongoPlugin } from '@fastgpt/service/core/plugin/schema';
|
||||
import { MongoDataset } from '@fastgpt/service/core/dataset/schema';
|
||||
import { DatasetTypeEnum } from '@fastgpt/global/core/dataset/constants';
|
||||
import { TeamErrEnum } from '@fastgpt/global/common/error/code/team';
|
||||
|
||||
export const checkDatasetLimit = async ({
|
||||
teamId,
|
||||
insertLen = 0
|
||||
}: {
|
||||
teamId: string;
|
||||
insertLen?: number;
|
||||
}) => {
|
||||
const [{ totalPoints, usedPoints, datasetMaxSize }, usedSize] = await Promise.all([
|
||||
getTeamSubPlans({ teamId, standardPlans: getStandardSubPlan() }),
|
||||
getVectorCountByTeamId(teamId)
|
||||
]);
|
||||
|
||||
if (usedSize + insertLen >= datasetMaxSize) {
|
||||
return Promise.reject(TeamErrEnum.datasetSizeNotEnough);
|
||||
}
|
||||
|
||||
if (usedPoints >= totalPoints) {
|
||||
return Promise.reject(TeamErrEnum.aiPointsNotEnough);
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
export const checkTeamAIPoints = async (teamId: string) => {
|
||||
const { totalPoints, usedPoints } = await getTeamSubPlans({
|
||||
teamId,
|
||||
standardPlans: getStandardSubPlan()
|
||||
});
|
||||
|
||||
if (usedPoints >= totalPoints) {
|
||||
return Promise.reject(TeamErrEnum.aiPointsNotEnough);
|
||||
}
|
||||
|
||||
return {
|
||||
totalPoints,
|
||||
usedPoints
|
||||
};
|
||||
};
|
||||
|
||||
export const checkTeamDatasetLimit = async (teamId: string) => {
|
||||
const [{ standardConstants }, datasetCount] = await Promise.all([
|
||||
getTeamStandPlan({ teamId, standardPlans: getStandardSubPlan() }),
|
||||
MongoDataset.countDocuments({
|
||||
teamId,
|
||||
type: DatasetTypeEnum.dataset
|
||||
})
|
||||
]);
|
||||
|
||||
if (standardConstants && datasetCount >= standardConstants.maxDatasetAmount) {
|
||||
return Promise.reject(TeamErrEnum.datasetAmountNotEnough);
|
||||
}
|
||||
};
|
||||
export const checkTeamAppLimit = async (teamId: string) => {
|
||||
const [{ standardConstants }, appCount] = await Promise.all([
|
||||
getTeamStandPlan({ teamId, standardPlans: getStandardSubPlan() }),
|
||||
MongoApp.count({ teamId })
|
||||
]);
|
||||
|
||||
if (standardConstants && appCount >= standardConstants.maxAppAmount) {
|
||||
return Promise.reject(TeamErrEnum.appAmountNotEnough);
|
||||
}
|
||||
};
|
||||
export const checkTeamPluginLimit = async (teamId: string) => {
|
||||
const [{ standardConstants }, pluginCount] = await Promise.all([
|
||||
getTeamStandPlan({ teamId, standardPlans: getStandardSubPlan() }),
|
||||
MongoPlugin.count({ teamId })
|
||||
]);
|
||||
|
||||
if (standardConstants && pluginCount >= standardConstants.maxAppAmount) {
|
||||
return Promise.reject(TeamErrEnum.pluginAmountNotEnough);
|
||||
}
|
||||
};
|
||||
|
||||
export const checkTeamReRankPermission = async (teamId: string) => {
|
||||
const { standardConstants } = await getTeamStandPlan({
|
||||
teamId,
|
||||
standardPlans: getStandardSubPlan()
|
||||
});
|
||||
|
||||
if (standardConstants && !standardConstants?.permissionReRank) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
export const checkTeamWebSyncPermission = async (teamId: string) => {
|
||||
const { standardConstants } = await getTeamStandPlan({
|
||||
teamId,
|
||||
standardPlans: getStandardSubPlan()
|
||||
});
|
||||
|
||||
if (standardConstants && !standardConstants?.permissionWebsiteSync) {
|
||||
return Promise.reject(TeamErrEnum.websiteSyncNotEnough);
|
||||
}
|
||||
};
|
23
projects/app/src/service/support/wallet/bill/controller.ts
Normal file
23
projects/app/src/service/support/wallet/bill/controller.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { ConcatBillProps, CreateBillProps } from '@fastgpt/global/support/wallet/bill/api';
|
||||
import { addLog } from '@fastgpt/service/common/system/log';
|
||||
import { POST } from '@fastgpt/service/common/api/plusRequest';
|
||||
import { FastGPTProUrl } from '@fastgpt/service/common/system/constants';
|
||||
|
||||
export function createBill(data: CreateBillProps) {
|
||||
if (!FastGPTProUrl) return;
|
||||
if (data.total === 0) {
|
||||
addLog.info('0 Bill', data);
|
||||
}
|
||||
try {
|
||||
POST('/support/wallet/bill/createBill', data);
|
||||
} catch (error) {}
|
||||
}
|
||||
export function concatBill(data: ConcatBillProps) {
|
||||
if (!FastGPTProUrl) return;
|
||||
if (data.total === 0) {
|
||||
addLog.info('0 Bill', data);
|
||||
}
|
||||
try {
|
||||
POST('/support/wallet/bill/concatBill', data);
|
||||
} catch (error) {}
|
||||
}
|
327
projects/app/src/service/support/wallet/bill/push.ts
Normal file
327
projects/app/src/service/support/wallet/bill/push.ts
Normal file
@@ -0,0 +1,327 @@
|
||||
import { BillSourceEnum } from '@fastgpt/global/support/wallet/bill/constants';
|
||||
import { ModelTypeEnum } from '@/service/core/ai/model';
|
||||
import type { ChatHistoryItemResType } from '@fastgpt/global/core/chat/type.d';
|
||||
import { formatStorePrice2Read } from '@fastgpt/global/support/wallet/bill/tools';
|
||||
import { addLog } from '@fastgpt/service/common/system/log';
|
||||
import { PostReRankProps } from '@fastgpt/global/core/ai/api';
|
||||
import { createBill, concatBill } from './controller';
|
||||
import { formatModelPrice2Store } from '@/service/support/wallet/bill/utils';
|
||||
|
||||
export const pushChatBill = ({
|
||||
appName,
|
||||
appId,
|
||||
teamId,
|
||||
tmbId,
|
||||
source,
|
||||
response
|
||||
}: {
|
||||
appName: string;
|
||||
appId: string;
|
||||
teamId: string;
|
||||
tmbId: string;
|
||||
source: `${BillSourceEnum}`;
|
||||
response: ChatHistoryItemResType[];
|
||||
}) => {
|
||||
const total = response.reduce((sum, item) => sum + (item.price || 0), 0);
|
||||
|
||||
createBill({
|
||||
teamId,
|
||||
tmbId,
|
||||
appName,
|
||||
appId,
|
||||
total,
|
||||
source,
|
||||
list: response.map((item) => ({
|
||||
moduleName: item.moduleName,
|
||||
amount: item.price || 0,
|
||||
model: item.model,
|
||||
inputTokens: item.inputTokens,
|
||||
outputTokens: item.outputTokens,
|
||||
charsLength: item.charsLength
|
||||
}))
|
||||
});
|
||||
addLog.info(`finish completions`, {
|
||||
source,
|
||||
teamId,
|
||||
tmbId,
|
||||
price: formatStorePrice2Read(total)
|
||||
});
|
||||
return { total };
|
||||
};
|
||||
|
||||
export const pushQABill = async ({
|
||||
teamId,
|
||||
tmbId,
|
||||
model,
|
||||
charsLength,
|
||||
billId
|
||||
}: {
|
||||
teamId: string;
|
||||
tmbId: string;
|
||||
model: string;
|
||||
charsLength: number;
|
||||
billId: string;
|
||||
}) => {
|
||||
// 计算价格
|
||||
const { total } = formatModelPrice2Store({
|
||||
model,
|
||||
inputLen: charsLength,
|
||||
type: ModelTypeEnum.llm
|
||||
});
|
||||
|
||||
concatBill({
|
||||
billId,
|
||||
teamId,
|
||||
tmbId,
|
||||
total,
|
||||
charsLength,
|
||||
listIndex: 1
|
||||
});
|
||||
|
||||
return { total };
|
||||
};
|
||||
|
||||
export const pushGenerateVectorBill = ({
|
||||
billId,
|
||||
teamId,
|
||||
tmbId,
|
||||
charsLength,
|
||||
model,
|
||||
source = BillSourceEnum.fastgpt,
|
||||
extensionModel,
|
||||
extensionInputTokens,
|
||||
extensionOutputTokens
|
||||
}: {
|
||||
billId?: string;
|
||||
teamId: string;
|
||||
tmbId: string;
|
||||
charsLength: number;
|
||||
model: string;
|
||||
source?: `${BillSourceEnum}`;
|
||||
|
||||
extensionModel?: string;
|
||||
extensionInputTokens?: number;
|
||||
extensionOutputTokens?: number;
|
||||
}) => {
|
||||
const { total: totalVector, modelName: vectorModelName } = formatModelPrice2Store({
|
||||
model,
|
||||
inputLen: charsLength,
|
||||
type: ModelTypeEnum.vector
|
||||
});
|
||||
|
||||
const { extensionTotal, extensionModelName } = (() => {
|
||||
if (!extensionModel || !extensionInputTokens || !extensionOutputTokens)
|
||||
return {
|
||||
extensionTotal: 0,
|
||||
extensionModelName: ''
|
||||
};
|
||||
const { total, modelName } = formatModelPrice2Store({
|
||||
model: extensionModel,
|
||||
inputLen: extensionInputTokens,
|
||||
outputLen: extensionOutputTokens,
|
||||
type: ModelTypeEnum.llm
|
||||
});
|
||||
return {
|
||||
extensionTotal: total,
|
||||
extensionModelName: modelName
|
||||
};
|
||||
})();
|
||||
|
||||
const total = totalVector + extensionTotal;
|
||||
|
||||
// 插入 Bill 记录
|
||||
if (billId) {
|
||||
concatBill({
|
||||
teamId,
|
||||
tmbId,
|
||||
total: totalVector,
|
||||
billId,
|
||||
charsLength,
|
||||
listIndex: 0
|
||||
});
|
||||
} else {
|
||||
createBill({
|
||||
teamId,
|
||||
tmbId,
|
||||
appName: 'wallet.moduleName.index',
|
||||
total,
|
||||
source,
|
||||
list: [
|
||||
{
|
||||
moduleName: 'wallet.moduleName.index',
|
||||
amount: totalVector,
|
||||
model: vectorModelName,
|
||||
charsLength
|
||||
},
|
||||
...(extensionModel !== undefined
|
||||
? [
|
||||
{
|
||||
moduleName: 'core.module.template.Query extension',
|
||||
amount: extensionTotal,
|
||||
model: extensionModelName,
|
||||
inputTokens: extensionInputTokens,
|
||||
outputTokens: extensionOutputTokens
|
||||
}
|
||||
]
|
||||
: [])
|
||||
]
|
||||
});
|
||||
}
|
||||
return { total };
|
||||
};
|
||||
|
||||
export const pushQuestionGuideBill = ({
|
||||
inputTokens,
|
||||
outputTokens,
|
||||
teamId,
|
||||
tmbId
|
||||
}: {
|
||||
inputTokens: number;
|
||||
outputTokens: number;
|
||||
teamId: string;
|
||||
tmbId: string;
|
||||
}) => {
|
||||
const qgModel = global.llmModels[0];
|
||||
const { total, modelName } = formatModelPrice2Store({
|
||||
inputLen: inputTokens,
|
||||
outputLen: outputTokens,
|
||||
model: qgModel.model,
|
||||
type: ModelTypeEnum.llm
|
||||
});
|
||||
|
||||
createBill({
|
||||
teamId,
|
||||
tmbId,
|
||||
appName: 'wallet.bill.Next Step Guide',
|
||||
total,
|
||||
source: BillSourceEnum.fastgpt,
|
||||
list: [
|
||||
{
|
||||
moduleName: 'wallet.bill.Next Step Guide',
|
||||
amount: total,
|
||||
model: modelName,
|
||||
inputTokens,
|
||||
outputTokens
|
||||
}
|
||||
]
|
||||
});
|
||||
};
|
||||
|
||||
export function pushAudioSpeechBill({
|
||||
appName = 'wallet.bill.Audio Speech',
|
||||
model,
|
||||
charsLength,
|
||||
teamId,
|
||||
tmbId,
|
||||
source = BillSourceEnum.fastgpt
|
||||
}: {
|
||||
appName?: string;
|
||||
model: string;
|
||||
charsLength: number;
|
||||
teamId: string;
|
||||
tmbId: string;
|
||||
source: `${BillSourceEnum}`;
|
||||
}) {
|
||||
const { total, modelName } = formatModelPrice2Store({
|
||||
model,
|
||||
inputLen: charsLength,
|
||||
type: ModelTypeEnum.audioSpeech
|
||||
});
|
||||
|
||||
createBill({
|
||||
teamId,
|
||||
tmbId,
|
||||
appName,
|
||||
total,
|
||||
source,
|
||||
list: [
|
||||
{
|
||||
moduleName: appName,
|
||||
amount: total,
|
||||
model: modelName,
|
||||
charsLength
|
||||
}
|
||||
]
|
||||
});
|
||||
}
|
||||
|
||||
export function pushWhisperBill({
|
||||
teamId,
|
||||
tmbId,
|
||||
duration
|
||||
}: {
|
||||
teamId: string;
|
||||
tmbId: string;
|
||||
duration: number;
|
||||
}) {
|
||||
const whisperModel = global.whisperModel;
|
||||
|
||||
if (!whisperModel) return;
|
||||
|
||||
const { total, modelName } = formatModelPrice2Store({
|
||||
model: whisperModel.model,
|
||||
inputLen: duration,
|
||||
type: ModelTypeEnum.whisper,
|
||||
multiple: 60
|
||||
});
|
||||
|
||||
const name = 'wallet.bill.Whisper';
|
||||
|
||||
createBill({
|
||||
teamId,
|
||||
tmbId,
|
||||
appName: name,
|
||||
total,
|
||||
source: BillSourceEnum.fastgpt,
|
||||
list: [
|
||||
{
|
||||
moduleName: name,
|
||||
amount: total,
|
||||
model: modelName,
|
||||
duration
|
||||
}
|
||||
]
|
||||
});
|
||||
}
|
||||
|
||||
export function pushReRankBill({
|
||||
teamId,
|
||||
tmbId,
|
||||
source,
|
||||
inputs
|
||||
}: {
|
||||
teamId: string;
|
||||
tmbId: string;
|
||||
source: `${BillSourceEnum}`;
|
||||
inputs: PostReRankProps['inputs'];
|
||||
}) {
|
||||
const reRankModel = global.reRankModels[0];
|
||||
if (!reRankModel) return { total: 0 };
|
||||
|
||||
const charsLength = inputs.reduce((sum, item) => sum + item.text.length, 0);
|
||||
|
||||
const { total, modelName } = formatModelPrice2Store({
|
||||
model: reRankModel.model,
|
||||
inputLen: charsLength,
|
||||
type: ModelTypeEnum.rerank
|
||||
});
|
||||
const name = 'wallet.bill.ReRank';
|
||||
|
||||
createBill({
|
||||
teamId,
|
||||
tmbId,
|
||||
appName: name,
|
||||
total,
|
||||
source,
|
||||
list: [
|
||||
{
|
||||
moduleName: name,
|
||||
amount: total,
|
||||
model: modelName,
|
||||
charsLength
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
return { total };
|
||||
}
|
54
projects/app/src/service/support/wallet/bill/utils.ts
Normal file
54
projects/app/src/service/support/wallet/bill/utils.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
import { ModelTypeEnum, getModelMap } from '@/service/core/ai/model';
|
||||
import { AuthUserTypeEnum } from '@fastgpt/global/support/permission/constant';
|
||||
import { BillSourceEnum, PRICE_SCALE } from '@fastgpt/global/support/wallet/bill/constants';
|
||||
|
||||
export function authType2BillSource({
|
||||
authType,
|
||||
shareId,
|
||||
source
|
||||
}: {
|
||||
authType?: `${AuthUserTypeEnum}`;
|
||||
shareId?: string;
|
||||
source?: `${BillSourceEnum}`;
|
||||
}) {
|
||||
if (source) return source;
|
||||
if (shareId) return BillSourceEnum.shareLink;
|
||||
if (authType === AuthUserTypeEnum.apikey) return BillSourceEnum.api;
|
||||
return BillSourceEnum.fastgpt;
|
||||
}
|
||||
|
||||
export const formatModelPrice2Store = ({
|
||||
model,
|
||||
inputLen = 0,
|
||||
outputLen = 0,
|
||||
type,
|
||||
multiple = 1000
|
||||
}: {
|
||||
model: string;
|
||||
inputLen: number;
|
||||
outputLen?: number;
|
||||
type: `${ModelTypeEnum}`;
|
||||
multiple?: number;
|
||||
}) => {
|
||||
const modelData = getModelMap?.[type]?.(model);
|
||||
if (!modelData)
|
||||
return {
|
||||
inputTotal: 0,
|
||||
outputTotal: 0,
|
||||
total: 0,
|
||||
modelName: ''
|
||||
};
|
||||
const inputTotal = modelData.inputPrice
|
||||
? Math.ceil(modelData.inputPrice * (inputLen / multiple) * PRICE_SCALE)
|
||||
: 0;
|
||||
const outputTotal = modelData.outputPrice
|
||||
? Math.ceil(modelData.outputPrice * (outputLen / multiple) * PRICE_SCALE)
|
||||
: 0;
|
||||
|
||||
return {
|
||||
modelName: modelData.name,
|
||||
inputTotal: inputTotal,
|
||||
outputTotal: outputTotal,
|
||||
total: inputTotal + outputTotal
|
||||
};
|
||||
};
|
@@ -1,23 +0,0 @@
|
||||
import { ConcatUsageProps, CreateUsageProps } from '@fastgpt/global/support/wallet/usage/api';
|
||||
import { addLog } from '@fastgpt/service/common/system/log';
|
||||
import { POST } from '@fastgpt/service/common/api/plusRequest';
|
||||
import { FastGPTProUrl } from '@fastgpt/service/common/system/constants';
|
||||
|
||||
export function createUsage(data: CreateUsageProps) {
|
||||
if (!FastGPTProUrl) return;
|
||||
if (data.totalPoints === 0) {
|
||||
addLog.info('0 totalPoints', data);
|
||||
}
|
||||
try {
|
||||
POST('/support/wallet/usage/createUsage', data);
|
||||
} catch (error) {}
|
||||
}
|
||||
export function concatUsage(data: ConcatUsageProps) {
|
||||
if (!FastGPTProUrl) return;
|
||||
if (data.totalPoints === 0) {
|
||||
addLog.info('0 totalPoints', data);
|
||||
}
|
||||
try {
|
||||
POST('/support/wallet/usage/concatUsage', data);
|
||||
} catch (error) {}
|
||||
}
|
@@ -1,274 +0,0 @@
|
||||
import { UsageSourceEnum } from '@fastgpt/global/support/wallet/usage/constants';
|
||||
import { ModelTypeEnum } from '@/service/core/ai/model';
|
||||
import type { ChatHistoryItemResType } from '@fastgpt/global/core/chat/type.d';
|
||||
import { addLog } from '@fastgpt/service/common/system/log';
|
||||
import { createUsage, concatUsage } from './controller';
|
||||
import { formatModelChars2Points } from '@/service/support/wallet/usage/utils';
|
||||
import { ChatModuleBillType } from '@fastgpt/global/support/wallet/bill/type';
|
||||
|
||||
export const pushChatUsage = ({
|
||||
appName,
|
||||
appId,
|
||||
teamId,
|
||||
tmbId,
|
||||
source,
|
||||
moduleDispatchBills
|
||||
}: {
|
||||
appName: string;
|
||||
appId: string;
|
||||
teamId: string;
|
||||
tmbId: string;
|
||||
source: `${UsageSourceEnum}`;
|
||||
moduleDispatchBills: ChatModuleBillType[];
|
||||
}) => {
|
||||
const totalPoints = moduleDispatchBills.reduce((sum, item) => sum + (item.totalPoints || 0), 0);
|
||||
|
||||
createUsage({
|
||||
teamId,
|
||||
tmbId,
|
||||
appName,
|
||||
appId,
|
||||
totalPoints,
|
||||
source,
|
||||
list: moduleDispatchBills.map((item) => ({
|
||||
moduleName: item.moduleName,
|
||||
amount: item.totalPoints || 0,
|
||||
model: item.model,
|
||||
charsLength: item.charsLength
|
||||
}))
|
||||
});
|
||||
addLog.info(`finish completions`, {
|
||||
source,
|
||||
teamId,
|
||||
tmbId,
|
||||
totalPoints
|
||||
});
|
||||
return { totalPoints };
|
||||
};
|
||||
|
||||
export const pushQAUsage = async ({
|
||||
teamId,
|
||||
tmbId,
|
||||
model,
|
||||
charsLength,
|
||||
billId
|
||||
}: {
|
||||
teamId: string;
|
||||
tmbId: string;
|
||||
model: string;
|
||||
charsLength: number;
|
||||
billId: string;
|
||||
}) => {
|
||||
// 计算价格
|
||||
const { totalPoints } = formatModelChars2Points({
|
||||
model,
|
||||
modelType: ModelTypeEnum.llm,
|
||||
charsLength
|
||||
});
|
||||
|
||||
concatUsage({
|
||||
billId,
|
||||
teamId,
|
||||
tmbId,
|
||||
totalPoints,
|
||||
charsLength,
|
||||
listIndex: 1
|
||||
});
|
||||
|
||||
return { totalPoints };
|
||||
};
|
||||
|
||||
export const pushGenerateVectorUsage = ({
|
||||
billId,
|
||||
teamId,
|
||||
tmbId,
|
||||
charsLength,
|
||||
model,
|
||||
source = UsageSourceEnum.fastgpt,
|
||||
extensionModel,
|
||||
extensionCharsLength
|
||||
}: {
|
||||
billId?: string;
|
||||
teamId: string;
|
||||
tmbId: string;
|
||||
charsLength: number;
|
||||
model: string;
|
||||
source?: `${UsageSourceEnum}`;
|
||||
|
||||
extensionModel?: string;
|
||||
extensionCharsLength?: number;
|
||||
}) => {
|
||||
const { totalPoints: totalVector, modelName: vectorModelName } = formatModelChars2Points({
|
||||
modelType: ModelTypeEnum.vector,
|
||||
model,
|
||||
charsLength
|
||||
});
|
||||
|
||||
const { extensionTotalPoints, extensionModelName } = (() => {
|
||||
if (!extensionModel || !extensionCharsLength)
|
||||
return {
|
||||
extensionTotalPoints: 0,
|
||||
extensionModelName: ''
|
||||
};
|
||||
const { totalPoints, modelName } = formatModelChars2Points({
|
||||
modelType: ModelTypeEnum.llm,
|
||||
model: extensionModel,
|
||||
charsLength: extensionCharsLength
|
||||
});
|
||||
return {
|
||||
extensionTotalPoints: totalPoints,
|
||||
extensionModelName: modelName
|
||||
};
|
||||
})();
|
||||
|
||||
const totalPoints = totalVector + extensionTotalPoints;
|
||||
|
||||
// 插入 Bill 记录
|
||||
if (billId) {
|
||||
concatUsage({
|
||||
teamId,
|
||||
tmbId,
|
||||
totalPoints,
|
||||
billId,
|
||||
charsLength,
|
||||
listIndex: 0
|
||||
});
|
||||
} else {
|
||||
createUsage({
|
||||
teamId,
|
||||
tmbId,
|
||||
appName: 'support.wallet.moduleName.index',
|
||||
totalPoints,
|
||||
source,
|
||||
list: [
|
||||
{
|
||||
moduleName: 'support.wallet.moduleName.index',
|
||||
amount: totalVector,
|
||||
model: vectorModelName,
|
||||
charsLength
|
||||
},
|
||||
...(extensionModel !== undefined
|
||||
? [
|
||||
{
|
||||
moduleName: 'core.module.template.Query extension',
|
||||
amount: extensionTotalPoints,
|
||||
model: extensionModelName,
|
||||
charsLength: extensionCharsLength
|
||||
}
|
||||
]
|
||||
: [])
|
||||
]
|
||||
});
|
||||
}
|
||||
return { totalPoints };
|
||||
};
|
||||
|
||||
export const pushQuestionGuideUsage = ({
|
||||
charsLength,
|
||||
teamId,
|
||||
tmbId
|
||||
}: {
|
||||
charsLength: number;
|
||||
teamId: string;
|
||||
tmbId: string;
|
||||
}) => {
|
||||
const qgModel = global.llmModels[0];
|
||||
const { totalPoints, modelName } = formatModelChars2Points({
|
||||
charsLength,
|
||||
model: qgModel.model,
|
||||
modelType: ModelTypeEnum.llm
|
||||
});
|
||||
|
||||
createUsage({
|
||||
teamId,
|
||||
tmbId,
|
||||
appName: 'core.app.Next Step Guide',
|
||||
totalPoints,
|
||||
source: UsageSourceEnum.fastgpt,
|
||||
list: [
|
||||
{
|
||||
moduleName: 'core.app.Next Step Guide',
|
||||
amount: totalPoints,
|
||||
model: modelName,
|
||||
charsLength
|
||||
}
|
||||
]
|
||||
});
|
||||
};
|
||||
|
||||
export function pushAudioSpeechUsage({
|
||||
appName = 'support.wallet.bill.Audio Speech',
|
||||
model,
|
||||
charsLength,
|
||||
teamId,
|
||||
tmbId,
|
||||
source = UsageSourceEnum.fastgpt
|
||||
}: {
|
||||
appName?: string;
|
||||
model: string;
|
||||
charsLength: number;
|
||||
teamId: string;
|
||||
tmbId: string;
|
||||
source: `${UsageSourceEnum}`;
|
||||
}) {
|
||||
const { totalPoints, modelName } = formatModelChars2Points({
|
||||
model,
|
||||
charsLength,
|
||||
modelType: ModelTypeEnum.audioSpeech
|
||||
});
|
||||
|
||||
createUsage({
|
||||
teamId,
|
||||
tmbId,
|
||||
appName,
|
||||
totalPoints,
|
||||
source,
|
||||
list: [
|
||||
{
|
||||
moduleName: appName,
|
||||
amount: totalPoints,
|
||||
model: modelName,
|
||||
charsLength
|
||||
}
|
||||
]
|
||||
});
|
||||
}
|
||||
|
||||
export function pushWhisperUsage({
|
||||
teamId,
|
||||
tmbId,
|
||||
duration
|
||||
}: {
|
||||
teamId: string;
|
||||
tmbId: string;
|
||||
duration: number;
|
||||
}) {
|
||||
const whisperModel = global.whisperModel;
|
||||
|
||||
if (!whisperModel) return;
|
||||
|
||||
const { totalPoints, modelName } = formatModelChars2Points({
|
||||
model: whisperModel.model,
|
||||
charsLength: duration,
|
||||
modelType: ModelTypeEnum.whisper,
|
||||
multiple: 60
|
||||
});
|
||||
|
||||
const name = 'support.wallet.bill.Whisper';
|
||||
|
||||
createUsage({
|
||||
teamId,
|
||||
tmbId,
|
||||
appName: name,
|
||||
totalPoints,
|
||||
source: UsageSourceEnum.fastgpt,
|
||||
list: [
|
||||
{
|
||||
moduleName: name,
|
||||
amount: totalPoints,
|
||||
model: modelName,
|
||||
duration
|
||||
}
|
||||
]
|
||||
});
|
||||
}
|
@@ -1,44 +0,0 @@
|
||||
import { ModelTypeEnum, getModelMap } from '@/service/core/ai/model';
|
||||
import { AuthUserTypeEnum } from '@fastgpt/global/support/permission/constant';
|
||||
import { UsageSourceEnum } from '@fastgpt/global/support/wallet/usage/constants';
|
||||
|
||||
export function authType2UsageSource({
|
||||
authType,
|
||||
shareId,
|
||||
source
|
||||
}: {
|
||||
authType?: `${AuthUserTypeEnum}`;
|
||||
shareId?: string;
|
||||
source?: `${UsageSourceEnum}`;
|
||||
}) {
|
||||
if (source) return source;
|
||||
if (shareId) return UsageSourceEnum.shareLink;
|
||||
if (authType === AuthUserTypeEnum.apikey) return UsageSourceEnum.api;
|
||||
return UsageSourceEnum.fastgpt;
|
||||
}
|
||||
|
||||
export const formatModelChars2Points = ({
|
||||
model,
|
||||
charsLength = 0,
|
||||
modelType,
|
||||
multiple = 1000
|
||||
}: {
|
||||
model: string;
|
||||
charsLength: number;
|
||||
modelType: `${ModelTypeEnum}`;
|
||||
multiple?: number;
|
||||
}) => {
|
||||
const modelData = getModelMap?.[modelType]?.(model);
|
||||
if (!modelData)
|
||||
return {
|
||||
totalPoints: 0,
|
||||
modelName: ''
|
||||
};
|
||||
|
||||
const totalPoints = (modelData.charsPointsPrice || 0) * (charsLength / multiple);
|
||||
|
||||
return {
|
||||
modelName: modelData.name,
|
||||
totalPoints
|
||||
};
|
||||
};
|
Reference in New Issue
Block a user