mirror of
https://github.com/labring/FastGPT.git
synced 2025-07-23 13:03:50 +00:00
fix colection create api (#766)
Co-authored-by: heheer <71265218+newfish-cmyk@users.noreply.github.com>
This commit is contained in:
@@ -1,10 +1,18 @@
|
||||
// The number of days left in the month is calculated as 30 days per month, and less than 1 day is calculated as 1 day
|
||||
export const getMonthRemainingDays = () => {
|
||||
const now = new Date();
|
||||
const year = now.getFullYear();
|
||||
const month = now.getMonth();
|
||||
const date = now.getDate();
|
||||
const days = new Date(year, month + 1, 0).getDate();
|
||||
const remainingDays = days - date;
|
||||
return remainingDays + 1;
|
||||
export const getMonthRemainingDays = (startDate = new Date()) => {
|
||||
const year = startDate.getFullYear();
|
||||
const month = startDate.getMonth();
|
||||
const endDay = new Date(year, month + 1, 0, 0, 0, 0);
|
||||
return calculateDaysBetweenDates(startDate, endDay);
|
||||
};
|
||||
|
||||
export const calculateDaysBetweenDates = (date1: Date, date2: Date) => {
|
||||
const oneDay = 24 * 60 * 60 * 1000;
|
||||
const firstDate = new Date(date1).getTime();
|
||||
const secondDate = new Date(date2).getTime();
|
||||
|
||||
const differenceInTime = Math.abs(secondDate - firstDate);
|
||||
const differenceInDays = Math.floor(differenceInTime / oneDay);
|
||||
|
||||
return differenceInDays;
|
||||
};
|
||||
|
@@ -7,13 +7,23 @@ export enum BillSourceEnum {
|
||||
api = 'api',
|
||||
shareLink = 'shareLink',
|
||||
training = 'training',
|
||||
datasetExpand = 'datasetExpand'
|
||||
extraDatasetSub = 'extraDatasetSub'
|
||||
}
|
||||
|
||||
export const BillSourceMap: Record<`${BillSourceEnum}`, string> = {
|
||||
[BillSourceEnum.fastgpt]: '在线使用',
|
||||
[BillSourceEnum.api]: 'Api',
|
||||
[BillSourceEnum.shareLink]: '免登录链接',
|
||||
[BillSourceEnum.training]: '数据训练',
|
||||
[BillSourceEnum.datasetExpand]: '知识库扩容'
|
||||
export const BillSourceMap = {
|
||||
[BillSourceEnum.fastgpt]: {
|
||||
label: '在线使用'
|
||||
},
|
||||
[BillSourceEnum.api]: {
|
||||
label: 'Api'
|
||||
},
|
||||
[BillSourceEnum.shareLink]: {
|
||||
label: '免登录链接'
|
||||
},
|
||||
[BillSourceEnum.training]: {
|
||||
label: '数据训练'
|
||||
},
|
||||
[BillSourceEnum.extraDatasetSub]: {
|
||||
label: '知识库扩容'
|
||||
}
|
||||
};
|
||||
|
@@ -7,6 +7,9 @@ export type BillListItemCountType = {
|
||||
charsLength?: number;
|
||||
duration?: number;
|
||||
|
||||
// sub
|
||||
datasetSize?: number;
|
||||
|
||||
// abandon
|
||||
tokenLen?: number;
|
||||
};
|
||||
@@ -23,7 +26,7 @@ export type BillSchema = CreateBillProps & {
|
||||
|
||||
export type BillItemType = {
|
||||
id: string;
|
||||
memberName: string;
|
||||
// memberName: string;
|
||||
time: Date;
|
||||
appName: string;
|
||||
source: BillSchema['source'];
|
||||
|
41
packages/global/support/wallet/pay/constants.ts
Normal file
41
packages/global/support/wallet/pay/constants.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
export enum PayTypeEnum {
|
||||
balance = 'balance',
|
||||
subStandard = 'subStandard',
|
||||
subExtraDatasetSize = 'subExtraDatasetSize',
|
||||
subExtraPoints = 'subExtraPoints'
|
||||
}
|
||||
export const payTypeMap = {
|
||||
[PayTypeEnum.balance]: {
|
||||
label: 'support.user.team.pay.type.balance'
|
||||
},
|
||||
[PayTypeEnum.subStandard]: {
|
||||
label: 'support.user.team.subscription.type.standard'
|
||||
},
|
||||
[PayTypeEnum.subExtraDatasetSize]: {
|
||||
label: 'support.user.team.subscription.type.extraDatasetSize'
|
||||
},
|
||||
[PayTypeEnum.subExtraPoints]: {
|
||||
label: 'support.user.team.subscription.type.extraPoints'
|
||||
}
|
||||
};
|
||||
|
||||
export enum PayStatusEnum {
|
||||
SUCCESS = 'SUCCESS',
|
||||
REFUND = 'REFUND',
|
||||
NOTPAY = 'NOTPAY',
|
||||
CLOSED = 'CLOSED'
|
||||
}
|
||||
export const payStatusMap = {
|
||||
[PayStatusEnum.SUCCESS]: {
|
||||
label: 'support.user.team.pay.status.success'
|
||||
},
|
||||
[PayStatusEnum.REFUND]: {
|
||||
label: 'support.user.team.pay.status.refund'
|
||||
},
|
||||
[PayStatusEnum.NOTPAY]: {
|
||||
label: 'support.user.team.pay.status.notpay'
|
||||
},
|
||||
[PayStatusEnum.CLOSED]: {
|
||||
label: 'support.user.team.pay.status.closed'
|
||||
}
|
||||
};
|
10
packages/global/support/wallet/pay/type.d.ts
vendored
10
packages/global/support/wallet/pay/type.d.ts
vendored
@@ -1,10 +1,18 @@
|
||||
import { SubModeEnum, SubTypeEnum } from '../sub/constants';
|
||||
import { PayTypeEnum } from './constants';
|
||||
|
||||
export type PaySchema = {
|
||||
_id: string;
|
||||
userId: string;
|
||||
teamId: string;
|
||||
tmbId: string;
|
||||
createTime: Date;
|
||||
price: number;
|
||||
orderId: string;
|
||||
status: 'SUCCESS' | 'REFUND' | 'NOTPAY' | 'CLOSED';
|
||||
type: `${PayType}`;
|
||||
|
||||
price: number;
|
||||
payWay: 'balance' | 'wx';
|
||||
|
||||
subMetadata: {};
|
||||
};
|
||||
|
13
packages/global/support/wallet/sub/api.d.ts
vendored
13
packages/global/support/wallet/sub/api.d.ts
vendored
@@ -1,4 +1,15 @@
|
||||
import { SubModeEnum } from './constants';
|
||||
|
||||
export type SubDatasetSizeParams = {
|
||||
size: number;
|
||||
renew: boolean;
|
||||
};
|
||||
export type SubDatasetSizePreviewCheckResponse = {
|
||||
payForNewSub: boolean; // Does this change require payment
|
||||
newSubSize: number; // new sub dataset size
|
||||
alreadySubSize: number; // old sub dataset size
|
||||
payPrice: number; // this change require payment
|
||||
newPrice: number; // the new sub price
|
||||
newSubStartTime: Date;
|
||||
newSubExpiredTime: Date;
|
||||
balanceEnough: boolean; // team balance is enough
|
||||
};
|
||||
|
@@ -1,37 +1,73 @@
|
||||
export enum SubTypeEnum {
|
||||
datasetStore = 'datasetStore'
|
||||
standard = 'standard',
|
||||
extraDatasetSize = 'extraDatasetSize',
|
||||
extraPoints = 'extraPoints'
|
||||
}
|
||||
|
||||
export const subTypeMap = {
|
||||
[SubTypeEnum.datasetStore]: {
|
||||
label: 'support.user.team.subscription.type.datasetStore'
|
||||
[SubTypeEnum.standard]: {
|
||||
label: 'support.user.team.subscription.type.standard'
|
||||
},
|
||||
[SubTypeEnum.extraDatasetSize]: {
|
||||
label: 'support.user.team.subscription.type.extraDatasetSize'
|
||||
},
|
||||
[SubTypeEnum.extraPoints]: {
|
||||
label: 'support.user.team.subscription.type.extraPoints'
|
||||
}
|
||||
};
|
||||
|
||||
export enum SubStatusEnum {
|
||||
active = 'active',
|
||||
canceled = 'canceled'
|
||||
}
|
||||
export const subStatusMap = {
|
||||
[SubStatusEnum.active]: {
|
||||
label: 'support.user.team.subscription.status.active'
|
||||
},
|
||||
[SubStatusEnum.canceled]: {
|
||||
label: 'support.user.team.subscription.status.canceled'
|
||||
}
|
||||
};
|
||||
export const subSelectMap = {
|
||||
true: SubStatusEnum.active,
|
||||
false: SubStatusEnum.canceled
|
||||
};
|
||||
|
||||
export enum SubModeEnum {
|
||||
month = 'month',
|
||||
year = 'year'
|
||||
}
|
||||
|
||||
export const subModeMap = {
|
||||
[SubModeEnum.month]: {
|
||||
label: 'support.user.team.subscription.mode.month'
|
||||
label: 'support.user.team.subscription.mode.month',
|
||||
durationMonth: 1
|
||||
},
|
||||
[SubModeEnum.year]: {
|
||||
label: 'support.user.team.subscription.mode.year'
|
||||
label: 'support.user.team.subscription.mode.year',
|
||||
durationMonth: 12
|
||||
}
|
||||
};
|
||||
|
||||
export enum SubStatusEnum {
|
||||
active = 'active',
|
||||
expired = 'expired'
|
||||
export enum StandardSubLevelEnum {
|
||||
free = 'free',
|
||||
experience = 'experience',
|
||||
team = 'team',
|
||||
enterprise = 'enterprise',
|
||||
custom = 'custom'
|
||||
}
|
||||
|
||||
export const subStatusMap = {
|
||||
[SubStatusEnum.active]: {
|
||||
label: 'support.user.team.subscription.status.active'
|
||||
export const standardSubLevelMap = {
|
||||
[StandardSubLevelEnum.free]: {
|
||||
label: 'support.user.team.subscription.standardSubLevel.free'
|
||||
},
|
||||
[SubStatusEnum.expired]: {
|
||||
label: 'support.user.team.subscription.status.expired'
|
||||
[StandardSubLevelEnum.experience]: {
|
||||
label: 'support.user.team.subscription.standardSubLevel.experience'
|
||||
},
|
||||
[StandardSubLevelEnum.team]: {
|
||||
label: 'support.user.team.subscription.standardSubLevel.team'
|
||||
},
|
||||
[StandardSubLevelEnum.enterprise]: {
|
||||
label: 'support.user.team.subscription.standardSubLevel.enterprise'
|
||||
},
|
||||
[StandardSubLevelEnum.custom]: {
|
||||
label: 'support.user.team.subscription.standardSubLevel.custom'
|
||||
}
|
||||
};
|
||||
|
33
packages/global/support/wallet/sub/type.d.ts
vendored
33
packages/global/support/wallet/sub/type.d.ts
vendored
@@ -1,12 +1,39 @@
|
||||
import { SubModeEnum, SubStatusEnum, SubTypeEnum } from './constants';
|
||||
import { StandardSubLevelEnum, SubModeEnum, SubStatusEnum, SubTypeEnum } from './constants';
|
||||
|
||||
export type TeamSubSchema = {
|
||||
_id: string;
|
||||
teamId: string;
|
||||
type: `${SubTypeEnum}`;
|
||||
mode: `${SubModeEnum}`;
|
||||
status: `${SubStatusEnum}`;
|
||||
renew: boolean;
|
||||
mode: `${SubModeEnum}`;
|
||||
startTime: Date;
|
||||
expiredTime: Date;
|
||||
price: number;
|
||||
|
||||
currentSubLevel?: `${StandardSubLevelEnum}`;
|
||||
nextSubLevel?: `${StandardSubLevelEnum}`;
|
||||
|
||||
currentExtraDatasetSize?: number;
|
||||
nextExtraDatasetSize?: number;
|
||||
|
||||
currentExtraPoints?: number;
|
||||
nextExtraPoints?: number;
|
||||
|
||||
maxTeamMember?: number;
|
||||
maxAppAmount?: number;
|
||||
maxDatasetAmount?: number;
|
||||
chatHistoryStoreDuration?: number;
|
||||
maxDatasetSize?: number;
|
||||
customApiKey?: boolean;
|
||||
customCopyright?: number;
|
||||
exportDatasetInterval?: number;
|
||||
websiteSyncInterval?: number;
|
||||
reRankWeight?: number;
|
||||
totalPoints?: number;
|
||||
|
||||
surplusPoints?: number;
|
||||
|
||||
// abandon
|
||||
datasetStoreAmount?: number;
|
||||
renew?: boolean;
|
||||
};
|
||||
|
@@ -49,7 +49,7 @@ export const addLog = {
|
||||
},
|
||||
error(msg: string, error?: any) {
|
||||
this.log('error', msg, {
|
||||
message: error?.message,
|
||||
message: error?.message || error,
|
||||
stack: error?.stack,
|
||||
...(error?.config && {
|
||||
config: {
|
||||
|
@@ -47,18 +47,19 @@ const ChatItemSchema = new Schema({
|
||||
default: () => new Date()
|
||||
},
|
||||
obj: {
|
||||
// chat role
|
||||
type: String,
|
||||
required: true,
|
||||
enum: Object.keys(ChatRoleMap)
|
||||
},
|
||||
value: {
|
||||
// chat content
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
userGoodFeedback: {
|
||||
type: String
|
||||
},
|
||||
userFeedback: String,
|
||||
userBadFeedback: {
|
||||
type: String
|
||||
},
|
||||
|
@@ -86,13 +86,13 @@ const DatasetDataSchema = new Schema({
|
||||
});
|
||||
|
||||
try {
|
||||
// same data check
|
||||
DatasetDataSchema.index({ teamId: 1, collectionId: 1, q: 1, a: 1 }, { background: true });
|
||||
// list collection and count data; list data
|
||||
DatasetDataSchema.index(
|
||||
{ teamId: 1, datasetId: 1, collectionId: 1, chunkIndex: 1, updateTime: -1 },
|
||||
{ background: true }
|
||||
);
|
||||
// same data check
|
||||
DatasetDataSchema.index({ teamId: 1, collectionId: 1, q: 1, a: 1 }, { background: true });
|
||||
// full text index
|
||||
DatasetDataSchema.index({ teamId: 1, datasetId: 1, fullTextToken: 'text' }, { background: true });
|
||||
// Recall vectors after data matching
|
||||
|
@@ -10,8 +10,10 @@ export const checkDatasetLimit = async ({
|
||||
freeSize?: number;
|
||||
insertLen?: number;
|
||||
}) => {
|
||||
const { maxSize } = await getTeamDatasetValidSub({ teamId, freeSize });
|
||||
const usedSize = await getVectorCountByTeamId(teamId);
|
||||
const [{ maxSize }, usedSize] = await Promise.all([
|
||||
getTeamDatasetValidSub({ teamId, freeSize }),
|
||||
getVectorCountByTeamId(teamId)
|
||||
]);
|
||||
|
||||
if (usedSize + insertLen >= maxSize) {
|
||||
return Promise.reject(`数据库容量不足,无法继续添加。可以在账号页面进行扩容。`);
|
||||
|
@@ -8,10 +8,6 @@ import {
|
||||
} from '@fastgpt/global/support/user/team/constant';
|
||||
|
||||
const BillSchema = new Schema({
|
||||
userId: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: 'user'
|
||||
},
|
||||
teamId: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: TeamCollectionName,
|
||||
@@ -28,7 +24,7 @@ const BillSchema = new Schema({
|
||||
},
|
||||
appId: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: 'model',
|
||||
ref: 'apps',
|
||||
required: false
|
||||
},
|
||||
time: {
|
||||
@@ -52,7 +48,7 @@ const BillSchema = new Schema({
|
||||
});
|
||||
|
||||
try {
|
||||
BillSchema.index({ teamId: 1, time: -1 });
|
||||
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);
|
||||
|
@@ -1,10 +1,15 @@
|
||||
import { connectionMongo, type Model } from '../../../common/mongo';
|
||||
const { Schema, model, models } = connectionMongo;
|
||||
import { TeamCollectionName } from '@fastgpt/global/support/user/team/constant';
|
||||
import { subModeMap, subStatusMap, subTypeMap } from '@fastgpt/global/support/wallet/sub/constants';
|
||||
import {
|
||||
standardSubLevelMap,
|
||||
subModeMap,
|
||||
subStatusMap,
|
||||
subTypeMap
|
||||
} from '@fastgpt/global/support/wallet/sub/constants';
|
||||
import type { TeamSubSchema } from '@fastgpt/global/support/wallet/sub/type';
|
||||
|
||||
export const subCollectionName = 'team.subscription';
|
||||
export const subCollectionName = 'team.subscriptions';
|
||||
|
||||
const SubSchema = new Schema({
|
||||
teamId: {
|
||||
@@ -17,29 +22,107 @@ const SubSchema = new Schema({
|
||||
enum: Object.keys(subTypeMap),
|
||||
required: true
|
||||
},
|
||||
status: {
|
||||
// active: continue sub; canceled: canceled sub;
|
||||
type: String,
|
||||
enum: Object.keys(subStatusMap),
|
||||
required: true
|
||||
},
|
||||
mode: {
|
||||
type: String,
|
||||
enum: Object.keys(subModeMap),
|
||||
required: true
|
||||
},
|
||||
status: {
|
||||
type: String,
|
||||
enum: Object.keys(subStatusMap),
|
||||
required: true
|
||||
},
|
||||
renew: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
startTime: {
|
||||
type: Date
|
||||
type: Date,
|
||||
default: () => new Date()
|
||||
},
|
||||
expiredTime: {
|
||||
type: Date
|
||||
type: Date,
|
||||
required: true
|
||||
},
|
||||
datasetStoreAmount: {
|
||||
price: {
|
||||
// last sub pay price(total price)
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
|
||||
// sub content
|
||||
currentSubLevel: {
|
||||
type: String,
|
||||
enum: Object.keys(standardSubLevelMap)
|
||||
},
|
||||
nextSubLevel: {
|
||||
type: String,
|
||||
enum: Object.keys(standardSubLevelMap)
|
||||
},
|
||||
|
||||
currentExtraDatasetSize: {
|
||||
type: Number
|
||||
}
|
||||
},
|
||||
nextExtraDatasetSize: {
|
||||
type: Number
|
||||
},
|
||||
|
||||
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
|
||||
},
|
||||
exportDatasetInterval: {
|
||||
// hours
|
||||
type: Number
|
||||
},
|
||||
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 {
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { SubStatusEnum } from '@fastgpt/global/support/wallet/sub/constants';
|
||||
import { SubTypeEnum } from '@fastgpt/global/support/wallet/sub/constants';
|
||||
import { MongoTeamSub } from './schema';
|
||||
|
||||
/* get team dataset size */
|
||||
@@ -11,17 +11,14 @@ export const getTeamDatasetValidSub = async ({
|
||||
}) => {
|
||||
const sub = await MongoTeamSub.findOne({
|
||||
teamId,
|
||||
status: SubStatusEnum.active
|
||||
})
|
||||
.sort({
|
||||
expiredTime: -1
|
||||
})
|
||||
.lean();
|
||||
type: SubTypeEnum.extraDatasetSize,
|
||||
expiredTime: { $gte: new Date() }
|
||||
}).lean();
|
||||
|
||||
const maxSize = (() => {
|
||||
if (!sub || !sub.datasetStoreAmount) return freeSize;
|
||||
if (!sub || !sub.currentExtraDatasetSize) return freeSize;
|
||||
|
||||
return sub.datasetStoreAmount + freeSize;
|
||||
return sub.currentExtraDatasetSize + freeSize;
|
||||
})();
|
||||
|
||||
return {
|
||||
|
@@ -1,9 +1,13 @@
|
||||
import React from 'react';
|
||||
import Editor from '@monaco-editor/react';
|
||||
import Editor, { loader } from '@monaco-editor/react';
|
||||
import { useCallback, useRef, useState } from 'react';
|
||||
import { Box, BoxProps } from '@chakra-ui/react';
|
||||
import MyIcon from '../../Icon';
|
||||
|
||||
loader.config({
|
||||
paths: { vs: "/js/monaco-editor.0.43.0" },
|
||||
});
|
||||
|
||||
type Props = Omit<BoxProps, 'onChange' | 'resize' | 'height'> & {
|
||||
height?: number;
|
||||
resize?: boolean;
|
||||
|
Reference in New Issue
Block a user