#
luxiaotao1123
2024-09-18 1908601b8f30b4df3247fa6de8fc500ed0e0e333
#
2个文件已修改
2个文件已添加
257 ■■■■■ 已修改文件
zy-acs-flow/src/page/code/CodeList.jsx 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-flow/src/page/code/ImportButton.jsx 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-flow/src/page/code/ImportModal.jsx 215 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/manager/entity/Code.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-flow/src/page/code/CodeList.jsx
@@ -42,6 +42,7 @@
import MyField from "../components/MyField";
import { PAGE_DRAWER_WIDTH, OPERATE_MODE } from '@/config/setting';
import * as Common from '@/utils/common';
import { ImportButton } from './ImportButton'
const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({
    '& .css-1vooibu-MuiSvgIcon-root': {
@@ -111,6 +112,7 @@
                        <FilterButton />
                        <MyCreateButton onClick={() => { setCreateDialog(true) }} />
                        <SelectColumnsButton preferenceKey='code' />
                        <ImportButton />
                        <MyExportButton />
                    </TopToolbar>
                )}
zy-acs-flow/src/page/code/ImportButton.jsx
New file
@@ -0,0 +1,28 @@
import UploadIcon from '@mui/icons-material/Upload';
import { useState } from 'react';
import { Button } from 'react-admin';
// import { ImportModal } from './ImportModal';
export const ImportButton = () => {
    const [modalOpen, setModalOpen] = useState(false);
    const handleOpenModal = () => {
        setModalOpen(true);
    };
    const handleCloseModal = () => {
        setModalOpen(false);
    };
    return (
        <>
            <Button
                startIcon={<UploadIcon />}
                label="Import"
                onClick={handleOpenModal}
            />
            {/* <ImportModal open={modalOpen} onClose={handleCloseModal} /> */}
        </>
    );
};
zy-acs-flow/src/page/code/ImportModal.jsx
New file
@@ -0,0 +1,215 @@
import { Box, CircularProgress, Stack, Typography } from '@mui/material';
import Alert from '@mui/material/Alert';
import Dialog from '@mui/material/Dialog';
import DialogActions from '@mui/material/DialogActions';
import DialogContent from '@mui/material/DialogContent';
import DialogTitle from '@mui/material/DialogTitle';
import MuiLink from '@mui/material/Link';
import {
    Button,
    FileField,
    FileInput,
    Form,
    Toolbar,
    useRefresh,
} from 'react-admin';
import { Link } from 'react-router-dom';
import { DialogCloseButton } from '../misc/DialogCloseButton';
import { usePapaParse } from '../misc/usePapaParse';
import { ContactImportSchema, useContactImport } from './useContactImport';
import { MouseEvent, useEffect, useState } from 'react';
import * as sampleCsv from './contacts_export.csv?raw';
const SAMPLE_URL = `data:text/csv;name=crm_contacts_sample.csv;charset=utf-8,${encodeURIComponent(sampleCsv.default)}`;
export function ImportModal({ open, onClose }) {
    const refresh = useRefresh();
    const { processBatch } = useContactImport();
    const { importer, parseCsv, reset } = usePapaParse<ContactImportSchema>({
        batchSize: 10,
        processBatch,
    });
    const [file, setFile] = useState(null);
    useEffect(() => {
        if (importer.state === 'complete') {
            refresh();
        }
    }, [importer.state, refresh]);
    const handleFileChange = (file) => {
        setFile(file);
    };
    const startImport = async () => {
        if (!file) {
            return;
        }
        parseCsv(file);
    };
    const handleClose = () => {
        reset();
        onClose();
    };
    const handleReset = (e) => {
        e.preventDefault();
        reset();
    };
    return (
        <Dialog open={open} maxWidth="md" fullWidth>
            <DialogCloseButton onClose={handleClose} />
            <DialogTitle>Import</DialogTitle>
            <DialogContent>
                <Form>
                    <Stack spacing={2}>
                        {importer.state === 'running' && (
                            <Stack gap={2}>
                                <Alert
                                    severity="info"
                                    action={
                                        <Box
                                            sx={{
                                                display: 'flex',
                                                height: '100%',
                                                alignItems: 'center',
                                                padding: '0',
                                            }}
                                        >
                                            <CircularProgress size={20} />
                                        </Box>
                                    }
                                    sx={{
                                        alignItems: 'center',
                                        '& .MuiAlert-action': {
                                            padding: 0,
                                            marginRight: 0,
                                        },
                                    }}
                                >
                                    The import is running, please do not close
                                    this tab.
                                </Alert>
                                <Typography variant="body2">
                                    Imported{' '}
                                    <strong>
                                        {importer.importCount} /{' '}
                                        {importer.rowCount}
                                    </strong>{' '}
                                    contacts, with{' '}
                                    <strong>{importer.errorCount}</strong>{' '}
                                    errors.
                                    {importer.remainingTime !== null && (
                                        <>
                                            {' '}
                                            Estimated remaining time:{' '}
                                            <strong>
                                                {millisecondsToTime(
                                                    importer.remainingTime
                                                )}
                                            </strong>
                                            .{' '}
                                            <MuiLink
                                                href="#"
                                                onClick={handleReset}
                                                color="error"
                                            >
                                                Stop import
                                            </MuiLink>
                                        </>
                                    )}
                                </Typography>
                            </Stack>
                        )}
                        {importer.state === 'error' && (
                            <Alert severity="error">
                                Failed to import this file, please make sure
                                your provided a valid CSV file.
                            </Alert>
                        )}
                        {importer.state === 'complete' && (
                            <Alert severity="success">
                                Contacts import complete. Imported{' '}
                                {importer.importCount} contacts, with{' '}
                                {importer.errorCount} errors
                            </Alert>
                        )}
                        {importer.state === 'idle' && (
                            <>
                                <Alert
                                    severity="info"
                                    action={
                                        <Button
                                            component={Link}
                                            label="Download CSV sample"
                                            color="info"
                                            to={SAMPLE_URL}
                                            download={'crm_contacts_sample.csv'}
                                        />
                                    }
                                >
                                    Here is a sample CSV file you can use as a
                                    template
                                </Alert>
                                <FileInput
                                    source="csv"
                                    label="CSV File"
                                    accept={{ 'text/csv': ['.csv'] }}
                                    onChange={handleFileChange}
                                >
                                    <FileField source="src" title="title" />
                                </FileInput>
                            </>
                        )}
                    </Stack>
                </Form>
            </DialogContent>
            <DialogActions
                sx={{
                    p: 0,
                    justifyContent: 'flex-start',
                }}
            >
                <Toolbar
                    sx={{
                        width: '100%',
                    }}
                >
                    {importer.state === 'idle' ? (
                        <>
                            <Button
                                label="Import"
                                variant="contained"
                                onClick={startImport}
                                disabled={!file}
                            />
                        </>
                    ) : (
                        <Button
                            label="Close"
                            onClick={handleClose}
                            disabled={importer.state === 'running'}
                        />
                    )}
                </Toolbar>
            </DialogActions>
        </Dialog>
    );
}
function millisecondsToTime(ms) {
    var seconds = Math.floor((ms / 1000) % 60);
    var minutes = Math.floor((ms / (60 * 1000)) % 60);
    return `${minutes}m ${seconds}s`;
}
zy-acs-manager/src/main/java/com/zy/acs/manager/manager/entity/Code.java
@@ -140,18 +140,6 @@
//            null    // 备注
//    );
    public String getStatus$(){
        if (null == this.status){ return null; }
        switch (this.status){
            case 1:
                return "正常";
            case 0:
                return "冻结";
            default:
                return String.valueOf(this.status);
        }
    }
    public Boolean getCornerBool(){
        if (null == this.concer){ return null; }
        switch (this.concer){