Parcourir la source

support export, to be continued

Xiaopeng Zhang il y a 6 mois
Parent
commit
295b40d4c0
5 fichiers modifiés avec 304 ajouts et 8 suppressions
  1. 119 5
      front/src/Home2.js
  2. 12 0
      front/src/Service.js
  3. 1 1
      front/webpack.config.js
  4. 17 1
      main.py
  5. 155 1
      subdir/db.py

+ 119 - 5
front/src/Home2.js

@@ -14,7 +14,8 @@ import AccountCircle from '@mui/icons-material/AccountCircle';
 import Fab from '@mui/material/Fab';
 import Tooltip from '@mui/material/Tooltip';
 import DeleteIcon from '@mui/icons-material/Delete';
-
+import Button from '@mui/material/Button';
+import Dialog from '@mui/material/Dialog';
 import Drawer from '@mui/material/Drawer';
 import Divider from '@mui/material/Divider';
 import IconButton from '@mui/material/IconButton';
@@ -22,6 +23,10 @@ import ChevronLeftIcon from '@mui/icons-material/ChevronLeft';
 import ChevronRightIcon from '@mui/icons-material/ChevronRight';
 import MenuIcon from '@mui/icons-material/Menu';
 import AddIcon from '@mui/icons-material/Add';
+import DialogTitle from '@mui/material/DialogTitle';
+import DialogActions from '@mui/material/DialogActions';
+import CircularProgress from '@mui/material/CircularProgress';
+import Backdrop from '@mui/material/Backdrop';
 
 export default function Home2() {
   const drawerWidth = 240;
@@ -29,21 +34,87 @@ export default function Home2() {
 
   const deleteItem = React.useCallback(
     (id) => () => {
+
+      itemRef.current = id;
+      /*
       console.log(id);
       Service.deleteFiles(id).then(x=> {
         Service.generateFiles2().then(x=>{
-          setDetail(x.map(y=>{return {'id': y[0], 'ID': y[0], '名称': y[1], '创建时间': y[2]};}));
+          setDetail(x.map(y=>{return {'id': y[0], 'ID': y[0], '名称': y[1], '创建时间': y[2], '操作': y[0]};}));
         });
-      });
+      });*/
+      setDopen(true);
     },
     [],
   );
+
+
+
+  function RenderDate(props) {
+    const { hasFocus, value } = props;
+    const buttonElement = React.useRef(null);
+    const rippleRef = React.useRef(null);
+  
+    React.useLayoutEffect(() => {
+      if (hasFocus) {
+        const input = buttonElement.current.querySelector('input');
+        input?.focus();
+      } else if (rippleRef.current) {
+        // Only available in @mui/material v5.4.1 or later
+        rippleRef.current.stop({});
+      }
+    }, [hasFocus]);
+  
+    return (
+      <strong>
+        
+        <Button
+          ref={buttonElement}
+          touchRippleRef={rippleRef}
+          variant="contained"
+          size="small"
+          style={{ marginLeft: 4 }}
+          
+          
+          onClick={(event) => {
+            console.log(value);
+            event.stopPropagation();
+            setBopen(true);
+            Service.download(value)
+                .then(blob => {
+                // Create a temporary URL for the Blob
+                const url = URL.createObjectURL(blob);
+    
+                // Create a link and set its href to the temporary URL
+                const link = document.createElement('a');
+                link.href = url;
+    
+                 // Set the link attributes for downloading
+                link.setAttribute('download', value.concat('.xml'));
+    
+                 // Programmatically click the link to initiate the download
+                link.click();
+    
+                 // Clean up the temporary URL
+                URL.revokeObjectURL(url);
+                setBopen(false);
+             })
+             .catch(error => console.error(error));
+          }}
+        >
+          导出文件
+        </Button>
+      </strong>
+    );
+  }
+  
  
   const columns = React.useMemo(
     () => [
       { field: 'ID', headerName: 'ID', width: 250 },
       { field: '名称', headerName: '名称', width: 400 },
       { field: '创建时间', headerName: '创建时间', width: 200 },
+      { field: '操作', headerName: '操作', width: 100 , sortable: false, renderCell: RenderDate},
       {
         field: 'actions',
         type: 'actions',
@@ -72,10 +143,13 @@ export default function Home2() {
     });
 
     const hotRef = React.useRef(null);
+    const itemRef = React.useRef(null);
     const navigate = useNavigate();
     let location = useLocation();
     const [detail, setDetail] = React.useState([]);
     const [open, setOpen] = React.useState(false);
+    const [dopen, setDopen] = React.useState(false);
+    const [bopen, setBopen] = React.useState(false);
     const [selectedFiles, setSelectedFiles] = React.useState([]);
 
     const handleFileChange = (event) => {
@@ -86,7 +160,7 @@ export default function Home2() {
          Service.uploadFile(fd).then(x=>{
             console.log("uploaded");
             Service.generateFiles2().then(x=>{
-              setDetail(x.map(y=>{return {'id': y[0], 'ID': y[0], '名称': y[1], '创建时间': y[2]};}));
+              setDetail(x.map(y=>{return {'id': y[0], 'ID': y[0], '名称': y[1], '创建时间': y[2], '操作': y[0]};}));
             });
 
          });
@@ -97,7 +171,7 @@ export default function Home2() {
     React.useEffect(
       () => {
          Service.generateFiles2().then(x=>{
-           setDetail(x.map(y=>{return {'id': y[0], 'ID': y[0], '名称': y[1], '创建时间': y[2]};}));
+           setDetail(x.map(y=>{return {'id': y[0], 'ID': y[0], '名称': y[1], '创建时间': y[2], '操作': y[0]};}));
          });
       }, []
     );
@@ -172,6 +246,22 @@ export default function Home2() {
     setOpen(true);
   };
 
+  const handleClose = () => {
+    setDopen(false);
+  };
+  const handleCloseB = () => {
+    setBopen(false);
+  };
+
+  const handleDelete = () => {
+    Service.deleteFiles(itemRef.current).then(x=> {
+      Service.generateFiles2().then(x=>{
+        setDetail(x.map(y=>{return {'id': y[0], 'ID': y[0], '名称': y[1], '创建时间': y[2], '操作': y[0]};}));
+      });
+    });
+    setDopen(false);
+  };
+
 
     return (
       <Box sx={{ display: 'flex' }}>
@@ -264,6 +354,30 @@ export default function Home2() {
     </div>
    
     </Main>
+    <Dialog
+        open={dopen}
+        onClose={handleClose}
+        aria-labelledby="alert-dialog-title"
+        aria-describedby="alert-dialog-description"
+      >
+        <DialogTitle id="alert-dialog-title">
+          {"删除该项目?"}
+        </DialogTitle>
+        
+        <DialogActions>
+          <Button onClick={handleClose}>取消</Button>
+          <Button onClick={handleDelete} autoFocus>
+            确定
+          </Button>
+        </DialogActions>
+      </Dialog>
+      <Backdrop
+        sx={(theme) => ({ color: '#fff', zIndex: theme.zIndex.drawer + 1 })}
+        open={bopen}
+        
+      >
+        <CircularProgress color="inherit" />
+      </Backdrop>
     </Box>
     );
   }

+ 12 - 0
front/src/Service.js

@@ -1012,6 +1012,18 @@ async generateQingdanTuijian(name, bh, bt, bm) {
         }
     }
 
+    async download(id) {
+        const response = await fetch(this.ip().concat( "/download/").concat(id.toString()));
+
+        if (!response.ok) {
+            //const error = await response.json();
+            console.error('error');
+        } else {
+            const data = await response.blob();
+            return data;
+        }
+    }
+
     async tiaojia(biao_id, bh, bm, mingcheng, danwei, jiage) {
         let glf = "";
         let lr = "";

+ 1 - 1
front/webpack.config.js

@@ -55,7 +55,7 @@ module.exports = {
     extensions: [".js", ".jsx"]
   },
 
-  mode: 'production',
+  mode: 'development',
   performance: {
     hints: false,
     maxEntrypointSize: 512000,

+ 17 - 1
main.py

@@ -18,6 +18,7 @@ import numpy as np
 from fastapi.staticfiles import StaticFiles
 from pymongo import AsyncMongoClient
 client = AsyncMongoClient()
+from fastapi.responses import FileResponse
 
 from fastapi import WebSocket, WebSocketDisconnect
 from fastapi import UploadFile
@@ -671,7 +672,22 @@ async def upload(file: UploadFile):
         return [file.filename]
         
         
-        
+@app.get("/download/{item_id}")
+async def download_file(item_id):
+    file_path = "export/contacts.xml"
+    # Create the root element
+    root = ET.Element("JingJiBiao")
+
+    # Create a sub-element
+    ##TouBiaoXx = ET.SubElement(root, "TouBiaoXx")
+    await db.build(client, root, item_id)
+
+    
+
+    # Create the tree and write to a file
+    tree = ET.ElementTree(root)
+    tree.write("export/contacts.xml", xml_declaration=True, encoding="UTF-8")
+    return FileResponse(file_path, media_type='application/octet-stream', filename="contacts.xml")
         
 
 

+ 155 - 1
subdir/db.py

@@ -450,10 +450,164 @@ async def resolve(data, client):
 
 
 
+def dfs(items):
+    result = []
+    for entry in items:
+        result.append([entry['序号'], entry['名称'], entry['金额'], entry['暂估价'], entry['类别']])
+        if '__children' in entry:
+            result_ = dfs(entry['__children'])
+            for r in result_:
+                result.append(r)
+    return result
+
+def dfs2(items):
+    result = []
+    for entry in items:
+        result.append([entry['序号'], entry['名称'], entry['取费基数'], entry['计算基础'], entry['费率'], entry['金额'], entry['类别']])
+        if '__children' in entry:
+            result_ = dfs2(entry['__children'])
+            for r in result_:
+                result.append(r)
+    return result
+
+def dfs3(items):
+    result = []
+    for entry in items:
+        result.append([entry['序号'], entry['名称'], entry['暂列金额'], entry['金额'], entry['项目类别'], entry['备注']])
+        if '__children' in entry:
+            result_ = dfs3(entry['__children'])
+            for r in result_:
+                result.append(r)
+    return result
+
+
+
+async def build(client, root, id):
+    db = client["baojia"]
+    collection = db["jingjibiao"]
+    document = await collection.find_one({'_id': ObjectId(id)})
+
+    root.set('BiaoDuanNO', document['BiaoDuanNO'])
+    root.set('Jsfs', document['Jsfs'])
+    root.set('Version', document['Version'])
+    root.set('Xmmc', document['Xmmc'])
+
+    TouBiaoXx = ET.SubElement(root, 'TouBiaoXx')
+    ##{'Tbzj' : '', 'Zgj' : '', 'Aqwmf' : '', 'Gf' : '' } 
+    TouBiaoXx.set('Tbzj', str(document['TouBiaoXx']['Tbzj']))
+    TouBiaoXx.set('Zgj', str(document['TouBiaoXx']['Zgj']))
+    TouBiaoXx.set('Aqwmf', str(document['TouBiaoXx']['Aqwmf']))
+    TouBiaoXx.set('Gf', str(document['TouBiaoXx']['Gf']))
+    if 'Zbr' in document['TouBiaoXx']:
+        TouBiaoXx.set('Zbr', str(document['TouBiaoXx']['Zbr']))
+    if 'Tbr' in document['TouBiaoXx']:
+        TouBiaoXx.set('Tbr', str(document['TouBiaoXx']['Tbr']))
+    if 'TbrDb' in document['TouBiaoXx']:
+        TouBiaoXx.set('TbrDb', str(document['TouBiaoXx']['TbrDb']))
+    if 'Bzr' in document['TouBiaoXx']:
+        TouBiaoXx.set('Bzr', str(document['TouBiaoXx']['Bzr']))
+    if 'BzTime' in document['TouBiaoXx']:
+        TouBiaoXx.set('BzTime', str(document['TouBiaoXx']['BzTime']))
+    for item in document['Dxgcxx']:
+        Dxgcxx = ET.SubElement(root, 'Dxgcxx')
+        Dxgcxx.set('Dxgcbh', str(item['Dxgcbh']))
+        Dxgcxx.set('Dxgcmc', str(item['Dxgcmc']))
+        Dxgcxx.set('Je', str(item['Je']))
+        Dxgcxx.set('Zgj', str(item['Zgj']))
+        Dxgcxx.set('Aqwmf', str(item['Aqwmf']))
+        Dxgcxx.set('Gf', str(item['Gf']))
+        for entry in item['Dwgc']:
+            Dwgcxx = ET.SubElement(Dxgcxx, 'Dwgcxx')
+            Dwgcxx.set('Dwgcbh', str(entry['Dwgcbh']))
+            Dwgcxx.set('Dwgcmc', str(entry['Dwgcmc']))
+            Dwgcxx.set('Zylb', str(entry['Zylb']))
+            Dwgcxx.set('SoftName', str(entry['SoftName']))
+            Dwgcxx.set('SoftNum', str(entry['SoftNum']))
+            Dwgcxx.set('DogNum', str(entry['DogNum']))
+            Dwgcxx.set('MachineKey', str(entry['MachineKey']))
+            collection = db["Dwgc"]
+            Dwgc = await collection.find_one({'biao_id': id, "Dwgcbh": entry['Dwgcbh']})
+            bjhz = dfs(Dwgc['bjhz'])
+            gfsj = dfs2(Dwgc['gfsj'])
+            qtxm = dfs3(Dwgc['qtxm'])
+            zlje = Dwgc['zlje']
+            zygczgj = Dwgc['zygczgj']
+            jrg = Dwgc['jrg']
+            zcbfwf = Dwgc['zcbfwf']
+            Fywj = ET.SubElement(Dwgcxx, 'Fywj')
+            for bjhz_ in bjhz:
+                FywjMx = ET.SubElement(Fywj, 'FywjMx')
+                FywjMx.set('Xh', str(bjhz_[0]))
+                FywjMx.set('Mc', str(bjhz_[1]))
+                FywjMx.set('Je', str(bjhz_[2]))
+                FywjMx.set('Zgj', str(bjhz_[3]))
+                FywjMx.set('Fyxlb', str(bjhz_[4]))
+            Gfsj = ET.SubElement(Dwgcxx, 'Gfsj')
+            for gfsj_ in gfsj:
+                GfsjMx = ET.SubElement(Gfsj, 'GfsjMx')
+                GfsjMx.set('Xh', str(gfsj_[0]))
+                GfsjMx.set('Mc', str(gfsj_[1]))
+                GfsjMx.set('Qfjs', str(gfsj_[2]))
+                GfsjMx.set('Jsjc', str(gfsj_[3]))
+                GfsjMx.set('Fl', str(gfsj_[4]))
+                GfsjMx.set('Je', str(gfsj_[5]))
+                GfsjMx.set('Fyxlb', str(gfsj_[6]))
+            Qtxm = ET.SubElement(Dwgcxx, 'Qtxm')
+            for qtxm_ in qtxm:
+                QtxmMx = ET.SubElement(Qtxm, 'QtxmMx')
+                QtxmMx.set('Xh', str(qtxm_[0]))
+                QtxmMx.set('Mc', str(qtxm_[1]))
+                QtxmMx.set('Je', str(qtxm_[2]))
+                QtxmMx.set('Xmlb', str(qtxm_[3]))
+                QtxmMx.set('Bz', str(qtxm_[4]))
+            Zlje = ET.SubElement(Dwgcxx, 'Zlje')
+            for i in range(len(zlje)):
+                ZljeMx = ET.SubElement(Zlje, 'ZljeMx')
+                ZljeMx.set('Xh', str(zlje[i][0]))
+                ZljeMx.set('Mc', str(zlje[i][1]))
+                ZljeMx.set('Dw', str(zlje[i][2]))
+                ZljeMx.set('Zdje', str(zlje[i][3]))
+                ZljeMx.set('Bz', str(zlje[i][4]))
+            Clzg = ET.SubElement(Dwgcxx, 'Clzg')
+            Zygczg = ET.SubElement(Dwgcxx, 'Zygczg')
+            for zygczgj_ in zygczgj:
+                ZygczgMx = ET.SubElement(Zygczg, 'ZygczgMx')
+                ZygczgMx.set('Xh', str(zygczgj_[0]))
+                ZygczgMx.set('Mc', str(zygczgj_[1]))
+                ZygczgMx.set('Gcnr', str(zygczgj_[2]))
+                ZygczgMx.set('Je', str(zygczgj_[3]))
+                ZygczgMx.set('Bz', str(zygczgj_[4]))
+            Jrg = ET.SubElement(Dwgcxx, 'Jrg')
+            for jrg_ in jrg:
+                JrgBt = ET.SubElement(Jrg, 'JrgBt')
+                JrgBt.set('Xh', str(jrg_[0]))
+                JrgBt.set('Mc', str(jrg_[1]))
+                JrgBt.set('Je', str(jrg_[2]))
+                JrgBt.set('Lb', str(jrg_[3]))
+            Zcbfwf = ET.SubElement(Dwgcxx, 'Zcbfwf')
+            for zcbfwf_ in zcbfwf:
+                ZcbfwfMx = ET.SubElement(Zcbfwf, 'ZcbfwfMx')
+                ZcbfwfMx.set('Xh', str(zcbfwf_[0]))
+                ZcbfwfMx.set('Mc', str(zcbfwf_[1]))
+                ZcbfwfMx.set('Xmjz', str(zcbfwf_[2]))
+                ZcbfwfMx.set('Fwnr', str(zcbfwf_[3]))
+                ZcbfwfMx.set('Jsjc', str(zcbfwf_[4]))
+                ZcbfwfMx.set('Fl', str(zcbfwf_[5]))
+                ZcbfwfMx.set('Je', str(zcbfwf_[6]))
+            Zjxmjdkzffj = ET.SubElement(Dwgcxx, 'Zjxmjdkzffj')
+
+
+
+
+
+
+
+
+
+
 
 
 
-    ##await manager.send_personal_message(f"You wrote: {data}", websocket)
 
 async def delete_files(client, id):
     db = client["baojia"]