Browse Source

djcs delete handsontable

Xiaopeng Zhang 6 tháng trước cách đây
mục cha
commit
be4d9270a8

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1 - 1
front/dist/report.html


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
front/dist/src_App2_js-node_modules_moment_locale_sync_recursive_-data_image_png_base64_iVBORw0KGgoAAAAN-c43643.bundle.js


+ 144 - 52
front/src/App2.js

@@ -1,7 +1,5 @@
 import * as React from 'react';
 import Box from "@mui/material/Box";
-import 'handsontable/dist/handsontable.full.min.css';
-//import 'handsontable/styles/ht-theme-main.min.css';
 import { styled, alpha } from '@mui/material/styles';
 import Paper from '@mui/material/Paper';
 import TextField from '@mui/material/TextField';
@@ -11,26 +9,27 @@ import Autocomplete from '@mui/material/Autocomplete';
 import { debounce } from '@mui/material/utils';
 import throttle from 'lodash/throttle';
 
-import { HandsonTable } from 'handsontable/base';
-import {HotTable} from "@handsontable/react";
-import { registerAllModules } from 'handsontable/registry';
 import {RichTreeView } from "@mui/x-tree-view/RichTreeView";
 import { Grid } from '@mui/material';
 import Tab from "@mui/material/Tab";
 import TabContext from "@mui/lab/TabContext";
 import TabList from "@mui/lab/TabList";
 import TabPanel from "@mui/lab/TabPanel";
-//import { registerPlugin, NestedRows } from 'handsontable/plugins';
-//registerPlugin(NestedRows);
 import Qingdan2 from './Qingdan2';
 import Gfsj from './Gfsj';
 import Tbxx from './Tbxx';
 import Bjhz from './Bjhz';
 import Zjcs2 from './Zjcs2';
-import Djcs2 from './Djcs2';
+import Djcs3 from './Djcs3';
 import Service from './Service';
 import Qufei from './Qufei';
 import Rcjhz from './Rcjhz';
+import Qtxm from './Qtxm';
+import Zlje from './Zlje';
+import Zygczgj from './Zygczgj';
+import Jrg from './Jrg';
+import Zcbfwf from './Zcbfwf';
+import Fbrgycl from './Fbrgycl';
 import {useLocation, useParams} from "react-router";
 import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
 import Typography from '@mui/material/Typography';
@@ -66,7 +65,6 @@ import {
 } from '@mui/x-data-grid';
 import Tooltip from '@mui/material/Tooltip';
 
-registerAllModules();
 const MUI_X_PRODUCTS = [
     {
       id: 'grid',
@@ -229,7 +227,19 @@ const MUI_X_PRODUCTS = [
     const [rcjhz, setRcjhz] = React.useState(false);
     const [gfsj, setGfsj] = React.useState(false);
     const [bjhz, setBjhz] = React.useState(false);
+    const [qtxm, setQtxm] = React.useState(false);
+    const [zlje, setZlje] = React.useState(false);
+    const [zygczgj, setZygczgj] = React.useState(false);
+    const [jrg, setJrg] = React.useState(false);
+    const [zcbfwf, setZcbfwf] = React.useState(false);
+    const [fbrgycl, setFbrgycl] = React.useState(false);
+    const [jrgData, setJrgData] = React.useState([]);
+    const [fbrgyclData, setFbrgyclData] = React.useState([]);
+    const [zcbfwfData, setZcbfwfData] = React.useState([]);
+    const [zygczgjData, setZygczgjData] = React.useState([]);
+    const [zljeData, setZljeData] = React.useState([]);
     const [gfsjData, setGfsjData] = React.useState([]);
+    const [qtxmData, setQtxmData] = React.useState([]);
     const [bjhzData, setBjhzData] = React.useState([]);
     const [tbxxData, setTbxxData] = React.useState([]);
     const [qdbt, setQdbt] = React.useState([]);
@@ -316,6 +326,9 @@ const MUI_X_PRODUCTS = [
 
     const handleChange = (event, newValue) => {
       setValue(newValue);
+      setRgde(null);
+      setJxde(null);
+      setClde(null);
     };
 
 
@@ -736,6 +749,12 @@ const MUI_X_PRODUCTS = [
                   setGfsj(false);
                   setBjhz(true);
                   setTbxx(false);
+                  setQtxm(false);
+                  setZlje(false);
+                  setZygczgj(false);
+                  setJrg(false);
+                  setZcbfwf(false);
+                  setFbrgycl(false);
                   //setColumnHeaders(["序号", "名称", "金额", "暂估价", "类别"]);
                 });
         }
@@ -752,6 +771,12 @@ const MUI_X_PRODUCTS = [
                   setGfsj(true);
                   setBjhz(false);
                   setTbxx(false);
+                  setQtxm(false);
+                  setZlje(false);
+                  setZygczgj(false);
+                  setJrg(false);
+                  setZcbfwf(false);
+                  setFbrgycl(false);
                   //setColumnHeaders(["序号", "名称", "取费基数", "计算基础","费率", "金额", "类别"]);
                 });
 
@@ -771,6 +796,12 @@ const MUI_X_PRODUCTS = [
                   setGfsj(false);
                   setBjhz(false);
                   setTbxx(false);
+                  setQtxm(false);
+                  setZlje(false);
+                  setZygczgj(false);
+                  setJrg(false);
+                  setZcbfwf(false);
+                  setFbrgycl(false);
                   //setColumnHeaders(["序号", "名称", "取费基数", "计算基础", "金额", "类别"]);
                 });
 
@@ -788,6 +819,12 @@ const MUI_X_PRODUCTS = [
           setGfsj(false);
           setBjhz(false);
           setTbxx(false);
+          setQtxm(false);
+          setZlje(false);
+          setZygczgj(false);
+          setJrg(false);
+          setZcbfwf(false);
+          setFbrgycl(false);
           //setColumnHeaders(["序号", "名称", "取费基数", "计算基础", "金额", "类别"]);
 
         }
@@ -797,7 +834,8 @@ const MUI_X_PRODUCTS = [
           setValue("1");
           //setColumnHeaders(["序号", "名称", "取费基数", "计算基础", "金额", "类别"]);
           Service.generateQitaxiangmu2(location["id"], id).then(x=>{
-                  setNestDetail(x);
+                  //setNestDetail(x);
+                  setQtxmData(x);
                   setNest(true);
                   setQingdan(false);
                   setCuoshi(false);
@@ -806,7 +844,13 @@ const MUI_X_PRODUCTS = [
                   setGfsj(false);
                   setBjhz(false);
                   setTbxx(false);
-                  setColumnHeaders(["序号", "名称", "金额", "项目类别", "备注"]);
+                  setQtxm(true);
+                  setZlje(false);
+                  setZygczgj(false);
+                  setJrg(false);
+                  setZcbfwf(false);
+                  setFbrgycl(false);
+                 //setColumnHeaders(["序号", "名称", "金额", "项目类别", "备注"]);
                 });
 
         } else if (itemId.includes("zhuan ye gong cheng zan gu jia")){
@@ -815,7 +859,7 @@ const MUI_X_PRODUCTS = [
           setValue("1");
           //setColumnHeaders(["序号", "名称", "取费基数", "计算基础", "金额", "类别"]);
           Service.generateZygczgj(location["id"], id).then(x=>{
-                  setDetail(x);
+                  setZygczgjData(x);
                   setNest(false);
                   setQingdan(false);
                   setCuoshi(false);
@@ -824,6 +868,12 @@ const MUI_X_PRODUCTS = [
                   setGfsj(false);
                   setBjhz(false);
                   setTbxx(false);
+                  setQtxm(false);
+                  setZlje(false);
+                  setZygczgj(true);
+                  setJrg(false);
+                  setZcbfwf(false);
+                  setFbrgycl(false);
                   //setColumnHeaders(["序号", "名称", "金额", "项目类别", "备注"]);
                 });
         }
@@ -833,7 +883,8 @@ const MUI_X_PRODUCTS = [
           setValue("1");
           //setColumnHeaders(["序号", "名称", "取费基数", "计算基础", "金额", "类别"]);
           Service.generateZanliejine2(location["id"], id).then(x=>{
-                  setDetail(x);
+                  //setDetail(x);
+                  setZljeData(x);
                   setNest(false);
                   setQingdan(false);
                   setCuoshi(false);
@@ -842,6 +893,12 @@ const MUI_X_PRODUCTS = [
                   setGfsj(false);
                   setBjhz(false);
                   setTbxx(false);
+                  setQtxm(false);
+                  setZlje(true);
+                  setZygczgj(false);
+                  setJrg(false);
+                  setZcbfwf(false);
+                  setFbrgycl(false);
                 });
 
         }
@@ -851,7 +908,7 @@ const MUI_X_PRODUCTS = [
           setValue("1");
           //setColumnHeaders(["序号", "名称", "取费基数", "计算基础", "金额", "类别"]);
           Service.generateJirigong2(location["id"], id).then(x=>{
-                  setDetail(x);
+                  setJrgData(x);
                   setNest(false);
                   setQingdan(false);
                   setCuoshi(false);
@@ -860,6 +917,12 @@ const MUI_X_PRODUCTS = [
                   setGfsj(false);
                   setBjhz(false);
                   setTbxx(false);
+                  setQtxm(false);
+                  setZlje(false);
+                  setZygczgj(false);
+                  setJrg(true);
+                  setZcbfwf(false);
+                  setFbrgycl(false);
                 });
 
         }
@@ -869,7 +932,7 @@ const MUI_X_PRODUCTS = [
           setValue("1");
           //setColumnHeaders(["序号", "名称", "取费基数", "计算基础", "金额", "类别"]);
           Service.generateZongchengbaofuwufei2(location["id"], id).then(x=>{
-                  setDetail(x);
+                  setZcbfwfData(x);
                   setNest(false);
                   setQingdan(false);
                   setCuoshi(false);
@@ -878,6 +941,12 @@ const MUI_X_PRODUCTS = [
                   setGfsj(false);
                   setBjhz(false);
                   setTbxx(false);
+                  setQtxm(false);
+                  setZlje(false);
+                  setZygczgj(false);
+                  setJrg(false);
+                  setZcbfwf(true);
+                  setFbrgycl(false);
                 });
 
         }
@@ -887,7 +956,7 @@ const MUI_X_PRODUCTS = [
           setValue("1");
           //setColumnHeaders(["序号", "名称", "取费基数", "计算基础", "金额", "类别"]);
           Service.generateFabaorengongyingcailiao2(location["id"], id).then(x=>{
-                  setDetail(x);
+                  setFbrgyclData(x);
                   setNest(false);
                   setQingdan(false);
                   setCuoshi(false);
@@ -896,6 +965,12 @@ const MUI_X_PRODUCTS = [
                   setGfsj(false);
                   setBjhz(false);
                   setTbxx(false);
+                  setQtxm(false);
+                  setZlje(false);
+                  setZygczgj(false);
+                  setJrg(false);
+                  setZcbfwf(false);
+                  setFbrgycl(true);
                 });
 
         }
@@ -914,6 +989,12 @@ const MUI_X_PRODUCTS = [
                   setGfsj(false);
                   setBjhz(false);
                   setTbxx(false);
+                  setQtxm(false);
+                  setZlje(false);
+                  setZygczgj(false);
+                  setJrg(false);
+                  setZcbfwf(false);
+                  setFbrgycl(false);
                   setQdbh(id);
                 //}
                 //)
@@ -931,6 +1012,12 @@ const MUI_X_PRODUCTS = [
             setGfsj(false);
             setBjhz(false);
             setTbxx(true);
+            setQtxm(false);
+            setZlje(false);
+            setZygczgj(false);
+            setJrg(false);
+            setZcbfwf(false);
+            setFbrgycl(false);
         });
 
         }
@@ -1090,6 +1177,12 @@ const MUI_X_PRODUCTS = [
                   setGfsj(false);
                   setBjhz(false);
                   setTbxx(false);
+                  setQtxm(false);
+                  setZlje(false);
+                  setZygczgj(false);
+                  setJrg(false);
+                  setZcbfwf(false);
+                  setFbrgycl(false);
                  }}>费率</Button>
 
             
@@ -1098,60 +1191,59 @@ const MUI_X_PRODUCTS = [
 
             </Grid>
             <Grid size={9}>
-              {!nest && !qingdan && !cuoshi && !qufei && rcjhz && !gfsj && !bjhz && !tbxx && <Rcjhz 
+              {!nest && !qingdan && !cuoshi && !qufei && rcjhz && !gfsj && !bjhz && !tbxx && !qtxm && !zlje && !zygczgj && !jrg && !zcbfwf && !fbrgycl && <Rcjhz 
               id={location['id']} 
               bh={qdbh}
               tiaojiaCallback={tiaojiaCallback}
               />}
 
-              {!nest && !qingdan && !cuoshi && !qufei && !rcjhz && !gfsj && !bjhz && tbxx && <Tbxx 
+               {!nest && !qingdan && !cuoshi && !qufei && !rcjhz && !gfsj && !bjhz && !tbxx && !qtxm && zlje && !zygczgj && !jrg && !zcbfwf && !fbrgycl && <Zlje 
+              data={zljeData} 
+              />}
+
+            {!nest && !qingdan && !cuoshi && !qufei && !rcjhz && !gfsj && !bjhz && !tbxx && !qtxm && !zlje && !zygczgj && !jrg && !zcbfwf && fbrgycl && <Fbrgycl
+              data={fbrgyclData} 
+              />}
+
+              {!nest && !qingdan && !cuoshi && !qufei && !rcjhz && !gfsj && !bjhz && !tbxx && !qtxm && !zlje && !zygczgj && !jrg && zcbfwf && !fbrgycl && <Zcbfwf
+              data={zcbfwfData} 
+              />}
+
+              {!nest && !qingdan && !cuoshi && !qufei && !rcjhz && !gfsj && !bjhz && !tbxx && !qtxm && !zlje && !zygczgj && jrg && !zcbfwf && !fbrgycl && <Jrg 
+              data={jrgData} 
+              />}
+              
+              {!nest && !qingdan && !cuoshi && !qufei && !rcjhz && !gfsj && !bjhz && !tbxx && !qtxm && !zlje && zygczgj && !jrg && !zcbfwf && !fbrgycl && <Zygczgj
+              data={zygczgjData} 
+              />}
+
+              {!nest && !qingdan && !cuoshi && !qufei && !rcjhz && !gfsj && !bjhz && tbxx && !qtxm && !zlje && !zygczgj && !jrg && !zcbfwf && !fbrgycl && <Tbxx 
               data={tbxxData} 
               
               />}
 
-              {nest && !qingdan && !cuoshi && !qufei && !rcjhz && gfsj && !bjhz && !tbxx && <Gfsj 
+              {nest && !qingdan && !cuoshi && !qufei && !rcjhz && gfsj && !bjhz && !tbxx && !qtxm && !zlje && !zygczgj && !jrg && !zcbfwf && !fbrgycl && <Gfsj 
                    data={gfsjData}
               
+              />}
+
+              {nest && !qingdan && !cuoshi && !qufei && !rcjhz && !gfsj && !bjhz && !tbxx && qtxm && !zlje && !zygczgj && !jrg && !zcbfwf && !fbrgycl && <Qtxm 
+                   data={qtxmData}
+              
               />}
 
 
-               {nest && !qingdan && !cuoshi && !qufei && !rcjhz && !gfsj && bjhz && !tbxx && <Bjhz 
+               {nest && !qingdan && !cuoshi && !qufei && !rcjhz && !gfsj && bjhz && !tbxx && !qtxm && !zlje && !zygczgj && !jrg && !zcbfwf && !fbrgycl && <Bjhz 
                    data={bjhzData}
               
                />}
              
-            {!nest && !qingdan && !cuoshi && !qufei && !rcjhz && !gfsj && !bjhz && !tbxx && <HotTable nestedRows={false}
-                    data={detail
-                    }
-                    rowHeaders={true}
-                    colHeaders={true}
-                    fixedRowsTop={1}
-
-                    height="800"
-                    readOnly={true}
-                    autoWrapRow={false}
-                    autoWrapCol={false}
-                    licenseKey="non-commercial-and-evaluation" // for non-commercial use only
-                  />}
-            {nest && !qingdan && !cuoshi && !qufei && !rcjhz && !gfsj && !bjhz && !tbxx && <HotTable nestedRows={true}
-                    data={nestDetail
-                    }
-                    readOnly={true}
-                    fixedRowsTop={1}
-
-                    rowHeaders={true}
-                    colHeaders={columnHeaders}
-                    height="auto"
-                    contextMenu={true}
-                    bindRowsWithHeaders={true}
-                    autoWrapRow={false}
-                    autoWrapCol={false}
-                    licenseKey="non-commercial-and-evaluation" // for non-commercial use only
-                  />}
-            {!qingdan && !cuoshi && qufei && !rcjhz && !gfsj && !bjhz && !tbxx && <Qufei id={location['id']} qufeiCallback={qufeiCallback}
+            
+            
+            {!qingdan && !cuoshi && qufei && !rcjhz && !gfsj && !bjhz && !tbxx && !qtxm && !zlje && !zygczgj && !jrg && !zcbfwf && !fbrgycl && <Qufei id={location['id']} qufeiCallback={qufeiCallback}
                   />}
 
-            {!nest && qingdan && !cuoshi && !qufei && !rcjhz && !gfsj && !bjhz  && !tbxx &&  <TabContext value={value}>
+            {!nest && qingdan && !cuoshi && !qufei && !rcjhz && !gfsj && !bjhz  && !tbxx && !qtxm && !zlje && !zygczgj && !jrg && !zcbfwf && !fbrgycl &&  <TabContext value={value}>
                    <Box sx={{ borderBottom: 1, borderColor: 'divider' }}>
                       <TabList scrollButtons='auto' 
                               variant="scrollable"
@@ -1180,7 +1272,7 @@ const MUI_X_PRODUCTS = [
                      </TabPanel>
                       )}
                 </TabContext>}
-            {!nest && !qingdan && cuoshi && !qufei && !rcjhz && !gfsj && !bjhz && !tbxx &&  <TabContext value={value}>
+            {!nest && !qingdan && cuoshi && !qufei && !rcjhz && !gfsj && !bjhz && !tbxx && !qtxm && !zlje && !zygczgj && !jrg && !zcbfwf && !fbrgycl &&  <TabContext value={value}>
                    <Box sx={{ borderBottom: 1, borderColor: 'divider' }}>
                       <TabList scrollButtons='auto' 
                               variant="scrollable"
@@ -1194,7 +1286,7 @@ const MUI_X_PRODUCTS = [
                      <Zjcs2 name={location["id"]} bh={dwgc} zjcsCallback={zjcsCallback}/>
                    </TabPanel>
                    <TabPanel sx={{p: 1}} value="2">
-                     <Djcs2 
+                     <Djcs3
                          name={location["id"]} 
                          bh={dwgc}
                          rgde={rgde}

+ 73 - 34
front/src/Djcs2.js

@@ -80,6 +80,7 @@ export default function Djcs2({name, bh, rgde, jxde, clde, beizhu, beizhuFK, cli
                });
                Service.generateQingdanTuijian(name, bh,bt,row._row.data['清单编码']).then(x=>{
                     setTuijian(x);
+                    if (tuijianTable.current) tuijianTable.current.replaceData(x);
                });
           } else {
                
@@ -184,6 +185,10 @@ export default function Djcs2({name, bh, rgde, jxde, clde, beizhu, beizhuFK, cli
     const hotRcjRef = React.useRef(null);
     const myRef = React.useRef(null);
     const myTable = React.useRef(null);
+    const tuijianRef = React.useRef(null);
+    const tuijianTable = React.useRef(null);
+    const rcj2Ref = React.useRef(null);
+    const rcj2Table = React.useRef(null);
     const [value, setValue] = React.useState("1");
     const [rcjhl, setRcjhl] = React.useState([]);
     const [rcjhl2, setRcjhl2] = React.useState([]);
@@ -342,6 +347,8 @@ export default function Djcs2({name, bh, rgde, jxde, clde, beizhu, beizhuFK, cli
                myTable.current.replaceData(x);
                });
         });
+
+        
     
    }, [bh]);
 
@@ -371,6 +378,63 @@ export default function Djcs2({name, bh, rgde, jxde, clde, beizhu, beizhuFK, cli
         }, [beizhu]
       );
 
+      React.useEffect(
+          () => {
+               if (tuijianRef.current != null ) {
+               tuijianTable.current = new Tabulator(tuijianRef.current, {
+                    index: "key",
+                    height: 200,
+                  data: tuijian, //link data to table
+                  reactiveData: false, //enable data reactivity
+                  dataTreeStartExpanded:false,
+                  dataTree: false,
+                  selectableRows:1, //make rows selectable
+                  
+                  
+                  columns: [ //Define Table Columns
+                               {title:"ID", field:"ID", width:80, headerSort:false, }, //never hide this column
+                               {title:"定额编号", field:"定额编号", width:120,headerSort:false,  formatter:"textarea" },
+                               {title:"工程量名称", field:"工程量名称", width:150, headerSort:false, formatter:"textarea"}, //hide this column first
+                               {title:"工作内容", field:"工作内容", width:150 , headerSort:false, formatter:"textarea"},
+                             
+                       ]
+               });
+               tuijianTable.current.on("tableBuilt", () => {
+                    
+                    tuijianTable.current.replaceData(tuijian);
+                         
+                  });
+               }
+               if (rcj2Ref.current != null ) {
+                    rcj2Table.current = new Tabulator(rcj2Ref.current, {
+                         index: "key",
+                         height: 200,
+                       data: rcjhl2, //link data to table
+                       reactiveData: false, //enable data reactivity
+                       dataTreeStartExpanded:false,
+                       dataTree: false,
+                       selectableRows:1, //make rows selectable
+                       
+                       
+                       columns: [ //Define Table Columns
+                                    {title:"人材机编码", field:"人材机编码", width:80, headerSort:false, }, //never hide this column
+                                    {title:"名称", field:"名称", width:120,headerSort:false,  formatter:"textarea" },
+                                    {title:"单位", field:"单位", width:150, headerSort:false, formatter:"textarea"}, //hide this column first
+                                    {title:"单价", field:"单价", width:150 , headerSort:false, formatter:"money"},
+                                    {title:"合价", field:"合价", width:150 , headerSort:false, formatter:"money"},
+                                    {title:"含量", field:"含量", width:150 , headerSort:false, formatter:"textarea"},
+                                  
+                            ]
+                    });
+                    rcj2Table.current.on("tableBuilt", () => {
+                         
+                         rcj2Table.current.replaceData(rcjhl2);
+                              
+                       });
+                    }
+          }, [value]
+        );
+
 
 
       React.useEffect(
@@ -482,21 +546,24 @@ export default function Djcs2({name, bh, rgde, jxde, clde, beizhu, beizhuFK, cli
           }
 
 
-          let bzrcjhl = [["人材机编码", "名称", "单位", "单价", "合价", "含量"]] 
+          let bzrcjhl = [] 
           if (rgde)
           for (let i = 0; i  < rgde.length; i++) {
-               bzrcjhl.push([rgde[i]["CLBH"], rgde[i]["CLMC"], rgde[i]["JLDW"], rgde[i]["YSJG"], rgde[i]["gf"], rgde[i]["gr"]]);
+               bzrcjhl.push({'人材机编码': rgde[i]["CLBH"], '名称': rgde[i]["CLMC"], '单位': rgde[i]["JLDW"], '单价': rgde[i]["YSJG"], '合价': rgde[i]["gf"], '含量': rgde[i]["gr"]});
           }
           
           if (clde)
           for (let i = 0; i  < clde.length; i++) {
-               bzrcjhl.push([clde[i]["CLBH"], clde[i]["CLMC"], clde[i]["JLDW"], clde[i]["YSJG"], clde[i]["HJ"], clde[i]["SL"]]);
+               bzrcjhl.push({'人材机编码': clde[i]["CLBH"], '名称': clde[i]["CLMC"], '单位': clde[i]["JLDW"], '单价': clde[i]["YSJG"], '合价': clde[i]["HJ"], '含量': clde[i]["SL"]});
           }
           if (jxde)
           for (let i = 0; i  < jxde.length; i++) {
-               bzrcjhl.push([jxde[i]["jxbh"], jxde[i]["jxmc"], jxde[i]["DW"], jxde[i]["tbdj"], jxde[i]["hj"], jxde[i]["sl"]]);
+               bzrcjhl.push({'人材机编码': jxde[i]["jxbh"], '名称': jxde[i]["jxmc"], '单位': jxde[i]["DW"], '单价': jxde[i]["tbdj"], '合价': jxde[i]["hj"], '含量': jxde[i]["sl"]});
           }
           setRcjhl2(bzrcjhl);
+          if (rcj2Table.current) {
+               rcj2Table.current.replaceData(bzrcjhl);
+          }
         }, [rgde, jxde, clde]
       );
 
@@ -641,21 +708,7 @@ export default function Djcs2({name, bh, rgde, jxde, clde, beizhu, beizhuFK, cli
 
                        </TabPanel>
                        <TabPanel value="2">
-                          <HotTable 
-                          nestedRows={false}
-                             data={rcjhl2
-                             }
-                             manualColumnResize={true}
-                             rowHeaders={true}
-                             colHeaders={true}
-                             height="200"
-                             readOnly={true}
-                             fixedRowsTop={1}
-                             selectionMode="single"
-                             autoWrapRow={false}
-                             autoWrapCol={false}
-                             licenseKey="non-commercial-and-evaluation" // for non-commercial use only
-                           />
+                       <div ref={rcj2Ref}></div>
 
                        </TabPanel>
                        <TabPanel value="3">
@@ -702,21 +755,7 @@ export default function Djcs2({name, bh, rgde, jxde, clde, beizhu, beizhuFK, cli
                        </TabPanel>
 
                        <TabPanel value="4">
-                          <HotTable 
-                          nestedRows={false}
-                             data={tuijian
-                             }
-                             manualColumnResize={true}
-                             rowHeaders={true}
-                             colHeaders={true}
-                             height="200"
-                             readOnly={true}
-                             fixedRowsTop={1}
-                             selectionMode="single"
-                             autoWrapRow={false}
-                             autoWrapCol={false}
-                             licenseKey="non-commercial-and-evaluation" // for non-commercial use only
-                           />
+                          <div ref={tuijianRef}></div>
 
                        </TabPanel>
                      </TabContext>

+ 854 - 0
front/src/Djcs3.js

@@ -0,0 +1,854 @@
+import * as React from 'react';
+import Box from "@mui/material/Box";
+import {RichTreeView } from "@mui/x-tree-view/RichTreeView";
+import { Grid } from '@mui/material';
+import Tab from "@mui/material/Tab";
+import TabContext from "@mui/lab/TabContext";
+import TabList from "@mui/lab/TabList";
+import TabPanel from "@mui/lab/TabPanel";
+import Stack from "@mui/material/Stack";
+import Service from './Service';
+import {TabulatorFull as Tabulator} from "tabulator-tables"; //import Tabulator library
+import "tabulator-tables/dist/css/tabulator.min.css"; //import Tabulator stylesheet
+import './Tabulator.css';
+import { DataGrid } from '@mui/x-data-grid';
+import {extractFuzhu, match_target} from './utils';
+import Button from '@mui/material/Button';
+import {shanchu_djcs, undo_djcs, redo_djcs, danxiangdinge_djcs, updateDercj_djcs, changguidinge_djcs, handleBeizhu_djcs, huan, updateShuliang_djcs} from './editor';
+import {copy} from './utils';
+
+import { Table, ConfigProvider, Button as AButton } from "antd";
+
+import zhCN from 'antd/locale/zh_CN';
+
+
+function number_equal(a, b) {
+     if (Number(a) - Number(b) < 0.0001 && Number(a) - Number(b) > -0.0001) {
+          return true;
+     }
+     return false;
+}
+export default function Djcs3({name, bh, rgde, jxde, clde, beizhu, beizhuFK, clickCallback, loadingCallback, dingeclick}) {
+     const lastClickRef = React.useRef(null);
+
+    
+     var editCheck = function(cell){
+          //cell - the cell component for the editable cell
+      
+          //get row data
+          //console.log(cell);
+          if(cell._cell.row.data['序号']) return false;
+          return true;
+      }
+
+      var editCheckRcj = function(cell){
+          //cell - the cell component for the editable cell
+      
+          //get row data
+          //console.log(cell);
+          if(isQdrcj.current) return false;
+          return true;
+      }
+
+
+
+      var sparklineFormatter = function(cell, formatterParams, onRendered){
+          for (let i = 0; i < highlight.current.length; i++) {
+               let entry = highlight.current[i];
+               if (entry.row + 1 == cell._cell.row.position && entry.col + 1 == cell._cell.column.getPosition()) {
+                    cell.getElement().style.fontWeight = 'bold';
+                    cell.getElement().style.color = 'green';
+                    cell.getElement().style.background = '#d7f1e1';
+               }
+              }
+              return Number(cell.getValue()).toFixed(2).toString(); 
+          };
+
+
+     function handleSelect(row){
+          //e - the click event object
+          //cell - cell component
+          console.log('rowSelected');
+          selectedRowKeysTable.current = [row._row['data']['key']];
+          let bt = "Djcs" ;
+          
+          if (row._row.data['序号'] != null && row._row.data['序号'].length >0) {
+               selectedRowKeysTableParent.current = row._row['data']['key'];
+
+               setFuzhu([]);
+               Service.generateQingdanrcj(name, bh,bt,row._row.data['清单编码']).then(x=>{
+                    let y =[];
+                    for (let i = 1; i < x.length; i++) {
+                         y.push({
+                              'ID' : x[i][0],
+                              '人材机编码' : x[i][1],
+                              '名称' : x[i][2],
+                              '规格型号': x[i][3],
+                              '单位' : x[i][4],
+                              '单价' : x[i][5],
+                              '产地' : x[i][6],
+                              '供应厂商' : x[i][7],
+                              '人材机类别' : x[i][8],
+                              '甲供标志': x[i][9],
+                              '含量' : x[i][10],
+                              '合价' : x[i][11],
+                              '暂估价标志' : x[i][12],
+                              '主要材料标志' : x[i][13],
+                              '主材标志' : x[i][14],
+                              '设备标志' : x[i][15] 
+
+                         });
+                    }
+                    setRcjhl(y);
+                    if (rcjTable.current) {
+                         rcjTable.current.replaceData(y);
+                    }
+
+                    isQdrcj.current=true;
+                    highlight.current = [];
+               });
+               Service.generateQingdanTuijian(name, bh,bt,row._row.data['清单编码']).then(x=>{
+                    setTuijian(x);
+                    if (tuijianTable.current) tuijianTable.current.replaceData(x);
+               });
+          } else {
+               
+               let row_parent = row._row;
+               while(row_parent.modules.dataTree.parent) {
+                   row_parent = row_parent.modules.dataTree.parent;
+               }
+               debmRef.current = row._row['data']['清单编码'];
+               selectedRowKeysTableParent.current = row_parent['data']['key'];
+
+
+                             clickCallback(row_parent['data']['清单编码'], row._row['data']['清单编码']);
+                             Service.generateDingercj(name, bh,bt,row_parent['data']['清单编码'], row._row['data']['清单编码']).then(x=>{
+                              let y =[];
+                              for (let i = 1; i < x[0].length; i++) {
+                                   y.push({
+                                        'ID' : x[0][i][0],
+                                        '人材机编码' : x[0][i][1],
+                                        '名称' : x[0][i][2],
+                                        '规格型号': x[0][i][3],
+                                        '单位' : x[0][i][4],
+                                        '单价' : x[0][i][5],
+                                        '产地' : x[0][i][6],
+                                        '供应厂商' : x[0][i][7],
+                                        '人材机类别' : x[0][i][8],
+                                        '甲供标志': x[0][i][9],
+                                        '含量' : x[0][i][10],
+                                        '合价' : x[0][i][11],
+                                        '暂估价标志' : x[0][i][12],
+                                        '主要材料标志' : x[0][i][13],
+                                        '主材标志' : x[0][i][14],
+                                        '设备标志' : x[0][i][15] 
+          
+                                   });
+                              }
+                              setRcjhl(y);
+                              if (rcjTable.current) {
+                                   rcjTable.current.replaceData(y);
+                              }
+                               isQdrcj.current = false;
+                               setFuzhuEnable(x[1]);
+                               let toHighlight = [];
+                               for(let i = 0; i < y.length; i++) {
+                                   let entry = y[i];
+                                   let bianhao = entry['人材机编码'];
+                                   let rcjlb = entry['人材机类别'];
+                                   if (Number(rcjlb) == 1 &&  rgdeRef.current  ) {
+                                      for (let j = 0;j < rgdeRef.current.length; j++) {
+                                         if (rgdeRef.current[j]["CLBH"] == bianhao) {
+                                              let danjia = Number(entry['单价']);
+                                              if (!number_equal(danjia , rgdeRef.current[j]["YSJG"])) {
+                                                   console.log(`[${i},5]danjia bu yizhi`);
+                                                   toHighlight.push({row: i, col: 5, });
+                                              }
+                                              let hanliang = Number(entry['含量']);
+                                              if (!number_equal(hanliang , rgdeRef.current[j]["gr"])) {
+                                                   console.log(`[${i}, 10]hanliang bu yizhi`);
+                                                   toHighlight.push({row: i, col: 10, });
+                                              }
+                                         }
+                                      }
+
+                                   }   
+                                   if (Number(rcjlb) == 3 && jxdeRef.current  ) {
+                                      for (let j = 0; j < jxdeRef.current.length; j++) {
+                                         if (jxdeRef.current[j]["jxbh"] == bianhao) {
+                                               let danjia = Number(entry['单价']);
+                                               if (!number_equal(danjia , jxdeRef.current[j]["tbdj"])) {
+                                                    console.log(`[${i},5]danjia bu yizhi`);
+                                                    toHighlight.push({row: i, col: 5, });
+                                               }
+                                               let hanliang = Number(entry['含量']);
+                                               if (!number_equal(hanliang , jxdeRef.current[j]["sl"])) {
+                                                    console.log(`[${i}, 10]hanliang bu yizhi`);
+                                                    toHighlight.push({row: i, col: 10, });
+                                               }
+                                         }
+                                      }
+
+                                   }   
+                                   if (Number(rcjlb) == 2 && cldeRef.current  ) {
+                                      for (let j = 0; j < cldeRef.current.length; j++) {
+                                         if (cldeRef.current[j]["CLBH"] == bianhao) {
+                                               let danjia = Number(entry['单价']);
+                                               if (!number_equal(danjia , cldeRef.current[j]["YSJG"])) {
+                                                    console.log(`[${i},5]danjia bu yizhi`);
+                                                    toHighlight.push({row: i, col: 5, });
+                                               }
+                                               let hanliang = Number(entry['含量']);
+                                               if (!number_equal(hanliang , cldeRef.current[j]["SL"])) {
+                                                    console.log(`[${i}, 10]hanliang bu yizhi`);
+                                                    toHighlight.push({row: i, col: 10, });
+                                               }
+                                         }
+                                      }
+
+                                   }   
+                               }
+                               highlight.current = toHighlight;
+                             });
+          }
+     }
+     
+  
+
+       
+    const [detail, setDetail] = React.useState([
+                    
+    ]);
+    const myRef = React.useRef(null);
+    const myTable = React.useRef(null);
+    const tuijianRef = React.useRef(null);
+    const tuijianTable = React.useRef(null);
+    const rcj2Ref = React.useRef(null);
+    const rcj2Table = React.useRef(null);
+    const rcjRef = React.useRef(null);
+    const rcjTable = React.useRef(null);
+    const [value, setValue] = React.useState("1");
+    const [rcjhl, setRcjhl] = React.useState([]);
+    const [rcjhl2, setRcjhl2] = React.useState([]);
+    const [fuzhu, setFuzhu] = React.useState([]);
+    const [tuijian, setTuijian] = React.useState([]);
+    const beizhuFKRef = React.useRef(null);
+
+    const [fuzhuEnable, setFuzhuEnable] = React.useState(false);
+
+   const [selectedRowKeys, setSelectedRowKeys] = React.useState([]);
+   const onSelectChange = (newSelectedRowKeys) => {
+     console.log('selectedRowKeys changed: ', newSelectedRowKeys);
+     setSelectedRowKeys(newSelectedRowKeys);
+     const [newData, newHl] = handleBeizhu_djcs(beizhuFKRef.current, selectedRowKeysTable.current[0], newSelectedRowKeys, fuzhu);
+                                  if (newData) {
+                                     myTable.current.updateData(newData.filter(x=>x['key'] == selectedRowKeysTableParent.current));
+                                     let y =[];
+                                     for (let i = 1; i < newHl.length; i++) {
+                                         y.push({
+                                          'ID' : newHl[i][0],
+                                          '人材机编码' : newHl[i][1],
+                                          '名称' : newHl[i][2],
+                                          '规格型号': newHl[i][3],
+                                          '单位' : newHl[i][4],
+                                          '单价' : newHl[i][5],
+                                          '产地' : newHl[i][6],
+                                          '供应厂商' : newHl[i][7],
+                                          '人材机类别' : newHl[i][8],
+                                          '甲供标志': newHl[i][9],
+                                          '含量' : newHl[i][10],
+                                          '合价' : newHl[i][11],
+                                          '暂估价标志' : newHl[i][12],
+                                          '主要材料标志' : newHl[i][13],
+                                          '主材标志' : newHl[i][14],
+                                          '设备标志' : newHl[i][15] 
+
+                                      });
+                                     }
+                                     setRcjhl(y);
+                                     if (rcjTable.current) {
+                                        rcjTable.current.replaceData(y);
+                                     }
+
+                                  }
+   };
+   const rowSelection = {
+     selectedRowKeys,
+     onChange: onSelectChange,
+     getCheckboxProps: (record) => {
+          return {
+               disabled: !fuzhuEnable
+          };
+     }
+   };
+    const highlight = React.useRef([]);
+
+    
+    const rgdeRef = React.useRef(null);
+    const jxdeRef = React.useRef(null);
+    const cldeRef = React.useRef(null);
+    const isQdrcj = React.useRef(false);
+    const debmRef = React.useRef(null);
+    const selectedRowKeysTable = React.useRef([]);
+    const selectedRowKeysTableParent = React.useRef(null);
+   
+
+    React.useEffect(() => {
+     myTable.current = new Tabulator(myRef.current, {
+          index: "key",
+          height: 380,
+        data: detail, //link data to table
+        reactiveData: false, //enable data reactivity
+        dataTreeStartExpanded:true,
+        dataTree: true,
+        selectableRows:1, //make rows selectable
+        editTriggerEvent:"dblclick", //trigger edit on double click
+        dataTreeStartExpanded:function(row, level){
+            //console.log(row);
+            //console.log(level);
+            return true; //expand rows where the "driver" data field is true;
+        },
+        columns: [ //Define Table Columns
+                     {title:"序号", field:"序号", width:80, headerSort:false, frozen: true}, //never hide this column
+                     {title:"清单编码", field:"清单编码", width:120,headerSort:false, frozen: true, formatter:"textarea" },
+                     {title:"名称", field:"名称", width:150, headerSort:false, formatter:"textarea"}, //hide this column first
+                     {title:"项目特征", field:"项目特征", width:150 , headerSort:false, formatter:"textarea"},
+                     {title:"计算规则", field:"计算规则", width:150, headerSort:false, formatter:"textarea"},
+                     {title:"单位", field:"单位", width:100, headerSort:false},
+                     {title:"数量", field:"数量", width:100, headerSort:false, editor: "input", editable: editCheck },
+                     {title:"综合单价", field:"综合单价", width:100, headerSort:false, formatter:"money"},
+                     {title:"合价", field:"合价", width:100, headerSort:false, formatter:"money"},
+                     {title:"人工费", field:"人工费", width:100, headerSort:false, formatter:"money"},
+                     {title:"主材费", field:"主材费", width:100, headerSort:false, formatter:"money"},
+                     {title:"设备费", field:"设备费", width:100, headerSort:false, formatter:"money"},
+                     {title:"辅材费", field:"辅材费", width:100, headerSort:false, formatter:"money"},
+                     {title:"材料费", field:"材料费", width:100, headerSort:false, formatter:"money"},
+                     {title:"机械费", field:"机械费", width:100, headerSort:false, formatter:"money"},
+                     {title:"管理费", field:"管理费", width:100, headerSort:false, formatter:"money"},
+                     {title:"利润", field:"利润", width:100, headerSort:false, formatter:"money"},
+                     {title:"暂估价", field:"暂估价", width:100, headerSort:false, formatter:"money"},
+                     {title:"综合人工工日", field:"综合人工工日", width:100, headerSort:false},
+             ]
+      }); 
+      
+      myTable.current.on("cellDblClick", function(e, cell){
+          //e - the click event object
+          //cell - cell component
+          console.log(cell);
+      });
+
+      myTable.current.on("rowSelected", handleSelect);
+      
+
+      myTable.current.on("cellEdited", function(cell){
+          //console.log("edited");
+          //console.log();
+          let key = cell._cell.row.data['key'];
+          myTable.current.deselectRow();
+          let [success, data] = updateShuliang_djcs(cell._cell.row.data['数量'], selectedRowKeysTable.current[0]);
+          if (success) {
+                           myTable.current.updateData(data.filter(x=>x['key'] == selectedRowKeysTableParent.current)).then(function() {
+                              let getRow = myTable.current.getRows(); //get array of currently selected row components.
+                              let component = null;
+                              for(let i = 0; i < getRow.length; i++) {
+                                   let entry = getRow[i]._row.modules.dataTree.children;
+                                   for(let j = 0; j < entry.length; j++) {
+                                        let child = entry[j];
+                                        if(child.data['key'] == key) {
+                                             //console.log(child);
+                                             component = child.component;
+                                             break;
+                                        }
+                                        
+                                   }
+
+                              }
+                              component.select();
+                              handleSelect(component);
+                              //handleSelect(getRow[0]);
+                           });                            
+                                                       
+          }
+      });
+
+
+      myTable.current.on("tableBuilt", () => {
+          Service.generateDjcs(name, bh).then(x=>{
+               myTable.current.replaceData(x);
+               });
+        });
+
+        
+    
+   }, [bh]);
+
+
+   React.useEffect(
+     () => {
+          beizhuFKRef.current = beizhuFK;
+     }, [beizhuFK]
+   );
+ 
+    React.useEffect(
+        () => {
+            console.log(beizhu);
+            let result = [];
+            if (beizhu != null) { 
+                let keys = Object.keys(beizhu["BZBH"]);
+                for(let i = 0; i < keys.length; i++) {
+                    let key = keys[i];
+                    result.push({'key': i+1, '序号': i+1, '编号': beizhu["BZBH"][key], '说明': beizhu["SM"][key]});//序号很重要
+                }
+                setFuzhu(result);
+                let newSelect = extractFuzhu(debmRef.current);
+                setSelectedRowKeys(newSelect);
+                //setSelectedRowKeys([1]);
+                
+            }
+        }, [beizhu]
+      );
+
+      React.useEffect(
+          () => {
+               if (tuijianRef.current != null ) {
+               tuijianTable.current = new Tabulator(tuijianRef.current, {
+                    index: "key",
+                    height: 200,
+                  data: tuijian, //link data to table
+                  reactiveData: false, //enable data reactivity
+                  dataTreeStartExpanded:false,
+                  dataTree: false,
+                  selectableRows:1, //make rows selectable
+                  
+                  
+                  columns: [ //Define Table Columns
+                               {title:"ID", field:"ID", width:80, headerSort:false, }, //never hide this column
+                               {title:"定额编号", field:"定额编号", width:120,headerSort:false,  formatter:"textarea" },
+                               {title:"工程量名称", field:"工程量名称", width:150, headerSort:false, formatter:"textarea"}, //hide this column first
+                               {title:"工作内容", field:"工作内容", width:150 , headerSort:false, formatter:"textarea"},
+                             
+                       ]
+               });
+               tuijianTable.current.on("tableBuilt", () => {
+                    
+                    tuijianTable.current.replaceData(tuijian);
+                         
+                  });
+               }
+               if (rcj2Ref.current != null ) {
+                    rcj2Table.current = new Tabulator(rcj2Ref.current, {
+                         index: "key",
+                         height: 200,
+                       data: rcjhl2, //link data to table
+                       reactiveData: false, //enable data reactivity
+                       dataTreeStartExpanded:false,
+                       dataTree: false,
+                       selectableRows:1, //make rows selectable
+                       
+                       
+                       columns: [ //Define Table Columns
+                                    {title:"人材机编码", field:"人材机编码", width:80, headerSort:false, }, //never hide this column
+                                    {title:"名称", field:"名称", width:120,headerSort:false,  formatter:"textarea" },
+                                    {title:"单位", field:"单位", width:150, headerSort:false, formatter:"textarea"}, //hide this column first
+                                    {title:"单价", field:"单价", width:150 , headerSort:false, formatter:"money"},
+                                    {title:"合价", field:"合价", width:150 , headerSort:false, formatter:"money"},
+                                    {title:"含量", field:"含量", width:150 , headerSort:false, formatter:"textarea"},
+                                  
+                            ]
+                    });
+                    rcj2Table.current.on("tableBuilt", () => {
+                         
+                         rcj2Table.current.replaceData(rcjhl2);
+                              
+                       });
+                    }
+
+               if (rcjRef.current != null ) {
+                         rcjTable.current = new Tabulator(rcjRef.current, {
+                              index: "key",
+                              height: 200,
+                            data: rcjhl, //link data to table
+                            reactiveData: false, //enable data reactivity
+                            dataTreeStartExpanded:false,
+                            dataTree: false,
+                            selectableRows:1, //make rows selectable
+                            editTriggerEvent:"dblclick",
+                            
+                            columns: [ //Define Table Columns
+                                         {title:"ID", field:"ID", width:80, headerSort:false, },
+                                         {title:"人材机编码", field:"人材机编码", width:80, headerSort:false, }, //never hide this column
+                                         {title:"名称", field:"名称", width:120,headerSort:false,  formatter:"textarea", editor: "input", editable: editCheckRcj },
+                                         {title:"规格型号", field:"规格型号", width:80, headerSort:false, editor: "input", editable: editCheckRcj },
+                                         {title:"单位", field:"单位", width:80, headerSort:false, formatter:"textarea"}, //hide this column first
+                                         {title:"单价", field:"单价", width:80 , headerSort:false, formatter: sparklineFormatter, editor: "input", editable: editCheckRcj },
+                                         {title:"产地", field:"产地", width:80, headerSort:false, },
+                                         {title:"供应厂商", field:"供应厂商", width:80, headerSort:false, },
+                                         {title:"人材机类别", field:"人材机类别", width:80, headerSort:false, },
+                                         {title:"甲供标志", field:"甲供标志", width:80 , headerSort:false, formatter:"textarea"},
+                                         {title:"含量", field:"含量", width:80 , headerSort:false, formatter:"money", formatterParams:{precision:4}, editor: "input", editable: editCheckRcj },
+                                         {title:"合价", field:"合价", width:80 , headerSort:false, formatter:"money"},
+                                         {title:"暂估价标志", field:"暂估价标志", width:80 , headerSort:false, formatter:"textarea"},
+                                         {title:"主要材料标志", field:"主要材料标志", width:100 , headerSort:false, formatter:"textarea"},
+                                         {title:"主材标志", field:"主材标志", width:80 , headerSort:false, formatter:"textarea"},
+                                         {title:"设备标志", field:"设备标志", width:80 , headerSort:false, formatter:"textarea"},
+                                       
+                                 ]
+                         });
+                         rcjTable.current.on("tableBuilt", () => {
+                              
+                              rcjTable.current.replaceData(rcjhl);
+                                   
+                            });
+                         rcjTable.current.on("cellEdited", function(cell){
+                              let data =  copy(cell._cell.table.getData());
+                              for(let i = 0; i < data.length; i++) {
+                                   data[i]['合价'] = Number(data[i]['单价']) * Number(data[i]['含量']);
+                              }
+                              setRcjhl(data);
+                              if (rcjTable.current) {
+                                   rcjTable.current.replaceData(data);
+                              }
+                              let data2 = [['ID', '人材机编码', '名称', '规格型号', '单位', '单价', '产地', '供应厂商', '人材机类别', '甲供标志', '含量', '合价', '暂估价标志', '主要材料标志', '主材标志', '设备标志']]
+                              for (let i = 0; i < data.length; i++) {
+                                   data2.push([data[i]['ID'], data[i]['人材机编码'], data[i]['名称'], data[i]['规格型号'], data[i]['单位'], 
+                                   data[i]['单价'], data[i]['产地'], data[i]['供应厂商'], data[i]['人材机类别'], 
+                                   data[i]['甲供标志'], data[i]['含量'], data[i]['合价'], data[i]['暂估价标志'], data[i]['主要材料标志'], data[i]['主材标志'], data[i]['设备标志']]);
+                              }
+     
+                              let newData = updateDercj_djcs(selectedRowKeysTable.current[0], data2);
+                              myTable.current.updateData(newData.filter(x=>x['key'] == selectedRowKeysTableParent.current)).then(function() {
+                              let getRow = myTable.current.getRows(); //get array of currently selected row components.
+                              let component = null;
+                              for(let i = 0; i < getRow.length; i++) {
+                                     let entry = getRow[i]._row.modules.dataTree.children;
+                                     for(let j = 0; j < entry.length; j++) {
+                                           let child = entry[j];
+                                           if(child.data['key'] == selectedRowKeysTable.current[0]) {
+                                                //console.log(child);
+                                               component = child.component;
+                                                break;
+                                            }
+                         
+                                      }
+
+                              }
+               
+                                handleSelect(component);
+                              });
+                         });
+                         }
+          }, [value]
+        );
+
+
+
+      React.useEffect(
+          () => {
+               myTable.current.deselectRow();
+               //console.log(dingeclick);
+               if (selectedRowKeysTable.current.length > 0 ) {
+                    const [success, data, key] = changguidinge_djcs(JSON.parse(dingeclick), selectedRowKeysTable.current[0]);
+                    if (success) {
+                         myTable.current.updateData(data.filter(x=>x['key'] == selectedRowKeysTableParent.current)).then(function(){
+                              let getRow = myTable.current.getRows(); //get array of currently selected row components.
+                              let component = null;
+                              for(let i = 0; i < getRow.length; i++) {
+                                   let entry = getRow[i]._row.modules.dataTree.children;
+                                   for(let j = 0; j < entry.length; j++) {
+                                        let child = entry[j];
+                                        if(child.data['key'] == key) {
+                                             //console.log(child);
+                                             component = child.component;
+                                             break;
+                                        }
+                                        
+                                   }
+
+                              }
+                              
+                              component.select();
+                              handleSelect(component);
+
+                                   
+                               
+                          });
+                    }
+               }
+               
+          }, [dingeclick]//常规添加定额
+      );
+
+    React.useEffect(
+        () => {
+          console.log("rgde changed");
+          console.log(rgde);
+          rgdeRef.current = rgde;
+          jxdeRef.current = jxde;
+          cldeRef.current = clde;
+          if (isQdrcj.current) {
+             highlight.current = [];
+          } else {
+          let toHighlight = [];
+          for(let i = 0; i < rcjhl.length; i++) {
+              let entry = rcjhl[i];
+              let bianhao = entry['人材机编码'];
+              let rcjlb = entry['人材机类别'];
+              if (Number(rcjlb) == Number(1) && rgde) {
+                  for (let j = 0; j < rgde.length; j++) {
+                      if (rgde[j]["CLBH"] == bianhao) {
+                          let danjia = Number(entry['单价']);
+                          if (!number_equal(danjia , rgde[j]["YSJG"])) {
+                               console.log(`[${i},5]danjia bu yizhi`);
+                               toHighlight.push({row: i, col: 5});
+                          }
+                          let hanliang = Number(entry['含量']);
+                          if (!number_equal(hanliang , rgde[j]["gr"])) {
+                               console.log(`[${i}, 10]hanliang bu yizhi`);
+                               toHighlight.push({row: i, col: 10});
+                          }
+
+                      }              
+                  }
+
+              }   
+              if (Number(rcjlb) == Number(3) && jxde ) {
+                   for (let j = 0; j < jxde.length; j++) {
+                      if (jxde[j]["jxbh"] == bianhao) {
+                         let danjia = Number(entry['单价']);
+                         if (!number_equal(danjia , jxde[j]["tbdj"])) {
+                              console.log(`[${i},5]danjia bu yizhi`);
+                              toHighlight.push({row: i, col: 5, });
+                         }
+                         let hanliang = Number(entry['含量']);
+                         if (!number_equal(hanliang , jxde[j]["sl"])) {
+                              console.log(`[${i}, 10]hanliang bu yizhi`);
+                              toHighlight.push({row: i, col: 10, });
+                         }
+                      }
+                   }
+
+              }   
+              if (Number(rcjlb) == Number(2) && clde ) {
+                   for (let j = 0; j < clde.length; j++) {
+                      if (clde[j]["CLBH"] == bianhao) {
+                         let danjia = Number(entry['单价']);
+                         if (!number_equal(danjia , clde[j]["YSJG"])) {
+                              console.log(`[${i},5]danjia bu yizhi`);
+                              toHighlight.push({row: i, col: 5, });
+                         }
+                         let hanliang = Number(entry['含量']);
+                         if (!number_equal(hanliang ,clde[j]["SL"])) {
+                              console.log(`[${i}, 10]hanliang bu yizhi`);
+                              toHighlight.push({row: i, col: 10, });
+                         }
+                      }
+                   }
+
+              }   
+          }
+          console.log(toHighlight);
+          highlight.current = toHighlight;
+          }
+
+
+          let bzrcjhl = [] 
+          if (rgde)
+          for (let i = 0; i  < rgde.length; i++) {
+               bzrcjhl.push({'人材机编码': rgde[i]["CLBH"], '名称': rgde[i]["CLMC"], '单位': rgde[i]["JLDW"], '单价': rgde[i]["YSJG"], '合价': rgde[i]["gf"], '含量': rgde[i]["gr"]});
+          }
+          
+          if (clde)
+          for (let i = 0; i  < clde.length; i++) {
+               bzrcjhl.push({'人材机编码': clde[i]["CLBH"], '名称': clde[i]["CLMC"], '单位': clde[i]["JLDW"], '单价': clde[i]["YSJG"], '合价': clde[i]["HJ"], '含量': clde[i]["SL"]});
+          }
+          if (jxde)
+          for (let i = 0; i  < jxde.length; i++) {
+               bzrcjhl.push({'人材机编码': jxde[i]["jxbh"], '名称': jxde[i]["jxmc"], '单位': jxde[i]["DW"], '单价': jxde[i]["tbdj"], '合价': jxde[i]["hj"], '含量': jxde[i]["sl"]});
+          }
+          setRcjhl2(bzrcjhl);
+          if (rcj2Table.current) {
+               rcj2Table.current.replaceData(bzrcjhl);
+          }
+        }, [rgde, jxde, clde]
+      );
+
+      const handleChange = (event, newValue) => {
+        setValue(newValue);
+      };
+
+
+    return (
+
+               <Stack spacing={1}>
+                         <Stack direction='row' spacing={2}>
+                   <Button variant="outlined" size="small" onClick={() => {
+                      if (selectedRowKeysTable.current.length > 0) {
+                         const [success, data] = danxiangdinge_djcs(selectedRowKeysTable.current[0]);
+                         if(success) {
+                            myTable.current.updateData(data.filter(x=>x['key'] == selectedRowKeysTableParent.current)).then(function(){
+                              selectedRowKeysTable.current = [];
+                              selectedRowKeysTableParent.current = null;
+                                   setRcjhl([]);
+                                   if (rcjTable.current) {
+                                        rcjTable.current.replaceData([]);
+                                   }
+                                   setFuzhu([]);
+                                   isQdrcj.current = true;
+                                   highlight.current = [];
+                            });
+                            //console.log(data);
+                         }
+                      }
+                 
+                      
+                      }}
+                   >单项定额</Button>
+                      <Button variant="outlined" size="small" onClick={() => {
+                      if (selectedRowKeysTable.current.length > 0) {
+                          let newData = shanchu_djcs(selectedRowKeysTable.current[0]);
+                          myTable.current.updateData(newData.filter(x=>x['key'] == selectedRowKeysTableParent.current)).then(function(){
+                              if (newData.filter(x=>x['key'] == selectedRowKeysTable.current[0]).length == 0) {
+                                   selectedRowKeysTable.current = [];
+                                   selectedRowKeysTableParent.current = [];
+                                   setRcjhl([]);
+                                   if (rcjTable.current) {
+                                        rcjTable.current.replaceData([]);
+                                   }
+                                   setFuzhu([]);
+                                   isQdrcj.current = true;
+                                   highlight.current = [];
+                               }
+                          });
+                          
+                          
+                          
+                      }
+                      
+                 
+                      
+                      }}
+                   >删除</Button>
+                   <Button variant="outlined" size="small" onClick={() => {
+                      let newData = undo_djcs();
+                      myTable.current.updateData(newData).then(function(){
+                         
+                            selectedRowKeysTable.current = [];
+                            selectedRowKeysTableParent.current = null;
+                            setRcjhl([]);
+                            if (rcjTable.current) {
+                              rcjTable.current.replaceData([]);
+                            }
+                            setFuzhu([]);
+                            isQdrcj.current = true;
+                            highlight.current = [];
+                            
+                        
+                      });
+                     
+                      
+                      }}
+                   >撤销</Button>
+                   <Button variant="outlined" size="small" onClick={() => {
+                      let newData = redo_djcs();
+                      myTable.current.updateData(newData).then(function(){
+                         selectedRowKeysTable.current = [];
+                         selectedRowKeysTableParent.current = null;
+
+                            setRcjhl([]);
+                            if (rcjTable.current) {
+                              rcjTable.current.replaceData([]);
+                            }
+                            setFuzhu([]);
+                            isQdrcj.current = true;
+                            highlight.current = [];
+                      });
+                      
+                      
+                      
+                      }}
+                   >重做</Button>
+                   <Button variant="outlined" size="small" onClick={() => {
+                            console.log("save to cloud");
+                            loadingCallback();
+                      
+                      }}
+                   >保存</Button>
+
+                  
+                   </Stack>
+                 <div ref={myRef}> 
+                  </div>
+                   <Box >
+                   
+                   <TabContext value={value}>
+                       <Box sx={{ borderBottom: 1, borderColor: 'divider' }}>
+                         <TabList onChange={handleChange} aria-label="lab API tabs example"  sx={{minHeight: '24px'}}   >
+                           <Tab sx={{p: 0, minHeight: '24px'}} label="人材机含量" value="1" />
+                           <Tab sx={{p: 0, minHeight: '24px'}} label="标准定额人材机含量" value="2" />
+                           <Tab sx={{p: 0, minHeight: '24px'}} label="定额附注" value="3" />
+                           <Tab sx={{p: 0, minHeight: '24px'}} label="组价推荐" value="4" />
+                         </TabList>
+                       </Box>
+                       <TabPanel value="1">
+                       <div ref={rcjRef}></div>
+                       </TabPanel>
+                       <TabPanel value="2">
+                       <div ref={rcj2Ref}></div>
+
+                       </TabPanel>
+                       <TabPanel value="3">
+                       <Box sx={{maxHeight: `200px`}}>
+                       <ConfigProvider
+                          locale={zhCN}
+                          theme={{
+                            components: {
+                              Table: {
+                                 /* here is your component tokens */
+                                 cellPaddingBlock : 8
+                              },
+                            },
+                          }}
+                        >
+
+                          <Table 
+                             scroll={{ x: 'max-content' , y : 200}}
+                             pagination={false}
+                             rowSelection={rowSelection}
+                             columns={
+                              [
+                                   { title: '序号', dataIndex: '序号', width : 80},
+                                   {
+                                        title: '编号',
+                                        dataIndex: '编号',
+                                     
+                                   },
+                                   {
+                                        title: '说明',
+                                        dataIndex: '说明',
+                                     width: 550
+                                    
+                                   },
+                                  
+                                 ]
+                             }
+                           dataSource={fuzhu} />
+
+                        </ConfigProvider>
+                       </Box>
+                      
+
+                       </TabPanel>
+
+                       <TabPanel value="4">
+                          <div ref={tuijianRef}></div>
+
+                       </TabPanel>
+                     </TabContext>
+                  </Box>
+
+                  </Stack>
+
+
+
+    );
+}

+ 82 - 0
front/src/Fbrgycl.js

@@ -0,0 +1,82 @@
+import * as React from 'react';
+import Box from "@mui/material/Box";
+import {RichTreeView } from "@mui/x-tree-view/RichTreeView";
+import { Grid } from '@mui/material';
+import Tab from "@mui/material/Tab";
+import TabContext from "@mui/lab/TabContext";
+import TabList from "@mui/lab/TabList";
+import TabPanel from "@mui/lab/TabPanel";
+import Stack from "@mui/material/Stack";
+//registerPlugin(NestedRows);
+import Service from './Service';
+import EditableSelect from './EditableSelect';
+import EditableSelectGC from './EditableSelectGC';
+import Editable from './Editable';
+import Button from '@mui/material/Button';
+
+import {copy} from './utils';
+import {TabulatorFull as Tabulator} from "tabulator-tables"; //import Tabulator library
+import "tabulator-tables/dist/css/tabulator.min.css"; //import Tabulator stylesheet
+import './Tabulator.css';
+export default function Fbrgycl({data}) {
+    const myRef = React.useRef();
+    const myTable = React.useRef(null);
+
+
+
+    React.useEffect(() => {
+      myTable.current = new Tabulator(myRef.current, {
+           index: "key",
+           height: 600,
+         data: data, //link data to table
+         reactiveData: false, //enable data reactivity
+         dataTreeStartExpanded:true,
+         dataTree: true,
+         selectableRows:1, //make rows selectable
+         editTriggerEvent:"dblclick", //trigger edit on double click
+         dataTreeStartExpanded:function(row, level){
+             //console.log(row);
+             //console.log(level);
+             return true; //expand rows where the "driver" data field is true;
+         },
+         columns: [ //Define Table Columns 序号", "名称", "取费基数", "计算基础","费率", "金额", "类别
+                      {title:"序号", field:"序号", width:80, headerSort:false,}, //never hide this column
+                      {title:"ID", field:"ID", width:150, headerSort:false, formatter:"textarea"}, //hide this column first
+                      {title:"材料编号", field:"材料编号", width:100,   formatter:"textarea", },
+                      {title:"名称", field:"名称", width:100,   formatter:"textarea"},
+                      {title:"规格型号", field:"规格型号", width:100,   formatter:"textarea"},
+                      {title:"单位", field:"单位", width:100,   formatter:"textarea"},
+                      {title:"数量", field:"数量", width:100,   formatter:"textarea"},
+                      {title:"单价", field:"单价", width:100,   formatter:"money"},
+                      {title:"合价", field:"合价", width:100,   formatter:"money"},
+                      {title:"交货方式", field:"交货方式", width:100,   formatter:"textarea"},
+                      {title:"送达地点", field:"送达地点", width:100,   formatter:"textarea"},
+                      {title:"备注", field:"备注", width:100,   formatter:"textarea"},
+
+                    
+              ]
+       }); 
+       
+       myTable.current.on("cellDblClick", function(e, cell){
+           //e - the click event object
+           //cell - cell component
+           console.log(cell);
+       });
+  
+       //myTable.current.on("rowSelected", handleSelect);
+       
+  
+       
+  
+  
+      
+     
+    }, [data]);
+    return (
+      <div ref={myRef}> 
+      </div>
+
+
+
+    );
+}

+ 73 - 0
front/src/Jrg.js

@@ -0,0 +1,73 @@
+import * as React from 'react';
+import Box from "@mui/material/Box";
+import {RichTreeView } from "@mui/x-tree-view/RichTreeView";
+import { Grid } from '@mui/material';
+import Tab from "@mui/material/Tab";
+import TabContext from "@mui/lab/TabContext";
+import TabList from "@mui/lab/TabList";
+import TabPanel from "@mui/lab/TabPanel";
+import Stack from "@mui/material/Stack";
+//registerPlugin(NestedRows);
+import Service from './Service';
+import EditableSelect from './EditableSelect';
+import EditableSelectGC from './EditableSelectGC';
+import Editable from './Editable';
+import Button from '@mui/material/Button';
+
+import {copy} from './utils';
+import {TabulatorFull as Tabulator} from "tabulator-tables"; //import Tabulator library
+import "tabulator-tables/dist/css/tabulator.min.css"; //import Tabulator stylesheet
+import './Tabulator.css';
+export default function Jrg({data}) {
+    const myRef = React.useRef();
+    const myTable = React.useRef(null);
+
+
+
+    React.useEffect(() => {
+      myTable.current = new Tabulator(myRef.current, {
+           index: "key",
+           height: 600,
+         data: data, //link data to table
+         reactiveData: false, //enable data reactivity
+         dataTreeStartExpanded:true,
+         dataTree: true,
+         selectableRows:1, //make rows selectable
+         editTriggerEvent:"dblclick", //trigger edit on double click
+         dataTreeStartExpanded:function(row, level){
+             //console.log(row);
+             //console.log(level);
+             return true; //expand rows where the "driver" data field is true;
+         },
+         columns: [ //Define Table Columns 序号", "名称", "取费基数", "计算基础","费率", "金额", "类别
+                      {title:"序号", field:"序号", width:80, headerSort:false,}, //never hide this column
+                      {title:"名称", field:"名称", width:150, headerSort:false, formatter:"textarea"}, //hide this column first
+                      {title:"金额", field:"金额", width:100,   formatter:"money", },
+                      {title:"类别", field:"类别", width:100,   formatter:"textarea"},
+                    
+              ]
+       }); 
+       
+       myTable.current.on("cellDblClick", function(e, cell){
+           //e - the click event object
+           //cell - cell component
+           console.log(cell);
+       });
+  
+       //myTable.current.on("rowSelected", handleSelect);
+       
+  
+       
+  
+  
+      
+     
+    }, [data]);
+    return (
+      <div ref={myRef}> 
+      </div>
+
+
+
+    );
+}

+ 74 - 0
front/src/Qtxm.js

@@ -0,0 +1,74 @@
+import * as React from 'react';
+import Box from "@mui/material/Box";
+import {RichTreeView } from "@mui/x-tree-view/RichTreeView";
+import { Grid } from '@mui/material';
+import Tab from "@mui/material/Tab";
+import TabContext from "@mui/lab/TabContext";
+import TabList from "@mui/lab/TabList";
+import TabPanel from "@mui/lab/TabPanel";
+import Stack from "@mui/material/Stack";
+//registerPlugin(NestedRows);
+import Service from './Service';
+import EditableSelect from './EditableSelect';
+import EditableSelectGC from './EditableSelectGC';
+import Editable from './Editable';
+import Button from '@mui/material/Button';
+
+import {copy} from './utils';
+import {TabulatorFull as Tabulator} from "tabulator-tables"; //import Tabulator library
+import "tabulator-tables/dist/css/tabulator.min.css"; //import Tabulator stylesheet
+import './Tabulator.css';
+export default function Qtxm({data}) {
+    const myRef = React.useRef();
+    const myTable = React.useRef(null);
+
+
+
+    React.useEffect(() => {
+      myTable.current = new Tabulator(myRef.current, {
+           index: "key",
+           height: 600,
+         data: data, //link data to table
+         reactiveData: false, //enable data reactivity
+         dataTreeStartExpanded:true,
+         dataTree: true,
+         selectableRows:1, //make rows selectable
+         editTriggerEvent:"dblclick", //trigger edit on double click
+         dataTreeStartExpanded:function(row, level){
+             //console.log(row);
+             //console.log(level);
+             return true; //expand rows where the "driver" data field is true;
+         },
+         columns: [ //Define Table Columns 序号", "名称", "取费基数", "计算基础","费率", "金额", "类别
+                      {title:"序号", field:"序号", width:80, headerSort:false,}, //never hide this column
+                      {title:"名称", field:"名称", width:150, headerSort:false, formatter:"textarea"}, //hide this column first
+                      {title:"金额", field:"金额", width:100,   formatter:"money", },
+                      {title:"项目类别", field:"项目类别", width:100,   formatter:"textarea"},
+                      {title:"备注", field:"备注", width:100,   formatter:"textarea"},
+                    
+              ]
+       }); 
+       
+       myTable.current.on("cellDblClick", function(e, cell){
+           //e - the click event object
+           //cell - cell component
+           console.log(cell);
+       });
+  
+       //myTable.current.on("rowSelected", handleSelect);
+       
+  
+       
+  
+  
+      
+     
+    }, [data]);
+    return (
+      <div ref={myRef}> 
+      </div>
+
+
+
+    );
+}

+ 76 - 0
front/src/Zcbfwf.js

@@ -0,0 +1,76 @@
+import * as React from 'react';
+import Box from "@mui/material/Box";
+import {RichTreeView } from "@mui/x-tree-view/RichTreeView";
+import { Grid } from '@mui/material';
+import Tab from "@mui/material/Tab";
+import TabContext from "@mui/lab/TabContext";
+import TabList from "@mui/lab/TabList";
+import TabPanel from "@mui/lab/TabPanel";
+import Stack from "@mui/material/Stack";
+//registerPlugin(NestedRows);
+import Service from './Service';
+import EditableSelect from './EditableSelect';
+import EditableSelectGC from './EditableSelectGC';
+import Editable from './Editable';
+import Button from '@mui/material/Button';
+
+import {copy} from './utils';
+import {TabulatorFull as Tabulator} from "tabulator-tables"; //import Tabulator library
+import "tabulator-tables/dist/css/tabulator.min.css"; //import Tabulator stylesheet
+import './Tabulator.css';
+export default function Zcbfwf({data}) {
+    const myRef = React.useRef();
+    const myTable = React.useRef(null);
+
+
+
+    React.useEffect(() => {
+      myTable.current = new Tabulator(myRef.current, {
+           index: "key",
+           height: 600,
+         data: data, //link data to table
+         reactiveData: false, //enable data reactivity
+         dataTreeStartExpanded:true,
+         dataTree: true,
+         selectableRows:1, //make rows selectable
+         editTriggerEvent:"dblclick", //trigger edit on double click
+         dataTreeStartExpanded:function(row, level){
+             //console.log(row);
+             //console.log(level);
+             return true; //expand rows where the "driver" data field is true;
+         },
+         columns: [ //Define Table Columns 序号", "名称", "取费基数", "计算基础","费率", "金额", "类别
+                      {title:"序号", field:"序号", width:80, headerSort:false,}, //never hide this column
+                      {title:"名称", field:"名称", width:150, headerSort:false, formatter:"textarea"}, //hide this column first
+                      {title:"项目价值", field:"项目价值", width:100,   formatter:"money", },
+                      {title:"服务内容", field:"服务内容", width:100,   formatter:"textarea"},
+                      {title:"计算基础", field:"计算基础", width:100,   formatter:"textarea"},
+                      {title:"费率", field:"费率", width:100,   formatter:"money"},
+                      {title:"金额", field:"金额", width:100,   formatter:"money"},
+                    
+              ]
+       }); 
+       
+       myTable.current.on("cellDblClick", function(e, cell){
+           //e - the click event object
+           //cell - cell component
+           console.log(cell);
+       });
+  
+       //myTable.current.on("rowSelected", handleSelect);
+       
+  
+       
+  
+  
+      
+     
+    }, [data]);
+    return (
+      <div ref={myRef}> 
+      </div>
+
+
+
+    );
+}

+ 0 - 7
front/src/Zjcs2.js

@@ -1,10 +1,5 @@
 import * as React from 'react';
 import Box from "@mui/material/Box";
-import 'handsontable/dist/handsontable.full.min.css';
-//import 'handsontable/styles/ht-theme-main.min.css';
-import { HandsonTable } from 'handsontable/base';
-import {HotTable} from "@handsontable/react";
-//import { registerAllModules } from 'handsontable/registry';
 import {RichTreeView } from "@mui/x-tree-view/RichTreeView";
 import { Grid } from '@mui/material';
 import Tab from "@mui/material/Tab";
@@ -20,8 +15,6 @@ import TabContext from "@mui/lab/TabContext";
 import TabList from "@mui/lab/TabList";
 import TabPanel from "@mui/lab/TabPanel";
 import Stack from "@mui/material/Stack";
-//import { registerPlugin, NestedRows } from 'handsontable/plugins';
-//registerPlugin(NestedRows);
 import Service from './Service';
 import {TabulatorFull as Tabulator} from "tabulator-tables"; //import Tabulator library
 import "tabulator-tables/dist/css/tabulator.min.css"; //import Tabulator stylesheet

+ 74 - 0
front/src/Zlje.js

@@ -0,0 +1,74 @@
+import * as React from 'react';
+import Box from "@mui/material/Box";
+import {RichTreeView } from "@mui/x-tree-view/RichTreeView";
+import { Grid } from '@mui/material';
+import Tab from "@mui/material/Tab";
+import TabContext from "@mui/lab/TabContext";
+import TabList from "@mui/lab/TabList";
+import TabPanel from "@mui/lab/TabPanel";
+import Stack from "@mui/material/Stack";
+//registerPlugin(NestedRows);
+import Service from './Service';
+import EditableSelect from './EditableSelect';
+import EditableSelectGC from './EditableSelectGC';
+import Editable from './Editable';
+import Button from '@mui/material/Button';
+
+import {copy} from './utils';
+import {TabulatorFull as Tabulator} from "tabulator-tables"; //import Tabulator library
+import "tabulator-tables/dist/css/tabulator.min.css"; //import Tabulator stylesheet
+import './Tabulator.css';
+export default function Zlje({data}) {
+    const myRef = React.useRef();
+    const myTable = React.useRef(null);
+
+
+
+    React.useEffect(() => {
+      myTable.current = new Tabulator(myRef.current, {
+           index: "key",
+           height: 600,
+         data: data, //link data to table
+         reactiveData: false, //enable data reactivity
+         dataTreeStartExpanded:true,
+         dataTree: true,
+         selectableRows:1, //make rows selectable
+         editTriggerEvent:"dblclick", //trigger edit on double click
+         dataTreeStartExpanded:function(row, level){
+             //console.log(row);
+             //console.log(level);
+             return true; //expand rows where the "driver" data field is true;
+         },
+         columns: [ //Define Table Columns 序号", "名称", "取费基数", "计算基础","费率", "金额", "类别
+                      {title:"序号", field:"序号", width:80, headerSort:false,}, //never hide this column
+                      {title:"名称", field:"名称", width:150, headerSort:false, formatter:"textarea"}, //hide this column first
+                      {title:"单位", field:"单位", width:100, },
+                      {title:"暂定金额", field:"暂定金额", width:100,   formatter:"money"},
+                      {title:"备注", field:"备注", width:100,   formatter:"textarea"},
+                    
+              ]
+       }); 
+       
+       myTable.current.on("cellDblClick", function(e, cell){
+           //e - the click event object
+           //cell - cell component
+           console.log(cell);
+       });
+  
+       //myTable.current.on("rowSelected", handleSelect);
+       
+  
+       
+  
+  
+      
+     
+    }, [data]);
+    return (
+      <div ref={myRef}> 
+      </div>
+
+
+
+    );
+}

+ 74 - 0
front/src/Zygczgj.js

@@ -0,0 +1,74 @@
+import * as React from 'react';
+import Box from "@mui/material/Box";
+import {RichTreeView } from "@mui/x-tree-view/RichTreeView";
+import { Grid } from '@mui/material';
+import Tab from "@mui/material/Tab";
+import TabContext from "@mui/lab/TabContext";
+import TabList from "@mui/lab/TabList";
+import TabPanel from "@mui/lab/TabPanel";
+import Stack from "@mui/material/Stack";
+//registerPlugin(NestedRows);
+import Service from './Service';
+import EditableSelect from './EditableSelect';
+import EditableSelectGC from './EditableSelectGC';
+import Editable from './Editable';
+import Button from '@mui/material/Button';
+
+import {copy} from './utils';
+import {TabulatorFull as Tabulator} from "tabulator-tables"; //import Tabulator library
+import "tabulator-tables/dist/css/tabulator.min.css"; //import Tabulator stylesheet
+import './Tabulator.css';
+export default function Zygczgj({data}) {
+    const myRef = React.useRef();
+    const myTable = React.useRef(null);
+
+
+
+    React.useEffect(() => {
+      myTable.current = new Tabulator(myRef.current, {
+           index: "key",
+           height: 600,
+         data: data, //link data to table
+         reactiveData: false, //enable data reactivity
+         dataTreeStartExpanded:true,
+         dataTree: true,
+         selectableRows:1, //make rows selectable
+         editTriggerEvent:"dblclick", //trigger edit on double click
+         dataTreeStartExpanded:function(row, level){
+             //console.log(row);
+             //console.log(level);
+             return true; //expand rows where the "driver" data field is true;
+         },
+         columns: [ //Define Table Columns 序号", "名称", "取费基数", "计算基础","费率", "金额", "类别
+                      {title:"序号", field:"序号", width:80, headerSort:false,}, //never hide this column
+                      {title:"名称", field:"名称", width:150, headerSort:false, formatter:"textarea"}, //hide this column first
+                      {title:"工程内容", field:"工程内容", width:100,   formatter:"textarea", },
+                      {title:"金额", field:"金额", width:100,   formatter:"money"},
+                      {title:"备注", field:"备注", width:100,   formatter:"textarea"},
+                    
+              ]
+       }); 
+       
+       myTable.current.on("cellDblClick", function(e, cell){
+           //e - the click event object
+           //cell - cell component
+           console.log(cell);
+       });
+  
+       //myTable.current.on("rowSelected", handleSelect);
+       
+  
+       
+  
+  
+      
+     
+    }, [data]);
+    return (
+      <div ref={myRef}> 
+      </div>
+
+
+
+    );
+}

+ 8 - 1
main.py

@@ -256,7 +256,14 @@ async def read_qtxm(info: InfoWithID):
 
 @app.post("/qitaxiangmu2/")
 async def read_qtxm2(info: InfoWithID):
-    return await db.getQtxm(client, info.name, info.id)
+    raw = await db.getQtxm(client, info.name, info.id)
+    raw2 = []
+    for entry in raw:
+        if "__children" in entry:
+            entry["_children"] = entry["__children"]
+            del entry["__children"]
+        raw2.append(entry)
+    return raw2
 
 @app.post("/zygczgj/")
 async def zygczgj(info: InfoWithID):

+ 20 - 20
subdir/service.py

@@ -215,13 +215,13 @@ def getDjcsQingdanrcj(root, bh, bt, bm):
 
 
 def getQingdanTuijian(bh, bt, bm):
-    result = [["ID", "定额编号", "工程量名称", "工作内容" ]]
+    result = []
     try:
         all = pd.read_csv("QingDanAllInOne.csv")
         bm_ = int(bm) // 1000
         hit = all[all["qdbh"] == str(bm_)]
         for i in range(len(hit)):
-            result.append([hit.iloc[i]["index"].item(), hit.iloc[i]["debh"], hit.iloc[i]["gclmc"], hit.iloc[i]["work"]])
+            result.append({'ID': hit.iloc[i]["index"].item(), '定额编号': hit.iloc[i]["debh"], '工程量名称': hit.iloc[i]["gclmc"], '工作内容': hit.iloc[i]["work"]})
     #result.append(["ming cheng", "jin e", "zan gu jia", "anquan wenming fei", "guifei"])
     finally:
 
@@ -549,7 +549,7 @@ def getZjcs(root, id):
     return result
 
 def getZcbfwf(root, id):
-    result = [["序号", "名称", "项目价值", "服务内容", "计算基础", "费率", "金额"]]
+    result = []
     #result.append(["ming cheng", "jin e", "zan gu jia", "anquan wenming fei", "guifei"])
     item = None
     for child in root:
@@ -568,9 +568,9 @@ def getZcbfwf(root, id):
             break
     for child in Fywj:
             result.append(
-                [child.attrib["Xh"], 
-            child.attrib["Mc"],  child.attrib["Xmjz"], child.attrib["Fwnr"], child.attrib["Jsjc"],
-            child.attrib["Fl"], child.attrib["Je"]]
+                {'序号': child.attrib["Xh"], 
+            "名称" : child.attrib["Mc"],  "项目价值" : child.attrib["Xmjz"], "服务内容" :child.attrib["Fwnr"], "计算基础" :child.attrib["Jsjc"],
+            "费率" :child.attrib["Fl"], "金额" :child.attrib["Je"]}
             )
     return result
 
@@ -605,7 +605,7 @@ def getRcjhz(root, id):
     return result  
 
 def getFbrgycl(root, id):
-    result = [["序号", "ID", "材料编号", "名称", "规格型号", "单位", "数量", "单价", "合价", "交货方式", "送达地点", "备注"]]
+    result = []
 
 
     for child in root:
@@ -624,15 +624,15 @@ def getFbrgycl(root, id):
             break
     for child in Fywj:
             result.append(
-                [child.attrib["Xh"], 
-            child.attrib["RcjId"],  child.attrib["Clbh"], child.attrib["Mc"], child.attrib["Ggxh"],
-            child.attrib["Dw"], child.attrib["Sl"], child.attrib["Dj"], child.attrib["Hj"], child.attrib["Jhfs"],
-            child.attrib["Sddd"], child.attrib["Bz"]]
+                {'序号': child.attrib["Xh"], 
+            'ID': child.attrib["RcjId"],  '材料编号': child.attrib["Clbh"], '名称': child.attrib["Mc"], '规格型号': child.attrib["Ggxh"],
+            '单位': child.attrib["Dw"], '数量': child.attrib["Sl"], '单价': child.attrib["Dj"], '合价': child.attrib["Hj"], '交货方式': child.attrib["Jhfs"],
+            '送达地点': child.attrib["Sddd"], '备注': child.attrib["Bz"]}
             )
     return result   
 
 def getJrg(root, id):
-    result = [["序号", "名称", "金额", "类别"]]
+    result = []
     #result.append(["ming cheng", "jin e", "zan gu jia", "anquan wenming fei", "guifei"])
     item = None
     for child in root:
@@ -651,13 +651,13 @@ def getJrg(root, id):
             break
     for child in Fywj:
             result.append(
-                [child.attrib["Xh"], 
-            child.attrib["Mc"],  child.attrib["Je"], child.attrib["Lb"]]
+                {'序号': child.attrib["Xh"], 
+                  '名称': child.attrib["Mc"],  '金额': child.attrib["Je"], '类别': child.attrib["Lb"]}
             )
     return result 
 
 def getZlje(root, id):
-    result = [["序号", "名称", "单位", "暂定金额", "备注"]]
+    result = []
     #result.append(["ming cheng", "jin e", "zan gu jia", "anquan wenming fei", "guifei"])
     item = None
     for child in root:
@@ -676,14 +676,14 @@ def getZlje(root, id):
             break
     for child in Fywj:
             result.append(
-                [child.attrib["Xh"], 
-            child.attrib["Mc"],   child.attrib["Dw"], child.attrib["Zdje"], child.attrib["Bz"]]
+                {'序号': child.attrib["Xh"], 
+            '名称': child.attrib["Mc"],   '单位': child.attrib["Dw"], '暂定金额': child.attrib["Zdje"], '备注': child.attrib["Bz"]}
             )
     return result  
 
 
 def getZygczgj(root, id):
-    result = [["序号", "名称", "工程内容", "金额", "备注"]]
+    result = []
     #result.append(["ming cheng", "jin e", "zan gu jia", "anquan wenming fei", "guifei"])
     item = None
     for child in root:
@@ -702,8 +702,8 @@ def getZygczgj(root, id):
             break
     for child in Fywj:
             result.append(
-                [child.attrib["Xh"], 
-            child.attrib["Mc"],   child.attrib["Gcnr"], child.attrib["Je"], child.attrib["Bz"]]
+                {'序号': child.attrib["Xh"], 
+            '名称': child.attrib["Mc"],  '工程内容': child.attrib["Gcnr"], '金额': child.attrib["Je"], '备注': child.attrib["Bz"]}
             )
     return result  
 

Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác