mirror of
https://github.com/labring/sealos.git
synced 2026-09-24 15:46:19 +08:00
fix(costcenter): update amount by the query (#4737)
This commit is contained in:
@@ -1,26 +1,24 @@
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import request from '@/service/request';
|
||||
import { ApiResp } from '@/types';
|
||||
import { deFormatMoney, formatMoney } from '@/utils/format';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { Text, Box, Flex } from '@chakra-ui/react';
|
||||
import CurrencySymbol from '@/components/CurrencySymbol';
|
||||
import useOverviewStore from '@/stores/overview';
|
||||
import useBillingStore from '@/stores/billing';
|
||||
|
||||
export default function AmountDisplay() {
|
||||
// const {data} = useQuery({
|
||||
// queryKey: ['getAccount'],
|
||||
// queryFn: () =>
|
||||
// request<any, ApiResp<{ deductionBalance: number; balance: number }>>('/api/account/getAmount')
|
||||
// });
|
||||
const startTime = useOverviewStore((s) => s.startTime);
|
||||
const endTime = useOverviewStore((s) => s.endTime);
|
||||
const { namespace, appType } = useBillingStore();
|
||||
const { data, isSuccess } = useQuery({
|
||||
queryKey: ['billing', 'buget', { startTime, endTime }],
|
||||
queryKey: ['billing', 'buget', { startTime, endTime, appType, namespace }],
|
||||
queryFn: () => {
|
||||
return request.post<{ amount: number }[]>('/api/billing/buget', {
|
||||
startTime,
|
||||
endTime
|
||||
endTime,
|
||||
appType,
|
||||
namespace
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import request from '@/service/request';
|
||||
import useBillingStore from '@/stores/billing';
|
||||
import { ApiResp } from '@/types';
|
||||
import {
|
||||
Button,
|
||||
@@ -15,11 +16,9 @@ import { useState } from 'react';
|
||||
|
||||
export default function AppMenu({
|
||||
isDisabled,
|
||||
setApp,
|
||||
...props
|
||||
}: {
|
||||
isDisabled: boolean;
|
||||
setApp: (x: string) => void;
|
||||
} & FlexProps) {
|
||||
const [appIdx, setAppIdx] = useState(0);
|
||||
const { data } = useQuery({
|
||||
@@ -28,6 +27,7 @@ export default function AppMenu({
|
||||
},
|
||||
queryKey: ['appList']
|
||||
});
|
||||
const { setAppType } = useBillingStore();
|
||||
const { isOpen, onClose, onOpen } = useDisclosure();
|
||||
const { t } = useTranslation();
|
||||
const appList: string[] = [t('All APP'), ...(data?.data?.appList || [])];
|
||||
@@ -88,7 +88,7 @@ export default function AppMenu({
|
||||
isDisabled={isDisabled}
|
||||
onClick={() => {
|
||||
setAppIdx(idx);
|
||||
setApp(idx === 0 ? '' : appList[idx]);
|
||||
setAppType(idx === 0 ? '' : appList[idx]);
|
||||
onClose();
|
||||
}}
|
||||
// _hover={{
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import useOverviewStore from '@/stores/overview';
|
||||
import { memo, useEffect, useState } from 'react';
|
||||
import { memo, useContext, useEffect, useState } from 'react';
|
||||
import { BillingData, BillingSpec, BillingType } from '@/types';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { formatISO } from 'date-fns';
|
||||
@@ -12,9 +12,9 @@ import SearchBox from '@/components/billing/SearchBox';
|
||||
import { CommonBillingTable } from '@/components/billing/billingTable';
|
||||
import AmountDisplay from '@/components/billing/AmountDisplay';
|
||||
import SwitchPage from '@/components/billing/SwitchPage';
|
||||
import NotFound from '../notFound';
|
||||
import useBillingStore from '@/stores/billing';
|
||||
|
||||
export default function InOutTabPanel({ namespace }: { namespace: string }) {
|
||||
export default function InOutTabPanel() {
|
||||
const startTime = useOverviewStore((state) => state.startTime);
|
||||
const endTime = useOverviewStore((state) => state.endTime);
|
||||
const [selectType, setType] = useState<BillingType>(BillingType.ALL);
|
||||
@@ -23,7 +23,7 @@ export default function InOutTabPanel({ namespace }: { namespace: string }) {
|
||||
const [currentPage, setcurrentPage] = useState(1);
|
||||
const [pageSize, setPageSize] = useState(10);
|
||||
const [totalItem, setTotalItem] = useState(10);
|
||||
const [appType, setApp] = useState('');
|
||||
const { namespace, appType } = useBillingStore();
|
||||
useEffect(() => {
|
||||
setcurrentPage(1);
|
||||
}, [startTime, endTime, selectType, namespace]);
|
||||
@@ -74,7 +74,7 @@ export default function InOutTabPanel({ namespace }: { namespace: string }) {
|
||||
<Text fontSize={'12px'} mx={'10px'} width={['60px', '60px', 'auto', 'auto']}>
|
||||
{t('APP Type')}
|
||||
</Text>
|
||||
<AppMenu isDisabled={isFetching} setApp={setApp} mr={'32px'} />
|
||||
<AppMenu isDisabled={isFetching} mr={'32px'} />
|
||||
</Flex>
|
||||
<Flex align={'center'} mb="24px">
|
||||
<Text fontSize={'12px'} mr={'12px'} width={['60px', '60px', 'auto', 'auto']}>
|
||||
|
||||
@@ -1,20 +1,16 @@
|
||||
import request from '@/service/request';
|
||||
import useBillingStore from '@/stores/billing';
|
||||
import useOverviewStore from '@/stores/overview';
|
||||
import { Button, Flex, Popover, PopoverContent, PopoverTrigger } from '@chakra-ui/react';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { useState } from 'react';
|
||||
|
||||
export default function NamespaceMenu({
|
||||
isDisabled,
|
||||
setNamespace
|
||||
}: {
|
||||
isDisabled: boolean;
|
||||
setNamespace: (x: string) => void;
|
||||
}) {
|
||||
export default function NamespaceMenu({ isDisabled }: { isDisabled: boolean }) {
|
||||
const startTime = useOverviewStore((s) => s.startTime);
|
||||
const endTime = useOverviewStore((s) => s.endTime);
|
||||
const [namespaceIdx, setNamespaceIdx] = useState(0);
|
||||
const { setNamespace } = useBillingStore();
|
||||
const { data: nsListData } = useQuery({
|
||||
queryFn() {
|
||||
return request.post('/api/billing/getNamespaceList', {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import useOverviewStore from '@/stores/overview';
|
||||
import { useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { useContext, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import {
|
||||
CellContext,
|
||||
createColumnHelper,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import useOverviewStore from '@/stores/overview';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useContext, useEffect, useState } from 'react';
|
||||
import { BillingData, BillingSpec, BillingType } from '@/types';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { formatISO } from 'date-fns';
|
||||
@@ -12,8 +12,9 @@ import SearchBox from '@/components/billing/SearchBox';
|
||||
import { TransferBillingTable } from '@/components/billing/billingTable';
|
||||
import SwitchPage from '@/components/billing/SwitchPage';
|
||||
import NotFound from '../notFound';
|
||||
import useBillingStore from '@/stores/billing';
|
||||
|
||||
export default function TransferTabPanel({ namespace }: { namespace: string }) {
|
||||
export default function TransferTabPanel() {
|
||||
const startTime = useOverviewStore((state) => state.startTime);
|
||||
const endTime = useOverviewStore((state) => state.endTime);
|
||||
const [selectType, setType] = useState<BillingType>(BillingType.ALL);
|
||||
@@ -22,6 +23,7 @@ export default function TransferTabPanel({ namespace }: { namespace: string }) {
|
||||
const [currentPage, setcurrentPage] = useState(1);
|
||||
const [pageSize, setPageSize] = useState(10);
|
||||
const [totalItem, setTotalItem] = useState(10);
|
||||
const { namespace } = useBillingStore();
|
||||
useEffect(() => {
|
||||
setcurrentPage(1);
|
||||
}, [startTime, endTime, selectType, namespace]);
|
||||
|
||||
@@ -7,7 +7,7 @@ import { CanvasRenderer } from 'echarts/renderers';
|
||||
import { formatMoney } from '@/utils/format';
|
||||
import { useMemo } from 'react';
|
||||
import { useBreakpointValue } from '@chakra-ui/react';
|
||||
import { BillingData } from '@/types/billing';
|
||||
import { BillingData, Costs } from '@/types/billing';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import useEnvStore from '@/stores/env';
|
||||
import {
|
||||
@@ -28,7 +28,7 @@ echarts.use([
|
||||
DatasetComponent
|
||||
]);
|
||||
|
||||
export default function CostChart({ data }: { data: BillingData['status']['deductionAmount'] }) {
|
||||
export default function CostChart({ data }: { data: Costs }) {
|
||||
const { t } = useTranslation();
|
||||
const { cpu = 0, memory = 0, storage = 0, gpu = 0, network = 0, port = 0 } = data;
|
||||
const gpuEnabled = useEnvStore((state) => state.gpuEnabled);
|
||||
|
||||
@@ -8,9 +8,11 @@ export default async function handler(req: NextApiRequest, resp: NextApiResponse
|
||||
if (user === null) {
|
||||
return jsonRes(resp, { code: 403, message: 'user null' });
|
||||
}
|
||||
const { endTime, startTime } = req.body as {
|
||||
const { endTime, startTime, appType, namespace } = req.body as {
|
||||
endTime?: Date;
|
||||
startTime?: Date;
|
||||
appType?: string;
|
||||
namespace?: string;
|
||||
};
|
||||
if (!endTime)
|
||||
return jsonRes(resp, {
|
||||
@@ -20,7 +22,7 @@ export default async function handler(req: NextApiRequest, resp: NextApiResponse
|
||||
if (!startTime)
|
||||
return jsonRes(resp, {
|
||||
code: 400,
|
||||
message: 'endTime is invalid'
|
||||
message: 'startTime is invalid'
|
||||
});
|
||||
const consumptionUrl = process.env.BILLING_URI + '/account/v1alpha1/costs/consumption';
|
||||
const rechagreUrl = process.env.BILLING_URI + '/account/v1alpha1/costs/recharge';
|
||||
@@ -33,6 +35,8 @@ export default async function handler(req: NextApiRequest, resp: NextApiResponse
|
||||
endTime,
|
||||
kubeConfig: kc.exportConfig(),
|
||||
owner: user.name,
|
||||
appType,
|
||||
namespace,
|
||||
startTime
|
||||
})
|
||||
})
|
||||
@@ -44,7 +48,7 @@ export default async function handler(req: NextApiRequest, resp: NextApiResponse
|
||||
endTime,
|
||||
kubeConfig: kc.exportConfig(),
|
||||
owner: user.name,
|
||||
startTime
|
||||
appType
|
||||
})
|
||||
})
|
||||
).json()
|
||||
|
||||
@@ -11,7 +11,7 @@ export default async function handler(req: NextApiRequest, resp: NextApiResponse
|
||||
if (user === null) {
|
||||
return jsonRes(resp, { code: 403, message: 'user null' });
|
||||
}
|
||||
const namespace = kc.getContexts()[0].namespace || GetUserDefaultNameSpace(user.name);
|
||||
const namespace = GetUserDefaultNameSpace(user.name);
|
||||
const name = new Date().getTime() + 'appquery';
|
||||
const crdSchema = {
|
||||
apiVersion: `account.sealos.io/v1`,
|
||||
|
||||
@@ -82,7 +82,8 @@ export default async function handler(req: NextApiRequest, resp: NextApiResponse
|
||||
...v,
|
||||
costs: convertGpu(v?.costs)
|
||||
})) || [];
|
||||
const deductionAmount = convertGpu(crd?.body?.status?.deductionAmount);
|
||||
const deductionAmount = crd.body.status.deductionAmount || 0;
|
||||
// convertGpu(crd?.body?.status?.deductionAmount);
|
||||
return jsonRes<BillingData>(resp, {
|
||||
code: 200,
|
||||
data: {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Flex, Heading, Img, Tab, TabList, TabPanels, Tabs } from '@chakra-ui/react';
|
||||
import { useState } from 'react';
|
||||
import { createContext, useMemo, useState } from 'react';
|
||||
import receipt_icon from '@/assert/receipt_long_black.svg';
|
||||
import { serverSideTranslations } from 'next-i18next/serverSideTranslations';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
@@ -7,16 +7,16 @@ import NamespaceMenu from '@/components/billing/NamespaceMenu';
|
||||
import RechargeTabPanel from '@/components/billing/RechargeTabPanel';
|
||||
import InOutTabPanel from '@/components/billing/InOutTabPanel';
|
||||
import TransferTabPanel from '@/components/billing/TransferTabPnel';
|
||||
|
||||
import useBillingStore from '@/stores/billing';
|
||||
function Billing() {
|
||||
const { t } = useTranslation();
|
||||
const [namespace, setNamespace] = useState('');
|
||||
const { setNamespace } = useBillingStore();
|
||||
return (
|
||||
<Flex flexDirection="column" w="100%" h="100%" bg={'white'} p="24px" overflow={'auto'}>
|
||||
<Flex mr="24px" align={'center'}>
|
||||
<Img src={receipt_icon.src} w={'24px'} h={'24px'} mr={'18px'} dropShadow={'#24282C'}></Img>
|
||||
<Heading size="lg">{t('SideBar.BillingDetails')}</Heading>
|
||||
<NamespaceMenu isDisabled={false} setNamespace={setNamespace} />
|
||||
<NamespaceMenu isDisabled={false} />
|
||||
</Flex>
|
||||
<Tabs mt={'20px'} flex={1} display={'flex'} flexDir={'column'}>
|
||||
<TabList borderColor={'#EFF0F1'}>
|
||||
@@ -46,9 +46,9 @@ function Billing() {
|
||||
</Tab>
|
||||
</TabList>
|
||||
<TabPanels mt="24px" flexDirection={'column'} flex={'1'} display={'flex'}>
|
||||
<InOutTabPanel namespace={namespace} />
|
||||
<InOutTabPanel />
|
||||
<RechargeTabPanel />
|
||||
<TransferTabPanel namespace={namespace} />
|
||||
<TransferTabPanel />
|
||||
</TabPanels>
|
||||
</Tabs>
|
||||
</Flex>
|
||||
|
||||
@@ -6,6 +6,10 @@ type BillingState = {
|
||||
storage: number;
|
||||
network: number;
|
||||
gpu: number;
|
||||
namespace: string;
|
||||
appType: string;
|
||||
setAppType: (appType: string) => void;
|
||||
setNamespace: (namespace: string) => void;
|
||||
updateCpu: (cpu: number) => void;
|
||||
updateMemory: (memory: number) => void;
|
||||
updateStorage: (storage: number) => void;
|
||||
@@ -18,6 +22,14 @@ const useBillingStore = create<BillingState>((set) => ({
|
||||
storage: 0,
|
||||
gpu: 0,
|
||||
network: 0,
|
||||
namespace: '',
|
||||
appType: '',
|
||||
setAppType(appType: string) {
|
||||
set({ appType });
|
||||
},
|
||||
setNamespace(namespace: string) {
|
||||
set({ namespace });
|
||||
},
|
||||
updateCpu: (cpu: number) => set({ cpu: formatMoney(cpu) }),
|
||||
updateMemory: (memory: number) => set({ memory: formatMoney(memory) }),
|
||||
updateStorage: (storage: number) => set({ storage: formatMoney(storage) }),
|
||||
|
||||
@@ -52,7 +52,7 @@ export type BillingData<T = Costs> = {
|
||||
metadata: any;
|
||||
spec: BillingSpec;
|
||||
status: {
|
||||
deductionAmount: T;
|
||||
deductionAmount: number;
|
||||
item: BillingItem<T>[];
|
||||
pageLength: number;
|
||||
totalCount: number;
|
||||
|
||||
@@ -9,4 +9,4 @@ module.exports = {
|
||||
locales: ['en', 'zh'],
|
||||
localeDetection: false
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/** @type {import('next').NextConfig} */
|
||||
const { i18n } = require('./next-i18next.config')
|
||||
const path = require('path')
|
||||
const { i18n } = require('./next-i18next.config');
|
||||
const path = require('path');
|
||||
|
||||
const nextConfig = {
|
||||
i18n,
|
||||
@@ -14,15 +14,15 @@ const nextConfig = {
|
||||
issuer: /\.[jt]sx?$/,
|
||||
use: ['@svgr/webpack']
|
||||
}
|
||||
])
|
||||
config.plugins = [...config.plugins]
|
||||
return config
|
||||
]);
|
||||
config.plugins = [...config.plugins];
|
||||
return config;
|
||||
},
|
||||
transpilePackages: ['@sealos/ui', 'sealos-desktop-sdk', '@sealos/driver'],
|
||||
experimental: {
|
||||
// this includes files from the monorepo base two directories up
|
||||
outputFileTracingRoot: path.join(__dirname, '../../')
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = nextConfig
|
||||
module.exports = nextConfig;
|
||||
|
||||
@@ -1,21 +1,11 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"lib": [
|
||||
"dom",
|
||||
"dom.iterable",
|
||||
"esnext"
|
||||
],
|
||||
"lib": ["dom", "dom.iterable", "esnext"],
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@/*": [
|
||||
"./src/*"
|
||||
]
|
||||
"@/*": ["./src/*"]
|
||||
}
|
||||
},
|
||||
"include": [
|
||||
"next-env.d.ts",
|
||||
"src/**/*.ts",
|
||||
"src/**/*.tsx"
|
||||
],
|
||||
"include": ["next-env.d.ts", "src/**/*.ts", "src/**/*.tsx"],
|
||||
"extends": "../../tsconfig.web.json"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user