import { ColumnDrawer as AlgorithmModelColumnDrawer } from '@/pages/Resource/AlgorithmModelList/components/ColumnDrawer'; import { AlgorithmModelColumns } from '@/pages/Resource/AlgorithmModelList/components/Columns'; import { postAlgorithmModelGetAlgorithmModelById, postAlgorithmModelGetAlgorithmModelFkSelect, postAlgorithmModelGetAlgorithmModelNames, putAlgorithmModelUpdateAlgorithmModel, } from '@/services/resource/AlgorithmModel'; import { deleteModelVersionDeleteModelVersion, deleteModelVersionDeleteModelVersionByIds, postModelVersionGetModelVersionList, } from '@/services/resource/ModelVersion'; import { DownOutlined, PlusOutlined } from '@ant-design/icons'; import type { ActionType, ProColumns } from '@ant-design/pro-components'; import { FooterToolbar, PageContainer, ProFormSelect, ProTable } from '@ant-design/pro-components'; import { Access, FormattedMessage, history, useAccess, useIntl } from '@umijs/max'; import { Button, Popconfirm, message , Dropdown} from 'antd'; // import { MenuProps } from 'rc-menu'; import React, { useRef, useState } from 'react'; import { ColumnDrawer } from './components/ColumnDrawer'; import MyCreateForm from './components/MyCreateForm'; import UpdateForm from './components/UpdateForm'; const ModelVersionList: React.FC = () => { /** * @en-US Pop-up window of new window * @zh-CN 新建窗口的弹窗 * */ const [publishModalOpen, setPublishModalOpen] = useState<boolean>(false); const [createModalOpen, setCreateModalOpen] = useState<boolean>(false); /** * @en-US The pop-up window of the distribution update window * @zh-CN 分布更新窗口的弹窗 * */ const [updateModalOpen, setUpdateModalOpen] = useState<boolean>(false); const [showDetail, setShowDetail] = useState<boolean>(false); /** * @en-US International configuration * @zh-CN 国际化配置 * */ const access = useAccess(); const intl = useIntl(); const actionRef = useRef<ActionType>(); const [currentRow, setCurrentRow] = useState<API.ModelVersion>(); const [selectedRowsState, setSelectedRows] = useState<API.ModelVersion[]>([]); const [model_fk_id_open, set_model_fk_id_open] = useState(false); const [model_fk_id, set_model_fk_id] = useState<API.AlgorithmModel>(); const [model_fk_id_column_open, set_model_fk_id_column_open] = useState(false); const [modelFkIdIds, setModelFkIdIds] = useState([]); const [modelFkIdMap, setModelFkIdMap] = useState<{ [key: number]: string }>({}); const handle_model_fk_id = (id: any) => { if (model_fk_id_open) { set_model_fk_id(undefined); set_model_fk_id_open(false); } else { postAlgorithmModelGetAlgorithmModelById({ id: id }).then((resp) => { set_model_fk_id(resp.data.algorithmModel); set_model_fk_id_open(true); }); } }; const handle_model_fk_id_column_open = () => { if (model_fk_id_column_open) { set_model_fk_id_column_open(false); } else { postAlgorithmModelGetAlgorithmModelNames({ ids: modelFkIdIds }).then((resp) => { let a: any = {}; resp.data.list.forEach((v: any) => { if (v.id) { a[v.id] = v.name; } }); setModelFkIdMap(a); }); set_model_fk_id_column_open(true); } }; const handleUpdateModal = () => { if (updateModalOpen) { setUpdateModalOpen(false); setCurrentRow(undefined); } else { setUpdateModalOpen(true); } }; const handlePublishModal = () => { if (publishModalOpen) { setPublishModalOpen(false); setCurrentRow(undefined); } else { setPublishModalOpen(true); } }; const handleCreateModal = () => { if (createModalOpen) { setCreateModalOpen(false); setCurrentRow(undefined); } else { setCreateModalOpen(true); } }; const handleColumnDrawer = () => { if (showDetail) { setShowDetail(false); setCurrentRow(undefined); } else { setShowDetail(true); } }; const handleDestroy = async (selectedRow: API.ModelVersion) => { deleteModelVersionDeleteModelVersion({ id: selectedRow.id }) .then(() => { message.success(intl.formatMessage({ id: 'common.success', defaultMessage: '$$$' })); actionRef.current?.reload(); }) .catch(() => { message.error(intl.formatMessage({ id: 'common.failure', defaultMessage: '$$$' })); }); }; //TODO 表单的操作按钮集合 type TableActionItemProps = { renderActions: any[]; }; const TableActionCard: React.FC<TableActionItemProps[]> = (props) => { const { renderActions } = props; const maxActionCount = 3; if (renderActions.length <= maxActionCount) { return renderActions.map((item) => { return <>{item}</>; }); } const prevActions: any[] = []; const moreActions: { key: string; label: any; }[] = []; renderActions.map((item, index) => { if (index < maxActionCount - 1) { prevActions.push(item); } else { moreActions.push({ key: index+"", label: item }); } // eslint-disable-next-line react/jsx-key }); return ( <> {prevActions.map((item,index) => { return <div key={index}>{item}</div>; })} <Dropdown menu={{items: moreActions}}> <a>更多<DownOutlined/></a> </Dropdown> </> ); }; const columns: ProColumns<API.ModelVersion>[] = [ { title: <FormattedMessage id="resource.model_version.table.list.id" defaultMessage="id" />, dataIndex: 'id', sorter: true, render: (dom, entity) => { return ( <a onClick={() => { setCurrentRow(entity); setShowDetail(true); }} > {dom} </a> ); }, }, { title: ( <FormattedMessage id="resource.model_version.table.list.modelFkId" defaultMessage="$$$" /> ), dataIndex: 'modelFkId', hideInSearch: false, render: (text, record) => { if (model_fk_id_column_open) { return ( <a onClick={() => { handle_model_fk_id(record.modelFkId); }} > {record?.modelFkId ? modelFkIdMap[record.modelFkId] : undefined} </a> ); } else { return ( <a onClick={() => { handle_model_fk_id(record.modelFkId); }} > {record.modelFkId} </a> ); } }, renderFormItem: () => { return ( // value 和 onchange 会通过 form 自动注入。 <ProFormSelect placeholder={`${intl.formatMessage({ id: 'common.please_select', defaultMessage: '$$$', })}`} required={false} showSearch debounceTime={1000} request={async (keyWord) => { const resp = await postAlgorithmModelGetAlgorithmModelFkSelect({ keyword: keyWord?.keyWords || '', }); return resp.data.list.map((v: any) => { return { label: v.name, value: v.id, }; }); }} /> ); }, }, { title: ( <FormattedMessage id="resource.model_version.table.list.version" defaultMessage="$$$" /> ), dataIndex: 'version', hideInSearch: true, }, { title: <FormattedMessage id="resource.model_version.table.list.path" defaultMessage="$$$" />, dataIndex: 'path', hideInSearch: true, }, { title: ( <FormattedMessage id="resource.model_version.table.list.startCode" defaultMessage="$$$" /> ), dataIndex: 'startCode', hideInSearch: true, }, { title: ( <FormattedMessage id="resource.model_version.table.list.isEnable" defaultMessage="$$$" /> ), dataIndex: 'isEnable', filters: true, onFilter: true, hideInSearch: true, valueType: 'switch', }, { title: ( <FormattedMessage id="resource.model_version.table.list.remark" defaultMessage="$$$" /> ), dataIndex: 'remark', hideInSearch: true, }, { title: ( <FormattedMessage id="resource.model_version.table.list.status" defaultMessage="$$$" /> ), dataIndex: 'status', hideInSearch: true, valueEnum: { 1: { text: '已创建', status: 'Default' }, 2: { text: '已发布', status: 'Processing' }, 3: { text: '已上架', status: 'Success' }, 4: { text: '已下架', status: 'Default' }, 5: { text: '已关闭', status: 'Error' }, }, }, { title: ( <FormattedMessage id="resource.model_version.table.list.createTime" defaultMessage="$$$" /> ), dataIndex: 'createTime', sorter: true, hideInSearch: true, valueType: 'dateTime', }, { title: ( <FormattedMessage id="resource.model_version.table.list.updateTime" defaultMessage="$$$" /> ), dataIndex: 'updateTime', sorter: true, hideInSearch: true, valueType: 'dateTime', }, { title: <FormattedMessage id="pages.searchTable.titleOption" defaultMessage="Operating" />, dataIndex: 'option', valueType: 'option', fixed: 'right', render: (_, record) => [ <Access accessible={access.canUpdate(history.location.pathname)} key={`${history.location.pathname}-add`} > <TableActionCard renderActions={[ <a key="update" onClick={() => { setUpdateModalOpen(true); setCurrentRow(record); }} > <FormattedMessage id="pages.searchTable.update" defaultMessage="Update" /> </a>, <a key="destroy" onClick={() => { handleDestroy(record).then(() => {}); }} > <FormattedMessage id="pages.searchTable.destroy" defaultMessage="Destroy" /> </a>, // eslint-disable-next-line react/jsx-key <Popconfirm title="发布模型" description="确认发布模型吗?" onConfirm={() => {}} onCancel={() => {}} okText="Yes" cancelText="No" > <a key="confirm_publish" onClick={() => { setPublishModalOpen(true); setCurrentRow(record); }} > <FormattedMessage id="common.confirm_publish" defaultMessage="confirm_publish" /> </a> </Popconfirm>, // eslint-disable-next-line react/jsx-key <Popconfirm title="设置为默认版本" description="确认设置为默认版本吗?" onConfirm={() => { putAlgorithmModelUpdateAlgorithmModel({ id: record.modelFkId, defaultVersionFkId: record.id, }) .then(() => { message.success( intl.formatMessage({ id: 'common.success', defaultMessage: '$$$' }), ); }) .catch(() => { message.error( intl.formatMessage({ id: 'common.failure', defaultMessage: '$$$' }), ); }); }} onCancel={() => {}} okText="Yes" cancelText="No" > <a key="set_default" onClick={() => {}}> <FormattedMessage id="common.set_default" defaultMessage="$$$" /> </a> </Popconfirm>, ]} ></TableActionCard> {/* <a key="update" onClick={() => { setUpdateModalOpen(true); setCurrentRow(record); }} > <FormattedMessage id="pages.searchTable.update" defaultMessage="Update" /> </a> <a key="destroy" onClick={() => { handleDestroy(record).then(() => {}); }} > <FormattedMessage id="pages.searchTable.destroy" defaultMessage="Destroy" /> </a> */} {/* <Popconfirm title="发布模型" description="确认发布模型吗?" onConfirm={()=>{}} onCancel={()=>{}} okText="Yes" cancelText="No" > <a key="confirm_publish" onClick={() => { setPublishModalOpen(true); setCurrentRow(record); }}> <FormattedMessage id="common.confirm_publish" defaultMessage="confirm_publish" /> </a> </Popconfirm> <Popconfirm title="设置为默认版本" description="确认设置为默认版本吗?" onConfirm={()=>{ putAlgorithmModelUpdateAlgorithmModel({id: record.modelFkId, defaultVersionFkId: record.id}).then(()=>{ message.success(intl.formatMessage({id: 'common.success', defaultMessage: '$$$'})) }).catch(()=>{ message.error(intl.formatMessage({id: 'common.failure', defaultMessage: '$$$'})) }) }} onCancel={()=>{}} okText="Yes" cancelText="No" > <a key="set_default" onClick={() => { }}> <FormattedMessage id="common.set_default" defaultMessage="$$$" /> </a> </Popconfirm> */} </Access>, ], }, ]; return ( <PageContainer> <ProTable<API.ModelVersion> headerTitle={intl.formatMessage({ id: 'pages.searchTable.title', defaultMessage: '$$$', })} options={{ fullScreen: true, setting: true, density: true, reload: true }} actionRef={actionRef} rowKey="key" search={{ labelWidth: 120, }} onDataSourceChange={(data) => { let ModelFkIdIds: any = data.map((v) => { return v.modelFkId; }); setModelFkIdIds(ModelFkIdIds); }} pagination={{ showSizeChanger: true, pageSize: 10, }} columnsState={{ persistenceKey: 'model_version_list', persistenceType: 'localStorage', }} toolBarRender={() => [ <Access accessible={access.canUpdate(history.location.pathname)} key={`${history.location.pathname}-add`} > <Button type="primary" key="model_fk_id_show" onClick={() => { handle_model_fk_id_column_open(); }} > {model_fk_id_column_open ? ( <FormattedMessage id="common.hide" defaultMessage="$$$" /> ) : ( <FormattedMessage id="common.show" defaultMessage="$$$" /> )} <FormattedMessage id="resource.model_version.table.list.modelFkId" defaultMessage="$$$" /> </Button> <Button type="primary" key="primary" onClick={() => { setCreateModalOpen(true); }} > <PlusOutlined /> <FormattedMessage id="pages.searchTable.new" defaultMessage="New" /> </Button> </Access>, ]} request={async (params = {}, sort) => { const { current, ...rest } = params; const reqParams = { page: current, desc: false, orderKey: '', ...rest, }; if (sort && Object.keys(sort).length) { reqParams.orderKey = Object.keys(sort)[0]; let sort_select = sort[reqParams.orderKey]; reqParams.desc = sort_select === 'descend'; } let resp = await postModelVersionGetModelVersionList({ ...reqParams }); return { data: resp.data.list.map((v: API.ModelVersion) => { return { ...v, key: v.id }; }), success: resp.success, total: resp.data.total, current: resp.data.page, pageSize: resp.data.pageSize, }; }} columns={columns} rowSelection={{ onChange: (_, selectedRows) => { setSelectedRows(selectedRows); }, }} /> {selectedRowsState?.length > 0 && ( <FooterToolbar extra={ <div> <FormattedMessage id="pages.searchTable.chosen" defaultMessage="Chosen" />{' '} <a style={{ fontWeight: 600 }}>{selectedRowsState.length}</a>{' '} <FormattedMessage id="pages.searchTable.item" defaultMessage="$$$" /> </div> } > <Button onClick={async () => { deleteModelVersionDeleteModelVersionByIds({ ids: selectedRowsState.map((v: API.ModelVersion) => { return v.id as number; }), }).then(() => { actionRef.current?.reloadAndRest?.(); }); }} > <FormattedMessage id="pages.searchTable.batchDeletion" defaultMessage="Batch deletion" /> </Button> </FooterToolbar> )} <MyCreateForm createModalOpen={createModalOpen} values={currentRow || {}} handleModal={handleCreateModal} reload={actionRef.current?.reload} /> <UpdateForm updateModalOpen={updateModalOpen} values={currentRow || {}} handleModal={handleUpdateModal} reload={actionRef.current?.reload} /> {/*<PublishForm*/} {/* publishModalOpen={publishModalOpen}*/} {/* handleModal={handlePublishModal}*/} {/* values={currentRow || {}}*/} {/* reload={actionRef.current?.reload}*/} {/*></PublishForm>*/} <ColumnDrawer handleDrawer={handleColumnDrawer} isShowDetail={showDetail} columns={columns} currentRow={currentRow} /> <AlgorithmModelColumnDrawer handleDrawer={handle_model_fk_id} isShowDetail={model_fk_id_open} columns={AlgorithmModelColumns} currentRow={model_fk_id} /> </PageContainer> ); }; export default ModelVersionList;