mirror of
https://github.com/labring/FastGPT.git
synced 2025-07-30 18:48:55 +00:00
V4.6.6-2 (#673)
This commit is contained in:
@@ -14,7 +14,7 @@ import {
|
||||
import { BillItemType } from '@fastgpt/global/support/wallet/bill/type.d';
|
||||
import dayjs from 'dayjs';
|
||||
import { BillSourceMap } from '@fastgpt/global/support/wallet/bill/constants';
|
||||
import { formatPrice } from '@fastgpt/global/support/wallet/bill/tools';
|
||||
import { formatStorePrice2Read } from '@fastgpt/global/support/wallet/bill/tools';
|
||||
import MyModal from '@/components/MyModal';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
|
||||
@@ -25,49 +25,107 @@ const BillDetail = ({ bill, onClose }: { bill: BillItemType; onClose: () => void
|
||||
[bill.list]
|
||||
);
|
||||
|
||||
const {
|
||||
hasModel,
|
||||
hasTokens,
|
||||
hasInputTokens,
|
||||
hasOutputTokens,
|
||||
hasTextLen,
|
||||
hasDuration,
|
||||
hasDataLen
|
||||
} = useMemo(() => {
|
||||
let hasModel = false;
|
||||
let hasTokens = false;
|
||||
let hasInputTokens = false;
|
||||
let hasOutputTokens = false;
|
||||
let hasTextLen = false;
|
||||
let hasDuration = false;
|
||||
let hasDataLen = false;
|
||||
|
||||
bill.list.forEach((item) => {
|
||||
if (item.model !== undefined) {
|
||||
hasModel = true;
|
||||
}
|
||||
if (item.tokenLen !== undefined) {
|
||||
hasTokens = true;
|
||||
}
|
||||
if (item.inputTokens !== undefined) {
|
||||
hasInputTokens = true;
|
||||
}
|
||||
if (item.outputTokens !== undefined) {
|
||||
hasOutputTokens = true;
|
||||
}
|
||||
if (item.textLen !== undefined) {
|
||||
hasTextLen = true;
|
||||
}
|
||||
if (item.duration !== undefined) {
|
||||
hasDuration = true;
|
||||
}
|
||||
if (item.dataLen !== undefined) {
|
||||
hasDataLen = true;
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
hasModel,
|
||||
hasTokens,
|
||||
hasInputTokens,
|
||||
hasOutputTokens,
|
||||
hasTextLen,
|
||||
hasDuration,
|
||||
hasDataLen
|
||||
};
|
||||
}, [bill.list]);
|
||||
|
||||
return (
|
||||
<MyModal
|
||||
isOpen={true}
|
||||
onClose={onClose}
|
||||
iconSrc="/imgs/modal/bill.svg"
|
||||
title={t('user.Bill Detail')}
|
||||
maxW={['90vw', '700px']}
|
||||
>
|
||||
<ModalBody>
|
||||
<Flex alignItems={'center'} pb={4}>
|
||||
<Box flex={'0 0 80px'}>用户:</Box>
|
||||
<Box flex={'0 0 80px'}>{t('wallet.bill.bill username')}:</Box>
|
||||
<Box>{t(bill.memberName)}</Box>
|
||||
</Flex>
|
||||
<Flex alignItems={'center'} pb={4}>
|
||||
<Box flex={'0 0 80px'}>订单号:</Box>
|
||||
<Box flex={'0 0 80px'}>{t('wallet.bill.Number')}:</Box>
|
||||
<Box>{bill.id}</Box>
|
||||
</Flex>
|
||||
<Flex alignItems={'center'} pb={4}>
|
||||
<Box flex={'0 0 80px'}>生成时间:</Box>
|
||||
<Box flex={'0 0 80px'}>{t('wallet.bill.Time')}:</Box>
|
||||
<Box>{dayjs(bill.time).format('YYYY/MM/DD HH:mm:ss')}</Box>
|
||||
</Flex>
|
||||
<Flex alignItems={'center'} pb={4}>
|
||||
<Box flex={'0 0 80px'}>应用名:</Box>
|
||||
<Box flex={'0 0 80px'}>{t('wallet.bill.App name')}:</Box>
|
||||
<Box>{t(bill.appName) || '-'}</Box>
|
||||
</Flex>
|
||||
<Flex alignItems={'center'} pb={4}>
|
||||
<Box flex={'0 0 80px'}>来源:</Box>
|
||||
<Box flex={'0 0 80px'}>{t('wallet.bill.Source')}:</Box>
|
||||
<Box>{BillSourceMap[bill.source]}</Box>
|
||||
</Flex>
|
||||
<Flex alignItems={'center'} pb={4}>
|
||||
<Box flex={'0 0 80px'}>总金额:</Box>
|
||||
<Box flex={'0 0 80px'}>{t('wallet.bill.Total')}:</Box>
|
||||
<Box fontWeight={'bold'}>{bill.total}元</Box>
|
||||
</Flex>
|
||||
<Box pb={4}>
|
||||
<Box flex={'0 0 80px'} mb={1}>
|
||||
扣费模块
|
||||
{t('wallet.bill.Bill Module')}
|
||||
</Box>
|
||||
<TableContainer>
|
||||
<Table>
|
||||
<Thead>
|
||||
<Tr>
|
||||
<Th>模块名</Th>
|
||||
<Th>AI模型</Th>
|
||||
<Th>Token长度</Th>
|
||||
<Th>{t('wallet.bill.Module name')}</Th>
|
||||
{hasModel && <Th>{t('wallet.bill.Ai model')}</Th>}
|
||||
{hasTokens && <Th>{t('wallet.bill.Token Length')}</Th>}
|
||||
{hasInputTokens && <Th>{t('wallet.bill.Input Token Length')}</Th>}
|
||||
{hasOutputTokens && <Th>{t('wallet.bill.Output Token Length')}</Th>}
|
||||
{hasTextLen && <Th>{t('wallet.bill.Text Length')}</Th>}
|
||||
{hasDuration && <Th>{t('wallet.bill.Duration')}</Th>}
|
||||
{hasDataLen && <Th>{t('wallet.bill.Data Length')}</Th>}
|
||||
<Th>费用(¥)</Th>
|
||||
</Tr>
|
||||
</Thead>
|
||||
@@ -75,9 +133,15 @@ const BillDetail = ({ bill, onClose }: { bill: BillItemType; onClose: () => void
|
||||
{filterBillList.map((item, i) => (
|
||||
<Tr key={i}>
|
||||
<Td>{t(item.moduleName)}</Td>
|
||||
<Td>{item.model || '-'}</Td>
|
||||
<Td>{item.tokenLen || '-'}</Td>
|
||||
<Td>{formatPrice(item.amount)}</Td>
|
||||
{hasModel && <Td>{item.model ?? '-'}</Td>}
|
||||
{hasTokens && <Td>{item.tokenLen ?? '-'}</Td>}
|
||||
{hasInputTokens && <Td>{item.inputTokens ?? '-'}</Td>}
|
||||
{hasOutputTokens && <Td>{item.outputTokens ?? '-'}</Td>}
|
||||
{hasTextLen && <Td>{item.textLen ?? '-'}</Td>}
|
||||
{hasDuration && <Td>{item.duration ?? '-'}</Td>}
|
||||
{hasDataLen && <Td>{item.dataLen ?? '-'}</Td>}
|
||||
|
||||
<Td>{formatStorePrice2Read(item.amount)}</Td>
|
||||
</Tr>
|
||||
))}
|
||||
</Tbody>
|
||||
|
@@ -29,7 +29,7 @@ import MyTooltip from '@/components/MyTooltip';
|
||||
import { langMap, setLngStore } from '@/web/common/utils/i18n';
|
||||
import { useRouter } from 'next/router';
|
||||
import MySelect from '@/components/Select';
|
||||
import { formatPrice } from '@fastgpt/global/support/wallet/bill/tools';
|
||||
import { formatStorePrice2Read } from '@fastgpt/global/support/wallet/bill/tools';
|
||||
import { putUpdateMemberName } from '@/web/support/user/team/api';
|
||||
import { getDocPath } from '@/web/common/system/doc';
|
||||
|
||||
@@ -239,7 +239,7 @@ const UserInfo = () => {
|
||||
{t('user.team.Balance')}:
|
||||
</Box>
|
||||
<Box flex={1}>
|
||||
<strong>{formatPrice(userInfo?.team?.balance).toFixed(3)}</strong> 元
|
||||
<strong>{formatStorePrice2Read(userInfo?.team?.balance).toFixed(3)}</strong> 元
|
||||
</Box>
|
||||
{feConfigs?.show_pay && userInfo?.team?.canWrite && (
|
||||
<Button size={['sm', 'md']} ml={5} onClick={onOpenPayModal}>
|
||||
|
@@ -8,7 +8,6 @@ import { getErrText } from '@fastgpt/global/common/error/utils';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import Markdown from '@/components/Markdown';
|
||||
import MyModal from '@/components/MyModal';
|
||||
import { priceMd } from '@/web/common/system/staticData';
|
||||
|
||||
const PayModal = ({ onClose }: { onClose: () => void }) => {
|
||||
const router = useRouter();
|
||||
@@ -68,13 +67,12 @@ const PayModal = ({ onClose }: { onClose: () => void }) => {
|
||||
onClose={payId ? undefined : onClose}
|
||||
title={t('user.Pay')}
|
||||
iconSrc="/imgs/modal/pay.svg"
|
||||
isCentered={!payId}
|
||||
>
|
||||
<ModalBody px={0} minH={payId ? 'auto' : '70vh'} display={'flex'} flexDirection={'column'}>
|
||||
<ModalBody px={0} display={'flex'} flexDirection={'column'}>
|
||||
{!payId && (
|
||||
<>
|
||||
<Grid gridTemplateColumns={'repeat(4,1fr)'} gridGap={5} mb={4} px={6}>
|
||||
{[10, 20, 50, 100].map((item) => (
|
||||
<Grid gridTemplateColumns={'repeat(3,1fr)'} gridGap={5} mb={4} px={6}>
|
||||
{[10, 20, 50, 100, 200, 500].map((item) => (
|
||||
<Button
|
||||
key={item}
|
||||
variant={item === inputVal ? 'solid' : 'outline'}
|
||||
@@ -84,7 +82,7 @@ const PayModal = ({ onClose }: { onClose: () => void }) => {
|
||||
</Button>
|
||||
))}
|
||||
</Grid>
|
||||
<Box mb={4} px={6}>
|
||||
<Box px={6}>
|
||||
<Input
|
||||
value={inputVal}
|
||||
type={'number'}
|
||||
@@ -95,9 +93,6 @@ const PayModal = ({ onClose }: { onClose: () => void }) => {
|
||||
}}
|
||||
></Input>
|
||||
</Box>
|
||||
<Box flex={[1, '1 0 0']} overflow={'overlay'} px={6}>
|
||||
<Markdown source={priceMd} />
|
||||
</Box>
|
||||
</>
|
||||
)}
|
||||
{/* 付费二维码 */}
|
||||
|
@@ -15,7 +15,7 @@ import { getPayOrders, checkPayResult } from '@/web/support/wallet/pay/api';
|
||||
import type { PaySchema } from '@fastgpt/global/support/wallet/pay/type.d';
|
||||
import dayjs from 'dayjs';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { formatPrice } from '@fastgpt/global/support/wallet/bill/tools';
|
||||
import { formatStorePrice2Read } from '@fastgpt/global/support/wallet/bill/tools';
|
||||
import { useToast } from '@/web/common/hooks/useToast';
|
||||
import { useLoading } from '@/web/common/hooks/useLoading';
|
||||
import MyIcon from '@/components/Icon';
|
||||
@@ -85,7 +85,7 @@ const PayRecordTable = () => {
|
||||
<Td>
|
||||
{item.createTime ? dayjs(item.createTime).format('YYYY/MM/DD HH:mm:ss') : '-'}
|
||||
</Td>
|
||||
<Td>{formatPrice(item.price)}元</Td>
|
||||
<Td>{formatStorePrice2Read(item.price)}元</Td>
|
||||
<Td>{item.status}</Td>
|
||||
<Td>
|
||||
{item.status === 'NOTPAY' && (
|
||||
|
@@ -1,9 +1,8 @@
|
||||
import React, { useCallback, useMemo, useRef } from 'react';
|
||||
import { Box, Flex, useTheme } from '@chakra-ui/react';
|
||||
import React, { useCallback } from 'react';
|
||||
import { Box, Flex, useDisclosure, useTheme } from '@chakra-ui/react';
|
||||
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
||||
import { useRouter } from 'next/router';
|
||||
import dynamic from 'next/dynamic';
|
||||
import { clearToken } from '@/web/support/user/auth';
|
||||
import { useUserStore } from '@/web/support/user/useUserStore';
|
||||
import { useConfirm } from '@/web/common/hooks/useConfirm';
|
||||
import PageContainer from '@/components/PageContainer';
|
||||
@@ -20,11 +19,13 @@ const BillTable = dynamic(() => import('./components/BillTable'));
|
||||
const PayRecordTable = dynamic(() => import('./components/PayRecordTable'));
|
||||
const InformTable = dynamic(() => import('./components/InformTable'));
|
||||
const ApiKeyTable = dynamic(() => import('./components/ApiKeyTable'));
|
||||
const PriceBox = dynamic(() => import('@/components/support/wallet/Price'));
|
||||
|
||||
enum TabEnum {
|
||||
'info' = 'info',
|
||||
'promotion' = 'promotion',
|
||||
'bill' = 'bill',
|
||||
'price' = 'price',
|
||||
'pay' = 'pay',
|
||||
'inform' = 'inform',
|
||||
'apikey' = 'apikey',
|
||||
@@ -50,6 +51,15 @@ const Account = ({ currentTab }: { currentTab: `${TabEnum}` }) => {
|
||||
}
|
||||
]
|
||||
: []),
|
||||
...(feConfigs?.isPlus && feConfigs?.show_pay
|
||||
? [
|
||||
{
|
||||
icon: 'support/pay/priceLight',
|
||||
label: t('support.user.Price'),
|
||||
id: TabEnum.price
|
||||
}
|
||||
]
|
||||
: []),
|
||||
...(feConfigs?.show_promotion
|
||||
? [
|
||||
{
|
||||
@@ -97,6 +107,11 @@ const Account = ({ currentTab }: { currentTab: `${TabEnum}` }) => {
|
||||
const { openConfirm, ConfirmModal } = useConfirm({
|
||||
content: '确认退出登录?'
|
||||
});
|
||||
const {
|
||||
isOpen: isOpenPriceBox,
|
||||
onOpen: onOpenPriceBox,
|
||||
onClose: onClosePriceBox
|
||||
} = useDisclosure();
|
||||
|
||||
const router = useRouter();
|
||||
const theme = useTheme();
|
||||
@@ -109,6 +124,8 @@ const Account = ({ currentTab }: { currentTab: `${TabEnum}` }) => {
|
||||
setUserInfo(null);
|
||||
router.replace('/login');
|
||||
})();
|
||||
} else if (tab === TabEnum.price) {
|
||||
onOpenPriceBox();
|
||||
} else {
|
||||
router.replace({
|
||||
query: {
|
||||
@@ -117,7 +134,7 @@ const Account = ({ currentTab }: { currentTab: `${TabEnum}` }) => {
|
||||
});
|
||||
}
|
||||
},
|
||||
[openConfirm, router, setUserInfo]
|
||||
[onOpenPriceBox, openConfirm, router, setUserInfo]
|
||||
);
|
||||
|
||||
return (
|
||||
@@ -169,6 +186,8 @@ const Account = ({ currentTab }: { currentTab: `${TabEnum}` }) => {
|
||||
</Flex>
|
||||
<ConfirmModal />
|
||||
</PageContainer>
|
||||
|
||||
{isOpenPriceBox && <PriceBox onClose={onClosePriceBox} />}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
Reference in New Issue
Block a user