From baf8c53a9d798861451a68620cdb946083d5c8a1 Mon Sep 17 00:00:00 2001
From: luxiaotao1123 <t1341870251@163.com>
Date: 星期四, 19 九月 2024 10:31:04 +0800
Subject: [PATCH] #

---
 zy-acs-flow/src/page/components/ImportModal.jsx  |   21 +++----
 zy-acs-flow/package.json                         |    1 
 zy-acs-flow/src/page/code/useCodeImport.jsx      |   14 ++++
 zy-acs-flow/package-lock.json                    |    6 ++
 zy-acs-flow/src/page/code/importTemp.csv         |    4 +
 zy-acs-flow/src/page/components/usePapaParse.jsx |  103 ++++++++++++++++++++++++++++++++++
 zy-acs-flow/src/page/code/CodeList.jsx           |    7 +
 zy-acs-flow/src/page/components/ImportButton.jsx |    8 +-
 8 files changed, 146 insertions(+), 18 deletions(-)

diff --git a/zy-acs-flow/package-lock.json b/zy-acs-flow/package-lock.json
index 1b7cb5d..ac0b674 100644
--- a/zy-acs-flow/package-lock.json
+++ b/zy-acs-flow/package-lock.json
@@ -12,6 +12,7 @@
         "@mui/x-tree-view": "^7.16.0",
         "axios": "^1.7.4",
         "date-fns": "^3.6.0",
+        "papaparse": "^5.4.1",
         "pixi.js": "^7.4.0",
         "react": "^18.3.0",
         "react-admin": "^5.1.0",
@@ -4818,6 +4819,11 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
+    "node_modules/papaparse": {
+      "version": "5.4.1",
+      "resolved": "https://registry.npmmirror.com/papaparse/-/papaparse-5.4.1.tgz",
+      "integrity": "sha512-HipMsgJkZu8br23pW15uvo6sib6wne/4woLZPlFf3rpDyMe9ywEXUsuD7+6K9PRkJlVT51j/sCOYDKGGS3ZJrw=="
+    },
     "node_modules/parent-module": {
       "version": "1.0.1",
       "resolved": "https://registry.npmmirror.com/parent-module/-/parent-module-1.0.1.tgz",
diff --git a/zy-acs-flow/package.json b/zy-acs-flow/package.json
index 67a49cf..4d0229e 100644
--- a/zy-acs-flow/package.json
+++ b/zy-acs-flow/package.json
@@ -17,6 +17,7 @@
     "axios": "^1.7.4",
     "date-fns": "^3.6.0",
     "pixi.js": "^7.4.0",
+    "papaparse": "^5.4.1",
     "react": "^18.3.0",
     "react-admin": "^5.1.0",
     "react-dom": "^18.3.0",
diff --git a/zy-acs-flow/src/page/code/CodeList.jsx b/zy-acs-flow/src/page/code/CodeList.jsx
index 2187341..30f4095 100644
--- a/zy-acs-flow/src/page/code/CodeList.jsx
+++ b/zy-acs-flow/src/page/code/CodeList.jsx
@@ -42,7 +42,10 @@
 import MyField from "../components/MyField";
 import { PAGE_DRAWER_WIDTH, OPERATE_MODE } from '@/config/setting';
 import * as Common from '@/utils/common';
-import { ImportButton } from './ImportButton'
+import { ImportButton } from '../components/ImportButton'
+import { useCodeImport } from './useCodeImport';
+
+import * as sampleCsv from './importTemp.csv?raw';
 
 const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({
     '& .css-1vooibu-MuiSvgIcon-root': {
@@ -112,7 +115,7 @@
                         <FilterButton />
                         <MyCreateButton onClick={() => { setCreateDialog(true) }} />
                         <SelectColumnsButton preferenceKey='code' />
-                        <ImportButton />
+                        <ImportButton sampleCsv={sampleCsv} useCodeImport={useCodeImport} />
                         <MyExportButton />
                     </TopToolbar>
                 )}
diff --git a/zy-acs-flow/src/page/code/importTemp.csv b/zy-acs-flow/src/page/code/importTemp.csv
new file mode 100644
index 0000000..9fccf29
--- /dev/null
+++ b/zy-acs-flow/src/page/code/importTemp.csv
@@ -0,0 +1,4 @@
+first_name,last_name,gender,title,company,email,phone_1_number,phone_1_type,phone_2_number,phone_2_type,background,first_seen,last_seen,has_newsletter,status,tags,linkedin_url
+John,Doe,male,Sales Executive,Acme,john@doe.example,659-980-2015,work,740.645.3807,home,,2024-07-01,2024-07-01T11:54:49.950Z,FALSE,in-contract,"influencer, developer",https://www.linkedin.com/in/johndoe
+Jane,Doe,female,Designer,Acme,jane@doe.example,659-980-2020,work,740.647.3802,home,,2024-07-01,2024-07-01T11:54:49.950Z,FALSE,in-contract,"UI, design",https://www.linkedin.com/in/janedoe
+Camille,Brown,nonbinary,Accountant,Atomic Corp,person@doe.example,659-910-3010,work,740.698.3752,home,,2024-07-01,2024-07-01T11:54:49.950Z,FALSE,in-contract,"payroll, accountant",,
\ No newline at end of file
diff --git a/zy-acs-flow/src/page/code/useCodeImport.jsx b/zy-acs-flow/src/page/code/useCodeImport.jsx
new file mode 100644
index 0000000..b53286c
--- /dev/null
+++ b/zy-acs-flow/src/page/code/useCodeImport.jsx
@@ -0,0 +1,14 @@
+import { useCallback, useMemo } from 'react';
+import { useDataProvider, useGetIdentity } from 'react-admin';
+
+export function useCodeImport() {
+
+    const processBatch = useCallback(async (batch) => {
+        console.log(batch);
+
+    }, []);
+
+    return {
+        processBatch,
+    };
+}
diff --git a/zy-acs-flow/src/page/code/ImportButton.jsx b/zy-acs-flow/src/page/components/ImportButton.jsx
similarity index 75%
rename from zy-acs-flow/src/page/code/ImportButton.jsx
rename to zy-acs-flow/src/page/components/ImportButton.jsx
index e23c474..cf21f69 100644
--- a/zy-acs-flow/src/page/code/ImportButton.jsx
+++ b/zy-acs-flow/src/page/components/ImportButton.jsx
@@ -1,9 +1,9 @@
 import UploadIcon from '@mui/icons-material/Upload';
 import { useState } from 'react';
 import { Button } from 'react-admin';
-// import { ImportModal } from './ImportModal';
+import { ImportModal } from './ImportModal';
 
-export const ImportButton = () => {
+export const ImportButton = (props) => {
     const [modalOpen, setModalOpen] = useState(false);
 
     const handleOpenModal = () => {
@@ -13,7 +13,7 @@
     const handleCloseModal = () => {
         setModalOpen(false);
     };
-
+    
     return (
         <>
             <Button
@@ -22,7 +22,7 @@
                 onClick={handleOpenModal}
             />
 
-            {/* <ImportModal open={modalOpen} onClose={handleCloseModal} /> */}
+            <ImportModal open={modalOpen} onClose={handleCloseModal} {...props} />
         </>
     );
 };
diff --git a/zy-acs-flow/src/page/code/ImportModal.jsx b/zy-acs-flow/src/page/components/ImportModal.jsx
similarity index 92%
rename from zy-acs-flow/src/page/code/ImportModal.jsx
rename to zy-acs-flow/src/page/components/ImportModal.jsx
index bab07e9..309ee86 100644
--- a/zy-acs-flow/src/page/code/ImportModal.jsx
+++ b/zy-acs-flow/src/page/components/ImportModal.jsx
@@ -1,3 +1,4 @@
+import { useEffect, useState } from 'react';
 import { Box, CircularProgress, Stack, Typography } from '@mui/material';
 import Alert from '@mui/material/Alert';
 import Dialog from '@mui/material/Dialog';
@@ -14,20 +15,16 @@
     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 DialogCloseButton from './DialogCloseButton';
+import { usePapaParse } from './usePapaParse';
 
-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 }) {
+export function ImportModal({ open, onClose, sampleCsv, useCodeImport }) {
     const refresh = useRefresh();
-    const { processBatch } = useContactImport();
-    const { importer, parseCsv, reset } = usePapaParse<ContactImportSchema>({
+
+    const SAMPLE_URL = `data:text/csv;name=crm_contacts_sample.csv;charset=utf-8,${encodeURIComponent(sampleCsv.default)}`;
+
+    const { processBatch } = useCodeImport();
+    const { importer, parseCsv, reset } = usePapaParse({
         batchSize: 10,
         processBatch,
     });
diff --git a/zy-acs-flow/src/page/components/usePapaParse.jsx b/zy-acs-flow/src/page/components/usePapaParse.jsx
new file mode 100644
index 0000000..a38c68e
--- /dev/null
+++ b/zy-acs-flow/src/page/components/usePapaParse.jsx
@@ -0,0 +1,103 @@
+import * as Papa from 'papaparse';
+import { useCallback, useMemo, useRef, useState } from 'react';
+
+export function usePapaParse({ batchSize = 10, processBatch }) {
+    const importIdRef = useRef(0);
+
+    const [importer, setImporter] = useState({
+        state: 'idle',
+    });
+
+    const reset = useCallback(() => {
+        setImporter({
+            state: 'idle',
+        });
+        importIdRef.current += 1;
+    }, []);
+
+    const parseCsv = useCallback((file) => {
+        setImporter({
+            state: 'parsing',
+        });
+
+        const importId = importIdRef.current;
+        Papa.parse(file, {
+            header: true,
+            skipEmptyLines: true,
+            async complete(results) {
+                if (importIdRef.current !== importId) {
+                    return;
+                }
+
+                setImporter({
+                    state: 'running',
+                    rowCount: results.data.length,
+                    errorCount: results.errors.length,
+                    importCount: 0,
+                    remainingTime: null,
+                });
+
+                let totalTime = 0;
+                for (let i = 0; i < results.data.length; i += batchSize) {
+                    if (importIdRef.current !== importId) {
+                        return;
+                    }
+
+                    const batch = results.data.slice(i, i + batchSize);
+                    try {
+                        const start = Date.now();
+                        await processBatch(batch);
+                        totalTime += Date.now() - start;
+
+                        const meanTime = totalTime / (i + batch.length);
+                        setImporter(previous => {
+                            if (previous.state === 'running') {
+                                const importCount =
+                                    previous.importCount + batch.length;
+                                return {
+                                    ...previous,
+                                    importCount,
+                                    remainingTime:
+                                        meanTime *
+                                        (results.data.length - importCount),
+                                };
+                            }
+                            return previous;
+                        });
+                    } catch (error) {
+                        console.error('Failed to import batch', error);
+                        setImporter(previous =>
+                            previous.state === 'running'
+                                ? {
+                                    ...previous,
+                                    errorCount:
+                                        previous.errorCount +
+                                        batch.length,
+                                }
+                                : previous
+                        );
+                    }
+                }
+
+                setImporter(previous =>
+                    previous.state === 'running'
+                        ? {
+                            ...previous,
+                            state: 'complete',
+                            remainingTime: null,
+                        }
+                        : previous
+                );
+            },
+            error(error) {
+                setImporter({
+                    state: 'error',
+                    error,
+                });
+            },
+            dynamicTyping: true,
+        });
+    }, [batchSize, processBatch]);
+
+    return useMemo(() => ({ importer, parseCsv, reset, }), [importer, parseCsv, reset]);
+}

--
Gitblit v1.9.1