mirror of
https://github.com/APIParkLab/APIPark.git
synced 2026-06-14 20:41:15 +08:00
feat: progress log
This commit is contained in:
@@ -5,19 +5,14 @@ import WithPermission from '@common/components/aoplatform/WithPermission'
|
||||
import { BasicResponse, RESPONSE_TIPS, STATUS_CODE } from '@common/const/const'
|
||||
import { useFetch } from '@common/hooks/http'
|
||||
import { $t } from '@common/locales/index.ts'
|
||||
import { App, Button, Typography } from 'antd'
|
||||
import { App, Button, Typography } from 'antd'
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
import { useSearchParams } from 'react-router-dom'
|
||||
import { LoadBalancingHandle, LoadBalancingItems } from './type'
|
||||
import TableBtnWithPermission from '@common/components/aoplatform/TableBtnWithPermission'
|
||||
import AddLoadBalancingModel from './AddModel'
|
||||
|
||||
|
||||
|
||||
const LoadBalancingPage = () => {
|
||||
const pageListRef = useRef<ActionType>(null)
|
||||
const [searchParams] = useSearchParams()
|
||||
const serviceId = searchParams.get('serviceId')
|
||||
const [searchWord, setSearchWord] = useState<string>('')
|
||||
const [columns, setColumns] = useState<PageProColumns<LoadBalancingItems>[]>([])
|
||||
const { modal, message } = App.useApp()
|
||||
@@ -40,9 +35,9 @@ const LoadBalancingPage = () => {
|
||||
closable: true,
|
||||
onOk: () => {
|
||||
return addModelRef.current?.save().then((res) => {
|
||||
if (res === true) {
|
||||
pageListRef.current?.reload()
|
||||
}
|
||||
if (res === true) {
|
||||
pageListRef.current?.reload()
|
||||
}
|
||||
})
|
||||
},
|
||||
wrapClassName: 'ant-modal-without-footer',
|
||||
@@ -58,16 +53,13 @@ const LoadBalancingPage = () => {
|
||||
* @returns
|
||||
*/
|
||||
const requestApis = () => {
|
||||
return fetchData<BasicResponse<{ list: LoadBalancingItems[]; total: number }>>(
|
||||
`ai/balances`,
|
||||
{
|
||||
method: 'GET',
|
||||
eoParams: {
|
||||
keyword: searchWord
|
||||
},
|
||||
eoTransformKeys: ['api_count', 'key_count']
|
||||
}
|
||||
)
|
||||
return fetchData<BasicResponse<{ list: LoadBalancingItems[]; total: number }>>(`ai/balances`, {
|
||||
method: 'GET',
|
||||
eoParams: {
|
||||
keyword: searchWord
|
||||
},
|
||||
eoTransformKeys: ['api_count', 'key_count']
|
||||
})
|
||||
.then((response) => {
|
||||
const { code, data, msg } = response
|
||||
if (code === STATUS_CODE.SUCCESS) {
|
||||
@@ -203,7 +195,9 @@ const LoadBalancingPage = () => {
|
||||
width: 120,
|
||||
ellipsis: true,
|
||||
key: 'state',
|
||||
render: (dom: React.ReactNode, record: LoadBalancingItems) => <span>{statusEnum[record.state]?.text || '-'}</span>
|
||||
render: (dom: React.ReactNode, record: LoadBalancingItems) => (
|
||||
<span>{statusEnum[record.state]?.text || '-'}</span>
|
||||
)
|
||||
},
|
||||
{
|
||||
title: $t('Apis'),
|
||||
|
||||
@@ -31,7 +31,13 @@ const SystemList: FC = () => {
|
||||
const [open, setOpen] = useState(false)
|
||||
const drawerFormRef = useRef<SystemConfigHandle>(null)
|
||||
const { checkPermission, accessInit, getGlobalAccessData, state } = useGlobalContext()
|
||||
|
||||
const [stateColumnMap] = useState<{ [k: string]: { text: string } }>({
|
||||
normal: { text: $t('正常') },
|
||||
deploying: { text: $t('部署中') },
|
||||
error: { text: $t('异常') },
|
||||
public: { text: $t('公共服务') },
|
||||
private: { text: $t('私有服务') }
|
||||
})
|
||||
const getSystemList = () => {
|
||||
if (!accessInit) {
|
||||
getGlobalAccessData()?.then?.(() => {
|
||||
@@ -131,9 +137,13 @@ const SystemList: FC = () => {
|
||||
setOpen(false)
|
||||
}
|
||||
const openLogsModal = (record: any) => {
|
||||
const closeModal = () => {
|
||||
modalInstance.destroy()
|
||||
manualReloadTable()
|
||||
}
|
||||
const modalInstance = modal.confirm({
|
||||
title: $t('部署过程'),
|
||||
content: <ServiceDeployment record={record} />,
|
||||
content: <ServiceDeployment record={record} closeModal={closeModal} />,
|
||||
footer: () => {
|
||||
return <LogsFooter record={record} modalInstance={modalInstance} />
|
||||
},
|
||||
@@ -163,7 +173,7 @@ const SystemList: FC = () => {
|
||||
if ((x.dataIndex as string) === 'state') {
|
||||
x.render = (text: any, record: any) => (
|
||||
<span
|
||||
className={`text-[13px] ${record.state === 'deploying' ? '[&>.ant-typography]:text-[#2196f3]' : record.state === 'error' ? '[&>.ant-typography]:text-[#ff4d4f]' : ''}`}
|
||||
className={`text-[13px] ${record.state === 'deploying' ? 'text-[#2196f3]' : record.state === 'error' ? 'text-[#ff4d4f]' : ''}`}
|
||||
onClick={(e) => {
|
||||
if (['deploying', 'error'].includes(record.state)) {
|
||||
e?.stopPropagation()
|
||||
@@ -171,7 +181,7 @@ const SystemList: FC = () => {
|
||||
}
|
||||
}}
|
||||
>
|
||||
{text}
|
||||
{stateColumnMap[record.state]?.text || '-'}
|
||||
</span>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -3,7 +3,8 @@ import { Steps } from 'antd'
|
||||
import { CheckCircleOutlined, LoadingOutlined, ClockCircleOutlined, CloseCircleOutlined } from '@ant-design/icons'
|
||||
import { Codebox } from '@common/components/postcat/api/Codebox'
|
||||
import { Collapse } from 'antd'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
import { $t } from '@common/locales/index.ts'
|
||||
import { useFetch } from '@common/hooks/http'
|
||||
|
||||
const getIcon = (status: string) => {
|
||||
@@ -21,43 +22,49 @@ const getIcon = (status: string) => {
|
||||
}
|
||||
}
|
||||
|
||||
export const ServiceDeployment = (props: { record: SystemTableListItem }) => {
|
||||
const { record } = props
|
||||
export const ServiceDeployment = (props: { record: SystemTableListItem, closeModal?: () => void }) => {
|
||||
const { record, closeModal } = props
|
||||
|
||||
const [stepItem, setStepItem] = useState<
|
||||
{
|
||||
id: string
|
||||
title: string
|
||||
description?: string
|
||||
status?: string
|
||||
}[]
|
||||
>([
|
||||
{
|
||||
title: 'Download',
|
||||
id: 'download',
|
||||
title: $t('下载'),
|
||||
status: 'pending'
|
||||
},
|
||||
{
|
||||
title: 'Deploy',
|
||||
id: 'deploy',
|
||||
title: $t('部署'),
|
||||
status: 'pending'
|
||||
},
|
||||
{
|
||||
title: 'Initializing',
|
||||
id: 'initializing',
|
||||
title: $t('初始化'),
|
||||
status: 'pending'
|
||||
}
|
||||
])
|
||||
|
||||
const [scriptStr, setScriptStr] = useState('')
|
||||
const [step, setStep] = useState(0)
|
||||
const step = useRef(0)
|
||||
const [collapseText] = useState('Progress log')
|
||||
const { fetchData } = useFetch()
|
||||
|
||||
useEffect(() => {
|
||||
const updateStepItems = (targetStep: number, description = '') => {
|
||||
setStepItem((prevItems) =>
|
||||
prevItems.map((item, index) => {
|
||||
return { ...item, status: index < step ? 'completed' : item.status }
|
||||
})
|
||||
)
|
||||
}, [step])
|
||||
|
||||
prevItems.map((item, index) => ({
|
||||
...item,
|
||||
description: item.id === 'download' ? description : item.description,
|
||||
status: index < targetStep ? 'completed' : index === targetStep ? 'inProgress' : 'pending',
|
||||
}))
|
||||
);
|
||||
step.current = targetStep;
|
||||
};
|
||||
useEffect(() => {
|
||||
fetchData(
|
||||
'model/local/deploy',
|
||||
@@ -72,42 +79,25 @@ export const ServiceDeployment = (props: { record: SystemTableListItem }) => {
|
||||
const parsedChunk = JSON.parse(chunk)
|
||||
// 下载中
|
||||
if (parsedChunk?.data?.state.includes('download')) {
|
||||
setStepItem((prevItems) =>
|
||||
prevItems.map((item) => {
|
||||
return item.title === 'Download'
|
||||
? {
|
||||
...item,
|
||||
description: `${parsedChunk?.data?.info?.current} / ${parsedChunk?.data?.info?.total}`,
|
||||
status: 'inProgress'
|
||||
}
|
||||
: item
|
||||
})
|
||||
)
|
||||
setStep(0)
|
||||
updateStepItems(0, `${parsedChunk?.data?.info?.current} / ${parsedChunk?.data?.info?.total}`);
|
||||
// 部署中
|
||||
} else if (parsedChunk?.data?.state.includes('deploy')) {
|
||||
setStepItem((prevItems) =>
|
||||
prevItems.map((item) => {
|
||||
return { ...item, status: item.title === 'Deploy' ? 'inProgress' : item.status }
|
||||
})
|
||||
)
|
||||
setStep(1)
|
||||
updateStepItems(1);
|
||||
// 初始化中
|
||||
} else if (parsedChunk?.data?.state.includes('initializing')) {
|
||||
setStepItem((prevItems) =>
|
||||
prevItems.map((item) => {
|
||||
return { ...item, status: item.title === 'Initializing' ? 'inProgress' : item.status }
|
||||
})
|
||||
)
|
||||
setStep(2)
|
||||
updateStepItems(2);
|
||||
// 完成
|
||||
} else if (parsedChunk?.data?.state.includes('finish')) {
|
||||
updateStepItems(4);
|
||||
setTimeout(() => {
|
||||
closeModal?.()
|
||||
}, 200)
|
||||
} else if (parsedChunk?.data?.state.includes('error')) {
|
||||
setStepItem((prevItems) =>
|
||||
prevItems.map((item) => {
|
||||
return { ...item, status: item.title === 'Initializing' ? 'completed' : item.status }
|
||||
prevItems.map((item, index) => {
|
||||
return { ...item, status: index === step.current ? 'error' : item.status }
|
||||
})
|
||||
)
|
||||
setStep(4)
|
||||
}
|
||||
setScriptStr(parsedChunk?.data?.message || '')
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user