Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

optimize payment process #3517

Merged
merged 1 commit into from
Jan 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/global/common/error/code/team.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { i18nT } from '../../../../web/i18n/utils';
export enum TeamErrEnum {
teamOverSize = 'teamOverSize',
unAuthTeam = 'unAuthTeam',
teamMemberOverSize = 'teamMemberOverSize',
aiPointsNotEnough = 'aiPointsNotEnough',
datasetSizeNotEnough = 'datasetSizeNotEnough',
datasetAmountNotEnough = 'datasetAmountNotEnough',
Expand Down
4 changes: 1 addition & 3 deletions packages/service/support/permission/teamLimit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@ export const checkDatasetLimit = async ({
if (!standardConstants) return;

if (usedDatasetSize + insertLen >= datasetMaxSize) {
return Promise.reject(
`您的知识库容量为: ${datasetMaxSize}组,已使用: ${usedDatasetSize}组,导入当前文件需要: ${insertLen}组,请增加知识库容量后导入。`
);
return Promise.reject(TeamErrEnum.datasetSizeNotEnough);
}

if (usedPoints >= totalPoints) {
Expand Down
1 change: 1 addition & 0 deletions packages/web/components/common/Icon/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ export const iconPaths = {
'common/variable': () => import('./icons/common/variable.svg'),
'common/viewLight': () => import('./icons/common/viewLight.svg'),
'common/voiceLight': () => import('./icons/common/voiceLight.svg'),
'common/wallet': () => import('./icons/common/wallet.svg'),
'common/warn': () => import('./icons/common/warn.svg'),
'common/wechatFill': () => import('./icons/common/wechatFill.svg'),
configmap: () => import('./icons/configmap.svg'),
Expand Down
4 changes: 4 additions & 0 deletions packages/web/components/common/Icon/icons/common/wallet.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions packages/web/i18n/en/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -1050,10 +1050,14 @@
"support.wallet.Ai point every thousand tokens_input": "Input:{{points}} points/1K tokens",
"support.wallet.Ai point every thousand tokens_output": "Output:{{points}} points/1K tokens",
"support.wallet.Amount": "Amount",
"support.wallet.App_amount_not_sufficient": "The number of your applications has reached the limit. Please upgrade your plan to continue using.",
"support.wallet.Buy": "Buy",
"support.wallet.Dataset_amount_not_sufficient": "The number of your datasets has reached the limit. Please upgrade your plan to continue using.",
"support.wallet.Dataset_not_sufficient": "Your dataset capacity is insufficient. Please upgrade your plan or purchase additional dataset capacity to continue using.",
"support.wallet.Not sufficient": "Insufficient AI Points, Please Upgrade Your Package or Purchase Additional AI Points to Continue Using.",
"support.wallet.Plan expired time": "Package Expiration Time",
"support.wallet.Standard Plan Detail": "Package Details",
"support.wallet.Team_member_over_size": "The number of your team members has reached the limit. Please upgrade your plan to continue using.",
"support.wallet.To read plan": "View Package",
"support.wallet.amount_0": "Purchase Quantity Cannot Be 0",
"support.wallet.apply_invoice": "Apply for Invoice",
Expand Down
4 changes: 4 additions & 0 deletions packages/web/i18n/zh-CN/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -1053,10 +1053,14 @@
"support.wallet.Ai point every thousand tokens_input": "输入:{{points}} 积分/1K tokens",
"support.wallet.Ai point every thousand tokens_output": "输出:{{points}} 积分/1K tokens",
"support.wallet.Amount": "金额",
"support.wallet.App_amount_not_sufficient": "您的应用数量已达上限,请升级套餐后继续使用。",
"support.wallet.Buy": "购买",
"support.wallet.Dataset_amount_not_sufficient": "您的知识库数量已达上限,请升级套餐后继续使用。",
"support.wallet.Dataset_not_sufficient": "您的知识库容量不足,请先升级套餐或购买额外知识库容量后继续使用。",
"support.wallet.Not sufficient": "您的 AI 积分不足,请先升级套餐或购买额外 AI 积分后继续使用。",
"support.wallet.Plan expired time": "套餐到期时间",
"support.wallet.Standard Plan Detail": "套餐详情",
"support.wallet.Team_member_over_size": "您的团队成员数量已达上限,请升级套餐后继续使用。",
"support.wallet.To read plan": "查看套餐",
"support.wallet.amount_0": "购买数量不能为0",
"support.wallet.apply_invoice": "申请开票",
Expand Down
4 changes: 4 additions & 0 deletions packages/web/i18n/zh-Hant/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -1050,10 +1050,14 @@
"support.wallet.Ai point every thousand tokens_input": "輸入:{{points}} 积分/1K tokens",
"support.wallet.Ai point every thousand tokens_output": "輸出:{{points}} 积分/1K tokens",
"support.wallet.Amount": "金額",
"support.wallet.App_amount_not_sufficient": "您的應用數量已達上限,請升級套餐後繼續使用。",
"support.wallet.Buy": "購買",
"support.wallet.Dataset_amount_not_sufficient": "您的知識庫數量已達上限,請升級套餐後繼續使用。",
"support.wallet.Dataset_not_sufficient": "您的知識庫容量不足,請先升級套餐或購買額外知識庫容量後繼續使用。",
"support.wallet.Not sufficient": "您的 AI 點數不足,請先升級方案或購買額外 AI 點數後繼續使用。",
"support.wallet.Plan expired time": "方案到期時間",
"support.wallet.Standard Plan Detail": "方案詳細資訊",
"support.wallet.Team_member_over_size": "您的團隊成員數量已達上限,請升級套餐後繼續使用。",
"support.wallet.To read plan": "檢視方案",
"support.wallet.amount_0": "購買數量不能為 0",
"support.wallet.apply_invoice": "申請發票",
Expand Down
4 changes: 2 additions & 2 deletions projects/app/src/components/Layout/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export const navbarWidth = '64px';
const Layout = ({ children }: { children: JSX.Element }) => {
const router = useRouter();
const { Loading } = useLoading();
const { loading, feConfigs, isNotSufficientModal } = useSystemStore();
const { loading, feConfigs, notSufficientModalType } = useSystemStore();
const { isPc } = useSystem();
const { userInfo } = useUserStore();
const { setUserDefaultLng } = useI18nLng();
Expand Down Expand Up @@ -113,7 +113,7 @@ const Layout = ({ children }: { children: JSX.Element }) => {
{feConfigs?.isPlus && (
<>
{!!userInfo && <UpdateInviteModal />}
{isNotSufficientModal && <NotSufficientModal />}
{notSufficientModalType && <NotSufficientModal type={notSufficientModalType} />}
{!!userInfo && <SystemMsgModal />}
{!!userInfo && importantInforms.length > 0 && (
<ImportantInform informs={importantInforms} refetch={refetchUnRead} />
Expand Down
159 changes: 136 additions & 23 deletions projects/app/src/components/support/wallet/NotSufficientModal/index.tsx
Original file line number Diff line number Diff line change
@@ -1,35 +1,148 @@
import React from 'react';
import React, { useMemo, useState } from 'react';
import MyModal from '@fastgpt/web/components/common/MyModal';
import { useTranslation } from 'next-i18next';
import { Button, ModalBody, ModalFooter } from '@chakra-ui/react';
import { useRouter } from 'next/router';
import { useSystemStore } from '@/web/common/system/useSystemStore';
import { Box, Button, Flex, ModalBody, ModalFooter, useDisclosure } from '@chakra-ui/react';
import { NotSufficientModalType, useSystemStore } from '@/web/common/system/useSystemStore';
import ExtraPlan from '@/pages/price/components/ExtraPlan';
import StandardPlan from '@/pages/price/components/Standard';
import FillRowTabs from '@fastgpt/web/components/common/Tabs/FillRowTabs';
import FormLabel from '@fastgpt/web/components/common/MyBox/FormLabel';
import { useUserStore } from '@/web/support/user/useUserStore';
import { standardSubLevelMap } from '@fastgpt/global/support/wallet/sub/constants';
import { TeamErrEnum } from '@fastgpt/global/common/error/code/team';

const NotSufficientModal = () => {
const NotSufficientModal = ({ type }: { type: NotSufficientModalType }) => {
const { t } = useTranslation();
const router = useRouter();
const { setIsNotSufficientModal } = useSystemStore();
const { setNotSufficientModalType } = useSystemStore();

const onClose = () => setIsNotSufficientModal(false);
const onClose = () => setNotSufficientModalType(undefined);

const {
isOpen: isRechargeModalOpen,
onOpen: onRechargeModalOpen,
onClose: onRechargeModalClose
} = useDisclosure();

const textMap = {
[TeamErrEnum.aiPointsNotEnough]: t('common:support.wallet.Not sufficient'),
[TeamErrEnum.datasetSizeNotEnough]: t('common:support.wallet.Dataset_not_sufficient'),
[TeamErrEnum.datasetAmountNotEnough]: t('common:support.wallet.Dataset_amount_not_sufficient'),
[TeamErrEnum.teamMemberOverSize]: t('common:support.wallet.Team_member_over_size'),
[TeamErrEnum.appAmountNotEnough]: t('common:support.wallet.App_amount_not_sufficient')
};

return (
<>
<MyModal
isOpen
iconSrc="common/confirm/deleteTip"
title={t('common:common.Warning')}
w={'420px'}
>
<ModalBody>{textMap[type]}</ModalBody>
<ModalFooter>
<Button variant={'whiteBase'} mr={2} onClick={onClose}>
{t('common:common.Close')}
</Button>
<Button
onClick={() => {
onRechargeModalOpen();
}}
>
{t('common:support.wallet.To read plan')}
</Button>
</ModalFooter>
</MyModal>

{isRechargeModalOpen && (
<RechargeModal onClose={onRechargeModalClose} onPaySuccess={onClose} />
)}
</>
);
};

export default NotSufficientModal;

const RechargeModal = ({
onClose,
onPaySuccess
}: {
onClose: () => void;
onPaySuccess: () => void;
}) => {
const { t } = useTranslation();
const { teamPlanStatus } = useUserStore();

const planName = useMemo(() => {
if (!teamPlanStatus?.standard?.currentSubLevel) return '';
return standardSubLevelMap[teamPlanStatus.standard.currentSubLevel].label;
}, [teamPlanStatus?.standard?.currentSubLevel]);

const [tab, setTab] = useState<'standard' | 'extra'>('standard');

return (
<MyModal isOpen iconSrc="common/confirm/deleteTip" title={t('common:common.Warning')}>
<ModalBody>{t('common:support.wallet.Not sufficient')}</ModalBody>
<ModalFooter>
<Button variant={'whiteBase'} mr={2} onClick={onClose}>
{t('common:common.Close')}
</Button>
<Button
onClick={() => {
router.push('/account/info');
onClose();
<MyModal
isOpen
iconSrc="common/wallet"
iconColor={'primary.600'}
title={t('common:user.Pay')}
onClose={onClose}
isCentered
minW={['100%', '1200px']}
minH={['100%', '800px']}
>
<ModalBody px={'52px'}>
<Flex alignItems={'center'} mb={6}>
<FormLabel fontSize={'16px'} fontWeight={'medium'}>
{t('common:support.wallet.subscription.Current plan')}
</FormLabel>
<Box fontSize={'14px'} ml={5} color={'myGray.900'}>
{t(planName as any)}
</Box>
</Flex>

<Flex alignItems={'center'} mb={6}>
<FormLabel fontSize={'16px'} fontWeight={'medium'}>
{t('common:info.resource')}
</FormLabel>
<Flex fontSize={'14px'} ml={5} color={'myGray.900'}>
<Box>{`${t('common:support.user.team.Dataset usage')}:`}</Box>
<Box
ml={2}
>{`${teamPlanStatus?.usedDatasetSize} / ${teamPlanStatus?.datasetMaxSize || t('account_info:unlimited')}`}</Box>
<Box ml={5}>{`${t('common:support.wallet.subscription.AI points usage')}:`}</Box>
<Box
ml={2}
>{`${Math.round(teamPlanStatus?.usedPoints || 0)} / ${teamPlanStatus?.totalPoints || t('account_info:unlimited')}`}</Box>
</Flex>
</Flex>

<FillRowTabs
list={[
{ label: t('common:support.wallet.subscription.Sub plan'), value: 'standard' },
{ label: t('common:support.wallet.subscription.Extra plan'), value: 'extra' }
]}
value={tab}
onChange={(e) => {
setTab(e as 'standard' | 'extra');
}}
/>

<Box
mt={3}
p={8}
bg={'myGray.50'}
border={'1px solid'}
borderColor={'myGray.200'}
rounded={'12px'}
>
{t('common:support.wallet.To read plan')}
</Button>
</ModalFooter>
{tab === 'standard' ? (
<StandardPlan standardPlan={teamPlanStatus?.standard} onPaySuccess={onPaySuccess} />
) : (
<ExtraPlan onPaySuccess={onPaySuccess} />
)}
</Box>
</ModalBody>
</MyModal>
);
};

export default NotSufficientModal;
6 changes: 4 additions & 2 deletions projects/app/src/pages/account/team/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { TeamContext, TeamModalContextProvider } from './components/context';
import dynamic from 'next/dynamic';
import TeamTagModal from '@/components/support/user/team/TeamTagModal';
import MemberTable from './components/MemberTable';
import { TeamErrEnum } from '@fastgpt/global/common/error/code/team';

const InviteModal = dynamic(() => import('./components/InviteModal'));
const PermissionManage = dynamic(() => import('./components/PermissionManage/index'));
Expand All @@ -39,7 +40,7 @@ const Team = () => {
const { toast } = useToast();
const { t } = useTranslation();
const { userInfo, teamPlanStatus } = useUserStore();
const { feConfigs } = useSystemStore();
const { feConfigs, setNotSufficientModalType } = useSystemStore();

const {
myTeams,
Expand Down Expand Up @@ -218,10 +219,11 @@ const Team = () => {
) {
toast({
status: 'warning',
title: t('user.team.Over Max Member Tip', {
title: t('common:user.team.Over Max Member Tip', {
max: teamPlanStatus.standardConstants.maxTeamMember
})
});
setNotSufficientModalType(TeamErrEnum.teamMemberOverSize);
} else {
onOpenInvite();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ const ApiDatasetForm = ({
</Flex>
<Input
bg={'myWhite.600'}
placeholder={'Token'}
placeholder={'User ID'}
maxLength={200}
{...register('yuqueServer.userId', { required: true })}
/>
Expand Down
23 changes: 6 additions & 17 deletions projects/app/src/pages/price/components/ExtraPlan.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Box, Flex, Grid, Button } from '@chakra-ui/react';
import { Box, Flex, Grid, Button, VStack } from '@chakra-ui/react';
import { useTranslation } from 'next-i18next';
import React, { useCallback, useState } from 'react';
import { useSystemStore } from '@/web/common/system/useSystemStore';
Expand All @@ -11,7 +11,7 @@ import { BillTypeEnum } from '@fastgpt/global/support/wallet/bill/constants';
import QRCodePayModal, { type QRPayProps } from '@/components/support/wallet/QRCodePayModal';
import MyNumberInput from '@fastgpt/web/components/common/Input/NumberInput';

const ExtraPlan = () => {
const ExtraPlan = ({ onPaySuccess }: { onPaySuccess?: () => void }) => {
const { t } = useTranslation();
const { toast } = useToast();
const { subPlans } = useSystemStore();
Expand Down Expand Up @@ -108,19 +108,8 @@ const ExtraPlan = () => {
);

return (
<Flex
mt={['40px', '100px']}
flexDirection={'column'}
alignItems={'center'}
position={'relative'}
>
<Box id={'extra-plan'} fontWeight={'bold'} fontSize={['24px', '36px']} color={'myGray.900'}>
{t('common:support.wallet.subscription.Extra plan')}
</Box>
<Box mt={2} mb={8} color={'myGray.600'} fontSize={'md'}>
{t('common:support.wallet.subscription.Extra plan tip')}
</Box>
<Grid mt={8} gridTemplateColumns={['1fr', '1fr 1fr']} gap={5} w={['100%', 'auto']}>
<VStack>
<Grid gridTemplateColumns={['1fr', '1fr 1fr']} gap={5} w={['100%', 'auto']}>
<Box
bg={'rgba(255, 255, 255, 0.90)'}
px={'32px'}
Expand Down Expand Up @@ -284,8 +273,8 @@ const ExtraPlan = () => {
</Box>
</Grid>

{!!qrPayData && <QRCodePayModal {...qrPayData} />}
</Flex>
{!!qrPayData && <QRCodePayModal onSuccess={onPaySuccess} {...qrPayData} />}
</VStack>
);
};

Expand Down
Loading
Loading