|  |  | 
 |  |  | import React, { useState, useRef, useEffect, useMemo } from "react"; | 
 |  |  | import { Box, Card, CardContent, LinearProgress, TextField, Button, Typography } from "@mui/material"; | 
 |  |  | import * as Icons from '@mui/icons-material'; | 
 |  |  | import { List, useTranslate, useListContext, Title, } from "react-admin"; | 
 |  |  | import { | 
 |  |  |   Box, | 
 |  |  |   Card, | 
 |  |  |   CardContent, | 
 |  |  |   LinearProgress, | 
 |  |  |   TextField, | 
 |  |  |   Button, | 
 |  |  |   Typography, | 
 |  |  | } from "@mui/material"; | 
 |  |  | import * as Icons from "@mui/icons-material"; | 
 |  |  | import { | 
 |  |  |   List, | 
 |  |  |   useTranslate, | 
 |  |  |   useListContext, | 
 |  |  |   Title, | 
 |  |  |   useGetList, | 
 |  |  |   useNotify, | 
 |  |  | } from "react-admin"; | 
 |  |  | import WhMatListAside from "./WhMatListAside"; | 
 |  |  | import { RichTreeView } from "@mui/x-tree-view/RichTreeView"; | 
 |  |  | import { TreeItem2 } from "@mui/x-tree-view/TreeItem2"; | 
 |  |  | import request from '@/utils/request'; | 
 |  |  | import { Add, Edit, Delete, Padding, Save } from '@mui/icons-material'; | 
 |  |  | import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown'; | 
 |  |  | import KeyboardArrowRightIcon from '@mui/icons-material/KeyboardArrowRight'; | 
 |  |  | import RefreshIcon from '@mui/icons-material/Refresh'; | 
 |  |  | import { useTreeItem2Utils } from '@mui/x-tree-view/hooks'; | 
 |  |  | import request from "@/utils/request"; | 
 |  |  | import { Add, Edit, Delete, Padding, Save } from "@mui/icons-material"; | 
 |  |  | import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown"; | 
 |  |  | import KeyboardArrowRightIcon from "@mui/icons-material/KeyboardArrowRight"; | 
 |  |  | import RefreshIcon from "@mui/icons-material/Refresh"; | 
 |  |  | import { useTreeItem2Utils } from "@mui/x-tree-view/hooks"; | 
 |  |  | import WhMatCreate from "./whMatCreate"; | 
 |  |  |  | 
 |  |  | // const RESOURCE = 'dept'; | 
 |  |  | const TITLE = 'menu.whMat'; | 
 |  |  | const TITLE = "menu.whMat"; | 
 |  |  |  | 
 |  |  | const WhMatListContent = () => { | 
 |  |  |     const translate = useTranslate(); | 
 |  |  |     const [searchVal, setSearchVal] = useState(''); | 
 |  |  |     const [createDialog, setCreateDialog] = React.useState(false); | 
 |  |  |     const [editRecord, setEditRecord] = React.useState(null); | 
 |  |  |     const treeData = [ | 
 |  |  |   const translate = useTranslate(); | 
 |  |  |   const [searchVal, setSearchVal] = useState(""); | 
 |  |  |   const [createDialog, setCreateDialog] = React.useState(false); | 
 |  |  |   const [editRecord, setEditRecord] = React.useState(null); | 
 |  |  |   const treeData = [ | 
 |  |  |     { | 
 |  |  |       id: "19", | 
 |  |  |       label: "半成品", | 
 |  |  |       secondaryLabel: "RM001", | 
 |  |  |       editable: true, | 
 |  |  |       children: [ | 
 |  |  |         { | 
 |  |  |             id: '19', | 
 |  |  |             label: '半成品', | 
 |  |  |             secondaryLabel: 'RM001', | 
 |  |  |             editable: true, | 
 |  |  |             children: [ | 
 |  |  |                 { | 
 |  |  |                     id: 'grid-community', primaryText: '半成品', | 
 |  |  |                     secondaryText: 'RM001', label: '@mui/x-data-grid', editable: true, children: [ | 
 |  |  |                         { | 
 |  |  |                             id: 'grid-community22', primaryText: '半成品', | 
 |  |  |                             secondaryText: 'RM001', label: '@mui/x-data-grid', editable: true | 
 |  |  |                         },] | 
 |  |  |                 }, | 
 |  |  |                 { | 
 |  |  |                     id: 'grid-pro', primaryText: '半成品', | 
 |  |  |                     secondaryText: 'RM001', label: '@mui/x-data-grid-pro', editable: true | 
 |  |  |                 }, | 
 |  |  |                 { | 
 |  |  |                     id: 'grid-premium', primaryText: '半成品', | 
 |  |  |                     secondaryText: 'RM001', label: '@mui/x-data-grid-premium', editable: true | 
 |  |  |                 }, | 
 |  |  |             ], | 
 |  |  |           id: "grid-community", | 
 |  |  |           primaryText: "半成品", | 
 |  |  |           secondaryText: "RM001", | 
 |  |  |           label: "@mui/x-data-grid", | 
 |  |  |           editable: true, | 
 |  |  |           children: [ | 
 |  |  |             { | 
 |  |  |               id: "grid-community22", | 
 |  |  |               primaryText: "半成品", | 
 |  |  |               secondaryText: "RM001", | 
 |  |  |               label: "@mui/x-data-grid", | 
 |  |  |               editable: true, | 
 |  |  |             }, | 
 |  |  |           ], | 
 |  |  |         }, | 
 |  |  |         { | 
 |  |  |             id: '18', | 
 |  |  |             label: '原材料', | 
 |  |  |             primaryText: '半成品', | 
 |  |  |             secondaryText: 'RM001', | 
 |  |  |           id: "grid-pro", | 
 |  |  |           primaryText: "半成品", | 
 |  |  |           secondaryText: "RM001", | 
 |  |  |           label: "@mui/x-data-grid-pro", | 
 |  |  |           editable: true, | 
 |  |  |         }, | 
 |  |  |         { | 
 |  |  |             id: 'charts', | 
 |  |  |             label: 'Charts', | 
 |  |  |             primaryText: '半成品', | 
 |  |  |             secondaryText: 'RM001', | 
 |  |  |             children: [{ | 
 |  |  |                 id: 'charts-community', primaryText: '半成品', | 
 |  |  |                 secondaryText: 'RM001', label: '@mui/x-charts' | 
 |  |  |             }], | 
 |  |  |           id: "grid-premium", | 
 |  |  |           primaryText: "半成品", | 
 |  |  |           secondaryText: "RM001", | 
 |  |  |           label: "@mui/x-data-grid-premium", | 
 |  |  |           editable: true, | 
 |  |  |         }, | 
 |  |  |       ], | 
 |  |  |     }, | 
 |  |  |     { | 
 |  |  |       id: "18", | 
 |  |  |       label: "原材料", | 
 |  |  |       primaryText: "半成品", | 
 |  |  |       secondaryText: "RM001", | 
 |  |  |     }, | 
 |  |  |     { | 
 |  |  |       id: "charts", | 
 |  |  |       label: "Charts", | 
 |  |  |       primaryText: "半成品", | 
 |  |  |       secondaryText: "RM001", | 
 |  |  |       children: [ | 
 |  |  |         { | 
 |  |  |             id: 'tree-view', | 
 |  |  |             label: 'Tree View', | 
 |  |  |             primaryText: '半成品', | 
 |  |  |             secondaryLabel: 'RM001', | 
 |  |  |             children: [{ | 
 |  |  |                 id: 'tree-view-community', primaryText: '半成品', | 
 |  |  |                 secondaryText: 'RM001', label: '@mui/x-tree-view' | 
 |  |  |             }], | 
 |  |  |           id: "charts-community", | 
 |  |  |           primaryText: "半成品", | 
 |  |  |           secondaryText: "RM001", | 
 |  |  |           label: "@mui/x-charts", | 
 |  |  |         }, | 
 |  |  |       ], | 
 |  |  |     }, | 
 |  |  |     { | 
 |  |  |       id: "tree-view", | 
 |  |  |       label: "Tree View", | 
 |  |  |       primaryText: "半成品", | 
 |  |  |       secondaryLabel: "RM001", | 
 |  |  |       children: [ | 
 |  |  |         { | 
 |  |  |             id: 'tree-view2', | 
 |  |  |             label: 'Tree View3', | 
 |  |  |             primaryText: '半成品', | 
 |  |  |             secondaryText: 'RM001', | 
 |  |  |             children: [{ | 
 |  |  |                 id: 'tree-view-community1', primaryText: '半成品', | 
 |  |  |                 secondaryText: 'RM001', label: '@mui/x-tree-view' | 
 |  |  |             }], | 
 |  |  |           id: "tree-view-community", | 
 |  |  |           primaryText: "半成品", | 
 |  |  |           secondaryText: "RM001", | 
 |  |  |           label: "@mui/x-tree-view", | 
 |  |  |         }, | 
 |  |  |     ]; | 
 |  |  |     const handleNodeSelect = (event, nodeId) => { | 
 |  |  |         console.log('Selected Node ID:', nodeId); | 
 |  |  |         // 在这里可以根据 nodeId 更新主内容区域 | 
 |  |  |     }; | 
 |  |  |     const handleSearch = () => { | 
 |  |  |         console.log('Search Input:', selectedOption); | 
 |  |  |     }; | 
 |  |  |       ], | 
 |  |  |     }, | 
 |  |  |     { | 
 |  |  |       id: "tree-view2", | 
 |  |  |       label: "Tree View3", | 
 |  |  |       primaryText: "半成品", | 
 |  |  |       secondaryText: "RM001", | 
 |  |  |       children: [ | 
 |  |  |         { | 
 |  |  |           id: "tree-view-community1", | 
 |  |  |           primaryText: "半成品", | 
 |  |  |           secondaryText: "RM001", | 
 |  |  |           label: "@mui/x-tree-view", | 
 |  |  |         }, | 
 |  |  |       ], | 
 |  |  |     }, | 
 |  |  |   ]; | 
 |  |  |  | 
 |  |  |   const notify = useNotify(); | 
 |  |  |   const handleNodeSelect = (event, nodeId) => { | 
 |  |  |     console.log("Selected Node ID:", nodeId); | 
 |  |  |     // 在这里可以根据 nodeId 更新主内容区域 | 
 |  |  |   }; | 
 |  |  |   const handleSearch = () => { | 
 |  |  |     console.log("Search Input:", selectedOption); | 
 |  |  |   }; | 
 |  |  |  | 
 |  |  |     const CustomCheckbox = React.forwardRef(function CustomCheckbox(props, ref) { | 
 |  |  |         return <input type="checkbox" ref={ref} {...props} />; | 
 |  |  |     }); | 
 |  |  |     function CustomLabel({ children, className, secondaryLabel }) { | 
 |  |  |         return ( | 
 |  |  |             <Box display={"flex"} alignItems={"end"}> | 
 |  |  |                 <Typography fontWeight={500}>{children}</Typography> | 
 |  |  |                 <Box width={10}></Box> | 
 |  |  |                 {secondaryLabel && ( | 
 |  |  |                     <Typography variant="caption" color="secondary"> | 
 |  |  |                         {secondaryLabel} | 
 |  |  |                     </Typography> | 
 |  |  |                 )} | 
 |  |  |             </Box> | 
 |  |  |         ); | 
 |  |  |   const handleInput = (value) => { | 
 |  |  |     setSearchVal(value); | 
 |  |  |   }; | 
 |  |  |  | 
 |  |  |   const CustomCheckbox = React.forwardRef(function CustomCheckbox(props, ref) { | 
 |  |  |     return <input type="checkbox" ref={ref} {...props} />; | 
 |  |  |   }); | 
 |  |  |  | 
 |  |  |   const getMatnrList = async () => { | 
 |  |  |     const { | 
 |  |  |       data: { code, data, msg }, | 
 |  |  |     } = await request.post("/matnr/list", {}); | 
 |  |  |     if (code === 200) { | 
 |  |  |       console.log(data); | 
 |  |  |     } else { | 
 |  |  |       notify(msg); | 
 |  |  |     } | 
 |  |  |     const CustomTreeItem = React.forwardRef(function CustomTreeItem(props, ref) { | 
 |  |  |         const { publicAPI } = useTreeItem2Utils({ | 
 |  |  |             itemId: props.itemId, | 
 |  |  |             children: props.children, | 
 |  |  |         }); | 
 |  |  |   }; | 
 |  |  |  | 
 |  |  |         const item = publicAPI.getItem(props.itemId); | 
 |  |  |   React.useEffect(() => { | 
 |  |  |     getMatnrList(); | 
 |  |  |   }, []); | 
 |  |  |  | 
 |  |  |         return ( | 
 |  |  |             <TreeItem2 | 
 |  |  |                 {...props} | 
 |  |  |                 ref={ref} | 
 |  |  |                 slots={{ | 
 |  |  |                     label: CustomLabel, | 
 |  |  |                 }} | 
 |  |  |                 slotProps={{ | 
 |  |  |                     label: { secondaryLabel: item?.secondaryLabel || '' }, | 
 |  |  |                 }} | 
 |  |  |  | 
 |  |  |             /> | 
 |  |  |         ); | 
 |  |  |   function CustomLabel({ children, className, secondaryLabel }) { | 
 |  |  |     return ( | 
 |  |  |       <Box display={"flex"} alignItems={"end"}> | 
 |  |  |         <Typography fontWeight={500}>{children}</Typography> | 
 |  |  |         <Box width={10}></Box> | 
 |  |  |         {secondaryLabel && ( | 
 |  |  |           <Typography variant="caption" color="secondary"> | 
 |  |  |             {secondaryLabel} | 
 |  |  |           </Typography> | 
 |  |  |         )} | 
 |  |  |       </Box> | 
 |  |  |     ); | 
 |  |  |   } | 
 |  |  |   const CustomTreeItem = React.forwardRef(function CustomTreeItem(props, ref) { | 
 |  |  |     const { publicAPI } = useTreeItem2Utils({ | 
 |  |  |       itemId: props.itemId, | 
 |  |  |       children: props.children, | 
 |  |  |     }); | 
 |  |  |  | 
 |  |  |     const isLoading = false; | 
 |  |  |  | 
 |  |  |     React.useEffect(() => { | 
 |  |  |         request.post('/matnrGroup/tree', {}) | 
 |  |  |             .then(res => { | 
 |  |  |                 if (res?.data?.code === 200) { | 
 |  |  |                     let data = res.data.data; | 
 |  |  |                     console.log(data); | 
 |  |  |  | 
 |  |  |                 } else { | 
 |  |  |                     notify(res.data.msg); | 
 |  |  |                 } | 
 |  |  |             }) | 
 |  |  |             .catch(error => { | 
 |  |  |                 notify('Error fetching tree data'); | 
 |  |  |             }); | 
 |  |  |     }, [searchVal]) | 
 |  |  |  | 
 |  |  |     const handleAdd = () => { | 
 |  |  |         setCreateDialog(true); | 
 |  |  |     }; | 
 |  |  |     const item = publicAPI.getItem(props.itemId); | 
 |  |  |  | 
 |  |  |     return ( | 
 |  |  |         <> | 
 |  |  |             <Box sx={{ mt: 1, mr: 3, display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}> | 
 |  |  |                 <WhMatCreate | 
 |  |  |                     editRecord={editRecord} | 
 |  |  |                     open={createDialog} | 
 |  |  |                     setOpen={setCreateDialog} | 
 |  |  |                 /> | 
 |  |  |                 <Box | 
 |  |  |                     width={300} | 
 |  |  |                     mb={1} | 
 |  |  |                 > | 
 |  |  |                     <TextField | 
 |  |  |                         label={translate('ra.action.search')} | 
 |  |  |                         value={searchVal} | 
 |  |  |                         onChange={(e) => handleInput(e.target.value)} | 
 |  |  |                     /> | 
 |  |  |                 </Box> | 
 |  |  |                 <Box> | 
 |  |  |                     <Button | 
 |  |  |                         variant="outlined" | 
 |  |  |                         color="primary" | 
 |  |  |                         startIcon={<Add />} | 
 |  |  |                         onClick={handleAdd} | 
 |  |  |                     > | 
 |  |  |                         {translate('ra.action.add')} | 
 |  |  |                     </Button> | 
 |  |  |                     <Button | 
 |  |  |                         variant="outlined" | 
 |  |  |                         color="error" | 
 |  |  |                         startIcon={<Delete />} | 
 |  |  |                         sx={{ ml: 1 }} | 
 |  |  |                     > | 
 |  |  |                         {translate('ra.action.delete')} | 
 |  |  |                     </Button> | 
 |  |  |                     <Button | 
 |  |  |                         variant="outlined" | 
 |  |  |                         color="primary" | 
 |  |  |                         sx={{ ml: 1 }} | 
 |  |  |                         startIcon={<Save />} | 
 |  |  |                     > | 
 |  |  |                         {translate('ra.action.save')} | 
 |  |  |                     </Button> | 
 |  |  |                 </Box> | 
 |  |  |             </Box> | 
 |  |  |       <TreeItem2 | 
 |  |  |         {...props} | 
 |  |  |         ref={ref} | 
 |  |  |         slots={{ | 
 |  |  |           label: CustomLabel, | 
 |  |  |         }} | 
 |  |  |         slotProps={{ | 
 |  |  |           label: { secondaryLabel: item?.secondaryLabel || "" }, | 
 |  |  |         }} | 
 |  |  |       /> | 
 |  |  |     ); | 
 |  |  |   }); | 
 |  |  |  | 
 |  |  |             <Card> | 
 |  |  |                 <CardContent> | 
 |  |  |                     <RichTreeView | 
 |  |  |                         defaultExpandedItems={['grid', 'pickers']} | 
 |  |  |                         checkboxSelection | 
 |  |  |                         items={treeData} | 
 |  |  |                         slots={{ item: CustomTreeItem }} | 
 |  |  |                         onItemClick={handleNodeSelect} // 监听节点点击事件 | 
 |  |  |                     /> | 
 |  |  |                 </CardContent> | 
 |  |  |             </Card> | 
 |  |  |         </> | 
 |  |  |     ) | 
 |  |  | } | 
 |  |  |   const isLoading = false; | 
 |  |  |  | 
 |  |  |   React.useEffect(() => { | 
 |  |  |     request | 
 |  |  |       .post("/matnrGroup/tree", {}) | 
 |  |  |       .then((res) => { | 
 |  |  |         if (res?.data?.code === 200) { | 
 |  |  |           let data = res.data.data; | 
 |  |  |           console.log(data); | 
 |  |  |         } else { | 
 |  |  |           notify(res.data.msg); | 
 |  |  |         } | 
 |  |  |       }) | 
 |  |  |       .catch((error) => { | 
 |  |  |         notify("Error fetching tree data"); | 
 |  |  |       }); | 
 |  |  |   }, [searchVal]); | 
 |  |  |  | 
 |  |  |   const handleAdd = () => { | 
 |  |  |     setCreateDialog(true); | 
 |  |  |   }; | 
 |  |  |  | 
 |  |  |   return ( | 
 |  |  |     <> | 
 |  |  |       <Box | 
 |  |  |         sx={{ | 
 |  |  |           mt: 1, | 
 |  |  |           mr: 3, | 
 |  |  |           display: "flex", | 
 |  |  |           alignItems: "center", | 
 |  |  |           justifyContent: "space-between", | 
 |  |  |         }} | 
 |  |  |       > | 
 |  |  |         <WhMatCreate | 
 |  |  |           editRecord={editRecord} | 
 |  |  |           open={createDialog} | 
 |  |  |           setOpen={setCreateDialog} | 
 |  |  |         /> | 
 |  |  |         <Box width={300} mb={1}> | 
 |  |  |           <TextField | 
 |  |  |             label={translate("ra.action.search")} | 
 |  |  |             value={searchVal} | 
 |  |  |             onChange={(e) => handleInput(e.target.value)} | 
 |  |  |           /> | 
 |  |  |         </Box> | 
 |  |  |         <Box> | 
 |  |  |           <Button | 
 |  |  |             variant="outlined" | 
 |  |  |             color="primary" | 
 |  |  |             startIcon={<Add />} | 
 |  |  |             onClick={handleAdd} | 
 |  |  |           > | 
 |  |  |             {translate("ra.action.add")} | 
 |  |  |           </Button> | 
 |  |  |           <Button | 
 |  |  |             variant="outlined" | 
 |  |  |             color="error" | 
 |  |  |             startIcon={<Delete />} | 
 |  |  |             sx={{ ml: 1 }} | 
 |  |  |           > | 
 |  |  |             {translate("ra.action.delete")} | 
 |  |  |           </Button> | 
 |  |  |           <Button | 
 |  |  |             variant="outlined" | 
 |  |  |             color="primary" | 
 |  |  |             sx={{ ml: 1 }} | 
 |  |  |             startIcon={<Save />} | 
 |  |  |           > | 
 |  |  |             {translate("ra.action.save")} | 
 |  |  |           </Button> | 
 |  |  |         </Box> | 
 |  |  |       </Box> | 
 |  |  |  | 
 |  |  |       <Card> | 
 |  |  |         <CardContent> | 
 |  |  |           <RichTreeView | 
 |  |  |             defaultExpandedItems={["grid", "pickers"]} | 
 |  |  |             checkboxSelection | 
 |  |  |             items={treeData} | 
 |  |  |             slots={{ item: CustomTreeItem }} | 
 |  |  |             onItemClick={handleNodeSelect} // 监听节点点击事件 | 
 |  |  |           /> | 
 |  |  |         </CardContent> | 
 |  |  |       </Card> | 
 |  |  |     </> | 
 |  |  |   ); | 
 |  |  | }; | 
 |  |  |  | 
 |  |  | const WhMatList = () => { | 
 |  |  |     const translate = useTranslate(); | 
 |  |  |     return ( | 
 |  |  |         <> | 
 |  |  |             <Box sx={{ | 
 |  |  |                 display: 'flex', | 
 |  |  |                 marginBottom: 24 | 
 |  |  |             }}> | 
 |  |  |                 <Title title={TITLE} /> | 
 |  |  |                 <Box> | 
 |  |  |                     <WhMatListAside /> | 
 |  |  |                 </Box> | 
 |  |  |                 <Box sx={{ flexGrow: 1 }}> | 
 |  |  |                     <WhMatListContent /> | 
 |  |  |                 </Box> | 
 |  |  |             </Box> | 
 |  |  |         </> | 
 |  |  |  | 
 |  |  |     ) | 
 |  |  | } | 
 |  |  | export default WhMatList; | 
 |  |  |   const translate = useTranslate(); | 
 |  |  |   return ( | 
 |  |  |     <> | 
 |  |  |       <Box | 
 |  |  |         sx={{ | 
 |  |  |           display: "flex", | 
 |  |  |           marginBottom: 24, | 
 |  |  |         }} | 
 |  |  |       > | 
 |  |  |         <Title title={TITLE} /> | 
 |  |  |         <Box> | 
 |  |  |           <WhMatListAside /> | 
 |  |  |         </Box> | 
 |  |  |         <Box sx={{ flexGrow: 1 }}> | 
 |  |  |           <WhMatListContent /> | 
 |  |  |         </Box> | 
 |  |  |       </Box> | 
 |  |  |     </> | 
 |  |  |   ); | 
 |  |  | }; | 
 |  |  | export default WhMatList; |