V4.6.9-first commit (#899)

* perf: insert mongo dataset data session

* perf: dataset data index

* remove delay

* rename bill schema

* rename bill record

* perf: bill table

* perf: prompt

* perf: sub plan

* change the usage count

* feat: usage bill

* publish usages

* doc

* 新增团队聊天功能 (#20)

* perf: doc

* feat 添加标签部分

feat 信息团队标签配置

feat 新增团队同步管理

feat team分享页面

feat 完成team分享页面

feat 实现模糊搜索

style 格式化

fix 修复迷糊匹配

style 样式修改

fix 团队标签功能修复

* fix 修复鉴权功能

* merge 合并代码

* fix 修复引用错误

* fix 修复pr问题

* fix 修复ts格式问题

---------

Co-authored-by: archer <545436317@qq.com>
Co-authored-by: liuxingwan <liuxingwan.lxw@alibaba-inc.com>

* update extra plan

* fix: ts

* format

* perf: bill field

* feat: standard plan

* fix: ts

* feat 个人账号页面修改 (#22)

* feat 添加标签部分

feat 信息团队标签配置

feat 新增团队同步管理

feat team分享页面

feat 完成team分享页面

feat 实现模糊搜索

style 格式化

fix 修复迷糊匹配

style 样式修改

fix 团队标签功能修复

* fix 修复鉴权功能

* merge 合并代码

* fix 修复引用错误

* fix 修复pr问题

* fix 修复ts格式问题

* feat 修改个人账号页

---------

Co-authored-by: liuxingwan <liuxingwan.lxw@alibaba-inc.com>

* sub plan page (#23)

* fix chunk index; error page text

* feat: dataset process Integral prediction

* feat: stand plan field

* feat: sub plan limit

* perf: index

* query extension

* perf: share link push app name

* perf: plan point unit

* perf: get sub plan

* perf: account page

* feat 新增套餐详情弹窗代码 (#24)

* merge 合并代码

* fix 新增套餐详情弹框

* fix 修复pr问题

* feat: change http node input to prompt editor (#21)

* feat: change http node input to prompt editor

* fix

* split PromptEditor to HttpInput

* Team plans (#25)

* perf: pay check

* perf: team plan test

* plan limit check

* replace sensitive text

* perf: fix some null

* collection null check

* perf: plans modal

* perf: http module

* pacakge (#26)

* individuation page and pay modal amount (#27)

* feat: individuation page

* team chat config

* pay modal

* plan count and replace invalid chars (#29)

* fix: user oneapi

* fix: training queue

* fix: qa queue

* perf: remove space chars

* replace invalid chars

* change httpinput dropdown menu (#28)

* perf: http

* reseet free plan

* perf: plan code to packages

* remove llm config to package

* perf: code

* perf: faq

* fix: get team plan

---------

Co-authored-by: yst <77910600+yu-and-liu@users.noreply.github.com>
Co-authored-by: liuxingwan <liuxingwan.lxw@alibaba-inc.com>
Co-authored-by: heheer <71265218+newfish-cmyk@users.noreply.github.com>
This commit is contained in:
Archer
2024-02-28 13:19:15 +08:00
committed by GitHub
parent 32686f9e3e
commit 064c64e74c
282 changed files with 7223 additions and 4731 deletions

View File

@@ -7,92 +7,110 @@ import {
NumberIncrementStepper,
NumberInputField,
NumberInputStepper,
Button,
useDisclosure,
ModalBody,
ModalFooter
Button
} from '@chakra-ui/react';
import { TeamSubSchema } from '@fastgpt/global/support/wallet/sub/type';
import { useTranslation } from 'next-i18next';
import React, { useEffect, useMemo, useState } from 'react';
import React, { useCallback, useState } from 'react';
import { useSystemStore } from '@/web/common/system/useSystemStore';
import MyIcon from '@fastgpt/web/components/common/Icon';
import { formatTime2YMDHM } from '@fastgpt/global/common/string/time';
import MySelect from '@/components/Select';
import {
SubStatusEnum,
SubTypeEnum,
subSelectMap
} from '@fastgpt/global/support/wallet/sub/constants';
import { useRequest } from '@/web/common/hooks/useRequest';
import {
posCheckTeamDatasetSizeSub,
postUpdateTeamDatasetSizeSub,
putTeamDatasetSubStatus
} from '@/web/support/wallet/sub/api';
import { SubDatasetSizePreviewCheckResponse } from '@fastgpt/global/support/wallet/sub/api.d';
import { useRouter } from 'next/router';
import { formatStorePrice2Read } from '@fastgpt/global/support/wallet/bill/tools';
import { useConfirm } from '@/web/common/hooks/useConfirm';
import { useUserStore } from '@/web/support/user/useUserStore';
import MyModal from '@/components/MyModal';
import { useForm } from 'react-hook-form';
import { useToast } from '@fastgpt/web/hooks/useToast';
import { getErrText } from '@fastgpt/global/common/error/utils';
import { getWxPayQRCode } from '@/web/support/wallet/bill/api';
import { BillTypeEnum } from '@fastgpt/global/support/wallet/bill/constants';
import QRCodePayModal, { type QRPayProps } from '@/components/support/wallet/QRCodePayModal';
const ExtraPlan = ({ extraDatasetSize }: { extraDatasetSize?: TeamSubSchema }) => {
const ExtraPlan = () => {
const { t } = useTranslation();
const { toast } = useToast();
const { subPlans } = useSystemStore();
const [loading, setLoading] = useState(false);
const [qrPayData, setQRPayData] = useState<QRPayProps>();
// extra dataset
const extraDatasetPrice = subPlans?.extraDatasetSize?.price || 0;
const [datasetSize, setDatasetSize] = useState(0);
const [isRenew, setIsRenew] = useState('false');
const router = useRouter();
const { userInfo } = useUserStore();
const [confirmPayExtraDatasetSizeData, setConfirmPayExtraDatasetSizeData] =
useState<SubDatasetSizePreviewCheckResponse>();
useEffect(() => {
setDatasetSize((extraDatasetSize?.nextExtraDatasetSize || 0) / 1000);
setIsRenew(extraDatasetSize?.status === SubStatusEnum.active ? 'true' : 'false');
}, [extraDatasetSize]);
const { mutate: onUpdateExtraDatasetSizeStatus } = useRequest({
mutationFn: (e: 'true' | 'false') => {
setIsRenew(e);
return putTeamDatasetSubStatus({
status: subSelectMap[e],
type: SubTypeEnum.extraDatasetSize
});
},
successToast: t('common.Update success'),
errorToast: t('common.error.Update error')
});
const { mutate: onClickUpdateExtraDatasetPlan, isLoading: isPayingExtraDatasetSize } = useRequest(
{
mutationFn: () => postUpdateTeamDatasetSizeSub({ size: datasetSize }),
onSuccess() {
setTimeout(() => {
router.reload();
}, 100);
},
successToast: t('common.Update success'),
errorToast: t('common.error.Update error')
const { register: registerDatasetSize, handleSubmit: handleSubmitDatasetSize } = useForm({
defaultValues: {
datasetSize: 0,
month: 1
}
);
const { mutate: onClickPreviewCheck, isLoading: isFetchingPreviewCheck } = useRequest({
mutationFn: () =>
posCheckTeamDatasetSizeSub({
size: datasetSize
}),
onSuccess(res: SubDatasetSizePreviewCheckResponse) {
if (!res.payForNewSub) {
onClickUpdateExtraDatasetPlan('');
return;
} else {
setConfirmPayExtraDatasetSizeData(res);
}
},
errorToast: t('common.error.Update error')
});
const onclickBuyDatasetSize = useCallback(
async ({ datasetSize, month }: { datasetSize: number; month: number }) => {
try {
const datasetSizePayAmount = datasetSize * month * extraDatasetPrice;
if (datasetSizePayAmount === 0) {
return toast({
status: 'warning',
title: '购买数量不能为0'
});
}
setLoading(true);
const res = await getWxPayQRCode({
type: BillTypeEnum.extraDatasetSub,
month,
extraDatasetSize: datasetSize
});
setQRPayData({
readPrice: res.readPrice,
codeUrl: res.codeUrl,
billId: res.billId
});
} catch (err) {
toast({
title: getErrText(err),
status: 'error'
});
}
setLoading(false);
},
[extraDatasetPrice, toast]
);
// extra ai points
const extraPointsPrice = subPlans?.extraPoints?.price || 0;
const { register: registerExtraPoints, handleSubmit: handleSubmitExtraPoints } = useForm({
defaultValues: {
points: 0,
month: 1
}
});
const onclickBuyExtraPoints = useCallback(
async ({ points }: { points: number }) => {
try {
const month = 1;
const payAmount = points * month * extraPointsPrice;
if (payAmount === 0) {
return toast({
status: 'warning',
title: '购买数量不能为0'
});
}
setLoading(true);
const res = await getWxPayQRCode({
type: BillTypeEnum.extraPoints,
extraPoints: points
});
setQRPayData({
readPrice: res.readPrice,
codeUrl: res.codeUrl,
billId: res.billId
});
} catch (err) {
toast({
title: getErrText(err),
status: 'error'
});
}
setLoading(false);
},
[extraPointsPrice, toast]
);
return (
<Flex
@@ -101,13 +119,13 @@ const ExtraPlan = ({ extraDatasetSize }: { extraDatasetSize?: TeamSubSchema }) =
alignItems={'center'}
position={'relative'}
>
<Box fontWeight={'bold'} fontSize={['24px', '36px']}>
<Box id={'extra-plan'} fontWeight={'bold'} fontSize={['24px', '36px']}>
{t('support.wallet.subscription.Extra plan')}
</Box>
<Box mt={8} mb={10} color={'myGray.500'} fontSize={'lg'}>
{t('support.wallet.subscription.Extra plan tip')}
</Box>
<Grid mt={8} gridTemplateColumns={['1fr', '1fr']}>
<Grid mt={8} gridTemplateColumns={['1fr', '1fr 1fr']} gap={5} w={['100%', 'auto']}>
<Box
bg={'rgba(255, 255, 255, 0.90)'}
px={'32px'}
@@ -116,78 +134,60 @@ const ExtraPlan = ({ extraDatasetSize }: { extraDatasetSize?: TeamSubSchema }) =
borderWidth={'1px'}
borderColor={'myGray.150'}
boxShadow={'1.5'}
w={['100%', '500px']}
>
<Flex w={['100%', '500px']} borderBottomWidth={'1px'} borderBottomColor={'myGray.200'}>
<Flex borderBottomWidth={'1px'} borderBottomColor={'myGray.200'}>
<Box flex={'1 0 0'}>
<Box fontSize={'xl'} color={'primary.600'}>
{t('support.wallet.subscription.Extra dataset size')}
</Box>
<Box mt={3} fontSize={['32px', '38px']} fontWeight={'bold'}>
{extraDatasetPrice}/1k{' '}
<Box mt={3} fontSize={['28px', '32px']} fontWeight={'bold'}>
{extraDatasetPrice}/1000{' '}
<Box ml={1} as={'span'} fontSize={'lg'} color={'myGray.600'} fontWeight={'normal'}>
/{t('common.month')}
</Box>
</Box>
</Box>
<MyIcon
transform={'translate(20px,-20px)'}
name={'support/pay/extraDatasetsize'}
display={['none', 'block']}
mt={'-30px'}
transform={'translateX(20px)'}
name={'support/bill/extraDatasetsize'}
fill={'none'}
/>
</Flex>
<Box>
<Box h={'120px'} w={'100%'}>
<Flex mt={4}>
<Box flex={'0 0 200px'}>
{t('support.wallet.subscription.Current dataset store')}:{' '}
</Box>
<Box fontWeight={'bold'} flex={1}>
{extraDatasetSize?.currentExtraDatasetSize || 0}
{t('core.dataset.data.unit')}
</Box>
</Flex>
{extraDatasetSize?.nextExtraDatasetSize !== undefined && (
<Flex mt={4}>
<Box flex={'0 0 200px'}>
{t('support.wallet.subscription.Next sub dataset size')}:
</Box>
<Box fontWeight={'bold'} flex={1}>
{extraDatasetSize?.nextExtraDatasetSize || 0}
{t('core.dataset.data.unit')}
</Box>
</Flex>
)}
{!!extraDatasetSize?.startTime && (
<Flex mt={3}>
<Box flex={'0 0 200px'}>: </Box>
<Box>{formatTime2YMDHM(extraDatasetSize?.startTime)}</Box>
</Flex>
)}
{!!extraDatasetSize?.expiredTime && (
<Flex mt={3}>
<Box flex={'0 0 200px'}>: </Box>
<Box>{formatTime2YMDHM(extraDatasetSize?.expiredTime)}</Box>
</Flex>
)}
<Flex mt={3} alignItems={'center'}>
<Box flex={'0 0 200px'}>: </Box>
<MySelect
value={isRenew}
size={'sm'}
w={'180px'}
bg={'myGray.50'}
boxShadow={'none'}
list={[
{ label: '自动续费', value: 'true' },
{ label: '不自动续费', value: 'false' }
]}
onchange={(e) => {
if (!extraDatasetSize) return;
onUpdateExtraDatasetSizeStatus(e);
}}
/>
<MyIcon mr={2} name={'support/bill/shoppingCart'} w={'16px'} color={'primary.600'} />
</Flex>
<Flex mt={4} alignItems={'center'}>
<Box flex={'0 0 200px'}>
<Box flex={['0 0 100px', '1 0 0']}>
{t('support.wallet.subscription.Month amount')}
</Box>
<Flex alignItems={'center'} mt={1} w={'180px'} position={'relative'}>
<NumberInput size={'sm'} flex={1} step={1} min={1} max={12} position={'relative'}>
<NumberInputField
pr={'30px'}
{...registerDatasetSize('month', {
required: true,
min: 1,
max: 12,
valueAsNumber: true
})}
/>
<NumberInputStepper>
<NumberIncrementStepper />
<NumberDecrementStepper />
</NumberInputStepper>
</NumberInput>
<Box position={'absolute'} right={'20px'} color={'myGray.500'} fontSize={'xs'}>
{t('common.month')}
</Box>
</Flex>
</Flex>
<Flex mt={4} alignItems={'center'}>
<Box flex={['0 0 100px', '1 0 0']}>
{t('support.wallet.subscription.Update extra dataset size')}
</Box>
<Flex alignItems={'center'} mt={1} w={'180px'} position={'relative'}>
@@ -197,13 +197,18 @@ const ExtraPlan = ({ extraDatasetSize }: { extraDatasetSize?: TeamSubSchema }) =
min={0}
max={10000}
step={1}
value={datasetSize}
position={'relative'}
onChange={(e) => {
setDatasetSize(Number(e));
}}
>
<NumberInputField pr={'30px'} value={datasetSize} step={1} min={0} max={10000} />
<NumberInputField
pr={'30px'}
{...registerDatasetSize('datasetSize', {
required: true,
min: 0,
max: 10000,
valueAsNumber: true
})}
step={1}
/>
<NumberInputStepper>
<NumberIncrementStepper />
<NumberDecrementStepper />
@@ -214,89 +219,125 @@ const ExtraPlan = ({ extraDatasetSize }: { extraDatasetSize?: TeamSubSchema }) =
</Box>
</Flex>
</Flex>
<Button
isDisabled={datasetSize * 1000 === extraDatasetSize?.nextExtraDatasetSize}
mt={6}
w={'100%'}
variant={'primaryGhost'}
isLoading={isPayingExtraDatasetSize || isFetchingPreviewCheck}
onClick={onClickPreviewCheck}
>
{t('common.change')}
</Button>
</Box>
<Button
mt={6}
w={'100%'}
variant={'primaryGhost'}
isLoading={loading}
onClick={handleSubmitDatasetSize(onclickBuyDatasetSize)}
>
{t('support.wallet.Buy')}
</Button>
</Box>
{/* points */}
<Box
bg={'rgba(255, 255, 255, 0.90)'}
w={['100%', '500px']}
px={'32px'}
py={'24px'}
borderRadius={'2xl'}
borderWidth={'1px'}
borderColor={'myGray.150'}
boxShadow={'1.5'}
>
<Flex borderBottomWidth={'1px'} borderBottomColor={'myGray.200'}>
<Box flex={'1 0 0'}>
<Box fontSize={'xl'} color={'primary.600'}>
{t('support.wallet.subscription.Extra ai points')}
</Box>
<Box mt={3} fontSize={['28px', '32px']} fontWeight={'bold'}>
{extraPointsPrice}/1000{' '}
<Box ml={1} as={'span'} fontSize={'lg'} color={'myGray.600'} fontWeight={'normal'}>
/{t('common.month')}
</Box>
</Box>
</Box>
<MyIcon
display={['none', 'block']}
mt={'-30px'}
transform={'translateX(20px)'}
name={'support/bill/extraPoints'}
fill={'none'}
/>
</Flex>
<Box h={'120px'} w={'100%'}>
<Flex mt={4}>
<MyIcon mr={2} name={'support/bill/shoppingCart'} w={'16px'} color={'primary.600'} />
</Flex>
{/* <Flex mt={4} alignItems={'center'}>
<Box flex={['0 0 100px', '1 0 0']}>
{t('support.wallet.subscription.Month amount')}
</Box>
<Flex alignItems={'center'} mt={1} w={'180px'} position={'relative'}>
<NumberInput size={'sm'} flex={1} step={1} min={1} max={12} position={'relative'}>
<NumberInputField
pr={'30px'}
{...registerExtraPoints('month', {
required: true,
min: 1,
max: 12,
valueAsNumber: true
})}
/>
<NumberInputStepper>
<NumberIncrementStepper />
<NumberDecrementStepper />
</NumberInputStepper>
</NumberInput>
<Box position={'absolute'} right={'20px'} color={'myGray.500'} fontSize={'xs'}>
{t('common.month')}
</Box>
</Flex>
</Flex> */}
<Flex mt={4} alignItems={'center'}>
<Box flex={['0 0 100px', '1 0 0']}>
{t('support.wallet.subscription.Update extra ai points')}
</Box>
<Flex alignItems={'center'} mt={1} w={'180px'} position={'relative'}>
<NumberInput
size={'sm'}
flex={1}
min={0}
max={10000}
step={1}
position={'relative'}
>
<NumberInputField
pr={'30px'}
step={1}
{...registerExtraPoints('points', {
required: true,
min: 0,
max: 10000,
valueAsNumber: true
})}
/>
<NumberInputStepper>
<NumberIncrementStepper />
<NumberDecrementStepper />
</NumberInputStepper>
</NumberInput>
<Box position={'absolute'} right={'20px'} color={'myGray.500'} fontSize={'xs'}>
000
</Box>
</Flex>
</Flex>
</Box>
<Button
mt={6}
w={'100%'}
variant={'primaryGhost'}
isLoading={loading}
onClick={handleSubmitExtraPoints(onclickBuyExtraPoints)}
>
{t('support.wallet.Buy')}
</Button>
</Box>
</Grid>
{/* extra dataset size modal */}
{!!confirmPayExtraDatasetSizeData && (
<MyModal
isOpen
onClose={() => setConfirmPayExtraDatasetSizeData(undefined)}
title={t('support.wallet.Confirm pay')}
iconSrc="common/confirm/rightTip"
>
<ModalBody px={8} py={5}>
<Flex>
<Box flex={'0 0 120px'} color={'myGray.600'}>
</Box>
<Box>{extraDatasetSize?.currentExtraDatasetSize || 0}</Box>
</Flex>
<Flex mt={4}>
<Box flex={'0 0 120px'} color={'myGray.600'}>
</Box>
<Box>{confirmPayExtraDatasetSizeData.newSubSize}</Box>
</Flex>
<Flex mt={4}>
<Box flex={'0 0 120px'} color={'myGray.600'}>
</Box>
<Box>{formatStorePrice2Read(confirmPayExtraDatasetSizeData.newPlanPrice)}</Box>
</Flex>
<Flex mt={4}>
<Box flex={'0 0 120px'} color={'myGray.600'}>
</Box>
<Box>30</Box>
</Flex>
{/* <Flex>
<Box flex={'0 0 120px'}>账号余额:</Box>
<Box>{formatStorePrice2Read(userInfo?.team?.balance).toFixed(3)}元</Box>
</Flex> */}
</ModalBody>
<ModalFooter mx={8} px={0} borderTopWidth={'1px'} borderTopColor={'myGray.200'}>
<Box color={'myGray.600'}></Box>
{confirmPayExtraDatasetSizeData.balanceEnough ? (
<>
<Box flex={'1 0 0'}>
{formatStorePrice2Read(userInfo?.team?.balance).toFixed(2)}
</Box>
<Button
isLoading={isPayingExtraDatasetSize}
onClick={() => onClickUpdateExtraDatasetPlan('')}
>
{formatStorePrice2Read(confirmPayExtraDatasetSizeData.payPrice).toFixed(2)}
</Button>
</>
) : (
<>
<Box color={'red.600'} flex={'1 0 0'}>
</Box>
<Button
isLoading={isPayingExtraDatasetSize}
onClick={() => router.push('/account')}
>
</Button>
</>
)}
</ModalFooter>
</MyModal>
)}
{!!qrPayData && <QRCodePayModal {...qrPayData} />}
</Flex>
);
};