From 65953b12f9d667c54049c34050d39bf90556585c Mon Sep 17 00:00:00 2001
From: skyouc
Date: 星期五, 21 二月 2025 17:08:39 +0800
Subject: [PATCH] Merge branch 'dev' of http://47.97.1.152:5880/r/wms-master into dev

---
 rsf-admin/src/page/basicInfo/warehouse/WarehouseList.jsx                                     |   10 
 rsf-admin/src/page/basicInfo/matnr/MatnrListAside.jsx                                        |   40 ++
 rsf-admin/src/page/basicInfo/matnrGroup/MatnrGroupPanel.jsx                                  |    2 
 rsf-admin/src/page/basicInfo/warehouse/WarehousePanel.jsx                                    |    2 
 rsf-admin/src/page/basicInfo/matnr/MatnrCreate.jsx                                           |    6 
 rsf-admin/src/page/basicInfo/shipper/index.jsx                                               |    0 
 rsf-admin/src/page/basicInfo/warehouse/index.jsx                                             |    0 
 rsf-admin/src/page/basicInfo/matnrGroup/MatnrGroupEdit.jsx                                   |  181 ++++++++++++
 rsf-admin/src/page/basicInfo/shipper/ShipperEdit.jsx                                         |    8 
 rsf-admin/src/page/basicInfo/matnr/MatnrPanel.jsx                                            |    2 
 rsf-admin/src/page/basicInfo/shipper/ShipperCreate.jsx                                       |    6 
 rsf-admin/src/page/basicInfo/warehouse/WarehouseCreate.jsx                                   |    6 
 rsf-admin/src/page/ResourceContent.js                                                        |    8 
 rsf-admin/src/page/basicInfo/warehouse/WarehouseEdit.jsx                                     |    8 
 rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/MatnrGroupController.java |    2 
 rsf-admin/src/page/basicInfo/matnrGroup/MatnrGroupList copy.jsx                              |   10 
 rsf-admin/src/page/basicInfo/matnrGroup/MatnrGroupList.jsx                                   |  339 ++++++++++++++++++++++++
 rsf-admin/src/page/basicInfo/matnr/MatnrEdit.jsx                                             |    8 
 /dev/null                                                                                    |  104 -------
 rsf-admin/src/page/basicInfo/shipper/ShipperList.jsx                                         |   10 
 rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/MatnrGroup.java               |    4 
 rsf-admin/src/page/basicInfo/shipper/ShipperPanel.jsx                                        |    2 
 rsf-admin/src/page/basicInfo/matnrGroup/index.jsx                                            |    0 
 rsf-admin/src/page/basicInfo/matnr/MatnrList.jsx                                             |   17 
 rsf-admin/src/page/basicInfo/matnr/index.jsx                                                 |    0 
 rsf-admin/src/page/basicInfo/matnrGroup/MatnrGroupCreate.jsx                                 |    6 
 26 files changed, 619 insertions(+), 162 deletions(-)

diff --git a/rsf-admin/src/page/ResourceContent.js b/rsf-admin/src/page/ResourceContent.js
index 4f8c9b4..d91a310 100644
--- a/rsf-admin/src/page/ResourceContent.js
+++ b/rsf-admin/src/page/ResourceContent.js
@@ -14,10 +14,10 @@
 import user from './system/user';
 import operationRecord from './system/operationRecord';
 import customer from './customer';
-import shipper from './shipper';
-import matnr from './matnr';
-import matnrGroup from './matnrGroup';
-import warehouse from './warehouse';
+import shipper from './basicInfo/shipper';
+import matnr from './basicInfo/matnr';
+import matnrGroup from './basicInfo/matnrGroup';
+import warehouse from './basicInfo/warehouse';
 import warehouseAreas from './warehouseAreas';
 import loc from './loc';
 import container from './container';
diff --git a/rsf-admin/src/page/matnr/MatnrCreate.jsx b/rsf-admin/src/page/basicInfo/matnr/MatnrCreate.jsx
similarity index 98%
rename from rsf-admin/src/page/matnr/MatnrCreate.jsx
rename to rsf-admin/src/page/basicInfo/matnr/MatnrCreate.jsx
index 0d7a4cc..7d92209 100644
--- a/rsf-admin/src/page/matnr/MatnrCreate.jsx
+++ b/rsf-admin/src/page/basicInfo/matnr/MatnrCreate.jsx
@@ -27,9 +27,9 @@
     Grid,
     Box,
 } from '@mui/material';
-import DialogCloseButton from "../components/DialogCloseButton";
-import StatusSelectInput from "../components/StatusSelectInput";
-import MemoInput from "../components/MemoInput";
+import DialogCloseButton from "@/page/components/DialogCloseButton";
+import StatusSelectInput from "@/page/components/StatusSelectInput";
+import MemoInput from "@/page/components/MemoInput";
 
 const MatnrCreate = (props) => {
     const { open, setOpen } = props;
diff --git a/rsf-admin/src/page/matnr/MatnrEdit.jsx b/rsf-admin/src/page/basicInfo/matnr/MatnrEdit.jsx
similarity index 97%
rename from rsf-admin/src/page/matnr/MatnrEdit.jsx
rename to rsf-admin/src/page/basicInfo/matnr/MatnrEdit.jsx
index 237e49b..49e84ab 100644
--- a/rsf-admin/src/page/matnr/MatnrEdit.jsx
+++ b/rsf-admin/src/page/basicInfo/matnr/MatnrEdit.jsx
@@ -24,10 +24,10 @@
 import { Stack, Grid, Box, Typography } from '@mui/material';
 import * as Common from '@/utils/common';
 import { EDIT_MODE, REFERENCE_INPUT_PAGESIZE } from '@/config/setting';
-import EditBaseAside from "../components/EditBaseAside";
-import CustomerTopToolBar from "../components/EditTopToolBar";
-import MemoInput from "../components/MemoInput";
-import StatusSelectInput from "../components/StatusSelectInput";
+import EditBaseAside from "@/page/components/EditBaseAside";
+import CustomerTopToolBar from "@/page/components/EditTopToolBar";
+import MemoInput from "@/page/components/MemoInput";
+import StatusSelectInput from "@/page/components/StatusSelectInput";
 
 const FormToolbar = () => {
     const { getValues } = useFormContext();
diff --git a/rsf-admin/src/page/matnr/MatnrList.jsx b/rsf-admin/src/page/basicInfo/matnr/MatnrList.jsx
similarity index 93%
rename from rsf-admin/src/page/matnr/MatnrList.jsx
rename to rsf-admin/src/page/basicInfo/matnr/MatnrList.jsx
index 9c8e8f3..47c7b15 100644
--- a/rsf-admin/src/page/matnr/MatnrList.jsx
+++ b/rsf-admin/src/page/basicInfo/matnr/MatnrList.jsx
@@ -36,14 +36,14 @@
 import { styled } from '@mui/material/styles';
 import MatnrCreate from "./MatnrCreate";
 import MatnrPanel from "./MatnrPanel";
-import EmptyData from "../components/EmptyData";
-import MyCreateButton from "../components/MyCreateButton";
-import MyExportButton from '../components/MyExportButton';
-import PageDrawer from "../components/PageDrawer";
-import MyField from "../components/MyField";
+import EmptyData from "@/page/components/EmptyData";
+import MyCreateButton from "@/page/components/MyCreateButton";
+import MyExportButton from '@/page/components/MyExportButton';
+import PageDrawer from "@/page/components/PageDrawer";
+import MyField from "@/page/components/MyField";
 import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting';
 import * as Common from '@/utils/common';
-import ImportButton from "../components/ImportButton";
+import ImportButton from "@/page/components/ImportButton";
 import MatListAside from './MatnrListAside';
 
 const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({
@@ -143,7 +143,10 @@
                 rowClick={(id, resource, record) => false}
                 expand={() => <MatnrPanel />}
                 expandSingle={true}
-                omit={['id', 'createTime', 'createBy', 'memo']}
+                omit={['id','shipperId','erpCode','spec','model','weight','color','size','describle'
+                    ,'nromNum','unit','purchaseUnit','stockUnit','stockLeval','isLabelMange','safeQty'
+                    ,'minQty','maxQty','stagn','valid','validWarn','flagCheck','updateTime', 'updateBy'
+                    , 'createTime', 'createBy', 'memo']}
             >
                 <NumberField source="id" />
                 <TextField source="name" label="table.field.matnr.name" />
diff --git a/rsf-admin/src/page/matnr/MatnrListAside.jsx b/rsf-admin/src/page/basicInfo/matnr/MatnrListAside.jsx
similarity index 79%
rename from rsf-admin/src/page/matnr/MatnrListAside.jsx
rename to rsf-admin/src/page/basicInfo/matnr/MatnrListAside.jsx
index f7cffc8..e9a9147 100644
--- a/rsf-admin/src/page/matnr/MatnrListAside.jsx
+++ b/rsf-admin/src/page/basicInfo/matnr/MatnrListAside.jsx
@@ -3,7 +3,15 @@
 import {
     SavedQueriesList,
     FilterLiveSearch,
-    useListContext,
+    useNotify,
+    FilterList,
+    FilterListItem,
+    useStore,
+    FilterFormInput,
+    FilterLiveForm,
+    TextInput,
+    useGetList,
+    useListContext
 } from 'react-admin';
 import BookmarkIcon from '@mui/icons-material/BookmarkBorder';
 import { Box, Typography, Card, CardContent, useTheme, TextField } from '@mui/material';
@@ -15,9 +23,32 @@
 
 const MatListAside = () => {
     const theme = useTheme();
+    const notify = useNotify();
     const { setFilters } = useListContext(); // 鑾峰彇鍒楄〃涓婁笅鏂�
     const [selectedOption, setSelectedOption] = useState(null);
-    const treeData = [
+    const [treeData, setTreeData] = useState([]);
+
+    useEffect(() => {
+        request.post('/matnrGroup/tree')
+            .then(res => {
+                console.log('Tree Data:', res);
+                if (res?.data?.code === 200) {
+                    setTreeData(res.data.data);
+                } else {
+                    notify(res.data.msg);
+                }
+            })
+            .catch(error => {
+                notify('Error fetching tree data');
+            });
+        
+        
+        
+    },[]);
+
+
+
+    const treeData1 = [
         {
             id: '19',
             label: '鍗婃垚鍝� ',
@@ -56,6 +87,9 @@
         setFilters({ groupId: nodeId });
         // 鍦ㄨ繖閲屽彲浠ユ牴鎹� nodeId 鏇存柊涓诲唴瀹瑰尯鍩�
     };
+    const handleSearch = () => {
+            console.log('Search Input:', selectedOption);
+    };
 
 
     const CustomCheckbox = React.forwardRef(function CustomCheckbox(props, ref) {
@@ -89,7 +123,7 @@
         >
             <CardContent>
                 <SavedQueriesList icon={<BookmarkIcon />} />
-                <FilterLiveSearch source='condition' hiddenLabel  />
+                <FilterLiveSearch source="condition"  />
                 <RichTreeView
                     defaultExpandedItems={['grid', 'pickers']}
                     expansionTrigger="iconContainer"
diff --git a/rsf-admin/src/page/matnr/MatnrPanel.jsx b/rsf-admin/src/page/basicInfo/matnr/MatnrPanel.jsx
similarity index 98%
rename from rsf-admin/src/page/matnr/MatnrPanel.jsx
rename to rsf-admin/src/page/basicInfo/matnr/MatnrPanel.jsx
index 9951914..ebf9a95 100644
--- a/rsf-admin/src/page/matnr/MatnrPanel.jsx
+++ b/rsf-admin/src/page/basicInfo/matnr/MatnrPanel.jsx
@@ -4,7 +4,7 @@
     useTranslate,
     useRecordContext,
 } from 'react-admin';
-import PanelTypography from "../components/PanelTypography";
+import PanelTypography from "@/page/components/PanelTypography";
 import * as Common from '@/utils/common'
 
 const MatnrPanel = () => {
diff --git a/rsf-admin/src/page/matnr/index.jsx b/rsf-admin/src/page/basicInfo/matnr/index.jsx
similarity index 100%
rename from rsf-admin/src/page/matnr/index.jsx
rename to rsf-admin/src/page/basicInfo/matnr/index.jsx
diff --git a/rsf-admin/src/page/matnrGroup/MatnrGroupCreate.jsx b/rsf-admin/src/page/basicInfo/matnrGroup/MatnrGroupCreate.jsx
similarity index 95%
rename from rsf-admin/src/page/matnrGroup/MatnrGroupCreate.jsx
rename to rsf-admin/src/page/basicInfo/matnrGroup/MatnrGroupCreate.jsx
index 3344309..0146f24 100644
--- a/rsf-admin/src/page/matnrGroup/MatnrGroupCreate.jsx
+++ b/rsf-admin/src/page/basicInfo/matnrGroup/MatnrGroupCreate.jsx
@@ -27,9 +27,9 @@
     Grid,
     Box,
 } from '@mui/material';
-import DialogCloseButton from "../components/DialogCloseButton";
-import StatusSelectInput from "../components/StatusSelectInput";
-import MemoInput from "../components/MemoInput";
+import DialogCloseButton from "@/page/components/DialogCloseButton";
+import StatusSelectInput from "@/page/components/StatusSelectInput";
+import MemoInput from "@/page/components/MemoInput";
 
 const MatnrGroupCreate = (props) => {
     const { open, setOpen } = props;
diff --git a/rsf-admin/src/page/basicInfo/matnrGroup/MatnrGroupEdit.jsx b/rsf-admin/src/page/basicInfo/matnrGroup/MatnrGroupEdit.jsx
new file mode 100644
index 0000000..206a847
--- /dev/null
+++ b/rsf-admin/src/page/basicInfo/matnrGroup/MatnrGroupEdit.jsx
@@ -0,0 +1,181 @@
+import React, { useState, useRef, useEffect, useMemo } from "react";
+import {
+    CreateBase,
+    useTranslate,
+    TextInput,
+    NumberInput,
+    BooleanInput,
+    DateInput,
+    SaveButton,
+    SelectInput,
+    ReferenceInput,
+    ReferenceArrayInput,
+    AutocompleteInput,
+    Toolbar,
+    required,
+    useNotify,
+    Form,
+    useUpdate,
+    useCreate,
+    useCreateContext,
+    Labeled,
+    NumberField,
+    useRecordContext,
+    DeleteButton,
+} from 'react-admin';
+import {
+    Dialog,
+    DialogActions,
+    DialogContent,
+    DialogTitle,
+    Stack,
+    Grid,
+    Box,
+} from '@mui/material';
+import DialogCloseButton from "@/page/components/DialogCloseButton";
+import TreeSelectInput from "@/page/components/TreeSelectInput";
+import { useWatch, useFormContext } from "react-hook-form";
+import * as Common from '@/utils/common';
+import { EDIT_MODE, REFERENCE_INPUT_PAGESIZE } from '@/config/setting';
+import EditBaseAside from "@/page/components/EditBaseAside";
+import CustomerTopToolBar from "@/page/components/EditTopToolBar";
+import MemoInput from "@/page/components/MemoInput";
+import StatusSelectInput from "@/page/components/StatusSelectInput";
+
+
+const EditContent = ({ editRecord }) => {
+    const { resource } = useCreateContext();
+    return (
+        <Grid container rowSpacing={2} columnSpacing={2}>
+            <Grid item xs={6} display="flex" gap={1}>
+                <TreeSelectInput
+                    label="table.field.matnrGroup.parentId"
+                    value={editRecord?.parentId}
+                    isTranslate
+                    resource={resource}
+                />
+            </Grid>
+            <Grid item xs={6} display="flex" gap={1}>
+                <TextInput
+                    label="table.field.matnrGroup.name"
+                    source="name"
+                    parse={v => v}
+                    validate={required()}
+                />
+            </Grid>
+            <Grid item xs={6} display="flex" gap={1}>
+                <TextInput
+                    label="table.field.matnrGroup.code"
+                    source="code"
+                    parse={v => v}
+                />
+            </Grid>
+        </Grid>
+    )
+}
+
+const MatnrGroupEdit = (props) => {
+    const { editRecord, open, setOpen, callback, resource } = props;
+    
+    const translate = useTranslate();
+    const notify = useNotify();
+
+    const [update] = useUpdate();
+    const [create] = useCreate();
+
+    const handleClose = (event, reason) => {
+        if (reason !== "backdropClick") {
+            setOpen(false);
+        }
+    };
+
+    const handleSuccess = async (data) => {
+        setOpen(false);
+        callback();
+        notify('common.response.success', { type: 'info' });
+    };
+
+    const handleError = async (data) => {
+        notify('common.response.fail', { type: 'error' });
+    };
+
+    const onSubmit = (data) => {
+        const _params = { ...data };
+        if (editRecord) {
+            if (_params.parentId === editRecord.id) {
+                notify('common.response.dataError', { type: 'error' });
+                return;
+            }
+            update(
+                resource,
+                {
+                    id: editRecord.id,
+                    data: _params,
+                },
+                {
+                    onSuccess: () => {
+                        handleSuccess();
+                    },
+                    onError: (error) => {
+                        handleError();
+                    },
+                }
+            );
+        } else {
+            create(
+                resource,
+                { data: _params },
+                {
+                    onSuccess: () => {
+                        handleSuccess();
+                    },
+                    onError: (error) => {
+                        handleError();
+                    },
+                }
+            );
+        }
+    };
+
+    return (
+    <>
+        <CreateBase>
+            <Dialog
+                open={open}
+                onClose={handleClose}
+                aria-labelledby="form-dialog-title"
+                fullWidth
+                disableRestoreFocus
+                maxWidth="md"   // 'xs' | 'sm' | 'md' | 'lg' | 'xl'
+            >
+                <Form record={editRecord} onSubmit={onSubmit}>
+                    <DialogTitle id="form-dialog-title" sx={{
+                        position: 'sticky',
+                        top: 0,
+                        backgroundColor: 'background.paper',
+                        zIndex: 1000
+                    }}
+                    >
+                        {editRecord ? translate('update.title') : translate('create.title')}
+                        <Box sx={{ position: 'absolute', top: 8, right: 8, zIndex: 1001 }}>
+                            <DialogCloseButton onClose={handleClose} />
+                        </Box>
+                    </DialogTitle>
+                    <DialogContent sx={{ mt: 2 }}>
+                        <EditContent
+                            editRecord={editRecord}
+                        />
+                    </DialogContent>
+                    <DialogActions sx={{ position: 'sticky', bottom: 0, backgroundColor: 'background.paper', zIndex: 1000 }}>
+                        <Toolbar sx={{ width: '100%', justifyContent: 'space-between' }}  >
+                            <SaveButton />
+                        </Toolbar>
+                    </DialogActions>
+                </Form>
+            </Dialog>
+        </CreateBase>
+    </>
+    )
+}
+
+export default MatnrGroupEdit;
diff --git a/rsf-admin/src/page/matnrGroup/MatnrGroupList.jsx b/rsf-admin/src/page/basicInfo/matnrGroup/MatnrGroupList copy.jsx
similarity index 94%
rename from rsf-admin/src/page/matnrGroup/MatnrGroupList.jsx
rename to rsf-admin/src/page/basicInfo/matnrGroup/MatnrGroupList copy.jsx
index 7a34054..b7ee747 100644
--- a/rsf-admin/src/page/matnrGroup/MatnrGroupList.jsx
+++ b/rsf-admin/src/page/basicInfo/matnrGroup/MatnrGroupList copy.jsx
@@ -36,11 +36,11 @@
 import { styled } from '@mui/material/styles';
 import MatnrGroupCreate from "./MatnrGroupCreate";
 import MatnrGroupPanel from "./MatnrGroupPanel";
-import EmptyData from "../components/EmptyData";
-import MyCreateButton from "../components/MyCreateButton";
-import MyExportButton from '../components/MyExportButton';
-import PageDrawer from "../components/PageDrawer";
-import MyField from "../components/MyField";
+import EmptyData from "@/page/components/EmptyData";
+import MyCreateButton from "@/page/components/MyCreateButton";
+import MyExportButton from '@/page/components/MyExportButton';
+import PageDrawer from "@/page/components/PageDrawer";
+import MyField from "@/page/components/MyField";
 import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting';
 import * as Common from '@/utils/common';
 
diff --git a/rsf-admin/src/page/basicInfo/matnrGroup/MatnrGroupList.jsx b/rsf-admin/src/page/basicInfo/matnrGroup/MatnrGroupList.jsx
new file mode 100644
index 0000000..8436018
--- /dev/null
+++ b/rsf-admin/src/page/basicInfo/matnrGroup/MatnrGroupList.jsx
@@ -0,0 +1,339 @@
+import React from 'react';
+import {
+    Title,
+    useTranslate,
+    useNotify,
+    useRedirect,
+    useRefresh,
+    useDelete,
+} from 'react-admin';
+import { styled } from '@mui/material/styles';
+import {
+    Box,
+    Collapse,
+    IconButton,
+    Table,
+    TableBody,
+    TableCell,
+    TableContainer,
+    TableHead,
+    TableRow,
+    Paper,
+    Card,
+    Typography,
+    TextField,
+    Tooltip,
+    Button,
+    Chip,
+    LinearProgress,
+} from '@mui/material';
+import { Add, Edit, Delete } 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 request from '@/utils/request';
+import MatnrGroupEdit from "./MatnrGroupEdit";
+import * as Icons from '@mui/icons-material';
+
+const RESOURCE = 'matnrGroup';
+const TITLE = 'menu.matnrGroup';
+
+const columns = [
+    {
+        id: 'name',
+        label: 'table.field.matnrGroup.name',
+        minWidth: 200,
+    },
+    {
+        id: 'code',
+        label: 'table.field.matnrGroup.code',
+        minWidth: 80,
+    },
+    {
+        id: 'parentId',
+        label: 'table.field.matnrGroup.parentId',
+        minWidth: 100,
+    }
+];
+
+const getIconComponent = (iconStr) => {
+    return Icons[iconStr] || null;
+};
+
+const StyledTableRow = styled(TableRow)(({ theme }) => ({
+    '& .MuiButtonBase-root': {
+        padding: '0px 8px'
+    }
+}));
+
+const StyledTableCell = styled(TableCell)(({ theme }) => ({
+    overflow: 'hidden',
+    textOverflow: 'ellipsis',
+    whiteSpace: 'nowrap',
+    maxWidth: 600,
+}));
+
+const TreeTableRow = (props) => {
+    const { row, depth = 0, openNodes, setOpenNodes, onEdit, onDelete } = props;
+    const translate = useTranslate();
+
+    const toggleNode = (id) => {
+        setOpenNodes(prevState => ({ ...prevState, [id]: !prevState[id] }));
+    };
+
+    const isOpen = openNodes[row.id] || false;
+
+    return (
+        <React.Fragment>
+            <StyledTableRow hover tabIndex={-1} key={row.id}>
+                <StyledTableCell sx={{ padding: 0 }}>
+                    {row.children && (
+                        <IconButton
+                            aria-label="expand row"
+                            size="small"
+                            onClick={() => toggleNode(row.id)}
+                        >
+                            {isOpen ? <KeyboardArrowDownIcon /> : <KeyboardArrowRightIcon />}
+                        </IconButton>
+                    )}
+                </StyledTableCell>
+                {columns.map((column, idx) => {
+                    if (column.id !== 'actions') {
+                        let value = row[column.id];
+                        if (column.id === 'name' && row['type'] === 0) {
+                            value = translate(value);
+                        }
+                        return (
+                            <StyledTableCell
+                                key={column.id}
+                                align={column.align || 'left'}
+                                style={{
+                                    paddingLeft: idx === 0 && (depth * 16 + 16),
+                                    opacity: column.id === 'icon' && .6
+                                }}
+                                onClick={() => toggleNode(row.id)}
+                            >
+                                {column.format ? column.format(value) : value}
+                            </StyledTableCell>
+                        )
+                    }
+                })}
+                <StyledTableCell>
+                    <Tooltip title="Edit">
+                        <IconButton onClick={() => onEdit(row)}>
+                            <Edit />
+                        </IconButton>
+                    </Tooltip>
+                    <Tooltip title="Delete">
+                        <IconButton onClick={() => onDelete(row)}>
+                            <Delete />
+                        </IconButton>
+                    </Tooltip>
+                </StyledTableCell>
+            </StyledTableRow>
+            {row.children && isOpen && (
+                row.children.map((child) => (
+                    <TreeTableRow
+                        key={child.id}
+                        row={child}
+                        depth={depth + 1}
+                        onEdit={onEdit}
+                        onDelete={onDelete}
+                        openNodes={openNodes}
+                        setOpenNodes={setOpenNodes}
+                    />
+                ))
+            )}
+        </React.Fragment>
+    );
+};
+
+const MatnrGroupList = () => {
+    const translate = useTranslate();
+    const notify = useNotify();
+    const redirect = useRedirect();
+    const refresh = useRefresh();
+    const [deleteOne] = useDelete();
+
+    const [treeData, setTreeData] = React.useState(null);
+    const [filter, setFilter] = React.useState("");
+    const [createDialog, setCreateDialog] = React.useState(false);
+    const [editRecord, setEditRecord] = React.useState(null);
+    const [openNodes, setOpenNodes] = React.useState({});
+    const [expandAll, setExpandAll] = React.useState(false);
+
+    const http = async () => {
+        const res = await request.post(RESOURCE + '/tree', {
+            condition: filter
+        });
+        if (res?.data?.code === 200) {
+            setTreeData(res.data.data);
+        } else {
+            notify(res.data.msg);
+        }
+    }
+
+    React.useEffect(() => {
+        http();
+    }, [filter]);
+
+    const handleRefresh = () => {
+        http();
+    };
+
+    const handleAdd = () => {
+        setEditRecord(null);
+        setCreateDialog(true);
+    };
+
+    const handleEdit = (node) => {
+        setEditRecord(node);
+        setCreateDialog(true);
+    };
+
+    const handleDelete = (node) => {
+        if (window.confirm(translate('ra.message.delete_content'))) {
+            deleteOne(
+                RESOURCE,
+                { id: node.id },
+                {
+                    onSuccess: () => {
+                        handleRefresh();
+                        notify('Department deleted successfully', { type: 'info', messageArgs: { _: 'Department deleted successfully' } });
+                    },
+                    onError: (error) => {
+                        notify(`Error: ${error.message}`, { type: 'warning', messageArgs: { _: `Error: ${error.message}` } });
+                    },
+                }
+            );
+        }
+    };
+
+    const toggleExpandAll = () => {
+        setExpandAll(prevExpandAll => {
+            const newExpandAll = !prevExpandAll;
+            const newOpenNodes = {};
+            const updateOpenNodes = (nodes) => {
+                nodes.forEach(node => {
+                    newOpenNodes[node.id] = newExpandAll;
+                    if (node.children) {
+                        updateOpenNodes(node.children);
+                    }
+                });
+            };
+            updateOpenNodes(treeData);
+            setOpenNodes(newOpenNodes);
+            return newExpandAll;
+        });
+    };
+
+    return (
+        <div>
+            <MatnrGroupEdit
+                editRecord={editRecord}
+                open={createDialog}
+                setOpen={setCreateDialog}
+                callback={() => {
+                    handleRefresh();
+                }}
+                resource={RESOURCE}
+            />
+            <Title title={TITLE} />
+            <Box sx={{ mt: 2, mr: 3, mb: 1, display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
+                <Box width={300} >
+                    <Button
+                        variant="outlined"
+                        color="primary"
+                        startIcon={expandAll ? <KeyboardArrowDownIcon /> : <KeyboardArrowRightIcon />}
+                        onClick={toggleExpandAll}
+                        sx={{ ml: 1 }}
+                    >
+                        {expandAll ? translate('common.action.collapseAll') : translate('common.action.expandAll')}
+                    </Button>
+                    {/* <TextField
+                        label="Search"
+                        value={filter}
+                        onChange={({ target }) => {
+                            setFilter(target.value)
+                        }}
+                        variant="filled"
+                        size="small"
+                        margin="dense"
+                        fullWidth
+                    /> */}
+                </Box>
+                <Box>
+                    <Button
+                        variant="outlined"
+                        color="primary"
+                        startIcon={<RefreshIcon />}
+                        onClick={handleRefresh}
+                        sx={{ ml: 1 }}
+                    >
+                        {translate('ra.action.refresh')}
+                    </Button>
+                    <Button
+                        variant="outlined"
+                        color="primary"
+                        startIcon={<Add />}
+                        onClick={handleAdd}
+                        sx={{ ml: 1 }}
+                    >
+                        {translate('ra.action.add')}
+                    </Button>
+                </Box>
+            </Box>
+            <Card sx={{
+                position: 'relative',
+            }}>
+                {!treeData && (
+                    <LinearProgress
+                        sx={{
+                            height: "3px",
+                            position: 'absolute',
+                            top: 0,
+                            left: 0,
+                            right: 0,
+                        }}
+                    />
+                )}
+                <TableContainer component={Paper}>
+                    <Table size="small">
+                        <TableHead>
+                            <TableRow>
+                                <StyledTableCell sx={{ padding: 0, width: 60 }} />
+                                {columns.map((column, idx) => (
+                                    <StyledTableCell
+                                        key={idx}
+                                        align={column.align || 'left'}
+                                        style={{
+                                            minWidth: column.minWidth
+                                        }}
+                                    >
+                                        {translate(column.label)}
+                                    </StyledTableCell>
+                                ))}
+                            </TableRow>
+                        </TableHead>
+                        <TableBody>
+                            {treeData && treeData.length > 0 && (
+                                treeData.map((row) => (
+                                    <TreeTableRow
+                                        key={row.id}
+                                        row={row}
+                                        onEdit={handleEdit}
+                                        onDelete={handleDelete}
+                                        openNodes={openNodes}
+                                        setOpenNodes={setOpenNodes}
+                                    />
+                                ))
+                            )}
+                        </TableBody>
+                    </Table>
+                </TableContainer>
+            </Card>
+        </div>
+    );
+}
+
+export default MatnrGroupList;
diff --git a/rsf-admin/src/page/matnrGroup/MatnrGroupPanel.jsx b/rsf-admin/src/page/basicInfo/matnrGroup/MatnrGroupPanel.jsx
similarity index 97%
rename from rsf-admin/src/page/matnrGroup/MatnrGroupPanel.jsx
rename to rsf-admin/src/page/basicInfo/matnrGroup/MatnrGroupPanel.jsx
index f704804..c00591c 100644
--- a/rsf-admin/src/page/matnrGroup/MatnrGroupPanel.jsx
+++ b/rsf-admin/src/page/basicInfo/matnrGroup/MatnrGroupPanel.jsx
@@ -4,7 +4,7 @@
     useTranslate,
     useRecordContext,
 } from 'react-admin';
-import PanelTypography from "../components/PanelTypography";
+import PanelTypography from "@/page/components/PanelTypography";
 import * as Common from '@/utils/common'
 
 const MatnrGroupPanel = () => {
diff --git a/rsf-admin/src/page/matnrGroup/index.jsx b/rsf-admin/src/page/basicInfo/matnrGroup/index.jsx
similarity index 100%
rename from rsf-admin/src/page/matnrGroup/index.jsx
rename to rsf-admin/src/page/basicInfo/matnrGroup/index.jsx
diff --git a/rsf-admin/src/page/shipper/ShipperCreate.jsx b/rsf-admin/src/page/basicInfo/shipper/ShipperCreate.jsx
similarity index 95%
rename from rsf-admin/src/page/shipper/ShipperCreate.jsx
rename to rsf-admin/src/page/basicInfo/shipper/ShipperCreate.jsx
index d4e07fd..b45fd01 100644
--- a/rsf-admin/src/page/shipper/ShipperCreate.jsx
+++ b/rsf-admin/src/page/basicInfo/shipper/ShipperCreate.jsx
@@ -27,9 +27,9 @@
     Grid,
     Box,
 } from '@mui/material';
-import DialogCloseButton from "../components/DialogCloseButton";
-import StatusSelectInput from "../components/StatusSelectInput";
-import MemoInput from "../components/MemoInput";
+import DialogCloseButton from "@/page/components/DialogCloseButton";
+import StatusSelectInput from "@/page/components/StatusSelectInput";
+import MemoInput from "@/page/components/MemoInput";
 
 const ShipperCreate = (props) => {
     const { open, setOpen } = props;
diff --git a/rsf-admin/src/page/shipper/ShipperEdit.jsx b/rsf-admin/src/page/basicInfo/shipper/ShipperEdit.jsx
similarity index 91%
rename from rsf-admin/src/page/shipper/ShipperEdit.jsx
rename to rsf-admin/src/page/basicInfo/shipper/ShipperEdit.jsx
index 7b6b543..e81f51e 100644
--- a/rsf-admin/src/page/shipper/ShipperEdit.jsx
+++ b/rsf-admin/src/page/basicInfo/shipper/ShipperEdit.jsx
@@ -24,10 +24,10 @@
 import { Stack, Grid, Box, Typography } from '@mui/material';
 import * as Common from '@/utils/common';
 import { EDIT_MODE, REFERENCE_INPUT_PAGESIZE } from '@/config/setting';
-import EditBaseAside from "../components/EditBaseAside";
-import CustomerTopToolBar from "../components/EditTopToolBar";
-import MemoInput from "../components/MemoInput";
-import StatusSelectInput from "../components/StatusSelectInput";
+import EditBaseAside from "@/page/components/EditBaseAside";
+import CustomerTopToolBar from "@/page/components/EditTopToolBar";
+import MemoInput from "@/page/components/MemoInput";
+import StatusSelectInput from "@/page/components/StatusSelectInput";
 
 const FormToolbar = () => {
     const { getValues } = useFormContext();
diff --git a/rsf-admin/src/page/shipper/ShipperList.jsx b/rsf-admin/src/page/basicInfo/shipper/ShipperList.jsx
similarity index 94%
rename from rsf-admin/src/page/shipper/ShipperList.jsx
rename to rsf-admin/src/page/basicInfo/shipper/ShipperList.jsx
index f97ca55..facfcd5 100644
--- a/rsf-admin/src/page/shipper/ShipperList.jsx
+++ b/rsf-admin/src/page/basicInfo/shipper/ShipperList.jsx
@@ -36,11 +36,11 @@
 import { styled } from '@mui/material/styles';
 import ShipperCreate from "./ShipperCreate";
 import ShipperPanel from "./ShipperPanel";
-import EmptyData from "../components/EmptyData";
-import MyCreateButton from "../components/MyCreateButton";
-import MyExportButton from '../components/MyExportButton';
-import PageDrawer from "../components/PageDrawer";
-import MyField from "../components/MyField";
+import EmptyData from "@/page/components/EmptyData";
+import MyCreateButton from "@/page/components/MyCreateButton";
+import MyExportButton from '@/page/components/MyExportButton';
+import PageDrawer from "@/page/components/PageDrawer";
+import MyField from "@/page/components/MyField";
 import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting';
 import * as Common from '@/utils/common';
 
diff --git a/rsf-admin/src/page/shipper/ShipperPanel.jsx b/rsf-admin/src/page/basicInfo/shipper/ShipperPanel.jsx
similarity index 97%
rename from rsf-admin/src/page/shipper/ShipperPanel.jsx
rename to rsf-admin/src/page/basicInfo/shipper/ShipperPanel.jsx
index 1f57cf0..f548e14 100644
--- a/rsf-admin/src/page/shipper/ShipperPanel.jsx
+++ b/rsf-admin/src/page/basicInfo/shipper/ShipperPanel.jsx
@@ -4,7 +4,7 @@
     useTranslate,
     useRecordContext,
 } from 'react-admin';
-import PanelTypography from "../components/PanelTypography";
+import PanelTypography from "@/page/components/PanelTypography";
 import * as Common from '@/utils/common'
 
 const ShipperPanel = () => {
diff --git a/rsf-admin/src/page/shipper/index.jsx b/rsf-admin/src/page/basicInfo/shipper/index.jsx
similarity index 100%
rename from rsf-admin/src/page/shipper/index.jsx
rename to rsf-admin/src/page/basicInfo/shipper/index.jsx
diff --git a/rsf-admin/src/page/warehouse/WarehouseCreate.jsx b/rsf-admin/src/page/basicInfo/warehouse/WarehouseCreate.jsx
similarity index 97%
rename from rsf-admin/src/page/warehouse/WarehouseCreate.jsx
rename to rsf-admin/src/page/basicInfo/warehouse/WarehouseCreate.jsx
index 5eb2bf9..b2127b6 100644
--- a/rsf-admin/src/page/warehouse/WarehouseCreate.jsx
+++ b/rsf-admin/src/page/basicInfo/warehouse/WarehouseCreate.jsx
@@ -27,9 +27,9 @@
     Grid,
     Box,
 } from '@mui/material';
-import DialogCloseButton from "../components/DialogCloseButton";
-import StatusSelectInput from "../components/StatusSelectInput";
-import MemoInput from "../components/MemoInput";
+import DialogCloseButton from "@/page/components/DialogCloseButton";
+import StatusSelectInput from "@/page/components/StatusSelectInput";
+import MemoInput from "@/page/components/MemoInput";
 
 const WarehouseCreate = (props) => {
     const { open, setOpen } = props;
diff --git a/rsf-admin/src/page/warehouse/WarehouseEdit.jsx b/rsf-admin/src/page/basicInfo/warehouse/WarehouseEdit.jsx
similarity index 95%
rename from rsf-admin/src/page/warehouse/WarehouseEdit.jsx
rename to rsf-admin/src/page/basicInfo/warehouse/WarehouseEdit.jsx
index 7c53724..5e83d70 100644
--- a/rsf-admin/src/page/warehouse/WarehouseEdit.jsx
+++ b/rsf-admin/src/page/basicInfo/warehouse/WarehouseEdit.jsx
@@ -24,10 +24,10 @@
 import { Stack, Grid, Box, Typography } from '@mui/material';
 import * as Common from '@/utils/common';
 import { EDIT_MODE, REFERENCE_INPUT_PAGESIZE } from '@/config/setting';
-import EditBaseAside from "../components/EditBaseAside";
-import CustomerTopToolBar from "../components/EditTopToolBar";
-import MemoInput from "../components/MemoInput";
-import StatusSelectInput from "../components/StatusSelectInput";
+import EditBaseAside from "@/page/components/EditBaseAside";
+import CustomerTopToolBar from "@/page/components/EditTopToolBar";
+import MemoInput from "@/page/components/MemoInput";
+import StatusSelectInput from "@/page/components/StatusSelectInput";
 
 const FormToolbar = () => {
     const { getValues } = useFormContext();
diff --git a/rsf-admin/src/page/warehouse/WarehouseList.jsx b/rsf-admin/src/page/basicInfo/warehouse/WarehouseList.jsx
similarity index 95%
rename from rsf-admin/src/page/warehouse/WarehouseList.jsx
rename to rsf-admin/src/page/basicInfo/warehouse/WarehouseList.jsx
index 2c902fd..233fce1 100644
--- a/rsf-admin/src/page/warehouse/WarehouseList.jsx
+++ b/rsf-admin/src/page/basicInfo/warehouse/WarehouseList.jsx
@@ -36,11 +36,11 @@
 import { styled } from '@mui/material/styles';
 import WarehouseCreate from "./WarehouseCreate";
 import WarehousePanel from "./WarehousePanel";
-import EmptyData from "../components/EmptyData";
-import MyCreateButton from "../components/MyCreateButton";
-import MyExportButton from '../components/MyExportButton';
-import PageDrawer from "../components/PageDrawer";
-import MyField from "../components/MyField";
+import EmptyData from "@/page/components/EmptyData";
+import MyCreateButton from "@/page/components/MyCreateButton";
+import MyExportButton from '@/page/components/MyExportButton';
+import PageDrawer from "@/page/components/PageDrawer";
+import MyField from "@/page/components/MyField";
 import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting';
 import * as Common from '@/utils/common';
 
diff --git a/rsf-admin/src/page/warehouse/WarehousePanel.jsx b/rsf-admin/src/page/basicInfo/warehouse/WarehousePanel.jsx
similarity index 98%
rename from rsf-admin/src/page/warehouse/WarehousePanel.jsx
rename to rsf-admin/src/page/basicInfo/warehouse/WarehousePanel.jsx
index acb6e40..b1fc42f 100644
--- a/rsf-admin/src/page/warehouse/WarehousePanel.jsx
+++ b/rsf-admin/src/page/basicInfo/warehouse/WarehousePanel.jsx
@@ -4,7 +4,7 @@
     useTranslate,
     useRecordContext,
 } from 'react-admin';
-import PanelTypography from "../components/PanelTypography";
+import PanelTypography from "@/page/components/PanelTypography";
 import * as Common from '@/utils/common'
 
 const WarehousePanel = () => {
diff --git a/rsf-admin/src/page/warehouse/index.jsx b/rsf-admin/src/page/basicInfo/warehouse/index.jsx
similarity index 100%
rename from rsf-admin/src/page/warehouse/index.jsx
rename to rsf-admin/src/page/basicInfo/warehouse/index.jsx
diff --git a/rsf-admin/src/page/matnrGroup/MatnrGroupEdit.jsx b/rsf-admin/src/page/matnrGroup/MatnrGroupEdit.jsx
deleted file mode 100644
index 8240f0c..0000000
--- a/rsf-admin/src/page/matnrGroup/MatnrGroupEdit.jsx
+++ /dev/null
@@ -1,104 +0,0 @@
-import React, { useState, useRef, useEffect, useMemo } from "react";
-import {
-    Edit,
-    SimpleForm,
-    FormDataConsumer,
-    useTranslate,
-    TextInput,
-    NumberInput,
-    BooleanInput,
-    DateInput,
-    SelectInput,
-    ReferenceInput,
-    ReferenceArrayInput,
-    AutocompleteInput,
-    SaveButton,
-    Toolbar,
-    Labeled,
-    NumberField,
-    required,
-    useRecordContext,
-    DeleteButton,
-} from 'react-admin';
-import { useWatch, useFormContext } from "react-hook-form";
-import { Stack, Grid, Box, Typography } from '@mui/material';
-import * as Common from '@/utils/common';
-import { EDIT_MODE, REFERENCE_INPUT_PAGESIZE } from '@/config/setting';
-import EditBaseAside from "../components/EditBaseAside";
-import CustomerTopToolBar from "../components/EditTopToolBar";
-import MemoInput from "../components/MemoInput";
-import StatusSelectInput from "../components/StatusSelectInput";
-
-const FormToolbar = () => {
-    const { getValues } = useFormContext();
-
-    return (
-        <Toolbar sx={{ justifyContent: 'space-between' }}>
-            <SaveButton />
-            <DeleteButton mutationMode="optimistic" />
-        </Toolbar>
-    )
-}
-
-const MatnrGroupEdit = () => {
-    const translate = useTranslate();
-
-    return (
-        <Edit
-            redirect="list"
-            mutationMode={EDIT_MODE}
-            actions={<CustomerTopToolBar />}
-            aside={<EditBaseAside />}
-        >
-            <SimpleForm
-                shouldUnregister
-                warnWhenUnsavedChanges
-                toolbar={<FormToolbar />}
-                mode="onTouched"
-                defaultValues={{}}
-            // validate={(values) => { }}
-            >
-                <Grid container width={{ xs: '100%', xl: '80%' }} rowSpacing={3} columnSpacing={3}>
-                    <Grid item xs={12} md={8}>
-                        <Typography variant="h6" gutterBottom>
-                            {translate('common.edit.title.main')}
-                        </Typography>
-                        <Stack direction='row' gap={2}>
-                            <TextInput
-                                label="table.field.matnrGroup.name"
-                                source="name"
-                                parse={v => v}
-                                validate={required()}
-                            />
-                        </Stack>
-                        <Stack direction='row' gap={2}>
-                            <TextInput
-                                label="table.field.matnrGroup.code"
-                                source="code"
-                                parse={v => v}
-                                validate={required()}
-                            />
-                        </Stack>
-                        <Stack direction='row' gap={2}>
-                            <NumberInput
-                                label="table.field.matnrGroup.parentId"
-                                source="parentId"
-                            />
-                        </Stack>
-
-                    </Grid>
-                    <Grid item xs={12} md={4}>
-                        <Typography variant="h6" gutterBottom>
-                            {translate('common.edit.title.common')}
-                        </Typography>
-                        <StatusSelectInput />
-                        <Box mt="2em" />
-                        <MemoInput />
-                    </Grid>
-                </Grid>
-            </SimpleForm>
-        </Edit >
-    )
-}
-
-export default MatnrGroupEdit;
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/MatnrGroupController.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/MatnrGroupController.java
index a1ba42a..bde419b 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/MatnrGroupController.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/MatnrGroupController.java
@@ -106,7 +106,7 @@
     }
 
     @PreAuthorize("hasAuthority('manager:matnrGroup:list')")
-    @GetMapping("/matnrGroup/tree")
+    @PostMapping("/matnrGroup/tree")
     public R tree() {
         List<MatnrGroup> matnrs = matnrGroupService.list(new LambdaQueryWrapper<>());
         List<MatnrGroup> treeData = Utils.toTreeData(matnrs, 0L, MatnrGroup::getParentId, MatnrGroup::getId, MatnrGroup::setChildren);
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/MatnrGroup.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/MatnrGroup.java
index acb2845..30f8dad 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/MatnrGroup.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/MatnrGroup.java
@@ -196,4 +196,8 @@
         }
     }
 
+    public String getLabel(){
+        return this.name;
+    }
+
 }

--
Gitblit v1.9.1