| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299 |
- import { CardStepTitle, FileLink, FileUpload } from "@/components";
- import ExamDataPublishController from "@/services/apis/ExamDataPublishController";
- import { ExamStatus, PublishStatus, ResourceFileType } from "@/services/enums";
- import { ActionType, ProTable } from "@ant-design/pro-components";
- import { history, useModel } from "@umijs/max";
- import { App, Button, Space, theme } from "antd";
- import { useCallback, useRef, useState } from "react";
- import ExamDataPublishEditModal from "./ExamDataPublishEditModal";
- /** 监测发布内容管理 */
- const ExamDataPublishList: React.FC<{ examPlanId: number, examPlanStatus?: ExamStatus }> = ({ examPlanId }) => {
- const { token } = theme.useToken();
- const actionRef = useRef<ActionType>();
- const dataRef = useRef<API.ExamDataPublishOutput[]>();
- const currentRef = useRef<Partial<API.ExamDataPublishOutput>>();
- const [editOpen, setEditOpen] = useState(false);
- const { getDictValueEnum } = useModel('useDict');
- const { message, modal } = App.useApp();
- // 移出
- const handleRemove = useCallback(async (id: number) => {
- modal.confirm({
- title: '警告',
- content: '确定立即移出吗',
- okText: '确定',
- cancelText: '取消',
- centered: true,
- onOk: async () => {
- await ExamDataPublishController.del({ id });
- message.success('已移出');
- actionRef.current?.reload();
- },
- });
- }, []);
- // 发布
- const handlePublish = useCallback(async (id: number) => {
- modal.confirm({
- title: '提示',
- content: '确定立即发布吗',
- okText: '确定',
- cancelText: '取消',
- centered: true,
- onOk: async () => {
- await ExamDataPublishController.publish({ id });
- message.success('已发布');
- actionRef.current?.reload();
- },
- });
- }, []);
- // 取消发布
- const handleUnpublish = useCallback(async (id: number) => {
- modal.confirm({
- title: '提示',
- content: '确定立即取消发布吗',
- okText: '确定',
- cancelText: '取消',
- centered: true,
- onOk: async () => {
- await ExamDataPublishController.unpublish({ id });
- message.success('已取消');
- actionRef.current?.reload();
- },
- });
- }, []);
- // 删除附件
- const handleDeleteAttachment = useCallback(async (id: number, fileId: string) => {
- modal.confirm({
- title: '警告',
- content: '确定立即删除吗',
- okText: '确定',
- cancelText: '取消',
- centered: true,
- onOk: async () => {
- await ExamDataPublishController.delAttachment({ sourceId: id, fileId })
- message.success('已删除');
- actionRef.current?.reload();
- },
- });
- }, []);
- return (
- <>
- <ProTable<API.ExamDataPublishOutput>
- headerTitle={<CardStepTitle>结果反馈</CardStepTitle>}
- style={{ marginTop: token.margin }}
- search={false}
- size="small"
- bordered
- scroll={{ x: '100%' }}
- sticky={{ offsetHeader: 56 }}
- actionRef={actionRef}
- options={{ density: false, fullScreen: false, setting: false }}
- pagination={false}
- columns={[
- {
- title: '序',
- valueType: 'option',
- fixed: 'left',
- width: 32,
- align: 'center',
- render: (_, r, index) => {
- return index + 1;
- },
- },
- {
- title: '发布类型',
- dataIndex: 'type',
- valueEnum: getDictValueEnum('data_publish_type'),
- width: 96,
- align: 'center',
- fixed: 'left',
- },
- {
- title: '发布名称',
- dataIndex: 'name',
- width: 180,
- },
- {
- title: '发布内容',
- valueType: 'option',
- width: 80,
- align: 'center',
- render: (_, r) => {
- return (
- <Button
- type="link"
- size="small"
- onClick={() => history.push(`/exam-c/plan/result/${examPlanId}/${r.id}`)}
- >管理</Button>
- );
- },
- },
- {
- title: '备注说明',
- dataIndex: 'remark',
- ellipsis: true,
- width: 400,
- },
- {
- title: '发布状态',
- dataIndex: 'status',
- valueEnum: getDictValueEnum('publish_status', true),
- width: 88,
- align: 'center',
- },
- {
- title: '发布时间',
- dataIndex: 'beginTime',
- width: 144,
- align: 'center',
- },
- {
- title: '附件',
- valueType: 'option',
- hideInSearch: true,
- width: 280 + token.paddingXS * 2,
- render: (_, r) => {
- const li = r.attachmentList?.map((t, i) => {
- return (
- <FileLink
- key={i}
- fileExtName={t.fileExtName}
- fileName={t.fileName}
- url={`${AppConfig.fileViewRoot}?id=${t.fileId}`}
- thumbUrl={t.thumbFileId && t.thumbFileId !== '0' ? `${AppConfig.fileViewRoot}?id=${t.thumbFileId}` : undefined}
- card
- onDelete={async () => handleDeleteAttachment(r.id, t.fileId)}
- />
- );
- });
- return (
- <Space direction="vertical" style={{ width: 280 }}>
- {li}
- {(li?.length ?? 0) < 9 &&
- <FileUpload
- addText="添加文件"
- // tipText="仅支持PDF或图片文件"
- accept="*.png,*.jpg,*.jpeg,*.gif,*.pdf,*.doc,*.docx,*.xls,*.xlsx,*.ppt,*.pptx,*.zip"
- limitSize={1024}
- onUpload={async (file, onUploadProgress) => {
- const fsp = file.name.split('.');
- let extName = '';
- if (fsp.length > 1) {
- extName = fsp[fsp.length - 1].toLowerCase();
- }
- if (extName === '' || !['jpg', 'jpeg', 'png', 'gif', 'pdf', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'zip'].includes(extName)) {
- message.error('文件类型错误,请重新选择!')
- return { success: false, errorType: 'fileTypeError', errorMessage: '文件类型错误' };
- }
- try {
- const formData = new FormData();
- formData.append('type', `${ResourceFileType.EXAM_DATA_PUBLISH_ATTACHMENT}`);
- formData.append('sourceId', `${r.id}`);
- formData.append('fileName', `${file.name}`);
- formData.append('file', file);
- await ExamDataPublishController.uploadAttachment(formData, {
- onUploadProgress: (p: any) => {
- const progress = parseFloat((p.loaded / p.total * 100).toFixed(1));
- onUploadProgress?.(progress);
- }
- });
- actionRef.current?.reload();
- return { success: true };
- }
- catch {
- return { success: false };
- }
- }}
- />
- }
- </Space>
- );
- },
- },
- {
- title: '操作',
- valueType: 'option',
- width: 196,
- align: 'center',
- fixed: 'right',
- render: (_, r) => {
- return (
- <>
- <Button
- type="link"
- size="small"
- disabled={r.status === PublishStatus.PUBLISHED}
- onClick={() => handleRemove(r.id)}
- >移出</Button>
- <Button
- type="link"
- size="small"
- disabled={r.status === PublishStatus.PUBLISHED}
- onClick={() => {
- currentRef.current = r;
- setEditOpen(true);
- }}
- >修改</Button>
- <Button
- type="link"
- size="small"
- disabled={r.status === PublishStatus.PUBLISHED}
- onClick={() => handlePublish(r.id)}
- >发布</Button>
- <Button
- type="link"
- size="small"
- disabled={r.status !== PublishStatus.PUBLISHED}
- onClick={() => handleUnpublish(r.id)}
- >取消</Button>
- </>
- );
- },
- }
- ]}
- rowKey="id"
- toolbar={{
- actions: [
- <Button
- key="add"
- type="primary"
- // disabled={examPlanStatus !== ExamStatus.READY}
- onClick={() => {
- currentRef.current = { id: 0, examPlanId };
- setEditOpen(true);
- }}
- >添加内容</Button>,
- ],
- }}
- request={async () => {
- const res = await ExamDataPublishController.getListByExamPlanId({ examplanid: examPlanId });
- dataRef.current = res ?? [];
- return {
- data: res,
- success: true,
- };
- }}
- />
- {editOpen && currentRef.current &&
- <ExamDataPublishEditModal
- data={currentRef.current}
- onClose={() => setEditOpen(false)}
- onFinish={() => actionRef.current?.reload()}
- />
- }
- </>
- );
- }
- export default ExamDataPublishList;
|