ci4sManagement-cloud/react-ui/src/pages/System/Approval/index.tsx

244 lines
6.3 KiB
TypeScript
Raw Normal View History

/*
* @Author:
* @Date: 2024-04-16 13:58:08
* @Description:
*/
import { ApprovalStatus, approvalStatusOptions } from '@/enums';
2026-03-09 10:51:00 +08:00
import { useCacheState } from '@/hooks/useCacheState';
import { getApprovalListReq } from '@/services/message';
import { openAntdModal } from '@/utils/modal';
import { to } from '@/utils/promise';
import tableCellRender, { TableCellValueType } from '@/utils/table';
2026-03-09 10:51:00 +08:00
import { useNavigate } from '@umijs/max';
import {
Button,
Divider,
Select,
Table,
Typography,
type TablePaginationConfig,
type TableProps,
} from 'antd';
import classNames from 'classnames';
import { useCallback, useEffect, useState } from 'react';
import ApprovalModal from './components/ApprovalModal';
import StatusCell from './components/StatusCell';
import styles from './index.less';
export interface ApprovalData {
id: number;
status: number;
result: null;
content: string;
applicant_id: number;
applicant_name: null;
applicant_time: Date;
approver_id: number;
approver_time: Date;
title: string;
type: ApprovalType;
url: string;
}
export enum ApprovalType {
Dataset = 'DATASET',
Model = 'MODEL',
2026-03-09 10:51:00 +08:00
IMAGE = 'IMAGE',
CODE = 'CODE',
SERVICE = 'SERVICE',
2026-04-03 08:20:09 +08:00
SKILL = 'SKILL',
}
const approvalTypeOptions = [
{ label: '数据集', value: ApprovalType.Dataset },
{ label: '模型', value: ApprovalType.Model },
2026-03-09 10:51:00 +08:00
{ label: '镜像', value: ApprovalType.IMAGE },
{ label: '代码配置', value: ApprovalType.CODE },
{ label: '应用', value: ApprovalType.SERVICE },
2026-04-03 08:20:09 +08:00
{ label: 'Skill', value: ApprovalType.SKILL },
];
const statusOptions = [{ label: '全部', value: '' }, ...approvalStatusOptions];
function ApprovalList() {
const [tableData, setTableData] = useState<ApprovalData[]>([]);
const [total, setTotal] = useState(0);
2026-03-09 10:51:00 +08:00
const [cacheState, setCacheState] = useCacheState();
const [status, setStatus] = useState(cacheState?.status ?? '');
const [pagination, setPagination] = useState<TablePaginationConfig>(
cacheState?.pagination ?? {
current: 1,
pageSize: 10,
},
);
const navigate = useNavigate();
// 获取审核列表
const getApprovalList = useCallback(async () => {
const params: Record<string, any> = {
2025-09-09 10:08:51 +08:00
pageNum: pagination.current,
pageSize: pagination.pageSize,
status: status,
};
const [res] = await to(getApprovalListReq(params));
if (res) {
const { rows = [], total = 0 } = res;
setTableData(rows);
setTotal(total);
}
}, [pagination, status]);
useEffect(() => {
getApprovalList();
}, [getApprovalList]);
// 审核
const approval = (record: ApprovalData) => {
const { close } = openAntdModal(ApprovalModal, {
record: record,
onOk: () => {
close();
getApprovalList();
},
});
};
// 分页切换
const handleTableChange: TableProps<ApprovalData>['onChange'] = (
pagination,
_filters,
_sorter,
{ action },
) => {
if (action === 'paginate') {
setPagination(pagination);
}
};
const columns: TableProps<ApprovalData>['columns'] = [
{
title: '内容',
dataIndex: 'title',
key: 'title',
render: (title) => (
<Typography.Text
style={{ width: '100%' }}
ellipsis={{ tooltip: title.replace(/<\/?b>/g, '') }}
>
<span dangerouslySetInnerHTML={{ __html: title }}></span>
</Typography.Text>
),
},
{
title: '类型',
dataIndex: 'type',
key: 'type',
2026-03-09 10:51:00 +08:00
width: 150,
render: tableCellRender(true, TableCellValueType.Enum, {
options: approvalTypeOptions,
}),
},
{
title: '申请者',
dataIndex: 'applicant_name',
key: 'applicant_name',
width: 180,
render: tableCellRender(true),
},
{
title: '申请时间',
dataIndex: 'applicant_time',
key: 'applicant_time',
width: 180,
render: tableCellRender(true, TableCellValueType.Date),
},
{
title: '审核意见',
dataIndex: 'result',
key: 'result',
width: 200,
render: tableCellRender(true),
},
{
title: '状态',
dataIndex: 'status',
key: 'status',
width: 100,
render: StatusCell,
},
{
title: '操作',
dataIndex: 'operation',
width: 150,
key: 'operation',
render: (_: any, record: ApprovalData) => (
2026-03-09 10:51:00 +08:00
<div className="table-operation-column">
{record.type !== ApprovalType.CODE && (
<Button
type="link"
size="small"
key="view"
onClick={() => {
if (record.url) {
setCacheState({
status,
pagination,
});
navigate(record.url);
}
}}
>
</Button>
)}
{record.type !== ApprovalType.CODE && record.status === ApprovalStatus.Pending && (
<Divider type="vertical" className="table-operation-divider" />
)}
{record.status === ApprovalStatus.Pending ? (
<Button type="link" size="small" key="audit" onClick={() => approval(record)}>
</Button>
) : null}
</div>
),
},
];
return (
<div className={styles['approval-list']}>
<div className={styles['approval-list__content']}>
2026-03-09 10:51:00 +08:00
<div>
<span></span>
<Select
style={{ width: 100 }}
placeholder="请选择"
onChange={(value) => setStatus(value ?? '')}
options={statusOptions}
value={status}
allowClear
></Select>
</div>
<div className={classNames('vertical-scroll-table', styles['approval-list__table'])}>
<Table
dataSource={tableData}
columns={columns}
scroll={{ y: 'calc(100% - 55px)' }}
pagination={{
...pagination,
total: total,
showSizeChanger: true,
showQuickJumper: true,
showTotal: () => `${total}`,
}}
onChange={handleTableChange}
rowKey="id"
/>
</div>
</div>
</div>
);
}
export default ApprovalList;