Skip to content

Commit

Permalink
optimize payment process (#3517)
Browse files Browse the repository at this point in the history
  • Loading branch information
newfish-cmyk authored and c121914yu committed Jan 5, 2025
1 parent b852146 commit a065456
Show file tree
Hide file tree
Showing 17 changed files with 237 additions and 86 deletions.
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 type { ErrType } from '../errorCode';
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 @@ -96,6 +96,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 @@ -1068,10 +1068,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 @@ -1071,10 +1071,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 @@ -1068,10 +1068,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 @@ -51,7 +51,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, isUpdateNotification, setIsUpdateNotification } = useUserStore();
const { setUserDefaultLng } = useI18nLng();
Expand Down Expand Up @@ -121,7 +121,7 @@ const Layout = ({ children }: { children: JSX.Element }) => {
{feConfigs?.isPlus && (
<>
{!!userInfo && <UpdateInviteModal />}
{isNotSufficientModal && <NotSufficientModal />}
{notSufficientModalType && <NotSufficientModal type={notSufficientModalType} />}
{!!userInfo && <SystemMsgModal />}
{showUpdateNotification && (
<UpdateNotification onClose={() => setIsUpdateNotification(false)} />
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 @@ -41,7 +42,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 @@ -221,10 +222,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

0 comments on commit a065456

Please sign in to comment.