From bbcefd8c900283c2618d8d792059d9e078daea96 Mon Sep 17 00:00:00 2001
From: skyouc
Date: 星期一, 24 三月 2025 16:35:29 +0800
Subject: [PATCH] Merge branch 'front' into devlop

---
 rsf-admin/src/page/basicInfo/locArea/LocAreaEdit.jsx                 |    3 
 rsf-admin/src/page/basicInfo/locAreaMat/BindLocModal.jsx             |  220 +++
 rsf-admin/src/page/system/host/HostList.jsx                          |    4 
 rsf-admin/src/page/fields/FieldsList.jsx                             |    8 
 rsf-admin/src/page/system/userLogin/UserLoginList.jsx                |    4 
 rsf-admin/src/page/basicInfo/locType/LocTypeList.jsx                 |   33 
 rsf-admin/src/page/warehouseAreasItem/WarehouseAreasItemList.jsx     |    2 
 rsf-admin/src/page/basicInfo/matnr/PrintModal.jsx                    |    9 
 rsf-admin/src/page/basicInfo/locAreaMat/LocAreaMatList.jsx           |  156 ++
 rsf-admin/src/page/basicInfo/companys/CompanysEdit.jsx               |    1 
 rsf-admin/src/page/basicInfo/locAreaMat/LocAreaMatCreate.jsx         |  137 ++
 rsf-admin/src/page/container/ContainerEdit.jsx                       |    1 
 rsf-admin/src/page/system/dicts/dictData/DictDataEdit.jsx            |    1 
 rsf-admin/src/i18n/en.js                                             |   18 
 rsf-admin/src/page/ResourceContent.js                                |    7 
 rsf-admin/.env                                                       |    4 
 rsf-admin/src/page/basicInfo/locAreaMat/LocAreaMatEdit.jsx           |  109 +
 rsf-admin/src/page/basicInfo/locArea/LocAreaList.jsx                 |    2 
 rsf-admin/src/page/components/ConfirmModal.jsx                       |   50 
 rsf-admin/src/page/system/tenant/TenantList.jsx                      |    4 
 rsf-admin/src/page/qlyInspect/QlyInspectList.jsx                     |    4 
 rsf-admin/src/page/system/dicts/dictData/DictDataList.jsx            |    2 
 rsf-admin/src/page/basicInfo/loc/InitModal.jsx                       |    2 
 rsf-admin/src/page/basicInfo/locAreaRela/LocAreaRelaList.jsx         |  154 ++
 rsf-admin/src/page/basicInfo/matnr/BindModal.jsx                     |  186 +++
 rsf-admin/src/page/basicInfo/loc/LocEdit.jsx                         |    2 
 rsf-admin/src/page/basicInfo/matnr/MatnrList.jsx                     |   28 
 rsf-admin/package-lock.json                                          |  432 +-----
 rsf-admin/src/page/basicInfo/locAreaRela/LocAreaRelaCreate.jsx       |  123 ++
 rsf-admin/src/page/basicInfo/matnrGroup/MatnrGroupCreate.jsx         |    3 
 rsf-admin/src/page/system/serialRuleItem/SerialRuleItemList.jsx      |    2 
 rsf-admin/src/page/contract/ContractEdit.jsx                         |    1 
 rsf-admin/src/page/basicInfo/locAreaMat/index.jsx                    |   18 
 rsf-admin/src/page/asnOrderItem/AsnOrderItemList.jsx                 |    2 
 rsf-admin/src/page/fieldsItem/FieldsItemList.jsx                     |    4 
 rsf-admin/src/page/basicInfo/locAreaMatRela/LocAreaMatRelaEdit.jsx   |  152 ++
 rsf-admin/src/page/qlyIsptItem/QlyIsptItemList.jsx                   |    4 
 rsf-admin/src/page/basicInfo/loc/BindModal.jsx                       |  197 +++
 rsf-admin/src/page/basicInfo/loc/LocCreate.jsx                       |    1 
 rsf-admin/src/page/basicInfo/locArea/LocAreaCreate.jsx               |    2 
 rsf-admin/src/page/basicInfo/matnrGroup/MatnrGroupEdit.jsx           |   77 
 rsf-admin/src/i18n/zh.js                                             |   20 
 rsf-admin/src/page/system/dicts/dictData/DictDataCreate.jsx          |    1 
 rsf-admin/src/page/basicInfo/warehouse/WarehouseEdit.jsx             |    1 
 rsf-admin/src/page/basicInfo/locAreaRela/index.jsx                   |   18 
 rsf-admin/src/page/system/serialRule/SerialRuleList.jsx              |    2 
 rsf-admin/src/page/basicInfo/locAreaMatRela/LocAreaMatRelaList.jsx   |  158 ++
 rsf-admin/src/page/basicInfo/locType/LocTypeEdit.jsx                 |    1 
 rsf-admin/src/page/basicInfo/locAreaRela/LocAreaRelaPanel.jsx        |   63 +
 rsf-admin/src/page/basicInfo/matnrGroup/MatnrGroupList.jsx           |    4 
 rsf-admin/src/page/basicInfo/locAreaMatRela/LocAreaMatRelaPanel.jsx  |   28 
 rsf-admin/src/page/basicInfo/loc/LocList.jsx                         |   41 
 rsf-admin/src/page/basicInfo/matnr/MatnrEdit.jsx                     |    1 
 rsf-admin/src/page/purchaseItem/PurchaseItemList.jsx                 |    2 
 rsf-admin/src/page/warehouseAreas/WarehouseAreasList.jsx             |    2 
 rsf-admin/src/page/basicInfo/locType/BindModal.jsx                   |  199 +++
 rsf-admin/src/page/system/config/ConfigList.jsx                      |    4 
 rsf-admin/src/page/basicInfo/locAreaRela/LocAreaRelaEdit.jsx         |   95 +
 rsf-admin/src/page/basicInfo/locAreaMatRela/index.jsx                |   18 
 rsf-admin/src/page/basicInfo/locAreaMat/BindMatnrModal.jsx           |  216 +++
 rsf-admin/src/page/system/dicts/dictType/DictTypeList.jsx            |    2 
 rsf-admin/src/page/basicInfo/locAreaMatRela/LocAreaMatRelaCreate.jsx |  179 ++
 rsf-admin/src/page/basicInfo/locAreaMat/LocAreaMatPanel.jsx          |  411 ++++++
 63 files changed, 3,222 insertions(+), 413 deletions(-)

diff --git a/rsf-admin/.env b/rsf-admin/.env
index ac2bce4..a8ce658 100644
--- a/rsf-admin/.env
+++ b/rsf-admin/.env
@@ -1,3 +1,3 @@
-VITE_BASE_IP=192.168.4.16
-#VITE_BASE_IP=47.76.147.249
+VITE_BASE_IP=192.168.4.24
+# VITE_BASE_IP=47.76.147.249
 VITE_BASE_PORT=8080
diff --git a/rsf-admin/package-lock.json b/rsf-admin/package-lock.json
index 2c2e71f..f731a50 100644
--- a/rsf-admin/package-lock.json
+++ b/rsf-admin/package-lock.json
@@ -23,17 +23,14 @@
         "pixi.js": "^7.4.0",
         "prop-types": "^15.8.1",
         "ra-i18n-polyglot": "^5.6.2",
-        "ra-language-chinese": "^2.0.10",
         "ra-language-english": "^5.6.2",
         "react": "^18.3.0",
-        "react-admin": "^5.6.3",
-        "react-barcode": "^1.6.1",
+        "react-admin": "^5.1.0",
         "react-dom": "^18.3.0",
         "react-hook-form": "^7.53.0",
         "react-router": "^6.22.0",
         "react-router-dom": "^6.26.1",
         "react-syntax-highlighter": "^15.5.0",
-        "react-to-print": "^3.0.5",
         "three": "^0.155.0",
         "tweedle.js": "^2.1.0"
       },
@@ -369,16 +366,15 @@
       }
     },
     "node_modules/@emotion/babel-plugin": {
-      "version": "11.13.5",
-      "resolved": "https://registry.npmmirror.com/@emotion/babel-plugin/-/babel-plugin-11.13.5.tgz",
-      "integrity": "sha512-pxHCpT2ex+0q+HH91/zsdHkw/lXd468DIN2zvfvLtPKLLMo6gQj7oLObq8PhkrxOZb/gGCq03S3Z7PDhS8pduQ==",
-      "license": "MIT",
+      "version": "11.12.0",
+      "resolved": "https://registry.npmmirror.com/@emotion/babel-plugin/-/babel-plugin-11.12.0.tgz",
+      "integrity": "sha512-y2WQb+oP8Jqvvclh8Q55gLUyb7UFvgv7eJfsj7td5TToBrIUtPay2kMrZi4xjq9qw2vD0ZR5fSho0yqoFgX7Rw==",
       "dependencies": {
         "@babel/helper-module-imports": "^7.16.7",
         "@babel/runtime": "^7.18.3",
         "@emotion/hash": "^0.9.2",
         "@emotion/memoize": "^0.9.0",
-        "@emotion/serialize": "^1.3.3",
+        "@emotion/serialize": "^1.2.0",
         "babel-plugin-macros": "^3.1.0",
         "convert-source-map": "^1.5.0",
         "escape-string-regexp": "^4.0.0",
@@ -390,14 +386,12 @@
     "node_modules/@emotion/babel-plugin/node_modules/convert-source-map": {
       "version": "1.9.0",
       "resolved": "https://registry.npmmirror.com/convert-source-map/-/convert-source-map-1.9.0.tgz",
-      "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==",
-      "license": "MIT"
+      "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A=="
     },
     "node_modules/@emotion/babel-plugin/node_modules/escape-string-regexp": {
       "version": "4.0.0",
       "resolved": "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
       "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
-      "license": "MIT",
       "engines": {
         "node": ">=10"
       },
@@ -437,17 +431,16 @@
       "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ=="
     },
     "node_modules/@emotion/react": {
-      "version": "11.14.0",
-      "resolved": "https://registry.npmmirror.com/@emotion/react/-/react-11.14.0.tgz",
-      "integrity": "sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA==",
-      "license": "MIT",
+      "version": "11.13.3",
+      "resolved": "https://registry.npmmirror.com/@emotion/react/-/react-11.13.3.tgz",
+      "integrity": "sha512-lIsdU6JNrmYfJ5EbUCf4xW1ovy5wKQ2CkPRM4xogziOxH1nXxBSjpC9YqbFAP7circxMfYp+6x676BqWcEiixg==",
       "dependencies": {
         "@babel/runtime": "^7.18.3",
-        "@emotion/babel-plugin": "^11.13.5",
-        "@emotion/cache": "^11.14.0",
-        "@emotion/serialize": "^1.3.3",
-        "@emotion/use-insertion-effect-with-fallbacks": "^1.2.0",
-        "@emotion/utils": "^1.4.2",
+        "@emotion/babel-plugin": "^11.12.0",
+        "@emotion/cache": "^11.13.0",
+        "@emotion/serialize": "^1.3.1",
+        "@emotion/use-insertion-effect-with-fallbacks": "^1.1.0",
+        "@emotion/utils": "^1.4.0",
         "@emotion/weak-memoize": "^0.4.0",
         "hoist-non-react-statics": "^3.3.1"
       },
@@ -479,17 +472,16 @@
       "integrity": "sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg=="
     },
     "node_modules/@emotion/styled": {
-      "version": "11.14.0",
-      "resolved": "https://registry.npmmirror.com/@emotion/styled/-/styled-11.14.0.tgz",
-      "integrity": "sha512-XxfOnXFffatap2IyCeJyNov3kiDQWoR08gPUQxvbL7fxKryGBKUZUkG6Hz48DZwVrJSVh9sJboyV1Ds4OW6SgA==",
-      "license": "MIT",
+      "version": "11.13.0",
+      "resolved": "https://registry.npmmirror.com/@emotion/styled/-/styled-11.13.0.tgz",
+      "integrity": "sha512-tkzkY7nQhW/zC4hztlwucpT8QEZ6eUzpXDRhww/Eej4tFfO0FxQYWRyg/c5CCXa4d/f174kqeXYjuQRnhzf6dA==",
       "dependencies": {
         "@babel/runtime": "^7.18.3",
-        "@emotion/babel-plugin": "^11.13.5",
+        "@emotion/babel-plugin": "^11.12.0",
         "@emotion/is-prop-valid": "^1.3.0",
-        "@emotion/serialize": "^1.3.3",
-        "@emotion/use-insertion-effect-with-fallbacks": "^1.2.0",
-        "@emotion/utils": "^1.4.2"
+        "@emotion/serialize": "^1.3.0",
+        "@emotion/use-insertion-effect-with-fallbacks": "^1.1.0",
+        "@emotion/utils": "^1.4.0"
       },
       "peerDependencies": {
         "@emotion/react": "^11.0.0-rc.0",
@@ -507,10 +499,9 @@
       "integrity": "sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg=="
     },
     "node_modules/@emotion/use-insertion-effect-with-fallbacks": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmmirror.com/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.2.0.tgz",
-      "integrity": "sha512-yJMtVdH59sxi/aVJBpk9FQq+OR8ll5GT8oWd57UpeaKEVGab41JWaCFA7FRLoMLloOZF/c/wsPoe+bfGmRKgDg==",
-      "license": "MIT",
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.1.0.tgz",
+      "integrity": "sha512-+wBOcIV5snwGgI2ya3u99D7/FJquOIniQT1IKyDsBmEgwvpxMNeS65Oib7OnE2d2aY+3BU4OiH+0Wchf8yk3Hw==",
       "peerDependencies": {
         "react": ">=16.8.0"
       }
@@ -1249,13 +1240,13 @@
       "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="
     },
     "node_modules/@mui/private-theming": {
-      "version": "6.4.8",
-      "resolved": "https://registry.npmmirror.com/@mui/private-theming/-/private-theming-6.4.8.tgz",
-      "integrity": "sha512-sWwQoNSn6elsPTAtSqCf+w5aaGoh7AASURNmpy+QTTD/zwJ0Jgwt0ZaaP6mXq2IcgHxYnYloM/+vJgHPMkRKTQ==",
+      "version": "6.4.6",
+      "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-6.4.6.tgz",
+      "integrity": "sha512-T5FxdPzCELuOrhpA2g4Pi6241HAxRwZudzAuL9vBvniuB5YU82HCmrARw32AuCiyTfWzbrYGGpZ4zyeqqp9RvQ==",
       "license": "MIT",
       "dependencies": {
         "@babel/runtime": "^7.26.0",
-        "@mui/utils": "^6.4.8",
+        "@mui/utils": "^6.4.6",
         "prop-types": "^15.8.1"
       },
       "engines": {
@@ -1276,13 +1267,13 @@
       }
     },
     "node_modules/@mui/private-theming/node_modules/@mui/utils": {
-      "version": "6.4.8",
-      "resolved": "https://registry.npmmirror.com/@mui/utils/-/utils-6.4.8.tgz",
-      "integrity": "sha512-C86gfiZ5BfZ51KqzqoHi1WuuM2QdSKoFhbkZeAfQRB+jCc4YNhhj11UXFVMMsqBgZ+Zy8IHNJW3M9Wj/LOwRXQ==",
+      "version": "6.4.6",
+      "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-6.4.6.tgz",
+      "integrity": "sha512-43nZeE1pJF2anGafNydUcYFPtHwAqiBiauRtaMvurdrZI3YrUjHkAu43RBsxef7OFtJMXGiHFvq43kb7lig0sA==",
       "license": "MIT",
       "dependencies": {
         "@babel/runtime": "^7.26.0",
-        "@mui/types": "~7.2.24",
+        "@mui/types": "^7.2.21",
         "@types/prop-types": "^15.7.14",
         "clsx": "^2.1.1",
         "prop-types": "^15.8.1",
@@ -1307,14 +1298,14 @@
     },
     "node_modules/@mui/private-theming/node_modules/react-is": {
       "version": "19.0.0",
-      "resolved": "https://registry.npmmirror.com/react-is/-/react-is-19.0.0.tgz",
+      "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.0.0.tgz",
       "integrity": "sha512-H91OHcwjZsbq3ClIDHMzBShc1rotbfACdWENsmEf0IFvZ3FgGPtdHMcsv45bQ1hAbgdfiA8SnxTKfDS+x/8m2g==",
       "license": "MIT"
     },
     "node_modules/@mui/styled-engine": {
-      "version": "6.4.8",
-      "resolved": "https://registry.npmmirror.com/@mui/styled-engine/-/styled-engine-6.4.8.tgz",
-      "integrity": "sha512-oyjx1b1FvUCI85ZMO4trrjNxGm90eLN3Ohy0AP/SqK5gWvRQg1677UjNf7t6iETOKAleHctJjuq0B3aXO2gtmw==",
+      "version": "6.4.6",
+      "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-6.4.6.tgz",
+      "integrity": "sha512-vSWYc9ZLX46be5gP+FCzWVn5rvDr4cXC5JBZwSIkYk9xbC7GeV+0kCvB8Q6XLFQJy+a62bbqtmdwS4Ghi9NBlQ==",
       "license": "MIT",
       "dependencies": {
         "@babel/runtime": "^7.26.0",
@@ -1346,16 +1337,16 @@
       }
     },
     "node_modules/@mui/system": {
-      "version": "6.4.8",
-      "resolved": "https://registry.npmmirror.com/@mui/system/-/system-6.4.8.tgz",
-      "integrity": "sha512-gV7iBHoqlsIenU2BP0wq14BefRoZcASZ/4LeyuQglayBl+DfLX5rEd3EYR3J409V2EZpR0NOM1LATAGlNk2cyA==",
+      "version": "6.4.7",
+      "resolved": "https://registry.npmjs.org/@mui/system/-/system-6.4.7.tgz",
+      "integrity": "sha512-7wwc4++Ak6tGIooEVA9AY7FhH2p9fvBMORT4vNLMAysH3Yus/9B9RYMbrn3ANgsOyvT3Z7nE+SP8/+3FimQmcg==",
       "license": "MIT",
       "dependencies": {
         "@babel/runtime": "^7.26.0",
-        "@mui/private-theming": "^6.4.8",
-        "@mui/styled-engine": "^6.4.8",
-        "@mui/types": "~7.2.24",
-        "@mui/utils": "^6.4.8",
+        "@mui/private-theming": "^6.4.6",
+        "@mui/styled-engine": "^6.4.6",
+        "@mui/types": "^7.2.21",
+        "@mui/utils": "^6.4.6",
         "clsx": "^2.1.1",
         "csstype": "^3.1.3",
         "prop-types": "^15.8.1"
@@ -1386,13 +1377,13 @@
       }
     },
     "node_modules/@mui/system/node_modules/@mui/utils": {
-      "version": "6.4.8",
-      "resolved": "https://registry.npmmirror.com/@mui/utils/-/utils-6.4.8.tgz",
-      "integrity": "sha512-C86gfiZ5BfZ51KqzqoHi1WuuM2QdSKoFhbkZeAfQRB+jCc4YNhhj11UXFVMMsqBgZ+Zy8IHNJW3M9Wj/LOwRXQ==",
+      "version": "6.4.6",
+      "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-6.4.6.tgz",
+      "integrity": "sha512-43nZeE1pJF2anGafNydUcYFPtHwAqiBiauRtaMvurdrZI3YrUjHkAu43RBsxef7OFtJMXGiHFvq43kb7lig0sA==",
       "license": "MIT",
       "dependencies": {
         "@babel/runtime": "^7.26.0",
-        "@mui/types": "~7.2.24",
+        "@mui/types": "^7.2.21",
         "@types/prop-types": "^15.7.14",
         "clsx": "^2.1.1",
         "prop-types": "^15.8.1",
@@ -1417,14 +1408,14 @@
     },
     "node_modules/@mui/system/node_modules/react-is": {
       "version": "19.0.0",
-      "resolved": "https://registry.npmmirror.com/react-is/-/react-is-19.0.0.tgz",
+      "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.0.0.tgz",
       "integrity": "sha512-H91OHcwjZsbq3ClIDHMzBShc1rotbfACdWENsmEf0IFvZ3FgGPtdHMcsv45bQ1hAbgdfiA8SnxTKfDS+x/8m2g==",
       "license": "MIT"
     },
     "node_modules/@mui/types": {
-      "version": "7.2.24",
-      "resolved": "https://registry.npmmirror.com/@mui/types/-/types-7.2.24.tgz",
-      "integrity": "sha512-3c8tRt/CbWZ+pEg7QpSwbdxOk36EfmhbKf6AGZsD1EcLDLTSZoxxJ86FVtcjxvjuhdyBiWKSTGZFaXCnidO2kw==",
+      "version": "7.2.21",
+      "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.21.tgz",
+      "integrity": "sha512-6HstngiUxNqLU+/DPqlUJDIPbzUBxIVHb1MmXP0eTWDIROiCR2viugXpEif0PPe2mLqqakPzzRClWAnK+8UJww==",
       "license": "MIT",
       "peerDependencies": {
         "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0"
@@ -2315,8 +2306,7 @@
     "node_modules/@types/parse-json": {
       "version": "4.0.2",
       "resolved": "https://registry.npmmirror.com/@types/parse-json/-/parse-json-4.0.2.tgz",
-      "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==",
-      "license": "MIT"
+      "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw=="
     },
     "node_modules/@types/prop-types": {
       "version": "15.7.14",
@@ -2343,11 +2333,10 @@
       }
     },
     "node_modules/@types/react-transition-group": {
-      "version": "4.4.12",
-      "resolved": "https://registry.npmmirror.com/@types/react-transition-group/-/react-transition-group-4.4.12.tgz",
-      "integrity": "sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w==",
-      "license": "MIT",
-      "peerDependencies": {
+      "version": "4.4.11",
+      "resolved": "https://registry.npmmirror.com/@types/react-transition-group/-/react-transition-group-4.4.11.tgz",
+      "integrity": "sha512-RM05tAniPZ5DZPzzNFP+DmrcOdD0efDUxMy3145oljWSl3x9ZV5vhme98gTxFrj2lhXvmGNnUiuDyJgY9IKkNA==",
+      "dependencies": {
         "@types/react": "*"
       }
     },
@@ -2356,13 +2345,6 @@
       "resolved": "https://registry.npmmirror.com/@types/semver/-/semver-7.5.8.tgz",
       "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==",
       "dev": true
-    },
-    "node_modules/@types/trusted-types": {
-      "version": "2.0.7",
-      "resolved": "https://registry.npmmirror.com/@types/trusted-types/-/trusted-types-2.0.7.tgz",
-      "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==",
-      "license": "MIT",
-      "optional": true
     },
     "node_modules/@types/unist": {
       "version": "2.0.11",
@@ -2795,10 +2777,9 @@
       "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
     },
     "node_modules/attr-accept": {
-      "version": "2.2.5",
-      "resolved": "https://registry.npmmirror.com/attr-accept/-/attr-accept-2.2.5.tgz",
-      "integrity": "sha512-0bDNnY/u6pPwHDMoF0FieU354oBi0a8rD9FcsLwzcGWbc8KS8KPIi7y+s13OlVY+gMWc/9xEMUgNE6Qm8ZllYQ==",
-      "license": "MIT",
+      "version": "2.2.2",
+      "resolved": "https://registry.npmmirror.com/attr-accept/-/attr-accept-2.2.2.tgz",
+      "integrity": "sha512-7prDjvt9HmqiZ0cl5CRjtS84sEyhsHP2coDkaZKRKVfCDo9s7iw7ChVmar78Gu9pC4SoR/28wFu/G5JJhTnqEg==",
       "engines": {
         "node": ">=4"
       }
@@ -2807,7 +2788,6 @@
       "version": "3.3.4",
       "resolved": "https://registry.npmmirror.com/autosuggest-highlight/-/autosuggest-highlight-3.3.4.tgz",
       "integrity": "sha512-j6RETBD2xYnrVcoV1S5R4t3WxOlWZKyDQjkwnggDPSjF5L4jV98ZltBpvPvbkM1HtoSe5o+bNrTHyjPbieGeYA==",
-      "license": "MIT",
       "dependencies": {
         "remove-accents": "^0.4.2"
       }
@@ -2841,7 +2821,6 @@
       "version": "3.1.0",
       "resolved": "https://registry.npmmirror.com/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz",
       "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==",
-      "license": "MIT",
       "dependencies": {
         "@babel/runtime": "^7.12.5",
         "cosmiconfig": "^7.0.0",
@@ -2853,20 +2832,16 @@
       }
     },
     "node_modules/babel-plugin-macros/node_modules/resolve": {
-      "version": "1.22.10",
-      "resolved": "https://registry.npmmirror.com/resolve/-/resolve-1.22.10.tgz",
-      "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==",
-      "license": "MIT",
+      "version": "1.22.8",
+      "resolved": "https://registry.npmmirror.com/resolve/-/resolve-1.22.8.tgz",
+      "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==",
       "dependencies": {
-        "is-core-module": "^2.16.0",
+        "is-core-module": "^2.13.0",
         "path-parse": "^1.0.7",
         "supports-preserve-symlinks-flag": "^1.0.0"
       },
       "bin": {
         "resolve": "bin/resolve"
-      },
-      "engines": {
-        "node": ">= 0.4"
       },
       "funding": {
         "url": "https://github.com/sponsors/ljharb"
@@ -3075,7 +3050,6 @@
       "version": "7.1.0",
       "resolved": "https://registry.npmmirror.com/cosmiconfig/-/cosmiconfig-7.1.0.tgz",
       "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==",
-      "license": "MIT",
       "dependencies": {
         "@types/parse-json": "^4.0.0",
         "import-fresh": "^3.2.1",
@@ -3112,8 +3086,7 @@
     "node_modules/css-mediaquery": {
       "version": "0.1.2",
       "resolved": "https://registry.npmmirror.com/css-mediaquery/-/css-mediaquery-0.1.2.tgz",
-      "integrity": "sha512-COtn4EROW5dBGlE/4PiKnh6rZpAPxDeFLaEEwt4i10jpDMFt2EhQGS79QmmrO+iKCHv0PU/HrOWEhijFd1x99Q==",
-      "license": "BSD"
+      "integrity": "sha512-COtn4EROW5dBGlE/4PiKnh6rZpAPxDeFLaEEwt4i10jpDMFt2EhQGS79QmmrO+iKCHv0PU/HrOWEhijFd1x99Q=="
     },
     "node_modules/csstype": {
       "version": "3.1.3",
@@ -3284,13 +3257,9 @@
       }
     },
     "node_modules/dompurify": {
-      "version": "3.2.4",
-      "resolved": "https://registry.npmmirror.com/dompurify/-/dompurify-3.2.4.tgz",
-      "integrity": "sha512-ysFSFEDVduQpyhzAob/kkuJjf5zWkZD8/A9ywSp1byueyuCfHamrCBa14/Oc2iiB0e51B+NpxSl5gmzn+Ms/mg==",
-      "license": "(MPL-2.0 OR Apache-2.0)",
-      "optionalDependencies": {
-        "@types/trusted-types": "^2.0.7"
-      }
+      "version": "2.5.6",
+      "resolved": "https://registry.npmmirror.com/dompurify/-/dompurify-2.5.6.tgz",
+      "integrity": "sha512-zUTaUBO8pY4+iJMPE1B9XlO2tXVYIcEA4SNGtvDELzTSCQO7RzH+j7S180BmhmJId78lqGU2z19vgVx2Sxs/PQ=="
     },
     "node_modules/earcut": {
       "version": "2.2.4",
@@ -3307,7 +3276,6 @@
       "version": "1.3.2",
       "resolved": "https://registry.npmmirror.com/error-ex/-/error-ex-1.3.2.tgz",
       "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
-      "license": "MIT",
       "dependencies": {
         "is-arrayish": "^0.2.1"
       }
@@ -3945,22 +3913,20 @@
       }
     },
     "node_modules/file-selector": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmmirror.com/file-selector/-/file-selector-2.1.2.tgz",
-      "integrity": "sha512-QgXo+mXTe8ljeqUFaX3QVHc5osSItJ/Km+xpocx0aSqWGMSCf6qYs/VnzZgS864Pjn5iceMRFigeAV7AfTlaig==",
-      "license": "MIT",
+      "version": "0.6.0",
+      "resolved": "https://registry.npmmirror.com/file-selector/-/file-selector-0.6.0.tgz",
+      "integrity": "sha512-QlZ5yJC0VxHxQQsQhXvBaC7VRJ2uaxTf+Tfpu4Z/OcVQJVpZO+DGU0rkoVW5ce2SccxugvpBJoMvUs59iILYdw==",
       "dependencies": {
-        "tslib": "^2.7.0"
+        "tslib": "^2.4.0"
       },
       "engines": {
         "node": ">= 12"
       }
     },
     "node_modules/file-selector/node_modules/tslib": {
-      "version": "2.8.1",
-      "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.8.1.tgz",
-      "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
-      "license": "0BSD"
+      "version": "2.6.3",
+      "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.6.3.tgz",
+      "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ=="
     },
     "node_modules/fill-range": {
       "version": "7.1.1",
@@ -3985,8 +3951,7 @@
     "node_modules/find-root": {
       "version": "1.1.0",
       "resolved": "https://registry.npmmirror.com/find-root/-/find-root-1.1.0.tgz",
-      "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==",
-      "license": "MIT"
+      "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng=="
     },
     "node_modules/find-up": {
       "version": "5.0.0",
@@ -4416,6 +4381,11 @@
         "react-is": "^16.7.0"
       }
     },
+    "node_modules/hotscript": {
+      "version": "1.0.13",
+      "resolved": "https://registry.npmmirror.com/hotscript/-/hotscript-1.0.13.tgz",
+      "integrity": "sha512-C++tTF1GqkGYecL+2S1wJTfoH6APGAsbb7PAWQ3iVIwgG/EFseAfEVOKFgAFq4yK3+6j1EjUD4UQ9dRJHX/sSQ=="
+    },
     "node_modules/ignore": {
       "version": "5.3.2",
       "resolved": "https://registry.npmmirror.com/ignore/-/ignore-5.3.2.tgz",
@@ -4529,8 +4499,7 @@
     "node_modules/is-arrayish": {
       "version": "0.2.1",
       "resolved": "https://registry.npmmirror.com/is-arrayish/-/is-arrayish-0.2.1.tgz",
-      "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
-      "license": "MIT"
+      "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg=="
     },
     "node_modules/is-async-function": {
       "version": "2.0.0",
@@ -4588,10 +4557,9 @@
       }
     },
     "node_modules/is-core-module": {
-      "version": "2.16.1",
-      "resolved": "https://registry.npmmirror.com/is-core-module/-/is-core-module-2.16.1.tgz",
-      "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==",
-      "license": "MIT",
+      "version": "2.15.1",
+      "resolved": "https://registry.npmmirror.com/is-core-module/-/is-core-module-2.15.1.tgz",
+      "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==",
       "dependencies": {
         "hasown": "^2.0.2"
       },
@@ -4930,12 +4898,6 @@
         "js-yaml": "bin/js-yaml.js"
       }
     },
-    "node_modules/jsbarcode": {
-      "version": "3.11.6",
-      "resolved": "https://registry.npmmirror.com/jsbarcode/-/jsbarcode-3.11.6.tgz",
-      "integrity": "sha512-G5TKGyKY1zJo0ZQKFM1IIMfy0nF2rs92BLlCz+cU4/TazIc4ZH+X1GYeDRt7TKjrYqmPfTjwTBkU/QnQlsYiuA==",
-      "license": "MIT"
-    },
     "node_modules/jsesc": {
       "version": "2.5.2",
       "resolved": "https://registry.npmmirror.com/jsesc/-/jsesc-2.5.2.tgz",
@@ -4956,8 +4918,7 @@
     "node_modules/json-parse-even-better-errors": {
       "version": "2.3.1",
       "resolved": "https://registry.npmmirror.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
-      "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
-      "license": "MIT"
+      "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w=="
     },
     "node_modules/json-schema-traverse": {
       "version": "0.4.1",
@@ -5031,8 +4992,7 @@
     "node_modules/lines-and-columns": {
       "version": "1.2.4",
       "resolved": "https://registry.npmmirror.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
-      "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
-      "license": "MIT"
+      "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="
     },
     "node_modules/locate-path": {
       "version": "6.0.0",
@@ -5438,7 +5398,6 @@
       "version": "5.2.0",
       "resolved": "https://registry.npmmirror.com/parse-json/-/parse-json-5.2.0.tgz",
       "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
-      "license": "MIT",
       "dependencies": {
         "@babel/code-frame": "^7.0.0",
         "error-ex": "^1.3.1",
@@ -5746,12 +5705,6 @@
         "ra-core": "^5.6.3"
       }
     },
-    "node_modules/ra-language-chinese": {
-      "version": "2.0.10",
-      "resolved": "https://registry.npmmirror.com/ra-language-chinese/-/ra-language-chinese-2.0.10.tgz",
-      "integrity": "sha512-k+X6XdkBEZnmpKIJZj9Lb77Lj8LCmterilJTj2ovp3i8/H/dLo9IujASfjFypjHnVUpN7Y63LT19kgPrS6+row==",
-      "license": "MIT"
-    },
     "node_modules/ra-language-english": {
       "version": "5.6.3",
       "resolved": "https://registry.npmjs.org/ra-language-english/-/ra-language-english-5.6.3.tgz",
@@ -5778,154 +5731,38 @@
       }
     },
     "node_modules/react-admin": {
-      "version": "5.6.3",
-      "resolved": "https://registry.npmmirror.com/react-admin/-/react-admin-5.6.3.tgz",
-      "integrity": "sha512-nZAlX1uRKgQKAQcOxMwugkjbDL7CPuU799lxoaxLK59O7AbkQl161uVqWLNUo4eaZRCpXCVqIe2an4lGlxs10g==",
-      "license": "MIT",
+      "version": "5.1.2",
+      "resolved": "https://registry.npmmirror.com/react-admin/-/react-admin-5.1.2.tgz",
+      "integrity": "sha512-f3L0XVEQrmMx5kbaApbE4GDJA5oSz9MPORlBD2ZHdVqcTJCfkbbDpR5McTT6Je6QRT8KSrOdWhcJQc3UTdHFyw==",
       "dependencies": {
-        "@emotion/react": "^11.14.0",
-        "@emotion/styled": "^11.14.0",
-        "@mui/icons-material": "^5.16.12 || ^6.0.0",
-        "@mui/material": "^5.16.12 || ^6.0.0",
-        "ra-core": "^5.6.3",
-        "ra-i18n-polyglot": "^5.6.3",
-        "ra-language-english": "^5.6.3",
-        "ra-ui-materialui": "^5.6.3",
-        "react-hook-form": "^7.53.0",
-        "react-router": "^6.28.1 || ^7.1.1",
-        "react-router-dom": "^6.28.1 || ^7.1.1"
+        "@emotion/react": "^11.4.1",
+        "@emotion/styled": "^11.3.0",
+        "@mui/icons-material": "^5.15.20",
+        "@mui/material": "^5.15.20",
+        "ra-core": "^5.1.2",
+        "ra-i18n-polyglot": "^5.1.2",
+        "ra-language-english": "^5.1.2",
+        "ra-ui-materialui": "^5.1.2",
+        "react-hook-form": "^7.52.0",
+        "react-router": "^6.22.0",
+        "react-router-dom": "^6.22.0"
       },
       "peerDependencies": {
         "react": "^18.0.0 || ^19.0.0",
         "react-dom": "^18.0.0 || ^19.0.0"
       }
     },
-    "node_modules/react-admin/node_modules/@mui/core-downloads-tracker": {
-      "version": "6.4.8",
-      "resolved": "https://registry.npmmirror.com/@mui/core-downloads-tracker/-/core-downloads-tracker-6.4.8.tgz",
-      "integrity": "sha512-vjP4+A1ybyCRhDZC7r5EPWu/gLseFZxaGyPdDl94vzVvk6Yj6gahdaqcjbhkaCrJjdZj90m3VioltWPAnWF/zw==",
-      "license": "MIT",
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/mui-org"
-      }
-    },
-    "node_modules/react-admin/node_modules/@mui/icons-material": {
-      "version": "6.4.8",
-      "resolved": "https://registry.npmmirror.com/@mui/icons-material/-/icons-material-6.4.8.tgz",
-      "integrity": "sha512-LKGWiLWRyoOw3dWxZQ+lV//mK+4DVTTAiLd2ljmJdD6XV0rDB8JFKjRD9nyn9cJAU5XgWnii7ZR3c93ttUnMKg==",
-      "license": "MIT",
-      "dependencies": {
-        "@babel/runtime": "^7.26.0"
-      },
-      "engines": {
-        "node": ">=14.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/mui-org"
-      },
-      "peerDependencies": {
-        "@mui/material": "^6.4.8",
-        "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0",
-        "react": "^17.0.0 || ^18.0.0 || ^19.0.0"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/react-admin/node_modules/@mui/material": {
-      "version": "6.4.8",
-      "resolved": "https://registry.npmmirror.com/@mui/material/-/material-6.4.8.tgz",
-      "integrity": "sha512-5S9UTjKZZBd9GfbcYh/nYfD9cv6OXmj5Y7NgKYfk7JcSoshp8/pW5zP4wecRiroBSZX8wcrywSgogpVNO+5W0Q==",
-      "license": "MIT",
-      "dependencies": {
-        "@babel/runtime": "^7.26.0",
-        "@mui/core-downloads-tracker": "^6.4.8",
-        "@mui/system": "^6.4.8",
-        "@mui/types": "~7.2.24",
-        "@mui/utils": "^6.4.8",
-        "@popperjs/core": "^2.11.8",
-        "@types/react-transition-group": "^4.4.12",
-        "clsx": "^2.1.1",
-        "csstype": "^3.1.3",
-        "prop-types": "^15.8.1",
-        "react-is": "^19.0.0",
-        "react-transition-group": "^4.4.5"
-      },
-      "engines": {
-        "node": ">=14.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/mui-org"
-      },
-      "peerDependencies": {
-        "@emotion/react": "^11.5.0",
-        "@emotion/styled": "^11.3.0",
-        "@mui/material-pigment-css": "^6.4.8",
-        "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0",
-        "react": "^17.0.0 || ^18.0.0 || ^19.0.0",
-        "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0"
-      },
-      "peerDependenciesMeta": {
-        "@emotion/react": {
-          "optional": true
-        },
-        "@emotion/styled": {
-          "optional": true
-        },
-        "@mui/material-pigment-css": {
-          "optional": true
-        },
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/react-admin/node_modules/@mui/utils": {
-      "version": "6.4.8",
-      "resolved": "https://registry.npmmirror.com/@mui/utils/-/utils-6.4.8.tgz",
-      "integrity": "sha512-C86gfiZ5BfZ51KqzqoHi1WuuM2QdSKoFhbkZeAfQRB+jCc4YNhhj11UXFVMMsqBgZ+Zy8IHNJW3M9Wj/LOwRXQ==",
-      "license": "MIT",
-      "dependencies": {
-        "@babel/runtime": "^7.26.0",
-        "@mui/types": "~7.2.24",
-        "@types/prop-types": "^15.7.14",
-        "clsx": "^2.1.1",
-        "prop-types": "^15.8.1",
-        "react-is": "^19.0.0"
-      },
-      "engines": {
-        "node": ">=14.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/mui-org"
-      },
-      "peerDependencies": {
-        "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0",
-        "react": "^17.0.0 || ^18.0.0 || ^19.0.0"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
     "node_modules/react-admin/node_modules/ra-ui-materialui": {
-      "version": "5.6.3",
-      "resolved": "https://registry.npmmirror.com/ra-ui-materialui/-/ra-ui-materialui-5.6.3.tgz",
-      "integrity": "sha512-3KOCo0JWBJ5BeqVb8g1cdnw00+GMnpI7jlX1VqX7YIyDT3TwDbFx1sDGUOvNiLrN7qZA5dIrZWfdYlutjZT/2Q==",
-      "license": "MIT",
+      "version": "5.1.2",
+      "resolved": "https://registry.npmmirror.com/ra-ui-materialui/-/ra-ui-materialui-5.1.2.tgz",
+      "integrity": "sha512-hhR5+NCC5tDNB6WtPl2sY7mKAqfs4A0S+x2Kh/GsYYxs7nFIRFIBMu7UE40vpVJqFrBCc2fyVB/3d9D2eEdoZA==",
       "dependencies": {
-        "@tanstack/react-query": "^5.21.7",
+        "@tanstack/react-query": "^5.8.4",
         "autosuggest-highlight": "^3.1.1",
         "clsx": "^2.1.1",
         "css-mediaquery": "^0.1.2",
-        "dompurify": "^3.2.4",
+        "dompurify": "^2.4.3",
+        "hotscript": "^1.0.12",
         "inflection": "^3.0.0",
         "jsonexport": "^3.2.0",
         "lodash": "~4.17.5",
@@ -5935,36 +5772,22 @@
         "react-transition-group": "^4.4.5"
       },
       "peerDependencies": {
-        "@mui/icons-material": "^5.16.12 || ^6.0.0",
-        "@mui/material": "^5.16.12 || ^6.0.0",
-        "@mui/utils": "^5.15.20 || ^6.0.0",
+        "@mui/icons-material": "^5.15.20",
+        "@mui/material": "^5.15.20",
         "ra-core": "^5.0.0",
         "react": "^18.0.0 || ^19.0.0",
         "react-dom": "^18.0.0 || ^19.0.0",
         "react-hook-form": "*",
-        "react-is": "^18.0.0 || ^19.0.0",
-        "react-router": "^6.28.1 || ^7.1.1",
-        "react-router-dom": "^6.28.1 || ^7.1.1"
+        "react-is": "^18.0.0",
+        "react-router": "^6.22.0",
+        "react-router-dom": "^6.22.0"
       }
     },
     "node_modules/react-admin/node_modules/react-is": {
-      "version": "19.0.0",
-      "resolved": "https://registry.npmmirror.com/react-is/-/react-is-19.0.0.tgz",
-      "integrity": "sha512-H91OHcwjZsbq3ClIDHMzBShc1rotbfACdWENsmEf0IFvZ3FgGPtdHMcsv45bQ1hAbgdfiA8SnxTKfDS+x/8m2g==",
-      "license": "MIT"
-    },
-    "node_modules/react-barcode": {
-      "version": "1.6.1",
-      "resolved": "https://registry.npmmirror.com/react-barcode/-/react-barcode-1.6.1.tgz",
-      "integrity": "sha512-pc4ftnO5syHa/UjCruEeRsomlhoxKSugIgTA8T4dH0fvc89UMHL+/1Sp25IAphqG44pJkE5hMXhv89iS09jQyw==",
-      "license": "ISC",
-      "dependencies": {
-        "jsbarcode": "^3.8.0",
-        "prop-types": "^15.6.2"
-      },
-      "peerDependencies": {
-        "react": "16 - 19"
-      }
+      "version": "18.3.1",
+      "resolved": "https://registry.npmmirror.com/react-is/-/react-is-18.3.1.tgz",
+      "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
+      "peer": true
     },
     "node_modules/react-dom": {
       "version": "18.3.1",
@@ -5979,13 +5802,12 @@
       }
     },
     "node_modules/react-dropzone": {
-      "version": "14.3.8",
-      "resolved": "https://registry.npmmirror.com/react-dropzone/-/react-dropzone-14.3.8.tgz",
-      "integrity": "sha512-sBgODnq+lcA4P296DY4wacOZz3JFpD99fp+hb//iBO2HHnyeZU3FwWyXJ6salNpqQdsZrgMrotuko/BdJMV8Ug==",
-      "license": "MIT",
+      "version": "14.2.3",
+      "resolved": "https://registry.npmmirror.com/react-dropzone/-/react-dropzone-14.2.3.tgz",
+      "integrity": "sha512-O3om8I+PkFKbxCukfIR3QAGftYXDZfOE2N1mr/7qebQJHs7U+/RSL/9xomJNpRg9kM5h9soQSdf0Gc7OHF5Fug==",
       "dependencies": {
-        "attr-accept": "^2.2.4",
-        "file-selector": "^2.1.0",
+        "attr-accept": "^2.2.2",
+        "file-selector": "^0.6.0",
         "prop-types": "^15.8.1"
       },
       "engines": {
@@ -6125,15 +5947,6 @@
         "react": ">= 0.14.0"
       }
     },
-    "node_modules/react-to-print": {
-      "version": "3.0.5",
-      "resolved": "https://registry.npmmirror.com/react-to-print/-/react-to-print-3.0.5.tgz",
-      "integrity": "sha512-Z15MwMOzYCHWi26CZeFNwflAg7Nr8uWD6FTj+EkfIOjYyjr0MXGbI0c7rF4Fgrbj3XG9hFndb1ourxpPz2RAiA==",
-      "license": "MIT",
-      "peerDependencies": {
-        "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ~19"
-      }
-    },
     "node_modules/react-transition-group": {
       "version": "4.4.5",
       "resolved": "https://registry.npmmirror.com/react-transition-group/-/react-transition-group-4.4.5.tgz",
@@ -6226,8 +6039,7 @@
     "node_modules/remove-accents": {
       "version": "0.4.4",
       "resolved": "https://registry.npmmirror.com/remove-accents/-/remove-accents-0.4.4.tgz",
-      "integrity": "sha512-EpFcOa/ISetVHEXqu+VwI96KZBmq+a8LJnGkaeFw45epGlxIZz5dhEEnNZMsQXgORu3qaMoLX4qJCzOik6ytAg==",
-      "license": "MIT"
+      "integrity": "sha512-EpFcOa/ISetVHEXqu+VwI96KZBmq+a8LJnGkaeFw45epGlxIZz5dhEEnNZMsQXgORu3qaMoLX4qJCzOik6ytAg=="
     },
     "node_modules/reselect": {
       "version": "5.1.1",
@@ -6481,7 +6293,6 @@
       "version": "0.5.7",
       "resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.5.7.tgz",
       "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==",
-      "license": "BSD-3-Clause",
       "engines": {
         "node": ">=0.10.0"
       }
@@ -7115,7 +6926,6 @@
       "version": "1.10.2",
       "resolved": "https://registry.npmmirror.com/yaml/-/yaml-1.10.2.tgz",
       "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==",
-      "license": "ISC",
       "engines": {
         "node": ">= 6"
       }
diff --git a/rsf-admin/src/i18n/en.js b/rsf-admin/src/i18n/en.js
index cb54b18..fe02573 100644
--- a/rsf-admin/src/i18n/en.js
+++ b/rsf-admin/src/i18n/en.js
@@ -129,6 +129,8 @@
         loc: 'Loc',
         locType: 'LocType',
         locArea: 'locArea',
+        LocAreaMat: 'LocAreaMat',
+        locAreaMatRela: 'LocAreaMatRela',
         container: 'Container',
         contract: 'Contract',
         qlyInspect: 'QlyInspect',
@@ -367,6 +369,18 @@
                 name: "name",
                 code: "code",
                 areaId: "areaId",
+                locId: "locId",
+            },
+            locAreaMat: {
+                code: "code",
+                depict: "depict",
+            },
+            locAreaMatRela: {
+                areaId: "areaId",
+                code: "code",
+                matnrId: "matnrId",
+                groupId: "groupId",
+                locTypeId: "locTypeId",
                 locId: "locId",
             },
             container: {
@@ -627,7 +641,9 @@
         locInit: 'loc init',
         batch: 'batch',
         confirm: 'confirm',
-        subzone: 'subzone'
+        subzone: 'subzone',
+        bindmatnr: 'bind matnr',
+        bindloc: 'bind loc',
     },
 };
 
diff --git a/rsf-admin/src/i18n/zh.js b/rsf-admin/src/i18n/zh.js
index 2f2f96b..f6dd347 100644
--- a/rsf-admin/src/i18n/zh.js
+++ b/rsf-admin/src/i18n/zh.js
@@ -129,6 +129,8 @@
         loc: '搴撲綅',
         locType: '搴撲綅绫诲瀷',
         locArea: '閫昏緫鍒嗗尯',
+        locAreaMat: '閫昏緫鍒嗗尯',
+        locAreaMatRela: '搴撳尯鐗╂枡鍏崇郴',
         container: '瀹瑰櫒绠$悊',
         contract: '鍚堝悓淇℃伅',
         qlyInspect: '璐ㄦ淇℃伅',
@@ -299,7 +301,7 @@
             warehouseAreas: {
                 uuid: "鍞竴缂栫爜",
                 name: "鍚嶇О",
-                wareId: "浠撳簱",
+                wareId: "鎵�灞炰粨搴�",
                 code: "缂栫爜",
                 shipperId: "璐т富",
                 supplierId: "渚涘簲鍟�",
@@ -367,6 +369,18 @@
                 name: "鍚嶇О",
                 code: "缂栫爜",
                 areaId: "搴撳尯",
+                locId: "搴撲綅",
+            },
+            locAreaMat: {
+                code: "閫昏緫缂栫爜",
+                depict: "閫昏緫鎻忚堪",
+            },
+            locAreaMatRela: {
+                areaId: "搴撳尯",
+                code: "缂栫爜",
+                matnrId: "鐗╂枡",
+                groupId: "鐗╂枡鍒嗙粍",
+                locTypeId: "搴撲綅绫诲瀷",
                 locId: "搴撲綅",
             },
             container: {
@@ -629,7 +643,9 @@
         locInit: '聽搴撲綅鍒濆鍖�',
         batch: '鎵归噺鎿嶄綔',
         confirm: '纭',
-        subzone: '缁戝畾鍒嗗尯'
+        subzone: '缁戝畾鍒嗗尯',
+        bindmatnr: '缁戝畾鐗╂枡',
+        bindloc: '缁戝畾搴撲綅',
     },
 };
 
diff --git a/rsf-admin/src/page/ResourceContent.js b/rsf-admin/src/page/ResourceContent.js
index b5b46b3..fb93236 100644
--- a/rsf-admin/src/page/ResourceContent.js
+++ b/rsf-admin/src/page/ResourceContent.js
@@ -27,6 +27,8 @@
 import companys from './basicInfo/companys';
 import locType from './basicInfo/locType';
 import locArea from './basicInfo//locArea';
+import locAreaMatRela from './basicInfo/locAreaMatRela';
+import locAreaMat from './basicInfo/locAreaMat';
 import serialRuleItem from './system/serialRuleItem';
 import serialRule from './system/serialRule';
 import whMat from './basicInfo/whMat';
@@ -106,6 +108,11 @@
             return locType;
         case 'locArea':
             return locArea;
+        case 'locAreaMatRela':
+            return locAreaMatRela;
+        case 'locAreaMat':
+            return locAreaMat;
+
 
         default:
             return {
diff --git a/rsf-admin/src/page/asnOrderItem/AsnOrderItemList.jsx b/rsf-admin/src/page/asnOrderItem/AsnOrderItemList.jsx
index c9a8366..c159ad9 100644
--- a/rsf-admin/src/page/asnOrderItem/AsnOrderItemList.jsx
+++ b/rsf-admin/src/page/asnOrderItem/AsnOrderItemList.jsx
@@ -142,8 +142,6 @@
             preferenceKey='asnOrderItem'
             bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />}
             rowClick={(id, resource, record) => false}
-            expand={() => <AsnOrderItemPanel />}
-            expandSingle={true}
             omit={['id', 'createTime', 'createBy', 'memo']}
           >
             <NumberField source="id" />
diff --git a/rsf-admin/src/page/basicInfo/companys/CompanysEdit.jsx b/rsf-admin/src/page/basicInfo/companys/CompanysEdit.jsx
index 72e465e..741ecf7 100644
--- a/rsf-admin/src/page/basicInfo/companys/CompanysEdit.jsx
+++ b/rsf-admin/src/page/basicInfo/companys/CompanysEdit.jsx
@@ -50,6 +50,7 @@
             mutationMode={EDIT_MODE}
             actions={<CustomerTopToolBar />}
             aside={<EditBaseAside />}
+            title={"menu.companys"}
         >
             <SimpleForm
                 shouldUnregister
diff --git a/rsf-admin/src/page/basicInfo/loc/BindModal.jsx b/rsf-admin/src/page/basicInfo/loc/BindModal.jsx
new file mode 100644
index 0000000..04cd607
--- /dev/null
+++ b/rsf-admin/src/page/basicInfo/loc/BindModal.jsx
@@ -0,0 +1,197 @@
+import React, { useState, useRef, useEffect, useMemo } from "react";
+import {
+    CreateBase,
+    useTranslate,
+    TextInput,
+    NumberInput,
+    BooleanInput,
+    DateInput,
+    SaveButton,
+    SelectInput,
+    ReferenceInput,
+    ReferenceArrayInput,
+    AutocompleteInput,
+    Toolbar,
+    required,
+    useDataProvider,
+    useNotify,
+    Form,
+    useCreateController,
+    useListContext,
+    useRefresh,
+    SelectArrayInput
+} from 'react-admin';
+import {
+    Dialog,
+    DialogActions,
+    DialogContent,
+    DialogTitle,
+    Grid,
+    TextField,
+    Box,
+    Button,
+    Paper,
+    TableContainer,
+    Table,
+    TableHead,
+    TableBody,
+    TableRow,
+    TableCell,
+    Tooltip,
+    IconButton,
+    styled,
+
+} from '@mui/material';
+import DialogCloseButton from "../../components/DialogCloseButton";
+import DictionarySelect from "../../components/DictionarySelect";
+import { useForm, Controller, useWatch, FormProvider, useFormContext } from "react-hook-form";
+import SaveIcon from '@mui/icons-material/Save';
+import request from '@/utils/request';
+import { Add, Edit, Delete } from '@mui/icons-material';
+import _ from 'lodash';
+import { DataGrid } from '@mui/x-data-grid';
+import StatusSelectInput from "../../components/StatusSelectInput";
+import TreeSelectInput from "@/page/components/TreeSelectInput";
+const MatnrModal = ({ open, setOpen }) => {
+    const refresh = useRefresh();
+    const translate = useTranslate();
+
+
+    const notify = useNotify();
+
+    const [formData, setFormData] = useState({
+        areaId: null,
+        groupId: null,
+        matnrId: null,
+    });
+
+    const { selectedIds, onUnselectItems } = useListContext();
+
+    const handleClose = (event, reason) => {
+        if (reason !== "backdropClick") {
+            setOpen(false);
+            reset()
+            refresh();
+            onUnselectItems()
+        }
+    };
+
+    const reset = () => {
+        setFormData({
+            areaId: null,
+            groupId: null,
+            matnrId: null,
+        })
+    }
+
+    const handleReset = (e) => {
+        e.preventDefault();
+    };
+
+    const handleChange = (value, name) => {
+        setFormData((prevData) => ({
+            ...prevData,
+            [name]: value
+        }));
+        refresh()
+    };
+
+    const removeEmptyKeys = (obj) => {
+        return _.pickBy(obj, (value) => {
+            if (_.isObject(value)) {
+                const newObj = removeEmptyKeys(value);
+                return !_.isEmpty(newObj);
+            }
+            return !_.isNil(value) && (_.isNumber(value) ? value !== 0 : !_.isEmpty(value));
+        });
+    }
+
+    const handleSubmit = async () => {
+        const parmas = {
+            locId: selectedIds,
+            areaId: formData.areaId,
+            matnrId: formData.matnrId,
+        }
+
+        const res = await request.post(`/locAreaMatRela/matnr/bind`, parmas);
+        if (res?.data?.code === 200) {
+            handleClose()
+
+        } else {
+            notify(res.data.msg);
+        }
+
+
+    }
+
+    const [groupId, setGroupId] = useState();
+
+    const warehouseChange = (e) => {
+        setGroupId(e.target.value)
+    }
+
+    return (
+        <Dialog open={open} maxWidth="md" fullWidth>
+            <Form onSubmit={handleSubmit}>
+                <DialogCloseButton onClose={handleClose} />
+                <DialogTitle>{translate('toolbar.bindmatnr')}</DialogTitle>
+                <DialogContent sx={{ mt: 2 }}>
+                    <Box sx={{ display: 'flex', flexDirection: 'column', gap: 3 }}>
+                        <Grid container spacing={2}>
+                            <Grid item xs={4}>
+                                <ReferenceInput
+                                    source="areaId"
+                                    reference="warehouseAreas"
+                                >
+                                    <AutocompleteInput
+                                        label="table.field.loc.areaId"
+                                        optionText="name"
+                                        onChange={(value) => handleChange(value, 'areaId')}
+                                        value={formData.areaId}
+                                        validate={required()}
+                                        filterToQuery={(val) => ({ name: val })}
+                                    />
+                                </ReferenceInput>
+
+                            </Grid>
+
+                            <Grid item xs={4}>
+                                <TreeSelectInput
+                                    label="table.field.locAreaMatRela.groupId"
+                                    resource={'matnrGroup'}
+                                    source="groupId"
+                                    value={formData.groupId}
+                                    onChange={(e) => handleChange(e.target.value, 'groupId')}
+                                />
+                            </Grid>
+
+
+                            <Grid item xs={4}>
+                                <ReferenceArrayInput source="matnrId" reference="matnr" filter={{ groupId: formData.groupId }}>
+                                    <SelectArrayInput
+                                        label="table.field.locAreaMatRela.matnrId"
+                                        validate={required()}
+                                        value={formData.matnrId}
+                                        onChange={(e) => handleChange(e.target.value, 'matnrId')}
+                                    />
+                                </ReferenceArrayInput>
+
+                            </Grid>
+
+                        </Grid>
+
+                    </Box>
+                </DialogContent>
+                <DialogActions sx={{ position: 'sticky', bottom: 0, backgroundColor: 'background.paper', zIndex: 1000 }}>
+                    <Box sx={{ width: '100%', display: 'flex', justifyContent: 'space-between' }}>
+                        <Button type="submit" variant="contained" startIcon={<SaveIcon />}>
+                            {translate('toolbar.confirm')}
+                        </Button>
+                    </Box>
+                </DialogActions>
+            </Form>
+        </Dialog>
+    );
+}
+
+export default MatnrModal;
\ No newline at end of file
diff --git a/rsf-admin/src/page/basicInfo/loc/InitModal.jsx b/rsf-admin/src/page/basicInfo/loc/InitModal.jsx
index 16a287a..931b943 100644
--- a/rsf-admin/src/page/basicInfo/loc/InitModal.jsx
+++ b/rsf-admin/src/page/basicInfo/loc/InitModal.jsx
@@ -153,7 +153,7 @@
 
                             <Grid item xs={4}>
                                 <ReferenceArrayInput source="typeIds" reference="locType" >
-                                    <SelectArrayInput label="table.field.loc.type" onChange={(e) => handleChange(e.target.value, 'typeIds')} />
+                                    <SelectArrayInput label="table.field.loc.type" onChange={(e) => handleChange(e.target.value, 'typeIds')} validate={[required()]} />
                                 </ReferenceArrayInput>
                             </Grid>
 
diff --git a/rsf-admin/src/page/basicInfo/loc/LocCreate.jsx b/rsf-admin/src/page/basicInfo/loc/LocCreate.jsx
index e5eb67a..23465f9 100644
--- a/rsf-admin/src/page/basicInfo/loc/LocCreate.jsx
+++ b/rsf-admin/src/page/basicInfo/loc/LocCreate.jsx
@@ -270,6 +270,7 @@
                                         label={translate("table.field.loc.useStatus")}
                                         name="useStatus"
                                         size="small"
+                                        validate={[required()]}
                                         dictTypeCode="sys_loc_use_stas"
                                     />
                                     {/* <ReferenceInput
diff --git a/rsf-admin/src/page/basicInfo/loc/LocEdit.jsx b/rsf-admin/src/page/basicInfo/loc/LocEdit.jsx
index 5c640c5..5b1182e 100644
--- a/rsf-admin/src/page/basicInfo/loc/LocEdit.jsx
+++ b/rsf-admin/src/page/basicInfo/loc/LocEdit.jsx
@@ -59,6 +59,7 @@
             mutationMode={EDIT_MODE}
             actions={<CustomerTopToolBar />}
             aside={<EditBaseAside />}
+            title={"menu.loc"}
         >
             <SimpleForm
                 shouldUnregister
@@ -177,6 +178,7 @@
                                 <DictionarySelect
                                     label={translate("table.field.loc.useStatus")}
                                     name="useStatus"
+                                    validate={[required()]}
                                     size="small"
                                     dictTypeCode="sys_loc_use_stas"
                                 />
diff --git a/rsf-admin/src/page/basicInfo/loc/LocList.jsx b/rsf-admin/src/page/basicInfo/loc/LocList.jsx
index d07243d..449dc0f 100644
--- a/rsf-admin/src/page/basicInfo/loc/LocList.jsx
+++ b/rsf-admin/src/page/basicInfo/loc/LocList.jsx
@@ -38,7 +38,7 @@
 import { Box, Typography, Card, Stack } from '@mui/material';
 import { styled } from '@mui/material/styles';
 import LocCreate from "./LocCreate";
-import LocPanel from "./LocPanel";
+import BindModal from "./BindModal";
 import EmptyData from "../../components/EmptyData";
 import DynamicField from "../../components/DynamicField";
 import MyCreateButton from "../../components/MyCreateButton";
@@ -54,7 +54,7 @@
 import EditIcon from '@mui/icons-material/Edit';
 import request from '@/utils/request';
 import DiscountIcon from '@mui/icons-material/Discount';
-import { textAlign } from "@mui/system";
+import LinkIcon from '@mui/icons-material/Link';
 
 const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({
     '& .css-1vooibu-MuiSvgIcon-root': {
@@ -70,14 +70,17 @@
     },
     '& .RaDatagrid-headerCell': {
         textAlign: 'left'
+    },
+    '& .RaDatagrid-rowCell': {
+        textAlign: 'left'
     }
 }));
 
 const filters = [
     <SearchInput source="condition" alwaysOn />,
 
-    <NumberField source="warehouseId$" label="table.field.loc.warehouseId" />,
-    <NumberField source="areaId$" label="table.field.loc.areaId" />,
+    <TextInput source="warehouseId$" label="table.field.loc.warehouseId" />,
+    <TextInput source="areaId$" label="table.field.loc.areaId" />,
     <TextInput source="code" label="table.field.loc.code" />,
     <TextInput source="type" label="table.field.loc.type" />,
     <TextInput source="name" label="table.field.loc.name" />,
@@ -148,6 +151,7 @@
                     bulkActionButtons={
                         <>
                             <BatchButton />
+                            <BindButton />
                             <SubzoneButton />
                             <BulkDeleteButton />
                         </>
@@ -157,9 +161,9 @@
                 >
                     <NumberField source="id" />
                     <NumberField source="warehouseId$" label="table.field.loc.warehouseId" />
-                    <NumberField source="areaId$" label="table.field.loc.areaId" align="left" />
-                    <TextField source="code" label="table.field.loc.code" align="left" />
-                    <TextField source="typeIds$" label="table.field.loc.type" align="left" />
+                    <NumberField source="areaId$" label="table.field.loc.areaId" />
+                    <TextField source="code" label="table.field.loc.code" />
+                    <TextField source="typeIds$" label="table.field.loc.type" />
                     {/* <TextField source="name" label="table.field.loc.name" /> */}
                     {/* <NumberField source="flagLogic" label="table.field.loc.flagLogic" />
                     <TextField source="fucAtrrs" label="table.field.loc.fucAtrrs" />
@@ -282,4 +286,27 @@
         </>
 
     )
+}
+
+const BindButton = () => {
+    const record = useRecordContext();
+    const notify = useNotify();
+    const refresh = useRefresh();
+
+
+    const [createDialog, setCreateDialog] = useState(false);
+
+    return (
+        <>
+            <Button onClick={() => setCreateDialog(true)} label={"toolbar.bindmatnr"}>
+                <LinkIcon />
+            </Button>
+
+            <BindModal
+                open={createDialog}
+                setOpen={setCreateDialog}
+            />
+        </>
+
+    )
 }
\ No newline at end of file
diff --git a/rsf-admin/src/page/basicInfo/locArea/LocAreaCreate.jsx b/rsf-admin/src/page/basicInfo/locArea/LocAreaCreate.jsx
index 38ac67a..363386b 100644
--- a/rsf-admin/src/page/basicInfo/locArea/LocAreaCreate.jsx
+++ b/rsf-admin/src/page/basicInfo/locArea/LocAreaCreate.jsx
@@ -88,6 +88,7 @@
                                     <TextInput
                                         label="table.field.locArea.name"
                                         source="name"
+                                        validate={[required()]}
                                         parse={v => v}
                                         autoFocus
                                     />
@@ -107,6 +108,7 @@
                                         <AutocompleteInput
                                             label="table.field.locArea.areaId"
                                             optionText="name"
+                                            validate={[required()]}
                                             filterToQuery={(val) => ({ name: val })}
                                         />
                                     </ReferenceInput>
diff --git a/rsf-admin/src/page/basicInfo/locArea/LocAreaEdit.jsx b/rsf-admin/src/page/basicInfo/locArea/LocAreaEdit.jsx
index afd0a4c..8e356d2 100644
--- a/rsf-admin/src/page/basicInfo/locArea/LocAreaEdit.jsx
+++ b/rsf-admin/src/page/basicInfo/locArea/LocAreaEdit.jsx
@@ -49,6 +49,7 @@
             mutationMode={EDIT_MODE}
             actions={<CustomerTopToolBar />}
             aside={<EditBaseAside />}
+            title={"menu.locArea"}
         >
             <SimpleForm
                 shouldUnregister
@@ -67,6 +68,7 @@
                             <TextInput
                                 label="table.field.locArea.name"
                                 source="name"
+                                validate={[required()]}
                                 parse={v => v}
                                 autoFocus
                             />
@@ -86,6 +88,7 @@
                                 <AutocompleteInput
                                     label="table.field.locArea.areaId"
                                     optionText="name"
+                                    validate={[required()]}
                                     filterToQuery={(val) => ({ name: val })}
                                 />
                             </ReferenceInput>
diff --git a/rsf-admin/src/page/basicInfo/locArea/LocAreaList.jsx b/rsf-admin/src/page/basicInfo/locArea/LocAreaList.jsx
index 9f92799..faacd4e 100644
--- a/rsf-admin/src/page/basicInfo/locArea/LocAreaList.jsx
+++ b/rsf-admin/src/page/basicInfo/locArea/LocAreaList.jsx
@@ -115,8 +115,6 @@
                     preferenceKey='locArea'
                     bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />}
                     rowClick={(id, resource, record) => false}
-                    expand={() => <LocAreaPanel />}
-                    expandSingle={true}
                     omit={['id', 'createTime', 'createBy', 'memo']}
                 >
                     <NumberField source="id" />
diff --git a/rsf-admin/src/page/basicInfo/locAreaMat/BindLocModal.jsx b/rsf-admin/src/page/basicInfo/locAreaMat/BindLocModal.jsx
new file mode 100644
index 0000000..07f22b4
--- /dev/null
+++ b/rsf-admin/src/page/basicInfo/locAreaMat/BindLocModal.jsx
@@ -0,0 +1,220 @@
+import React, { useState, useRef, useEffect, useMemo } from "react";
+import {
+    CreateBase,
+    useTranslate,
+    TextInput,
+    NumberInput,
+    BooleanInput,
+    DateInput,
+    SaveButton,
+    SelectInput,
+    ReferenceInput,
+    ReferenceArrayInput,
+    AutocompleteInput,
+    Toolbar,
+    required,
+    useDataProvider,
+    useNotify,
+    Form,
+    useCreateController,
+    useListContext,
+    useRefresh,
+    SelectArrayInput,
+    useRecordContext,
+
+} from 'react-admin';
+import {
+    Dialog,
+    DialogActions,
+    DialogContent,
+    DialogTitle,
+    Grid,
+    TextField,
+    Box,
+    Button,
+    Paper,
+    TableContainer,
+    Table,
+    TableHead,
+    TableBody,
+    TableRow,
+    TableCell,
+    Tooltip,
+    IconButton,
+    styled,
+
+} from '@mui/material';
+import DialogCloseButton from "../../components/DialogCloseButton";
+import DictionarySelect from "../../components/DictionarySelect";
+import { useForm, Controller, useWatch, FormProvider, useFormContext } from "react-hook-form";
+import SaveIcon from '@mui/icons-material/Save';
+import request from '@/utils/request';
+import { Add, Edit, Delete } from '@mui/icons-material';
+import _ from 'lodash';
+import { DataGrid } from '@mui/x-data-grid';
+import StatusSelectInput from "../../components/StatusSelectInput";
+import TreeSelectInput from "@/page/components/TreeSelectInput";
+const BindMatnrModal = ({ open, setOpen, reload }) => {
+    const refresh = useRefresh();
+    const translate = useTranslate();
+    const record = useRecordContext();
+
+    const notify = useNotify();
+
+    const [formData, setFormData] = useState({
+        areaId: null,
+        warehouseId: null,
+        matnrId: null,
+        typeId: null,
+    });
+
+
+    const handleClose = (event, reason) => {
+        if (reason !== "backdropClick") {
+            setOpen(false);
+            reset()
+        }
+    };
+
+    const reset = () => {
+        setFormData({
+            areaId: null,
+            matnrId: null,
+            warehouseId: null,
+            typeId: null,
+        })
+    }
+
+
+    const handleChange = (value, name) => {
+        setFormData((prevData) => ({
+            ...prevData,
+            [name]: value
+        }));
+        refresh()
+    };
+
+    const removeEmptyKeys = (obj) => {
+        return _.pickBy(obj, (value) => {
+            if (_.isObject(value)) {
+                const newObj = removeEmptyKeys(value);
+                return !_.isEmpty(newObj);
+            }
+            return !_.isNil(value) && (_.isNumber(value) ? value !== 0 : !_.isEmpty(value));
+        });
+    }
+
+    const handleSubmit = async () => {
+        const parmas = {
+            areaMatId: record.id,
+            matnrId: formData.matnrId,
+            areaId: formData.areaId,
+            warehouseId: formData.warehouseId,
+            typeId: formData.typeId,
+        }
+
+
+        const res = await request.post(`/locAreaMatRela/matnr/bind`, parmas);
+        if (res?.data?.code === 200) {
+            handleClose()
+            reload()
+
+        } else {
+            notify(res.data.msg);
+        }
+    }
+
+    const [groupId, setGroupId] = useState();
+
+    const warehouseChange = (e) => {
+        setGroupId(e.target.value)
+    }
+
+    return (
+        <Dialog open={open} maxWidth="md" fullWidth>
+            <Form onSubmit={handleSubmit}>
+                <DialogCloseButton onClose={handleClose} />
+                <DialogTitle>{translate('toolbar.bindmatnr')}</DialogTitle>
+                <DialogContent sx={{ mt: 2 }}>
+                    <Box sx={{ display: 'flex', flexDirection: 'column', gap: 3 }}>
+                        <Grid container spacing={2}>
+                            <Grid item xs={4}>
+                                <ReferenceInput
+                                    source="warehouseId"
+                                    reference="warehouse"
+                                >
+                                    <AutocompleteInput
+                                        label="table.field.loc.warehouseId"
+                                        optionText="name"
+                                        onChange={(value) => handleChange(value, 'warehouseId')}
+                                        value={formData.warehouseId}
+                                        validate={required()}
+                                        filterToQuery={(val) => ({ name: val })}
+                                    />
+                                </ReferenceInput>
+
+                            </Grid>
+
+                            <Grid item xs={4}>
+                                <ReferenceInput
+                                    source="areaId"
+                                    reference="warehouseAreas"
+                                >
+                                    <AutocompleteInput
+                                        label="table.field.loc.areaId"
+                                        optionText="name"
+                                        onChange={(value) => handleChange(value, 'areaId')}
+                                        value={formData.areaId}
+                                        validate={required()}
+                                        filterToQuery={(val) => ({ name: val })}
+                                    />
+                                </ReferenceInput>
+
+                            </Grid>
+
+                            <Grid item xs={4}>
+                                <ReferenceArrayInput source="typeId" reference="locType" >
+                                    <SelectArrayInput
+                                        label="table.field.locAreaMatRela.locTypeId"
+                                        validate={required()}
+                                        optionText={'name'}
+                                        value={formData.typeId}
+                                        onChange={(e) => handleChange(e.target.value, 'typeId')}
+                                    />
+                                </ReferenceArrayInput>
+
+                            </Grid>
+
+
+                            <Grid item xs={4}>
+                                <ReferenceArrayInput source="matnrId" reference="matnr" filter={{ groupId: formData.groupId }}>
+                                    <SelectArrayInput
+                                        label="table.field.locAreaMatRela.matnrId"
+                                        validate={required()}
+                                        value={formData.matnrId}
+                                        onChange={(e) => handleChange(e.target.value, 'matnrId')}
+                                    />
+                                </ReferenceArrayInput>
+                            </Grid>
+
+
+
+
+
+                        </Grid>
+
+                    </Box>
+                </DialogContent>
+                <DialogActions sx={{ position: 'sticky', bottom: 0, backgroundColor: 'background.paper', zIndex: 1000 }}>
+                    <Box sx={{ width: '100%', display: 'flex', justifyContent: 'space-between' }}>
+                        <Button type="submit" variant="contained" startIcon={<SaveIcon />}>
+                            {translate('toolbar.confirm')}
+                        </Button>
+                    </Box>
+                </DialogActions>
+            </Form>
+        </Dialog>
+    );
+}
+
+export default BindMatnrModal;
\ No newline at end of file
diff --git a/rsf-admin/src/page/basicInfo/locAreaMat/BindMatnrModal.jsx b/rsf-admin/src/page/basicInfo/locAreaMat/BindMatnrModal.jsx
new file mode 100644
index 0000000..9523f61
--- /dev/null
+++ b/rsf-admin/src/page/basicInfo/locAreaMat/BindMatnrModal.jsx
@@ -0,0 +1,216 @@
+import React, { useState, useRef, useEffect, useMemo } from "react";
+import {
+    CreateBase,
+    useTranslate,
+    TextInput,
+    NumberInput,
+    BooleanInput,
+    DateInput,
+    SaveButton,
+    SelectInput,
+    ReferenceInput,
+    ReferenceArrayInput,
+    AutocompleteInput,
+    Toolbar,
+    required,
+    useDataProvider,
+    useNotify,
+    Form,
+    useCreateController,
+    useListContext,
+    useRefresh,
+    SelectArrayInput,
+    useRecordContext,
+
+} from 'react-admin';
+import {
+    Dialog,
+    DialogActions,
+    DialogContent,
+    DialogTitle,
+    Grid,
+    TextField,
+    Box,
+    Button,
+    Paper,
+    TableContainer,
+    Table,
+    TableHead,
+    TableBody,
+    TableRow,
+    TableCell,
+    Tooltip,
+    IconButton,
+    styled,
+
+} from '@mui/material';
+import DialogCloseButton from "../../components/DialogCloseButton";
+import DictionarySelect from "../../components/DictionarySelect";
+import { useForm, Controller, useWatch, FormProvider, useFormContext } from "react-hook-form";
+import SaveIcon from '@mui/icons-material/Save';
+import request from '@/utils/request';
+import { Add, Edit, Delete } from '@mui/icons-material';
+import _ from 'lodash';
+import { DataGrid } from '@mui/x-data-grid';
+import StatusSelectInput from "../../components/StatusSelectInput";
+import TreeSelectInput from "@/page/components/TreeSelectInput";
+const BindMatnrModal = ({ open, setOpen, reload }) => {
+    const refresh = useRefresh();
+    const translate = useTranslate();
+    const record = useRecordContext();
+
+    const notify = useNotify();
+
+    const [formData, setFormData] = useState({
+        areaId: null,
+        warehouseId: null,
+        groupId: null,
+        locId: null,
+    });
+
+
+    const handleClose = (event, reason) => {
+        if (reason !== "backdropClick") {
+            setOpen(false);
+            reset()
+        }
+    };
+
+    const reset = () => {
+        setFormData({
+            areaId: null,
+            warehouseId: null,
+            groupId: null,
+            locId: null,
+        })
+    }
+
+
+    const handleChange = (value, name) => {
+        setFormData((prevData) => ({
+            ...prevData,
+            [name]: value
+        }));
+        refresh()
+    };
+
+    const removeEmptyKeys = (obj) => {
+        return _.pickBy(obj, (value) => {
+            if (_.isObject(value)) {
+                const newObj = removeEmptyKeys(value);
+                return !_.isEmpty(newObj);
+            }
+            return !_.isNil(value) && (_.isNumber(value) ? value !== 0 : !_.isEmpty(value));
+        });
+    }
+
+    const handleSubmit = async () => {
+        const parmas = {
+            areaMatId: record.id,
+            groupId: [formData.groupId],
+            areaId: formData.areaId,
+            warehouseId: formData.warehouseId,
+            locId: formData.locId,
+        }
+
+
+        const res = await request.post(`/locAreaMatRela/matnr/bind`, parmas);
+        if (res?.data?.code === 200) {
+            handleClose()
+            reload()
+
+        } else {
+            notify(res.data.msg);
+        }
+    }
+
+    const [groupId, setGroupId] = useState();
+
+    const warehouseChange = (e) => {
+        setGroupId(e.target.value)
+    }
+
+    return (
+        <Dialog open={open} maxWidth="md" fullWidth>
+            <Form onSubmit={handleSubmit}>
+                <DialogCloseButton onClose={handleClose} />
+                <DialogTitle>{translate('toolbar.bindloc')}</DialogTitle>
+                <DialogContent sx={{ mt: 2 }}>
+                    <Box sx={{ display: 'flex', flexDirection: 'column', gap: 3 }}>
+                        <Grid container spacing={2}>
+                            <Grid item xs={4}>
+                                <ReferenceInput
+                                    source="warehouseId"
+                                    reference="warehouse"
+                                >
+                                    <AutocompleteInput
+                                        label="table.field.loc.warehouseId"
+                                        optionText="name"
+                                        onChange={(value) => handleChange(value, 'warehouseId')}
+                                        value={formData.warehouseId}
+                                        validate={required()}
+                                        filterToQuery={(val) => ({ name: val })}
+                                    />
+                                </ReferenceInput>
+                            </Grid>
+
+                            <Grid item xs={4}>
+                                <ReferenceInput
+                                    source="areaId"
+                                    reference="warehouseAreas"
+                                >
+                                    <AutocompleteInput
+                                        label="table.field.loc.areaId"
+                                        optionText="name"
+                                        onChange={(value) => handleChange(value, 'areaId')}
+                                        value={formData.areaId}
+                                        validate={required()}
+                                        filterToQuery={(val) => ({ name: val })}
+                                    />
+                                </ReferenceInput>
+
+                            </Grid>
+
+                            <Grid item xs={4}>
+                                <TreeSelectInput
+                                    label="table.field.locAreaMatRela.groupId"
+                                    resource={'matnrGroup'}
+                                    source="groupId"
+                                    value={formData.groupId}
+                                    onChange={(e) => handleChange(e.target.value, 'groupId')}
+                                />
+                            </Grid>
+
+
+
+
+                            <Grid item xs={4}>
+                                <ReferenceArrayInput source="locId" reference="loc" >
+                                    <SelectArrayInput
+                                        label="table.field.locAreaMatRela.locId"
+                                        validate={required()}
+                                        optionText={'code'}
+                                        value={formData.locId}
+                                        onChange={(e) => handleChange(e.target.value, 'locId')}
+                                    />
+                                </ReferenceArrayInput>
+
+                            </Grid>
+
+                        </Grid>
+
+                    </Box>
+                </DialogContent>
+                <DialogActions sx={{ position: 'sticky', bottom: 0, backgroundColor: 'background.paper', zIndex: 1000 }}>
+                    <Box sx={{ width: '100%', display: 'flex', justifyContent: 'space-between' }}>
+                        <Button type="submit" variant="contained" startIcon={<SaveIcon />}>
+                            {translate('toolbar.confirm')}
+                        </Button>
+                    </Box>
+                </DialogActions>
+            </Form>
+        </Dialog>
+    );
+}
+
+export default BindMatnrModal;
\ No newline at end of file
diff --git a/rsf-admin/src/page/basicInfo/locAreaMat/LocAreaMatCreate.jsx b/rsf-admin/src/page/basicInfo/locAreaMat/LocAreaMatCreate.jsx
new file mode 100644
index 0000000..9f726dc
--- /dev/null
+++ b/rsf-admin/src/page/basicInfo/locAreaMat/LocAreaMatCreate.jsx
@@ -0,0 +1,137 @@
+import React, { useState, useRef, useEffect, useMemo } from "react";
+import {
+    CreateBase,
+    useTranslate,
+    TextInput,
+    NumberInput,
+    BooleanInput,
+    DateInput,
+    SaveButton,
+    SelectInput,
+    ReferenceInput,
+    ReferenceArrayInput,
+    AutocompleteInput,
+    Toolbar,
+    required,
+    useDataProvider,
+    useNotify,
+    Form,
+    useCreateController,
+} from 'react-admin';
+import {
+    Dialog,
+    DialogActions,
+    DialogContent,
+    DialogTitle,
+    Stack,
+    Grid,
+    Box,
+} from '@mui/material';
+import DialogCloseButton from "../../components/DialogCloseButton";
+import StatusSelectInput from "../../components/StatusSelectInput";
+import MemoInput from "../../components/MemoInput";
+
+const LocAreaMatCreate = (props) => {
+    const { open, setOpen } = props;
+
+    const translate = useTranslate();
+    const notify = useNotify();
+
+    const handleClose = (event, reason) => {
+        if (reason !== "backdropClick") {
+            setOpen(false);
+        }
+    };
+
+    const handleSuccess = async (data) => {
+        setOpen(false);
+        notify('common.response.success');
+    };
+
+    const handleError = async (error) => {
+        notify(error.message || 'common.response.fail', { type: 'error', messageArgs: { _: error.message } });
+    };
+
+    return (
+        <>
+            <CreateBase
+                record={{}}
+                transform={(data) => {
+                    return data;
+                }}
+                mutationOptions={{ onSuccess: handleSuccess, onError: handleError }}
+            >
+                <Dialog
+                    open={open}
+                    onClose={handleClose}
+                    aria-labelledby="form-dialog-title"
+                    fullWidth
+                    disableRestoreFocus
+                    maxWidth="md"   // 'xs' | 'sm' | 'md' | 'lg' | 'xl'
+                >
+                    <Form>
+                        <DialogTitle id="form-dialog-title" sx={{
+                            position: 'sticky',
+                            top: 0,
+                            backgroundColor: 'background.paper',
+                            zIndex: 1000
+                        }}
+                        >
+                            {translate('create.title')}
+                            <Box sx={{ position: 'absolute', top: 8, right: 8, zIndex: 1001 }}>
+                                <DialogCloseButton onClose={handleClose} />
+                            </Box>
+                        </DialogTitle>
+                        <DialogContent sx={{ mt: 2 }}>
+                            <Grid container rowSpacing={2} columnSpacing={2}>
+                                <Grid item xs={6} display="flex" gap={1}>
+                                    <TextInput
+                                        label="table.field.locAreaMat.code"
+                                        source="code"
+                                        parse={v => v}
+                                        autoFocus
+                                    />
+                                </Grid>
+                                {/* <Grid item xs={6} display="flex" gap={1}>
+                                    <NumberInput
+                                        label="table.field.locAreaMat.warehouseId"
+                                        source="warehouseId"
+                                    />
+                                </Grid>
+                                <Grid item xs={6} display="flex" gap={1}>
+                                    <NumberInput
+                                        label="table.field.locAreaMat.areaId"
+                                        source="areaId"
+                                    />
+                                </Grid> */}
+                                <Grid item xs={6} display="flex" gap={1}>
+                                    <TextInput
+                                        label="table.field.locAreaMat.depict"
+                                        source="depict"
+                                        parse={v => v}
+                                    />
+                                </Grid>
+
+                                <Grid item xs={6} display="flex" gap={1}>
+                                    <StatusSelectInput />
+                                </Grid>
+                                <Grid item xs={12} display="flex" gap={1}>
+                                    <Stack direction="column" spacing={1} width={'100%'}>
+                                        <MemoInput />
+                                    </Stack>
+                                </Grid>
+                            </Grid>
+                        </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 LocAreaMatCreate;
diff --git a/rsf-admin/src/page/basicInfo/locAreaMat/LocAreaMatEdit.jsx b/rsf-admin/src/page/basicInfo/locAreaMat/LocAreaMatEdit.jsx
new file mode 100644
index 0000000..752dbfd
--- /dev/null
+++ b/rsf-admin/src/page/basicInfo/locAreaMat/LocAreaMatEdit.jsx
@@ -0,0 +1,109 @@
+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 LocAreaMatEdit = () => {
+    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.locAreaMat.code"
+                                source="code"
+                                parse={v => v}
+                                autoFocus
+                            />
+                        </Stack>
+                        {/* <Stack direction='row' gap={2}>
+                            <NumberInput
+                                label="table.field.locAreaMat.warehouseId"
+                                source="warehouseId"
+                            />
+                        </Stack>
+                        <Stack direction='row' gap={2}>
+                            <NumberInput
+                                label="table.field.locAreaMat.areaId"
+                                source="areaId"
+                            />
+                        </Stack> */}
+                        <Stack direction='row' gap={2}>
+                            <TextInput
+                                label="table.field.locAreaMat.depict"
+                                source="depict"
+                                parse={v => v}
+                            />
+                        </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 LocAreaMatEdit;
diff --git a/rsf-admin/src/page/basicInfo/locAreaMat/LocAreaMatList.jsx b/rsf-admin/src/page/basicInfo/locAreaMat/LocAreaMatList.jsx
new file mode 100644
index 0000000..a27e68c
--- /dev/null
+++ b/rsf-admin/src/page/basicInfo/locAreaMat/LocAreaMatList.jsx
@@ -0,0 +1,156 @@
+import React, { useState, useRef, useEffect, useMemo, useCallback } from "react";
+import { useNavigate } from 'react-router-dom';
+import {
+    List,
+    DatagridConfigurable,
+    SearchInput,
+    TopToolbar,
+    SelectColumnsButton,
+    EditButton,
+    FilterButton,
+    CreateButton,
+    ExportButton,
+    BulkDeleteButton,
+    WrapperField,
+    useRecordContext,
+    useTranslate,
+    useNotify,
+    useListContext,
+    FunctionField,
+    TextField,
+    NumberField,
+    DateField,
+    BooleanField,
+    ReferenceField,
+    TextInput,
+    DateTimeInput,
+    DateInput,
+    SelectInput,
+    NumberInput,
+    ReferenceInput,
+    ReferenceArrayInput,
+    AutocompleteInput,
+    DeleteButton,
+} from 'react-admin';
+import { Box, Typography, Card, Stack } from '@mui/material';
+import { styled } from '@mui/material/styles';
+import LocAreaMatCreate from "./LocAreaMatCreate";
+import LocAreaMatPanel from "./LocAreaMatPanel";
+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 { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting';
+import * as Common from '@/utils/common';
+
+const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({
+    '& .css-1vooibu-MuiSvgIcon-root': {
+        height: '.9em'
+    },
+    '& .RaDatagrid-row': {
+        cursor: 'auto'
+    },
+    '& .column-name': {
+    },
+    '& .opt': {
+        width: 200
+    },
+}));
+
+const filters = [
+    <SearchInput source="condition" alwaysOn />,
+
+    <TextInput source="code" label="table.field.locAreaMat.code" />,
+    <NumberInput source="warehouseId" label="table.field.locAreaMat.warehouseId" />,
+    <NumberInput source="areaId" label="table.field.locAreaMat.areaId" />,
+    <TextInput source="depict" label="table.field.locAreaMat.depict" />,
+
+    <TextInput label="common.field.memo" source="memo" />,
+    <SelectInput
+        label="common.field.status"
+        source="status"
+        choices={[
+            { id: '1', name: 'common.enums.statusTrue' },
+            { id: '0', name: 'common.enums.statusFalse' },
+        ]}
+        resettable
+    />,
+]
+
+const LocAreaMatList = () => {
+    const translate = useTranslate();
+
+    const [createDialog, setCreateDialog] = useState(false);
+    const [drawerVal, setDrawerVal] = useState(false);
+
+    return (
+        <Box display="flex">
+            <List
+                sx={{
+                    flexGrow: 1,
+                    transition: (theme) =>
+                        theme.transitions.create(['all'], {
+                            duration: theme.transitions.duration.enteringScreen,
+                        }),
+                    marginRight: drawerVal ? `${PAGE_DRAWER_WIDTH}px` : 0,
+                }}
+                title={"menu.locAreaMat"}
+                empty={<EmptyData onClick={() => { setCreateDialog(true) }} />}
+                filters={filters}
+                sort={{ field: "create_time", order: "desc" }}
+                actions={(
+                    <TopToolbar>
+                        <FilterButton />
+                        <MyCreateButton onClick={() => { setCreateDialog(true) }} />
+                        <SelectColumnsButton preferenceKey='locAreaMat' />
+                        <MyExportButton />
+                    </TopToolbar>
+                )}
+                perPage={DEFAULT_PAGE_SIZE}
+            >
+                <StyledDatagrid
+                    preferenceKey='locAreaMat'
+                    bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />}
+                    rowClick={(id, resource, record) => false}
+                    expand={() => <LocAreaMatPanel />}
+                    expandSingle={true}
+                    omit={['id', 'createTime', 'createBy', 'memo']}
+                >
+                    <NumberField source="id" />
+                    <TextField source="code" label="table.field.locAreaMat.code" />
+                    {/* <NumberField source="warehouseId" label="table.field.locAreaMat.warehouseId" />
+                    <NumberField source="areaId" label="table.field.locAreaMat.areaId" /> */}
+                    <TextField source="depict" label="table.field.locAreaMat.depict" />
+
+                    <ReferenceField source="updateBy" label="common.field.updateBy" reference="user" link={false} sortable={false}>
+                        <TextField source="nickname" />
+                    </ReferenceField>
+                    <DateField source="updateTime" label="common.field.updateTime" showTime />
+                    <ReferenceField source="createBy" label="common.field.createBy" reference="user" link={false} sortable={false}>
+                        <TextField source="nickname" />
+                    </ReferenceField>
+                    <DateField source="createTime" label="common.field.createTime" showTime />
+                    <BooleanField source="statusBool" label="common.field.status" sortable={false} />
+                    <TextField source="memo" label="common.field.memo" sortable={false} />
+                    <WrapperField cellClassName="opt" label="common.field.opt">
+                        <EditButton sx={{ padding: '1px', fontSize: '.75rem' }} />
+                        <DeleteButton sx={{ padding: '1px', fontSize: '.75rem' }} mutationMode={OPERATE_MODE} />
+                    </WrapperField>
+                </StyledDatagrid>
+            </List>
+            <LocAreaMatCreate
+                open={createDialog}
+                setOpen={setCreateDialog}
+            />
+            <PageDrawer
+                title='LocAreaMat Detail'
+                drawerVal={drawerVal}
+                setDrawerVal={setDrawerVal}
+            >
+            </PageDrawer>
+        </Box>
+    )
+}
+
+export default LocAreaMatList;
diff --git a/rsf-admin/src/page/basicInfo/locAreaMat/LocAreaMatPanel.jsx b/rsf-admin/src/page/basicInfo/locAreaMat/LocAreaMatPanel.jsx
new file mode 100644
index 0000000..6ca9111
--- /dev/null
+++ b/rsf-admin/src/page/basicInfo/locAreaMat/LocAreaMatPanel.jsx
@@ -0,0 +1,411 @@
+import React, { useState, useRef, useEffect } from "react";
+import {
+    Grid, Card, Typography, Button, Checkbox, Tooltip,
+    IconButton,
+} from '@mui/material';
+import { useTranslate, useRecordContext, useNotify } from 'react-admin';
+import { RichTreeView } from '@mui/x-tree-view/RichTreeView';
+import { TreeItem2 } from "@mui/x-tree-view/TreeItem2";
+import { useTreeViewApiRef } from '@mui/x-tree-view/hooks';
+import FiberManualRecordIcon from '@mui/icons-material/FiberManualRecord';
+import AddIcon from '@mui/icons-material/Add';
+import DeleteIcon from '@mui/icons-material/Delete';
+import BindMatnrModal from './BindMatnrModal';
+import BindLocModal from './BindLocModal';
+import ConfirmModal from "@/page/components/ConfirmModal";
+import { DataGrid } from '@mui/x-data-grid';
+import request from '@/utils/request';
+
+const LocAreaMatPanel = () => {
+    const record = useRecordContext();
+    if (!record) return null;
+    const translate = useTranslate();
+    const notify = useNotify();
+
+    const columns = [
+        { field: 'id', headerName: 'ID', width: 100 },
+        { field: 'areaId$', headerName: translate('table.field.locAreaMatRela.areaId'), width: 100 },
+        { field: 'matnrId$', headerName: translate('table.field.locAreaMatRela.matnrId'), width: 100 },
+        { field: 'groupId$', headerName: translate('table.field.locAreaMatRela.groupId'), width: 100 },
+        { field: 'locTypeId$', headerName: translate('table.field.locAreaMatRela.locTypeId'), width: 100 },
+        { field: 'locId$', headerName: translate('table.field.locAreaMatRela.locId'), width: 100 },
+        {
+            field: 'action',
+            headerName: '鎿嶄綔',
+            minWidth: 100,
+            sticky: 'left',
+            flex: 1,
+            renderCell: (params) => (
+                <Tooltip title="Delete">
+                    <IconButton onClick={(e) => handleDelete(params.row, e)}>
+                        <DeleteIcon />
+                    </IconButton>
+                </Tooltip>
+            ),
+        },
+    ];
+
+    const handleDelete = async (row, e) => {
+        e.stopPropagation()
+        const { data: { code, data, msg } } = await request.post(`/locAreaMatRela/remove/${row.id}`);
+
+        if (code === 200) {
+            reload()
+            notify(msg);
+        } else {
+            notify(msg);
+        }
+
+    }
+
+    const [parmas, setParmas] = useState({
+        areaMatId: record.id,
+    });
+
+    const [tableData, setTableData] = useState([]);
+    const [matnrTree, setMatnrTree] = useState([]);
+    const [locTree, setLocTree] = useState([]);
+
+    useEffect(() => {
+        reload()
+    }, [parmas])
+
+    const reload = () => {
+        requestTable()
+        requestMatnr()
+        requestLocType()
+    }
+
+    const requestTable = async () => {
+        const { data: { code, data, msg } } = await request.post(`/locAreaMatRela/page`, parmas);
+
+        if (code === 200) {
+            setTableData(data.records || [])
+        } else {
+            notify(msg);
+        }
+    }
+
+    const requestMatnr = async () => {
+        const { data: { code, data, msg } } = await request.get(`/locAreaMatRela/groups/${record.id}`);
+
+        if (code === 200) {
+            setMatnrTree(data || [])
+        } else {
+            notify(msg);
+        }
+    }
+
+    const requestLocType = async () => {
+        const { data: { code, data, msg } } = await request.get(`/locAreaMatRela/locType/${record.id}`);
+
+        if (code === 200) {
+            setLocTree(data || [])
+        } else {
+            notify(msg);
+        }
+    }
+
+
+    return (
+        <Grid container spacing={2}>
+            {/* 鐗╂枡鍒嗙粍 */}
+            <Grid item xs={2}>
+                <MatnrTree matnrTree={matnrTree} setParmas={setParmas} reload={reload} />
+            </Grid>
+
+            {/* 搴撲綅绫诲瀷 */}
+            <Grid item xs={2}>
+                <LocTree locTree={locTree} setParmas={setParmas} reload={reload} />
+            </Grid>
+
+            {/* 鍏朵粬鍐呭 */}
+            <Grid item xs={8}>
+                <DataGrid
+                    size="small"
+                    rows={tableData}
+                    columns={columns}
+                    checkboxSelection
+                    disableColumnMenu={true}
+                    disableColumnSorting
+                    disableMultipleColumnsSorting
+                    columnBufferPx={100}
+                />
+            </Grid>
+        </Grid>
+    );
+};
+
+export default LocAreaMatPanel;
+
+
+const MatnrTree = ({ matnrTree, setParmas, reload }) => {
+
+    const record = useRecordContext();
+    const notify = useNotify();
+
+    function getItemDescendantsIds(item) {
+        const ids = [];
+        item.children?.forEach((child) => {
+            ids.push(child.id);
+            ids.push(...getItemDescendantsIds(child));
+        });
+
+        return ids;
+    }
+
+    const [selectedItems, setSelectedItems] = useState([]);
+    const toggledItemRef = useRef({});
+    const apiRef = useTreeViewApiRef();
+
+    const handleItemSelectionToggle = (event, itemId, isSelected) => {
+        event.stopPropagation()
+        event.preventDefault();
+        toggledItemRef.current[itemId] = isSelected;
+    };
+
+    const handleSelectedItemsChange = (event, newSelectedItems) => {
+        event.stopPropagation()
+        event.preventDefault();
+        setSelectedItems(newSelectedItems);
+
+        const itemsToSelect = [];
+        const itemsToUnSelect = {};
+        Object.entries(toggledItemRef.current).forEach(([itemId, isSelected]) => {
+            const item = apiRef.current.getItem(itemId);
+            if (isSelected) {
+                itemsToSelect.push(...getItemDescendantsIds(item));
+            } else {
+                getItemDescendantsIds(item).forEach((descendantId) => {
+                    itemsToUnSelect[descendantId] = true;
+                });
+            }
+        });
+
+        const newSelectedItemsWithChildren = Array.from(
+            new Set(
+                [...newSelectedItems, ...itemsToSelect].filter(
+                    (itemId) => !itemsToUnSelect[itemId],
+                ),
+            ),
+        );
+
+        setSelectedItems(newSelectedItemsWithChildren);
+
+        toggledItemRef.current = {};
+    };
+
+    const [addDialog, setAddDialog] = useState(false);
+    const [delectDialog, setDelectDialog] = useState(false);
+
+
+    const handleDelete = () => {
+        if (selectedItems.length > 0) {
+            setDelectDialog(true)
+        } else {
+            notify('璇烽�夋嫨鐗╂枡鍒嗙粍');
+        }
+
+    };
+
+    const contirmDelete = async () => {
+        const parmas = {
+            aeaMatId: record.id,
+            groupId: selectedItems
+        }
+
+        const res = await request.post(`/locAreaMatRela/group/remove/`, parmas);
+        if (res?.data?.code === 200) {
+            reload()
+            notify(res.data.msg);
+
+        } else {
+            notify(res.data.msg);
+        }
+
+    };
+
+    const handleAdd = () => {
+        setAddDialog(true)
+
+    };
+
+    const handleNodeSelect = (event, nodeId) => {
+        event.stopPropagation()
+    };
+
+    return (
+        <Card sx={{ p: 1 }}>
+            <div style={{ display: 'flex', justifyContent: 'space-between', paddingBottom: '3px', marginBottom: '3px', borderBottom: '1px dashed #d4d4d4' }}>
+                <div style={{ fontSize: '17px' }}>鐗╂枡鍒嗙粍</div>
+                <div style={{ display: 'flex', alignItems: 'center', gap: '3px' }}>
+                    <AddIcon color={'info'} sx={{ cursor: 'pointer' }} onClick={() => handleAdd()} />
+
+                    <DeleteIcon color={'warning'} sx={{ cursor: 'pointer' }} onClick={() => handleDelete()} />
+                </div>
+            </div>
+
+            <RichTreeView
+                expansionTrigger="iconContainer"
+                checkboxSelection
+                multiSelect
+                items={matnrTree}
+                apiRef={apiRef}
+                selectedItems={selectedItems}
+                getItemId={(item) => item.id}
+                getItemLabel={(item) => item.name}
+                defaultExpandedItems={['grid']}
+                onSelectedItemsChange={handleSelectedItemsChange}
+                onItemSelectionToggle={handleItemSelectionToggle}
+                onItemClick={handleNodeSelect}
+            />
+
+            <BindMatnrModal
+                open={addDialog}
+                setOpen={setAddDialog}
+                selectedItems={selectedItems}
+                reload={reload}
+            />
+
+            <ConfirmModal
+                open={delectDialog}
+                setOpen={setDelectDialog}
+                onConfirm={contirmDelete}
+            />
+        </Card>
+    )
+}
+
+const LocTree = ({ locTree, setParmas, reload }) => {
+
+    const record = useRecordContext();
+    const notify = useNotify();
+
+    function getItemDescendantsIds(item) {
+        const ids = [];
+        item.children?.forEach((child) => {
+            ids.push(child.id);
+            ids.push(...getItemDescendantsIds(child));
+        });
+
+        return ids;
+    }
+
+    const [selectedItems, setSelectedItems] = useState([]);
+    const toggledItemRef = useRef({});
+    const apiRef = useTreeViewApiRef();
+
+    const handleItemSelectionToggle = (event, itemId, isSelected) => {
+        toggledItemRef.current[itemId] = isSelected;
+    };
+
+    const handleSelectedItemsChange = (event, newSelectedItems) => {
+        setSelectedItems(newSelectedItems);
+
+        const itemsToSelect = [];
+        const itemsToUnSelect = {};
+        Object.entries(toggledItemRef.current).forEach(([itemId, isSelected]) => {
+            const item = apiRef.current.getItem(itemId);
+            if (isSelected) {
+                itemsToSelect.push(...getItemDescendantsIds(item));
+            } else {
+                getItemDescendantsIds(item).forEach((descendantId) => {
+                    itemsToUnSelect[descendantId] = true;
+                });
+            }
+        });
+
+        const newSelectedItemsWithChildren = Array.from(
+            new Set(
+                [...newSelectedItems, ...itemsToSelect].filter(
+                    (itemId) => !itemsToUnSelect[itemId],
+                ),
+            ),
+        );
+
+        setSelectedItems(newSelectedItemsWithChildren);
+
+        toggledItemRef.current = {};
+    };
+
+    const [addDialog, setAddDialog] = useState(false);
+    const [delectDialog, setDelectDialog] = useState(false);
+
+
+    const handleDelete = () => {
+        if (selectedItems.length > 0) {
+            setDelectDialog(true)
+        } else {
+            notify('璇烽�夋嫨搴撲綅绫诲瀷');
+        }
+
+    };
+
+    const contirmDelete = async () => {
+        const parmas = {
+            areaMatId: record.id,
+            typeId: selectedItems
+        }
+
+        const res = await request.post(`/locAreaMatRela/locType/remove/`, parmas);
+        if (res?.data?.code === 200) {
+            reload()
+            notify(res.data.msg);
+
+        } else {
+            notify(res.data.msg);
+        }
+
+    };
+
+    const handleAdd = () => {
+        setAddDialog(true)
+
+    };
+
+    const handleNodeSelect = (event, nodeId) => {
+        // event.preventDefault();
+        console.log(nodeId)
+    };
+
+    return (
+        <Card sx={{ p: 1 }}>
+            <div style={{ display: 'flex', justifyContent: 'space-between', paddingBottom: '3px', marginBottom: '3px', borderBottom: '1px dashed #d4d4d4' }}>
+                <div style={{ fontSize: '17px' }}>搴撲綅绫诲瀷</div>
+                <div style={{ display: 'flex', alignItems: 'center', gap: '3px' }}>
+                    <AddIcon color={'info'} sx={{ cursor: 'pointer' }} onClick={() => handleAdd()} />
+
+                    <DeleteIcon color={'warning'} sx={{ cursor: 'pointer' }} onClick={() => handleDelete()} />
+                </div>
+            </div>
+
+            <RichTreeView
+                expansionTrigger="iconContainer"
+                checkboxSelection
+                multiSelect
+                items={locTree}
+                apiRef={apiRef}
+                selectedItems={selectedItems}
+                getItemId={(item) => item.id}
+                getItemLabel={(item) => item.name}
+                defaultExpandedItems={['grid']}
+                onSelectedItemsChange={handleSelectedItemsChange}
+                onItemSelectionToggle={handleItemSelectionToggle}
+                onItemClick={handleNodeSelect}
+            />
+
+            <BindLocModal
+                open={addDialog}
+                setOpen={setAddDialog}
+                selectedItems={selectedItems}
+                reload={reload}
+            />
+
+            <ConfirmModal
+                open={delectDialog}
+                setOpen={setDelectDialog}
+                onConfirm={contirmDelete}
+            />
+        </Card>
+    )
+}
\ No newline at end of file
diff --git a/rsf-admin/src/page/basicInfo/locAreaMat/index.jsx b/rsf-admin/src/page/basicInfo/locAreaMat/index.jsx
new file mode 100644
index 0000000..625a369
--- /dev/null
+++ b/rsf-admin/src/page/basicInfo/locAreaMat/index.jsx
@@ -0,0 +1,18 @@
+import React, { useState, useRef, useEffect, useMemo } from "react";
+import {
+    ListGuesser,
+    EditGuesser,
+    ShowGuesser,
+} from "react-admin";
+
+import LocAreaMatList from "./LocAreaMatList";
+import LocAreaMatEdit from "./LocAreaMatEdit";
+
+export default {
+    list: LocAreaMatList,
+    edit: LocAreaMatEdit,
+    show: ShowGuesser,
+    recordRepresentation: (record) => {
+        return `${record.id}`
+    }
+};
diff --git a/rsf-admin/src/page/basicInfo/locAreaMatRela/LocAreaMatRelaCreate.jsx b/rsf-admin/src/page/basicInfo/locAreaMatRela/LocAreaMatRelaCreate.jsx
new file mode 100644
index 0000000..c685d20
--- /dev/null
+++ b/rsf-admin/src/page/basicInfo/locAreaMatRela/LocAreaMatRelaCreate.jsx
@@ -0,0 +1,179 @@
+import React, { useState, useRef, useEffect, useMemo } from "react";
+import {
+    CreateBase,
+    useTranslate,
+    TextInput,
+    NumberInput,
+    BooleanInput,
+    DateInput,
+    SaveButton,
+    SelectInput,
+    ReferenceInput,
+    ReferenceArrayInput,
+    AutocompleteInput,
+    SelectArrayInput,
+    Toolbar,
+    required,
+    useDataProvider,
+    useNotify,
+    Form,
+    useCreateController,
+} from 'react-admin';
+import {
+    Dialog,
+    DialogActions,
+    DialogContent,
+    DialogTitle,
+    Stack,
+    Grid,
+    Box,
+} from '@mui/material';
+import DialogCloseButton from "../../components/DialogCloseButton";
+import StatusSelectInput from "../../components/StatusSelectInput";
+import MemoInput from "../../components/MemoInput";
+import TreeSelectInput from "@/page/components/TreeSelectInput";
+
+const LocAreaMatRelaCreate = (props) => {
+    const { open, setOpen } = props;
+
+    const translate = useTranslate();
+    const notify = useNotify();
+
+    const handleClose = (event, reason) => {
+        if (reason !== "backdropClick") {
+            setOpen(false);
+        }
+    };
+
+    const handleSuccess = async (data) => {
+        setOpen(false);
+        notify('common.response.success');
+    };
+
+    const handleError = async (error) => {
+        notify(error.message || 'common.response.fail', { type: 'error', messageArgs: { _: error.message } });
+    };
+
+    return (
+        <>
+            <CreateBase
+                record={{}}
+                transform={(data) => {
+                    return data;
+                }}
+                mutationOptions={{ onSuccess: handleSuccess, onError: handleError }}
+            >
+                <Dialog
+                    open={open}
+                    onClose={handleClose}
+                    aria-labelledby="form-dialog-title"
+                    fullWidth
+                    disableRestoreFocus
+                    maxWidth="md"   // 'xs' | 'sm' | 'md' | 'lg' | 'xl'
+                >
+                    <Form>
+                        <DialogTitle id="form-dialog-title" sx={{
+                            position: 'sticky',
+                            top: 0,
+                            backgroundColor: 'background.paper',
+                            zIndex: 1000
+                        }}
+                        >
+                            {translate('create.title')}
+                            <Box sx={{ position: 'absolute', top: 8, right: 8, zIndex: 1001 }}>
+                                <DialogCloseButton onClose={handleClose} />
+                            </Box>
+                        </DialogTitle>
+                        <DialogContent sx={{ mt: 2 }}>
+                            <Grid container rowSpacing={2} columnSpacing={2}>
+                                <Grid item xs={6} display="flex" gap={1}>
+                                    <ReferenceInput
+                                        source="areaId"
+                                        reference="warehouseAreas"
+                                    >
+                                        <AutocompleteInput
+                                            label="table.field.locAreaMatRela.areaId"
+                                            optionText="name"
+                                            validate={[required()]}
+                                            filterToQuery={(val) => ({ name: val })}
+                                        />
+                                    </ReferenceInput>
+                                </Grid>
+                                <Grid item xs={6} display="flex" gap={1}>
+                                    <TextInput
+                                        label="table.field.locAreaMatRela.code"
+                                        source="code"
+                                        parse={v => v}
+                                    />
+                                </Grid>
+                                <Grid item xs={6} display="flex" gap={1}>
+                                    <ReferenceInput
+                                        source="matnrId"
+                                        reference="matnr"
+                                    >
+                                        <AutocompleteInput
+                                            label="table.field.locAreaMatRela.matnrId"
+                                            optionText="name"
+                                            filterToQuery={(val) => ({ name: val })}
+                                        />
+                                    </ReferenceInput>
+                                </Grid>
+                                <Grid item xs={6} display="flex" gap={1}>
+                                    <TreeSelectInput
+                                        label="table.field.locAreaMatRela.groupId"
+                                        resource={'matnrGroup'}
+                                        source="groupId"
+                                    />
+                                </Grid>
+                                <Grid item xs={6} display="flex" gap={1}>
+                                    <ReferenceInput
+                                        source="locId"
+                                        reference="loc"
+                                    >
+                                        <AutocompleteInput
+                                            label="table.field.locAreaMatRela.locId"
+                                            optionText="code"
+                                            filterToQuery={(val) => ({ code: val })}
+                                        />
+                                    </ReferenceInput>
+                                </Grid>
+                                <Grid item xs={6} display="flex" gap={1}>
+                                    {/* <ReferenceArrayInput source="locTypeId" reference="locType" >
+                                        <SelectArrayInput label="table.field.locAreaMatRela.locTypeId" />
+                                    </ReferenceArrayInput> */}
+                                    <ReferenceInput
+                                        source="locTypeId"
+                                        reference="locType"
+                                    >
+                                        <AutocompleteInput
+                                            label="table.field.locAreaMatRela.locTypeId"
+                                            optionText="name"
+                                            filterToQuery={(val) => ({ name: val })}
+                                        />
+                                    </ReferenceInput>
+                                </Grid>
+
+
+                                <Grid item xs={6} display="flex" gap={1}>
+                                    <StatusSelectInput />
+                                </Grid>
+                                <Grid item xs={12} display="flex" gap={1}>
+                                    <Stack direction="column" spacing={1} width={'100%'}>
+                                        <MemoInput />
+                                    </Stack>
+                                </Grid>
+                            </Grid>
+                        </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 LocAreaMatRelaCreate;
diff --git a/rsf-admin/src/page/basicInfo/locAreaMatRela/LocAreaMatRelaEdit.jsx b/rsf-admin/src/page/basicInfo/locAreaMatRela/LocAreaMatRelaEdit.jsx
new file mode 100644
index 0000000..63bb3ae
--- /dev/null
+++ b/rsf-admin/src/page/basicInfo/locAreaMatRela/LocAreaMatRelaEdit.jsx
@@ -0,0 +1,152 @@
+import React, { useState, useRef, useEffect, useMemo } from "react";
+import {
+    Edit,
+    SimpleForm,
+    FormDataConsumer,
+    useTranslate,
+    TextInput,
+    NumberInput,
+    BooleanInput,
+    DateInput,
+    SelectInput,
+    ReferenceInput,
+    ReferenceArrayInput,
+    AutocompleteInput,
+    SelectArrayInput,
+    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";
+import TreeSelectInput from "@/page/components/TreeSelectInput";
+
+const FormToolbar = () => {
+    const { getValues } = useFormContext();
+
+    return (
+        <Toolbar sx={{ justifyContent: 'space-between' }}>
+            <SaveButton />
+            <DeleteButton mutationMode="optimistic" />
+        </Toolbar>
+    )
+}
+
+const LocAreaMatRelaEdit = () => {
+    const translate = useTranslate();
+
+    return (
+        <Edit
+            redirect="list"
+            mutationMode={EDIT_MODE}
+            actions={<CustomerTopToolBar />}
+            aside={<EditBaseAside />}
+            title={"menu.locAreaMatRela"}
+        >
+            <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}>
+                            <ReferenceInput
+                                source="areaId"
+                                reference="warehouseAreas"
+                            >
+                                <AutocompleteInput
+                                    label="table.field.locAreaMatRela.areaId"
+                                    optionText="name"
+                                    validate={[required()]}
+                                    filterToQuery={(val) => ({ name: val })}
+                                />
+                            </ReferenceInput>
+                        </Stack>
+                        <Stack direction='row' gap={2}>
+                            <TextInput
+                                label="table.field.locAreaMatRela.code"
+                                source="code"
+                                parse={v => v}
+                            />
+                        </Stack>
+                        <Stack direction='row' gap={2}>
+                            <ReferenceInput
+                                source="matnrId"
+                                reference="matnr"
+                            >
+                                <AutocompleteInput
+                                    label="table.field.locAreaMatRela.matnrId"
+                                    optionText="name"
+                                    filterToQuery={(val) => ({ name: val })}
+                                />
+                            </ReferenceInput>
+                        </Stack>
+                        <Stack direction='row' gap={2}>
+                            <TreeSelectInput
+                                label="table.field.locAreaMatRela.groupId"
+                                resource={'matnrGroup'}
+                                source="groupId"
+                            />
+                        </Stack>
+                        <Stack direction='row' gap={2}>
+                            <ReferenceInput
+                                source="locId"
+                                reference="loc"
+                            >
+                                <AutocompleteInput
+                                    label="table.field.locAreaMatRela.locId"
+                                    optionText="code"
+                                    filterToQuery={(val) => ({ code: val })}
+                                />
+                            </ReferenceInput>
+                        </Stack>
+                        <Stack direction='row' gap={2}>
+                            {/* <ReferenceArrayInput source="locTypeId" reference="locType" >
+                                <SelectArrayInput label="table.field.locAreaMatRela.locTypeId" />
+                            </ReferenceArrayInput> */}
+                            <ReferenceInput
+                                source="locTypeId"
+                                reference="locType"
+                            >
+                                <AutocompleteInput
+                                    label="table.field.locAreaMatRela.locTypeId"
+                                    optionText="name"
+                                    filterToQuery={(val) => ({ name: val })}
+                                />
+                            </ReferenceInput>
+                        </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 LocAreaMatRelaEdit;
diff --git a/rsf-admin/src/page/basicInfo/locAreaMatRela/LocAreaMatRelaList.jsx b/rsf-admin/src/page/basicInfo/locAreaMatRela/LocAreaMatRelaList.jsx
new file mode 100644
index 0000000..2af0ab4
--- /dev/null
+++ b/rsf-admin/src/page/basicInfo/locAreaMatRela/LocAreaMatRelaList.jsx
@@ -0,0 +1,158 @@
+import React, { useState, useRef, useEffect, useMemo, useCallback } from "react";
+import { useNavigate } from 'react-router-dom';
+import {
+    List,
+    DatagridConfigurable,
+    SearchInput,
+    TopToolbar,
+    SelectColumnsButton,
+    EditButton,
+    FilterButton,
+    CreateButton,
+    ExportButton,
+    BulkDeleteButton,
+    WrapperField,
+    useRecordContext,
+    useTranslate,
+    useNotify,
+    useListContext,
+    FunctionField,
+    TextField,
+    NumberField,
+    DateField,
+    BooleanField,
+    ReferenceField,
+    TextInput,
+    DateTimeInput,
+    DateInput,
+    SelectInput,
+    NumberInput,
+    ReferenceInput,
+    ReferenceArrayInput,
+    AutocompleteInput,
+    DeleteButton,
+} from 'react-admin';
+import { Box, Typography, Card, Stack } from '@mui/material';
+import { styled } from '@mui/material/styles';
+import LocAreaMatRelaCreate from "./LocAreaMatRelaCreate";
+import LocAreaMatRelaPanel from "./LocAreaMatRelaPanel";
+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 { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting';
+import * as Common from '@/utils/common';
+
+const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({
+    '& .css-1vooibu-MuiSvgIcon-root': {
+        height: '.9em'
+    },
+    '& .RaDatagrid-row': {
+        cursor: 'auto'
+    },
+    '& .column-name': {
+    },
+    '& .opt': {
+        width: 200
+    },
+}));
+
+const filters = [
+    <SearchInput source="condition" alwaysOn />,
+
+    <NumberInput source="areaId" label="table.field.locAreaMatRela.areaId" />,
+    <TextInput source="code" label="table.field.locAreaMatRela.code" />,
+    <NumberInput source="matnrId" label="table.field.locAreaMatRela.matnrId" />,
+    <NumberInput source="groupId" label="table.field.locAreaMatRela.groupId" />,
+    <NumberInput source="locTypeId" label="table.field.locAreaMatRela.locTypeId" />,
+    <NumberInput source="locId" label="table.field.locAreaMatRela.locId" />,
+
+    <TextInput label="common.field.memo" source="memo" />,
+    <SelectInput
+        label="common.field.status"
+        source="status"
+        choices={[
+            { id: '1', name: 'common.enums.statusTrue' },
+            { id: '0', name: 'common.enums.statusFalse' },
+        ]}
+        resettable
+    />,
+]
+
+const LocAreaMatRelaList = () => {
+    const translate = useTranslate();
+
+    const [createDialog, setCreateDialog] = useState(false);
+    const [drawerVal, setDrawerVal] = useState(false);
+
+    return (
+        <Box display="flex">
+            <List
+                sx={{
+                    flexGrow: 1,
+                    transition: (theme) =>
+                        theme.transitions.create(['all'], {
+                            duration: theme.transitions.duration.enteringScreen,
+                        }),
+                    marginRight: drawerVal ? `${PAGE_DRAWER_WIDTH}px` : 0,
+                }}
+                title={"menu.locAreaMatRela"}
+                empty={<EmptyData onClick={() => { setCreateDialog(true) }} />}
+                filters={filters}
+                sort={{ field: "create_time", order: "desc" }}
+                actions={(
+                    <TopToolbar>
+                        <FilterButton />
+                        <MyCreateButton onClick={() => { setCreateDialog(true) }} />
+                        <SelectColumnsButton preferenceKey='locAreaMatRela' />
+                        <MyExportButton />
+                    </TopToolbar>
+                )}
+                perPage={DEFAULT_PAGE_SIZE}
+            >
+                <StyledDatagrid
+                    preferenceKey='locAreaMatRela'
+                    bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />}
+                    rowClick={(id, resource, record) => false}
+                    omit={['id', 'createTime', 'createBy', 'memo']}
+                >
+                    <NumberField source="id" />
+                    <NumberField source="areaId$" label="table.field.locAreaMatRela.areaId" />
+                    <TextField source="code" label="table.field.locAreaMatRela.code" />
+                    <NumberField source="matnrId$" label="table.field.locAreaMatRela.matnrId" />
+                    <NumberField source="groupId$" label="table.field.locAreaMatRela.groupId" />
+                    <NumberField source="locTypeId$" label="table.field.locAreaMatRela.locTypeId" />
+                    <NumberField source="locId$" label="table.field.locAreaMatRela.locId" />
+
+                    <ReferenceField source="updateBy" label="common.field.updateBy" reference="user" link={false} sortable={false}>
+                        <TextField source="nickname" />
+                    </ReferenceField>
+                    <DateField source="updateTime" label="common.field.updateTime" showTime />
+                    <ReferenceField source="createBy" label="common.field.createBy" reference="user" link={false} sortable={false}>
+                        <TextField source="nickname" />
+                    </ReferenceField>
+                    <DateField source="createTime" label="common.field.createTime" showTime />
+                    <BooleanField source="statusBool" label="common.field.status" sortable={false} />
+                    <TextField source="memo" label="common.field.memo" sortable={false} />
+                    <WrapperField cellClassName="opt" label="common.field.opt">
+                        <EditButton sx={{ padding: '1px', fontSize: '.75rem' }} />
+                        <DeleteButton sx={{ padding: '1px', fontSize: '.75rem' }} mutationMode={OPERATE_MODE} />
+                    </WrapperField>
+                </StyledDatagrid>
+            </List>
+            <LocAreaMatRelaCreate
+                open={createDialog}
+                setOpen={setCreateDialog}
+            />
+            <PageDrawer
+                title='LocAreaMatRela Detail'
+                drawerVal={drawerVal}
+                setDrawerVal={setDrawerVal}
+            >
+            </PageDrawer>
+        </Box>
+    )
+}
+
+export default LocAreaMatRelaList;
diff --git a/rsf-admin/src/page/basicInfo/locAreaMatRela/LocAreaMatRelaPanel.jsx b/rsf-admin/src/page/basicInfo/locAreaMatRela/LocAreaMatRelaPanel.jsx
new file mode 100644
index 0000000..47c1a00
--- /dev/null
+++ b/rsf-admin/src/page/basicInfo/locAreaMatRela/LocAreaMatRelaPanel.jsx
@@ -0,0 +1,28 @@
+import React, { useState, useRef, useEffect, useMemo } from "react";
+import { Box, Card, CardContent, Grid, Typography, Tooltip } from '@mui/material';
+import {
+    useTranslate,
+    useRecordContext,
+} from 'react-admin';
+import PanelTypography from "../../components/PanelTypography";
+import * as Common from '@/utils/common'
+
+const LocAreaMatRelaPanel = () => {
+    const record = useRecordContext();
+    if (!record) return null;
+    const translate = useTranslate();
+    return (
+        <>
+            <Card >
+                <CardContent>
+                    <Grid container spacing={2}>1</Grid>
+                    <Grid container spacing={2}>1</Grid>
+                    <Grid container spacing={2}>1</Grid>
+
+                </CardContent >
+            </Card >
+        </>
+    );
+};
+
+export default LocAreaMatRelaPanel;
diff --git a/rsf-admin/src/page/basicInfo/locAreaMatRela/index.jsx b/rsf-admin/src/page/basicInfo/locAreaMatRela/index.jsx
new file mode 100644
index 0000000..87ce528
--- /dev/null
+++ b/rsf-admin/src/page/basicInfo/locAreaMatRela/index.jsx
@@ -0,0 +1,18 @@
+import React, { useState, useRef, useEffect, useMemo } from "react";
+import {
+    ListGuesser,
+    EditGuesser,
+    ShowGuesser,
+} from "react-admin";
+
+import LocAreaMatRelaList from "./LocAreaMatRelaList";
+import LocAreaMatRelaEdit from "./LocAreaMatRelaEdit";
+
+export default {
+    list: LocAreaMatRelaList,
+    edit: LocAreaMatRelaEdit,
+    show: ShowGuesser,
+    recordRepresentation: (record) => {
+        return `${record.areaId}`
+    }
+};
diff --git a/rsf-admin/src/page/basicInfo/locAreaRela/LocAreaRelaCreate.jsx b/rsf-admin/src/page/basicInfo/locAreaRela/LocAreaRelaCreate.jsx
new file mode 100644
index 0000000..fdbc7a7
--- /dev/null
+++ b/rsf-admin/src/page/basicInfo/locAreaRela/LocAreaRelaCreate.jsx
@@ -0,0 +1,123 @@
+import React, { useState, useRef, useEffect, useMemo } from "react";
+import {
+    CreateBase,
+    useTranslate,
+    TextInput,
+    NumberInput,
+    BooleanInput,
+    DateInput,
+    SaveButton,
+    SelectInput,
+    ReferenceInput,
+    ReferenceArrayInput,
+    AutocompleteInput,
+    Toolbar,
+    required,
+    useDataProvider,
+    useNotify,
+    Form,
+    useCreateController,
+} from 'react-admin';
+import {
+    Dialog,
+    DialogActions,
+    DialogContent,
+    DialogTitle,
+    Stack,
+    Grid,
+    Box,
+} from '@mui/material';
+import DialogCloseButton from "../../components/DialogCloseButton";
+import StatusSelectInput from "../../components/StatusSelectInput";
+import MemoInput from "../../components/MemoInput";
+
+const LocAreaRelaCreate = (props) => {
+    const { open, setOpen } = props;
+
+    const translate = useTranslate();
+    const notify = useNotify();
+
+    const handleClose = (event, reason) => {
+        if (reason !== "backdropClick") {
+            setOpen(false);
+        }
+    };
+
+    const handleSuccess = async (data) => {
+        setOpen(false);
+        notify('common.response.success');
+    };
+
+    const handleError = async (error) => {
+        notify(error.message || 'common.response.fail', { type: 'error', messageArgs: { _: error.message } });
+    };
+
+    return (
+        <>
+            <CreateBase
+                record={{}}
+                transform={(data) => {
+                    return data;
+                }}
+                mutationOptions={{ onSuccess: handleSuccess, onError: handleError }}
+            >
+                <Dialog
+                    open={open}
+                    onClose={handleClose}
+                    aria-labelledby="form-dialog-title"
+                    fullWidth
+                    disableRestoreFocus
+                    maxWidth="md"   // 'xs' | 'sm' | 'md' | 'lg' | 'xl'
+                >
+                    <Form>
+                        <DialogTitle id="form-dialog-title" sx={{
+                            position: 'sticky',
+                            top: 0,
+                            backgroundColor: 'background.paper',
+                            zIndex: 1000
+                        }}
+                        >
+                            {translate('create.title')}
+                            <Box sx={{ position: 'absolute', top: 8, right: 8, zIndex: 1001 }}>
+                                <DialogCloseButton onClose={handleClose} />
+                            </Box>
+                        </DialogTitle>
+                        <DialogContent sx={{ mt: 2 }}>
+                            <Grid container rowSpacing={2} columnSpacing={2}>
+                                <Grid item xs={6} display="flex" gap={1}>
+                                    <NumberInput
+                                        label="table.field.locAreaRela.locAreaId"
+                                        source="locAreaId"
+                                        autoFocus
+                                    />
+                                </Grid>
+                                <Grid item xs={6} display="flex" gap={1}>
+                                    <NumberInput
+                                        label="table.field.locAreaRela.locId"
+                                        source="locId"
+                                    />
+                                </Grid>
+
+                                <Grid item xs={6} display="flex" gap={1}>
+                                    <StatusSelectInput />
+                                </Grid>
+                                <Grid item xs={12} display="flex" gap={1}>
+                                    <Stack direction="column" spacing={1} width={'100%'}>
+                                        <MemoInput />
+                                    </Stack>
+                                </Grid>
+                            </Grid>
+                        </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 LocAreaRelaCreate;
diff --git a/rsf-admin/src/page/basicInfo/locAreaRela/LocAreaRelaEdit.jsx b/rsf-admin/src/page/basicInfo/locAreaRela/LocAreaRelaEdit.jsx
new file mode 100644
index 0000000..fd66e5f
--- /dev/null
+++ b/rsf-admin/src/page/basicInfo/locAreaRela/LocAreaRelaEdit.jsx
@@ -0,0 +1,95 @@
+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 LocAreaRelaEdit = () => {
+    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}>
+                            <NumberInput
+                                label="table.field.locAreaRela.locAreaId"
+                                source="locAreaId"
+                                autoFocus
+                            />
+                        </Stack>
+                        <Stack direction='row' gap={2}>
+                            <NumberInput
+                                label="table.field.locAreaRela.locId"
+                                source="locId"
+                            />
+                        </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 LocAreaRelaEdit;
diff --git a/rsf-admin/src/page/basicInfo/locAreaRela/LocAreaRelaList.jsx b/rsf-admin/src/page/basicInfo/locAreaRela/LocAreaRelaList.jsx
new file mode 100644
index 0000000..46e26d8
--- /dev/null
+++ b/rsf-admin/src/page/basicInfo/locAreaRela/LocAreaRelaList.jsx
@@ -0,0 +1,154 @@
+import React, { useState, useRef, useEffect, useMemo, useCallback } from "react";
+import { useNavigate } from 'react-router-dom';
+import {
+    List,
+    DatagridConfigurable,
+    SearchInput,
+    TopToolbar,
+    SelectColumnsButton,
+    EditButton,
+    FilterButton,
+    CreateButton,
+    ExportButton,
+    BulkDeleteButton,
+    WrapperField,
+    useRecordContext,
+    useTranslate,
+    useNotify,
+    useListContext,
+    FunctionField,
+    TextField,
+    NumberField,
+    DateField,
+    BooleanField,
+    ReferenceField,
+    TextInput,
+    DateTimeInput,
+    DateInput,
+    SelectInput,
+    NumberInput,
+    ReferenceInput,
+    ReferenceArrayInput,
+    AutocompleteInput,
+    DeleteButton,
+} from 'react-admin';
+import { Box, Typography, Card, Stack } from '@mui/material';
+import { styled } from '@mui/material/styles';
+import LocAreaRelaCreate from "./LocAreaRelaCreate";
+import LocAreaRelaPanel from "./LocAreaRelaPanel";
+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 { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting';
+import * as Common from '@/utils/common';
+
+const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({
+    '& .css-1vooibu-MuiSvgIcon-root': {
+        height: '.9em'
+    },
+    '& .RaDatagrid-row': {
+        cursor: 'auto'
+    },
+    '& .column-name': {
+    },
+    '& .opt': {
+        width: 200
+    },
+}));
+
+const filters = [
+    <SearchInput source="condition" alwaysOn />,
+    <DateInput label='common.time.after' source="timeStart" alwaysOn />,
+    <DateInput label='common.time.before' source="timeEnd" alwaysOn />,
+
+    <NumberInput source="locAreaId" label="table.field.locAreaRela.locAreaId" />,
+    <NumberInput source="locId" label="table.field.locAreaRela.locId" />,
+
+    <TextInput label="common.field.memo" source="memo" />,
+    <SelectInput
+        label="common.field.status"
+        source="status"
+        choices={[
+            { id: '1', name: 'common.enums.statusTrue' },
+            { id: '0', name: 'common.enums.statusFalse' },
+        ]}
+        resettable
+    />,
+]
+
+const LocAreaRelaList = () => {
+    const translate = useTranslate();
+
+    const [createDialog, setCreateDialog] = useState(false);
+    const [drawerVal, setDrawerVal] = useState(false);
+
+    return (
+        <Box display="flex">
+            <List
+                sx={{
+                    flexGrow: 1,
+                    transition: (theme) =>
+                        theme.transitions.create(['all'], {
+                            duration: theme.transitions.duration.enteringScreen,
+                        }),
+                    marginRight: drawerVal ? `${PAGE_DRAWER_WIDTH}px` : 0,
+                }}
+                title={"menu.locAreaRela"}
+                empty={<EmptyData onClick={() => { setCreateDialog(true) }} />}
+                filters={filters}
+                sort={{ field: "create_time", order: "desc" }}
+                actions={(
+                    <TopToolbar>
+                        <FilterButton />
+                        <MyCreateButton onClick={() => { setCreateDialog(true) }} />
+                        <SelectColumnsButton preferenceKey='locAreaRela' />
+                        <MyExportButton />
+                    </TopToolbar>
+                )}
+                perPage={DEFAULT_PAGE_SIZE}
+            >
+                <StyledDatagrid
+                    preferenceKey='locAreaRela'
+                    bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />}
+                    rowClick={(id, resource, record) => false}
+                    expand={() => <LocAreaRelaPanel />}
+                    expandSingle={true}
+                    omit={['id', 'createTime', 'createBy', 'memo']}
+                >
+                    <NumberField source="id" />
+                    <NumberField source="locAreaId" label="table.field.locAreaRela.locAreaId" />
+                    <NumberField source="locId" label="table.field.locAreaRela.locId" />
+
+                    <ReferenceField source="updateBy" label="common.field.updateBy" reference="user" link={false} sortable={false}>
+                        <TextField source="nickname" />
+                    </ReferenceField>
+                    <DateField source="updateTime" label="common.field.updateTime" showTime />
+                    <ReferenceField source="createBy" label="common.field.createBy" reference="user" link={false} sortable={false}>
+                        <TextField source="nickname" />
+                    </ReferenceField>
+                    <DateField source="createTime" label="common.field.createTime" showTime />
+                    <BooleanField source="statusBool" label="common.field.status" sortable={false} />
+                    <TextField source="memo" label="common.field.memo" sortable={false} />
+                    <WrapperField cellClassName="opt" label="common.field.opt">
+                        <EditButton sx={{ padding: '1px', fontSize: '.75rem' }} />
+                        <DeleteButton sx={{ padding: '1px', fontSize: '.75rem' }} mutationMode={OPERATE_MODE} />
+                    </WrapperField>
+                </StyledDatagrid>
+            </List>
+            <LocAreaRelaCreate
+                open={createDialog}
+                setOpen={setCreateDialog}
+            />
+            <PageDrawer
+                title='LocAreaRela Detail'
+                drawerVal={drawerVal}
+                setDrawerVal={setDrawerVal}
+            >
+            </PageDrawer>
+        </Box>
+    )
+}
+
+export default LocAreaRelaList;
diff --git a/rsf-admin/src/page/basicInfo/locAreaRela/LocAreaRelaPanel.jsx b/rsf-admin/src/page/basicInfo/locAreaRela/LocAreaRelaPanel.jsx
new file mode 100644
index 0000000..47c67d4
--- /dev/null
+++ b/rsf-admin/src/page/basicInfo/locAreaRela/LocAreaRelaPanel.jsx
@@ -0,0 +1,63 @@
+import React, { useState, useRef, useEffect, useMemo } from "react";
+import { Box, Card, CardContent, Grid, Typography, Tooltip } from '@mui/material';
+import {
+    useTranslate,
+    useRecordContext,
+} from 'react-admin';
+import PanelTypography from "../../components/PanelTypography";
+import * as Common from '@/utils/common'
+
+const LocAreaRelaPanel = () => {
+    const record = useRecordContext();
+    if (!record) return null;
+    const translate = useTranslate();
+    return (
+        <>
+            <Card sx={{ width: { xs: 300, sm: 500, md: 600, lg: 800 }, margin: 'auto' }}>
+                <CardContent>
+                    <Grid container spacing={2}>
+                        <Grid item xs={12} sx={{ display: 'flex', justifyContent: 'space-between' }}>
+                            <Typography variant="h6" gutterBottom align="left" sx={{
+                                maxWidth: { xs: '100px', sm: '180px', md: '260px', lg: '360px' },
+                                whiteSpace: 'nowrap',
+                                overflow: 'hidden',
+                                textOverflow: 'ellipsis',
+                            }}>
+                                {Common.camelToPascalWithSpaces(translate('table.field.locAreaRela.locAreaId'))}: {record.locAreaId}
+                            </Typography>
+                            {/*  inherit, primary, secondary, textPrimary, textSecondary, error */}
+                            <Typography variant="h6" gutterBottom align="right" >
+                                ID: {record.id}
+                            </Typography>
+                        </Grid>
+                    </Grid>
+                    <Grid container spacing={2}>
+                        <Grid item xs={12} container alignContent="flex-end">
+                            <Typography variant="caption" color="textSecondary" sx={{ wordWrap: 'break-word', wordBreak: 'break-all' }}>
+                                {Common.camelToPascalWithSpaces(translate('common.field.memo'))}:{record.memo}
+                            </Typography>
+                        </Grid>
+                    </Grid>
+                    <Box height={20}>&nbsp;</Box>
+                    <Grid container spacing={2}>
+                        <Grid item xs={6}>
+                            <PanelTypography
+                                title="table.field.locAreaRela.locAreaId"
+                                property={record.locAreaId}
+                            />
+                        </Grid>
+                        <Grid item xs={6}>
+                            <PanelTypography
+                                title="table.field.locAreaRela.locId"
+                                property={record.locId}
+                            />
+                        </Grid>
+
+                    </Grid>
+                </CardContent>
+            </Card >
+        </>
+    );
+};
+
+export default LocAreaRelaPanel;
diff --git a/rsf-admin/src/page/basicInfo/locAreaRela/index.jsx b/rsf-admin/src/page/basicInfo/locAreaRela/index.jsx
new file mode 100644
index 0000000..a68c3b2
--- /dev/null
+++ b/rsf-admin/src/page/basicInfo/locAreaRela/index.jsx
@@ -0,0 +1,18 @@
+import React, { useState, useRef, useEffect, useMemo } from "react";
+import {
+    ListGuesser,
+    EditGuesser,
+    ShowGuesser,
+} from "react-admin";
+
+import LocAreaRelaList from "./LocAreaRelaList";
+import LocAreaRelaEdit from "./LocAreaRelaEdit";
+
+export default {
+    list: LocAreaRelaList,
+    edit: LocAreaRelaEdit,
+    show: ShowGuesser,
+    recordRepresentation: (record) => {
+        return `${record.locAreaId}`
+    }
+};
diff --git a/rsf-admin/src/page/basicInfo/locType/BindModal.jsx b/rsf-admin/src/page/basicInfo/locType/BindModal.jsx
new file mode 100644
index 0000000..310dd74
--- /dev/null
+++ b/rsf-admin/src/page/basicInfo/locType/BindModal.jsx
@@ -0,0 +1,199 @@
+import React, { useState, useRef, useEffect, useMemo } from "react";
+import {
+    CreateBase,
+    useTranslate,
+    TextInput,
+    NumberInput,
+    BooleanInput,
+    DateInput,
+    SaveButton,
+    SelectInput,
+    ReferenceInput,
+    ReferenceArrayInput,
+    AutocompleteInput,
+    Toolbar,
+    required,
+    useDataProvider,
+    useNotify,
+    Form,
+    useCreateController,
+    useListContext,
+    useRefresh,
+    SelectArrayInput
+} from 'react-admin';
+import {
+    Dialog,
+    DialogActions,
+    DialogContent,
+    DialogTitle,
+    Grid,
+    TextField,
+    Box,
+    Button,
+    Paper,
+    TableContainer,
+    Table,
+    TableHead,
+    TableBody,
+    TableRow,
+    TableCell,
+    Tooltip,
+    IconButton,
+    styled,
+
+
+
+} from '@mui/material';
+import DialogCloseButton from "../../components/DialogCloseButton";
+import DictionarySelect from "../../components/DictionarySelect";
+import { useForm, Controller, useWatch, FormProvider, useFormContext } from "react-hook-form";
+import SaveIcon from '@mui/icons-material/Save';
+import request from '@/utils/request';
+import { Add, Edit, Delete } from '@mui/icons-material';
+import _ from 'lodash';
+import { DataGrid } from '@mui/x-data-grid';
+import StatusSelectInput from "../../components/StatusSelectInput";
+import TreeSelectInput from "@/page/components/TreeSelectInput";
+const MatnrModal = ({ open, setOpen }) => {
+    const refresh = useRefresh();
+    const translate = useTranslate();
+
+
+    const notify = useNotify();
+
+    const [formData, setFormData] = useState({
+        areaId: null,
+        groupId: null,
+        matnrId: null,
+    });
+
+    const { selectedIds, onUnselectItems } = useListContext();
+
+    const handleClose = (event, reason) => {
+        if (reason !== "backdropClick") {
+            setOpen(false);
+            reset()
+            refresh();
+            onUnselectItems()
+        }
+    };
+
+    const reset = () => {
+        setFormData({
+            areaId: null,
+            groupId: null,
+            matnrId: null,
+        })
+    }
+
+    const handleReset = (e) => {
+        e.preventDefault();
+    };
+
+    const handleChange = (value, name) => {
+        setFormData((prevData) => ({
+            ...prevData,
+            [name]: value
+        }));
+        refresh()
+    };
+
+    const removeEmptyKeys = (obj) => {
+        return _.pickBy(obj, (value) => {
+            if (_.isObject(value)) {
+                const newObj = removeEmptyKeys(value);
+                return !_.isEmpty(newObj);
+            }
+            return !_.isNil(value) && (_.isNumber(value) ? value !== 0 : !_.isEmpty(value));
+        });
+    }
+
+    const handleSubmit = async () => {
+        const parmas = {
+            typeId: selectedIds,
+            areaId: formData.areaId,
+            matnrId: formData.matnrId,
+        }
+
+        const res = await request.post(`/locAreaMatRela/matnr/bind`, parmas);
+        if (res?.data?.code === 200) {
+            handleClose()
+
+        } else {
+            notify(res.data.msg);
+        }
+
+
+    }
+
+    const [groupId, setGroupId] = useState();
+
+    const warehouseChange = (e) => {
+        setGroupId(e.target.value)
+    }
+
+    return (
+        <Dialog open={open} maxWidth="md" fullWidth>
+            <Form onSubmit={handleSubmit}>
+                <DialogCloseButton onClose={handleClose} />
+                <DialogTitle>{translate('toolbar.bindmatnr')}</DialogTitle>
+                <DialogContent sx={{ mt: 2 }}>
+                    <Box sx={{ display: 'flex', flexDirection: 'column', gap: 3 }}>
+                        <Grid container spacing={2}>
+                            <Grid item xs={4}>
+                                <ReferenceInput
+                                    source="areaId"
+                                    reference="warehouseAreas"
+                                >
+                                    <AutocompleteInput
+                                        label="table.field.loc.areaId"
+                                        optionText="name"
+                                        onChange={(value) => handleChange(value, 'areaId')}
+                                        value={formData.areaId}
+                                        validate={required()}
+                                        filterToQuery={(val) => ({ name: val })}
+                                    />
+                                </ReferenceInput>
+
+                            </Grid>
+
+                            <Grid item xs={4}>
+                                <TreeSelectInput
+                                    label="table.field.locAreaMatRela.groupId"
+                                    resource={'matnrGroup'}
+                                    source="groupId"
+                                    value={formData.groupId}
+                                    onChange={(e) => handleChange(e.target.value, 'groupId')}
+                                />
+                            </Grid>
+
+
+                            <Grid item xs={4}>
+                                <ReferenceArrayInput source="matnrId" reference="matnr" filter={{ groupId: formData.groupId }}>
+                                    <SelectArrayInput
+                                        label="table.field.locAreaMatRela.matnrId"
+                                        validate={required()}
+                                        value={formData.matnrId}
+                                        onChange={(e) => handleChange(e.target.value, 'matnrId')}
+                                    />
+                                </ReferenceArrayInput>
+
+                            </Grid>
+
+                        </Grid>
+
+                    </Box>
+                </DialogContent>
+                <DialogActions sx={{ position: 'sticky', bottom: 0, backgroundColor: 'background.paper', zIndex: 1000 }}>
+                    <Box sx={{ width: '100%', display: 'flex', justifyContent: 'space-between' }}>
+                        <Button type="submit" variant="contained" startIcon={<SaveIcon />}>
+                            {translate('toolbar.confirm')}
+                        </Button>
+                    </Box>
+                </DialogActions>
+            </Form>
+        </Dialog>
+    );
+}
+
+export default MatnrModal;
\ No newline at end of file
diff --git a/rsf-admin/src/page/basicInfo/locType/LocTypeEdit.jsx b/rsf-admin/src/page/basicInfo/locType/LocTypeEdit.jsx
index a630b99..666cd88 100644
--- a/rsf-admin/src/page/basicInfo/locType/LocTypeEdit.jsx
+++ b/rsf-admin/src/page/basicInfo/locType/LocTypeEdit.jsx
@@ -49,6 +49,7 @@
             mutationMode={EDIT_MODE}
             actions={<CustomerTopToolBar />}
             aside={<EditBaseAside />}
+            title={"menu.locType"}
         >
             <SimpleForm
                 shouldUnregister
diff --git a/rsf-admin/src/page/basicInfo/locType/LocTypeList.jsx b/rsf-admin/src/page/basicInfo/locType/LocTypeList.jsx
index 45a4e4d..5fd0003 100644
--- a/rsf-admin/src/page/basicInfo/locType/LocTypeList.jsx
+++ b/rsf-admin/src/page/basicInfo/locType/LocTypeList.jsx
@@ -31,6 +31,9 @@
     ReferenceArrayInput,
     AutocompleteInput,
     DeleteButton,
+    useRefresh,
+    Button,
+    useList
 } from 'react-admin';
 import { Box, Typography, Card, Stack } from '@mui/material';
 import { styled } from '@mui/material/styles';
@@ -42,6 +45,8 @@
 import PageDrawer from "../../components/PageDrawer";
 import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting';
 import * as Common from '@/utils/common';
+import BindModal from "./BindModal";
+import LinkIcon from '@mui/icons-material/Link';
 
 const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({
     '& .css-1vooibu-MuiSvgIcon-root': {
@@ -109,7 +114,10 @@
             >
                 <StyledDatagrid
                     preferenceKey='locType'
-                    bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />}
+                    bulkActionButtons={<>
+                        <BindButton />
+                        <BulkDeleteButton />
+                    </>}
                     rowClick={(id, resource, record) => false}
                     omit={['id', 'createTime', 'createBy', 'memo']}
                 >
@@ -150,3 +158,26 @@
 }
 
 export default LocTypeList;
+
+const BindButton = () => {
+    const record = useRecordContext();
+    const notify = useNotify();
+    const refresh = useRefresh();
+
+
+    const [createDialog, setCreateDialog] = useState(false);
+
+    return (
+        <>
+            <Button onClick={() => setCreateDialog(true)} label={"toolbar.bindmatnr"}>
+                <LinkIcon />
+            </Button>
+
+            <BindModal
+                open={createDialog}
+                setOpen={setCreateDialog}
+            />
+        </>
+
+    )
+}
diff --git a/rsf-admin/src/page/basicInfo/matnr/BindModal.jsx b/rsf-admin/src/page/basicInfo/matnr/BindModal.jsx
new file mode 100644
index 0000000..3ada880
--- /dev/null
+++ b/rsf-admin/src/page/basicInfo/matnr/BindModal.jsx
@@ -0,0 +1,186 @@
+import React, { useState, useRef, useEffect, useMemo } from "react";
+import {
+    CreateBase,
+    useTranslate,
+    TextInput,
+    NumberInput,
+    BooleanInput,
+    DateInput,
+    SaveButton,
+    SelectInput,
+    ReferenceInput,
+    ReferenceArrayInput,
+    AutocompleteInput,
+    Toolbar,
+    required,
+    useDataProvider,
+    useNotify,
+    Form,
+    useCreateController,
+    useListContext,
+    useRefresh,
+    SelectArrayInput
+} from 'react-admin';
+import {
+    Dialog,
+    DialogActions,
+    DialogContent,
+    DialogTitle,
+    Grid,
+    TextField,
+    Box,
+    Button,
+    Paper,
+    TableContainer,
+    Table,
+    TableHead,
+    TableBody,
+    TableRow,
+    TableCell,
+    Tooltip,
+    IconButton,
+    styled,
+
+} from '@mui/material';
+import DialogCloseButton from "../../components/DialogCloseButton";
+import DictionarySelect from "../../components/DictionarySelect";
+import { useForm, Controller, useWatch, FormProvider, useFormContext } from "react-hook-form";
+import SaveIcon from '@mui/icons-material/Save';
+import request from '@/utils/request';
+import { Add, Edit, Delete } from '@mui/icons-material';
+import _ from 'lodash';
+import { DataGrid } from '@mui/x-data-grid';
+import StatusSelectInput from "../../components/StatusSelectInput";
+import TreeSelectInput from "@/page/components/TreeSelectInput";
+const MatnrModal = ({ open, setOpen }) => {
+    const refresh = useRefresh();
+    const translate = useTranslate();
+
+
+    const notify = useNotify();
+
+    const [formData, setFormData] = useState({
+        areaId: null,
+        locId: null,
+    });
+
+    const { selectedIds, onUnselectItems } = useListContext();
+
+    const handleClose = (event, reason) => {
+        if (reason !== "backdropClick") {
+            setOpen(false);
+            reset()
+            refresh();
+            onUnselectItems()
+        }
+    };
+
+    const reset = () => {
+        setFormData({
+            areaId: null,
+            locId: null,
+        })
+    }
+
+    const handleReset = (e) => {
+        e.preventDefault();
+    };
+
+    const handleChange = (value, name) => {
+        setFormData((prevData) => ({
+            ...prevData,
+            [name]: value
+        }));
+        refresh()
+    };
+
+    const removeEmptyKeys = (obj) => {
+        return _.pickBy(obj, (value) => {
+            if (_.isObject(value)) {
+                const newObj = removeEmptyKeys(value);
+                return !_.isEmpty(newObj);
+            }
+            return !_.isNil(value) && (_.isNumber(value) ? value !== 0 : !_.isEmpty(value));
+        });
+    }
+
+    const handleSubmit = async () => {
+        const parmas = {
+            matnrId: selectedIds,
+            areaId: formData.areaId,
+            locId: formData.locId,
+        }
+
+        const res = await request.post(`/locAreaMatRela/matnr/bind`, parmas);
+        if (res?.data?.code === 200) {
+            handleClose()
+
+        } else {
+            notify(res.data.msg);
+        }
+
+
+    }
+
+    const [groupId, setGroupId] = useState();
+
+    const warehouseChange = (e) => {
+        setGroupId(e.target.value)
+    }
+
+    return (
+        <Dialog open={open} maxWidth="md" fullWidth>
+            <Form onSubmit={handleSubmit}>
+                <DialogCloseButton onClose={handleClose} />
+                <DialogTitle>{translate('toolbar.bindloc')}</DialogTitle>
+                <DialogContent sx={{ mt: 2 }}>
+                    <Box sx={{ display: 'flex', flexDirection: 'column', gap: 3 }}>
+                        <Grid container spacing={2}>
+                            <Grid item xs={4}>
+                                <ReferenceInput
+                                    source="areaId"
+                                    reference="warehouseAreas"
+                                >
+                                    <AutocompleteInput
+                                        label="table.field.loc.areaId"
+                                        optionText="name"
+                                        onChange={(value) => handleChange(value, 'areaId')}
+                                        value={formData.areaId}
+                                        validate={required()}
+                                        filterToQuery={(val) => ({ name: val })}
+                                    />
+                                </ReferenceInput>
+
+                            </Grid>
+
+
+                            <Grid item xs={4}>
+                                <ReferenceArrayInput source="locId" reference="loc" >
+                                    <SelectArrayInput
+                                        label="table.field.locAreaMatRela.locId"
+                                        validate={required()}
+                                        optionText={'code'}
+                                        value={formData.locId}
+                                        onChange={(e) => handleChange(e.target.value, 'locId')}
+                                    />
+                                </ReferenceArrayInput>
+
+                            </Grid>
+
+                        </Grid>
+
+                    </Box>
+                </DialogContent>
+                <DialogActions sx={{ position: 'sticky', bottom: 0, backgroundColor: 'background.paper', zIndex: 1000 }}>
+                    <Box sx={{ width: '100%', display: 'flex', justifyContent: 'space-between' }}>
+                        <Button type="submit" variant="contained" startIcon={<SaveIcon />}>
+                            {translate('toolbar.confirm')}
+                        </Button>
+                    </Box>
+                </DialogActions>
+            </Form>
+        </Dialog>
+    );
+}
+
+export default MatnrModal;
\ No newline at end of file
diff --git a/rsf-admin/src/page/basicInfo/matnr/MatnrEdit.jsx b/rsf-admin/src/page/basicInfo/matnr/MatnrEdit.jsx
index 8cb7351..2264d6e 100644
--- a/rsf-admin/src/page/basicInfo/matnr/MatnrEdit.jsx
+++ b/rsf-admin/src/page/basicInfo/matnr/MatnrEdit.jsx
@@ -101,6 +101,7 @@
             mutationMode={EDIT_MODE}
             actions={<CustomerTopToolBar />}
             aside={<EditBaseAside />}
+            title={"menu.matnr"}
         >
             <SimpleForm
                 shouldUnregister
diff --git a/rsf-admin/src/page/basicInfo/matnr/MatnrList.jsx b/rsf-admin/src/page/basicInfo/matnr/MatnrList.jsx
index e27b5e6..5dc0c6c 100644
--- a/rsf-admin/src/page/basicInfo/matnr/MatnrList.jsx
+++ b/rsf-admin/src/page/basicInfo/matnr/MatnrList.jsx
@@ -55,6 +55,8 @@
 import request from '@/utils/request';
 import BatchModal from './BatchModal';
 import PrintModal from './PrintModal';
+import LinkIcon from '@mui/icons-material/Link';
+import BindModal from './BindModal';
 
 const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({
     '& .css-1vooibu-MuiSvgIcon-root': {
@@ -84,7 +86,7 @@
         overflow: 'hidden',
         textOverflow: 'ellipsis',
         display: 'block',
-        width: '100px',
+        width: '300px',
     },
     '& .RaDatagrid-table': {
         width: '100%'
@@ -238,6 +240,7 @@
                     preferenceKey='matnr'
                     bulkActionButtons={<>
                         <BatchButton />
+                        <BindButton />
                         <PrintButton />
                         <BulkDeleteButton mutationMode={OPERATE_MODE} />
                     </>}
@@ -379,4 +382,27 @@
         </>
 
     )
+}
+
+const BindButton = () => {
+    const record = useRecordContext();
+    const notify = useNotify();
+    const refresh = useRefresh();
+
+
+    const [createDialog, setCreateDialog] = useState(false);
+
+    return (
+        <>
+            <Button onClick={() => setCreateDialog(true)} label={"toolbar.bindloc"}>
+                <LinkIcon />
+            </Button>
+
+            <BindModal
+                open={createDialog}
+                setOpen={setCreateDialog}
+            />
+        </>
+
+    )
 }
\ No newline at end of file
diff --git a/rsf-admin/src/page/basicInfo/matnr/PrintModal.jsx b/rsf-admin/src/page/basicInfo/matnr/PrintModal.jsx
index 7513fbe..f618577 100644
--- a/rsf-admin/src/page/basicInfo/matnr/PrintModal.jsx
+++ b/rsf-admin/src/page/basicInfo/matnr/PrintModal.jsx
@@ -210,9 +210,12 @@
                 }
             }))
             setData(val)
-            val.forEach((el) => {
-                jsbarcode(`#barcode${el.code}`, el.code, { height: 30 });
-            });
+            setTimeout(() => {
+                val.forEach((el) => {
+                    jsbarcode(`#barcode${el.code}`, el.code, { height: 30 });
+                });
+            }, 10);
+
 
 
         } else {
diff --git a/rsf-admin/src/page/basicInfo/matnrGroup/MatnrGroupCreate.jsx b/rsf-admin/src/page/basicInfo/matnrGroup/MatnrGroupCreate.jsx
index 0146f24..4c9aa78 100644
--- a/rsf-admin/src/page/basicInfo/matnrGroup/MatnrGroupCreate.jsx
+++ b/rsf-admin/src/page/basicInfo/matnrGroup/MatnrGroupCreate.jsx
@@ -84,7 +84,7 @@
                         </DialogTitle>
                         <DialogContent sx={{ mt: 2 }}>
                             <Grid container rowSpacing={2} columnSpacing={2}>
-    
+
                                 <Grid item xs={6} display="flex" gap={1}>
                                     <TextInput
                                         label="table.field.matnrGroup.name"
@@ -104,6 +104,7 @@
                                 <Grid item xs={6} display="flex" gap={1}>
                                     <NumberInput
                                         label="table.field.matnrGroup.parentId"
+                                        validate={[required()]}
                                         source="parentId"
                                     />
                                 </Grid>
diff --git a/rsf-admin/src/page/basicInfo/matnrGroup/MatnrGroupEdit.jsx b/rsf-admin/src/page/basicInfo/matnrGroup/MatnrGroupEdit.jsx
index 206a847..1cfd61c 100644
--- a/rsf-admin/src/page/basicInfo/matnrGroup/MatnrGroupEdit.jsx
+++ b/rsf-admin/src/page/basicInfo/matnrGroup/MatnrGroupEdit.jsx
@@ -50,6 +50,7 @@
             <Grid item xs={6} display="flex" gap={1}>
                 <TreeSelectInput
                     label="table.field.matnrGroup.parentId"
+                    validate={[required()]}
                     value={editRecord?.parentId}
                     isTranslate
                     resource={resource}
@@ -76,7 +77,7 @@
 
 const MatnrGroupEdit = (props) => {
     const { editRecord, open, setOpen, callback, resource } = props;
-    
+
     const translate = useTranslate();
     const notify = useNotify();
 
@@ -138,43 +139,43 @@
     };
 
     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>
-    </>
+        <>
+            <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>
+        </>
     )
 }
 
diff --git a/rsf-admin/src/page/basicInfo/matnrGroup/MatnrGroupList.jsx b/rsf-admin/src/page/basicInfo/matnrGroup/MatnrGroupList.jsx
index 732710c..5b22181 100644
--- a/rsf-admin/src/page/basicInfo/matnrGroup/MatnrGroupList.jsx
+++ b/rsf-admin/src/page/basicInfo/matnrGroup/MatnrGroupList.jsx
@@ -268,7 +268,7 @@
                     >
                         {expandAll ? translate('common.action.collapseAll') : translate('common.action.expandAll')}
                     </Button>
-                    {/* <TextField
+                    <TextField
                         label="Search"
                         value={filter}
                         onChange={({ target }) => {
@@ -278,7 +278,7 @@
                         size="small"
                         margin="dense"
                         fullWidth
-                    /> */}
+                    />
                 </Box>
                 <Box>
                     <Button
diff --git a/rsf-admin/src/page/basicInfo/warehouse/WarehouseEdit.jsx b/rsf-admin/src/page/basicInfo/warehouse/WarehouseEdit.jsx
index 18c97bd..c04ccc1 100644
--- a/rsf-admin/src/page/basicInfo/warehouse/WarehouseEdit.jsx
+++ b/rsf-admin/src/page/basicInfo/warehouse/WarehouseEdit.jsx
@@ -49,6 +49,7 @@
             mutationMode={EDIT_MODE}
             actions={<CustomerTopToolBar />}
             aside={<EditBaseAside />}
+            title={"menu.warehouse"}
         >
             <SimpleForm
                 shouldUnregister
diff --git a/rsf-admin/src/page/components/ConfirmModal.jsx b/rsf-admin/src/page/components/ConfirmModal.jsx
new file mode 100644
index 0000000..118cab1
--- /dev/null
+++ b/rsf-admin/src/page/components/ConfirmModal.jsx
@@ -0,0 +1,50 @@
+import React, { useState, useRef, useEffect, useMemo, useCallback } from "react";
+import { Button, Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle } from '@mui/material';
+import {
+    useTranslate,
+} from 'react-admin';
+
+const ConfirmModal = (props) => {
+    const { open, onConfirm, setOpen } = props;
+    const translate = useTranslate();
+
+
+
+    const handleClose = (event) => {
+        event.stopPropagation();
+        setOpen(false);
+    };
+
+    const handleConfirm = (event) => {
+        handleClose(event);
+        onConfirm();
+    };
+
+    return (
+        <>
+            <Dialog
+                aria-labelledby="dialog-title"
+                aria-describedby="dialog-description"
+                open={open}
+                onClose={handleClose}
+            >
+                <DialogTitle>{translate('common.msg.confirm.tip')}</DialogTitle>
+                <DialogContent>
+                    <DialogContentText>
+                        {translate('common.msg.confirm.desc')}
+                    </DialogContentText>
+                </DialogContent>
+                <DialogActions>
+                    <Button onClick={handleClose} color="primary">
+                        {translate('ra.action.cancel')}
+                    </Button>
+                    <Button onClick={handleConfirm} color="primary">
+                        {translate('ra.action.confirm')}
+                    </Button>
+                </DialogActions>
+            </Dialog>
+        </>
+    )
+}
+
+export default ConfirmModal;
\ No newline at end of file
diff --git a/rsf-admin/src/page/container/ContainerEdit.jsx b/rsf-admin/src/page/container/ContainerEdit.jsx
index d31de24..e1623bd 100644
--- a/rsf-admin/src/page/container/ContainerEdit.jsx
+++ b/rsf-admin/src/page/container/ContainerEdit.jsx
@@ -50,6 +50,7 @@
             mutationMode={EDIT_MODE}
             actions={<CustomerTopToolBar />}
             aside={<EditBaseAside />}
+            title={"menu.container"}
         >
             <SimpleForm
                 shouldUnregister
diff --git a/rsf-admin/src/page/contract/ContractEdit.jsx b/rsf-admin/src/page/contract/ContractEdit.jsx
index 503ed00..ef0e6b5 100644
--- a/rsf-admin/src/page/contract/ContractEdit.jsx
+++ b/rsf-admin/src/page/contract/ContractEdit.jsx
@@ -49,6 +49,7 @@
             mutationMode={EDIT_MODE}
             actions={<CustomerTopToolBar />}
             aside={<EditBaseAside />}
+            title={"menu.contract"}
         >
             <SimpleForm
                 shouldUnregister
diff --git a/rsf-admin/src/page/fields/FieldsList.jsx b/rsf-admin/src/page/fields/FieldsList.jsx
index 5c1f785..78970d9 100644
--- a/rsf-admin/src/page/fields/FieldsList.jsx
+++ b/rsf-admin/src/page/fields/FieldsList.jsx
@@ -68,13 +68,13 @@
     <SelectInput source="unique" label="table.field.fields.unique"
         choices={[
             { id: 0, name: ' 闈炲敮涓�' },
-            { id:   1, name: '  鍞竴' },
+            { id: 1, name: '  鍞竴' },
         ]}
     />,
     <SelectInput source="flagEnable" label="table.field.fields.flagEnable"
         choices={[
             { id: 0, name: ' 涓嶅惎鐢�' },
-            { id:  1, name: ' 鍚敤' },
+            { id: 1, name: ' 鍚敤' },
         ]}
     />,
 
@@ -105,7 +105,7 @@
                         theme.transitions.create(['all'], {
                             duration: theme.transitions.duration.enteringScreen,
                         }),
-                    marginRight: !!drawerVal ? `${PAGE_DRAWER_WIDTH}px` : 0,
+                    marginRight: drawerVal ? `${PAGE_DRAWER_WIDTH}px` : 0,
                 }}
                 title={"menu.fields"}
                 empty={<EmptyData onClick={() => { setCreateDialog(true) }} />}
@@ -125,8 +125,6 @@
                     preferenceKey='fields'
                     bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />}
                     rowClick={(id, resource, record) => false}
-                    expand={() => <FieldsPanel />}
-                    expandSingle={true}
                     omit={['id', 'createTime', 'createBy', 'memo']}
                 >
                     <NumberField source="id" />
diff --git a/rsf-admin/src/page/fieldsItem/FieldsItemList.jsx b/rsf-admin/src/page/fieldsItem/FieldsItemList.jsx
index 41c2121..914518f 100644
--- a/rsf-admin/src/page/fieldsItem/FieldsItemList.jsx
+++ b/rsf-admin/src/page/fieldsItem/FieldsItemList.jsx
@@ -96,7 +96,7 @@
                         theme.transitions.create(['all'], {
                             duration: theme.transitions.duration.enteringScreen,
                         }),
-                    marginRight: !!drawerVal ? `${PAGE_DRAWER_WIDTH}px` : 0,
+                    marginRight: drawerVal ? `${PAGE_DRAWER_WIDTH}px` : 0,
                 }}
                 title={"menu.fieldsItem"}
                 empty={<EmptyData onClick={() => { setCreateDialog(true) }} />}
@@ -116,8 +116,6 @@
                     preferenceKey='fieldsItem'
                     bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />}
                     rowClick={(id, resource, record) => false}
-                    expand={() => <FieldsItemPanel />}
-                    expandSingle={true}
                     omit={['id', 'createTime', 'createBy', 'memo']}
                 >
                     <NumberField source="id" />
diff --git a/rsf-admin/src/page/purchaseItem/PurchaseItemList.jsx b/rsf-admin/src/page/purchaseItem/PurchaseItemList.jsx
index 139441c..ce3083d 100644
--- a/rsf-admin/src/page/purchaseItem/PurchaseItemList.jsx
+++ b/rsf-admin/src/page/purchaseItem/PurchaseItemList.jsx
@@ -129,8 +129,6 @@
             preferenceKey='purchaseItem'
             bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />}
             rowClick={(id, resource, record) => false}
-            expand={() => <PurchaseItemPanel />}
-            expandSingle={true}
             omit={['id', 'createTime', 'createBy', 'memo']}
           >
             <NumberField source="id" />
diff --git a/rsf-admin/src/page/qlyInspect/QlyInspectList.jsx b/rsf-admin/src/page/qlyInspect/QlyInspectList.jsx
index d1fa634..a23f223 100644
--- a/rsf-admin/src/page/qlyInspect/QlyInspectList.jsx
+++ b/rsf-admin/src/page/qlyInspect/QlyInspectList.jsx
@@ -97,7 +97,7 @@
                         theme.transitions.create(['all'], {
                             duration: theme.transitions.duration.enteringScreen,
                         }),
-                    marginRight: !!drawerVal ? `${PAGE_DRAWER_WIDTH}px` : 0,
+                    marginRight: drawerVal ? `${PAGE_DRAWER_WIDTH}px` : 0,
                 }}
                 title={"menu.qlyInspect"}
                 empty={<EmptyData onClick={() => { setCreateDialog(true) }} />}
@@ -117,8 +117,6 @@
                     preferenceKey='qlyInspect'
                     bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />}
                     rowClick={(id, resource, record) => false}
-                    expand={() => <QlyInspectPanel />}
-                    expandSingle={true}
                     omit={['id', 'createTime', 'createBy', 'memo']}
                 >
                     <NumberField source="id" />
diff --git a/rsf-admin/src/page/qlyIsptItem/QlyIsptItemList.jsx b/rsf-admin/src/page/qlyIsptItem/QlyIsptItemList.jsx
index ae7a557..b53c5c3 100644
--- a/rsf-admin/src/page/qlyIsptItem/QlyIsptItemList.jsx
+++ b/rsf-admin/src/page/qlyIsptItem/QlyIsptItemList.jsx
@@ -103,7 +103,7 @@
                         theme.transitions.create(['all'], {
                             duration: theme.transitions.duration.enteringScreen,
                         }),
-                    marginRight: !!drawerVal ? `${PAGE_DRAWER_WIDTH}px` : 0,
+                    marginRight: drawerVal ? `${PAGE_DRAWER_WIDTH}px` : 0,
                 }}
                 title={"menu.qlyIsptItem"}
                 empty={<EmptyData onClick={() => { setCreateDialog(true) }} />}
@@ -123,8 +123,6 @@
                     preferenceKey='qlyIsptItem'
                     bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />}
                     rowClick={(id, resource, record) => false}
-                    expand={() => <QlyIsptItemPanel />}
-                    expandSingle={true}
                     omit={['id', 'createTime', 'createBy', 'memo']}
                 >
                     <NumberField source="id" />
diff --git a/rsf-admin/src/page/system/config/ConfigList.jsx b/rsf-admin/src/page/system/config/ConfigList.jsx
index fb9b7c5..7dee9f5 100644
--- a/rsf-admin/src/page/system/config/ConfigList.jsx
+++ b/rsf-admin/src/page/system/config/ConfigList.jsx
@@ -100,7 +100,7 @@
                         theme.transitions.create(['all'], {
                             duration: theme.transitions.duration.enteringScreen,
                         }),
-                    marginRight: !!drawerVal ? `${PAGE_DRAWER_WIDTH}px` : 0,
+                    marginRight: drawerVal ? `${PAGE_DRAWER_WIDTH}px` : 0,
                 }}
                 title={"menu.config"}
                 empty={<EmptyData onClick={() => { setCreateDialog(true) }} />}
@@ -121,8 +121,6 @@
                     preferenceKey='config'
                     bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />}
                     rowClick={(id, resource, record) => false}
-                    expand={() => <ConfigPanel />}
-                    expandSingle={true}
                     omit={['id', 'createTime', 'memo']}
                 >
                     <NumberField source="id" />
diff --git a/rsf-admin/src/page/system/dicts/dictData/DictDataCreate.jsx b/rsf-admin/src/page/system/dicts/dictData/DictDataCreate.jsx
index f15c25d..afc4ea0 100644
--- a/rsf-admin/src/page/system/dicts/dictData/DictDataCreate.jsx
+++ b/rsf-admin/src/page/system/dicts/dictData/DictDataCreate.jsx
@@ -114,6 +114,7 @@
                                 <Grid item xs={6} display="flex" gap={1}>
                                     <TextInput
                                         label="table.field.dictData.label"
+                                        validate={required()}
                                         source="label"
                                         parse={v => v}
                                     />
diff --git a/rsf-admin/src/page/system/dicts/dictData/DictDataEdit.jsx b/rsf-admin/src/page/system/dicts/dictData/DictDataEdit.jsx
index a52a4c2..80fac6f 100644
--- a/rsf-admin/src/page/system/dicts/dictData/DictDataEdit.jsx
+++ b/rsf-admin/src/page/system/dicts/dictData/DictDataEdit.jsx
@@ -93,6 +93,7 @@
                             <TextInput
                                 label="table.field.dictData.label"
                                 source="label"
+                                validate={required()}
                                 parse={v => v}
                             />
                         </Stack>
diff --git a/rsf-admin/src/page/system/dicts/dictData/DictDataList.jsx b/rsf-admin/src/page/system/dicts/dictData/DictDataList.jsx
index 21a3f45..7af9d9d 100644
--- a/rsf-admin/src/page/system/dicts/dictData/DictDataList.jsx
+++ b/rsf-admin/src/page/system/dicts/dictData/DictDataList.jsx
@@ -128,8 +128,6 @@
                         preferenceKey='dictData'
                         bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />}
                         rowClick={(id, resource, record) => false}
-                        expand={() => <DictDataPanel />}
-                        expandSingle={true}
                         omit={['id', 'createTime', 'createBy', 'memo']}
                     >
                         <NumberField source="id" />
diff --git a/rsf-admin/src/page/system/dicts/dictType/DictTypeList.jsx b/rsf-admin/src/page/system/dicts/dictType/DictTypeList.jsx
index 09058f4..e7d18bd 100644
--- a/rsf-admin/src/page/system/dicts/dictType/DictTypeList.jsx
+++ b/rsf-admin/src/page/system/dicts/dictType/DictTypeList.jsx
@@ -119,8 +119,6 @@
                     preferenceKey='dictType'
                     bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />}
                     rowClick={(id, resource, record) => false}
-                    expand={() => <DictTypePanel />}
-                    expandSingle={true}
                     omit={['id', 'createTime', 'createBy', 'memo']}
                 >
                     <NumberField source="id" />
diff --git a/rsf-admin/src/page/system/host/HostList.jsx b/rsf-admin/src/page/system/host/HostList.jsx
index 1038cf0..82dd1e8 100644
--- a/rsf-admin/src/page/system/host/HostList.jsx
+++ b/rsf-admin/src/page/system/host/HostList.jsx
@@ -82,7 +82,7 @@
                         theme.transitions.create(['all'], {
                             duration: theme.transitions.duration.enteringScreen,
                         }),
-                    marginRight: !!drawerVal ? `${PAGE_DRAWER_WIDTH}px` : 0,
+                    marginRight: drawerVal ? `${PAGE_DRAWER_WIDTH}px` : 0,
                 }}
                 title={"menu.host"}
                 empty={<EmptyData onClick={() => { setCreateDialog(true) }} />}
@@ -102,8 +102,6 @@
                     preferenceKey='host'
                     bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />}
                     rowClick={(id, resource, record) => false}
-                    expand={() => <HostPanel />}
-                    expandSingle={true}
                     omit={['id', 'createTime', 'memo']}
                 >
                     <NumberField source="id" />
diff --git a/rsf-admin/src/page/system/serialRule/SerialRuleList.jsx b/rsf-admin/src/page/system/serialRule/SerialRuleList.jsx
index 355c08f..6008fab 100644
--- a/rsf-admin/src/page/system/serialRule/SerialRuleList.jsx
+++ b/rsf-admin/src/page/system/serialRule/SerialRuleList.jsx
@@ -146,8 +146,6 @@
             <BulkDeleteButton mutationMode={OPERATE_MODE} />
           )}
           rowClick={(id, resource, record) => false}
-          expand={() => <SerialRulePanel />}
-          expandSingle={true}
           omit={["id", "createTime", "createBy", "memo"]}
         >
           <NumberField source="id" />
diff --git a/rsf-admin/src/page/system/serialRuleItem/SerialRuleItemList.jsx b/rsf-admin/src/page/system/serialRuleItem/SerialRuleItemList.jsx
index 2e198d2..703190d 100644
--- a/rsf-admin/src/page/system/serialRuleItem/SerialRuleItemList.jsx
+++ b/rsf-admin/src/page/system/serialRuleItem/SerialRuleItemList.jsx
@@ -148,8 +148,6 @@
               <BulkDeleteButton mutationMode={OPERATE_MODE} />
             )}
             rowClick={(id, resource, record) => false}
-            expand={() => <SerialRuleItemPanel />}
-            expandSingle={true}
             omit={["id", "createTime", "createBy", "memo"]}
           >
             <NumberField source="id" />
diff --git a/rsf-admin/src/page/system/tenant/TenantList.jsx b/rsf-admin/src/page/system/tenant/TenantList.jsx
index 701461d..7774295 100644
--- a/rsf-admin/src/page/system/tenant/TenantList.jsx
+++ b/rsf-admin/src/page/system/tenant/TenantList.jsx
@@ -86,7 +86,7 @@
                         theme.transitions.create(['all'], {
                             duration: theme.transitions.duration.enteringScreen,
                         }),
-                    marginRight: !!drawerVal ? `${PAGE_DRAWER_WIDTH}px` : 0,
+                    marginRight: drawerVal ? `${PAGE_DRAWER_WIDTH}px` : 0,
                 }}
                 title={"menu.tenant"}
                 empty={<EmptyData onClick={() => { setCreateDialog(true) }} />}
@@ -106,8 +106,6 @@
                     preferenceKey='tenant'
                     bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />}
                     rowClick={(id, resource, record) => false}
-                    expand={() => <TenantPanel />}
-                    expandSingle={true}
                     omit={['id', 'createTime', 'memo']}
                 >
                     <NumberField source="id" />
diff --git a/rsf-admin/src/page/system/userLogin/UserLoginList.jsx b/rsf-admin/src/page/system/userLogin/UserLoginList.jsx
index b8758f8..4f66a88 100644
--- a/rsf-admin/src/page/system/userLogin/UserLoginList.jsx
+++ b/rsf-admin/src/page/system/userLogin/UserLoginList.jsx
@@ -100,7 +100,7 @@
                         theme.transitions.create(['all'], {
                             duration: theme.transitions.duration.enteringScreen,
                         }),
-                    marginRight: !!drawerVal ? `${PAGE_DRAWER_WIDTH}px` : 0,
+                    marginRight: drawerVal ? `${PAGE_DRAWER_WIDTH}px` : 0,
                 }}
                 title={"menu.userLogin"}
                 empty={<EmptyData onClick={() => { setCreateDialog(true) }} />}
@@ -120,8 +120,6 @@
                     preferenceKey='userLogin'
                     bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />}
                     rowClick={(id, resource, record) => false}
-                    expand={() => <UserLoginPanel />}
-                    expandSingle={true}
                     omit={['id', 'memo', 'type', 'system', 'updateTime']}
                 >
                     <NumberField source="id" />
diff --git a/rsf-admin/src/page/warehouseAreas/WarehouseAreasList.jsx b/rsf-admin/src/page/warehouseAreas/WarehouseAreasList.jsx
index 227cb83..ea777c0 100644
--- a/rsf-admin/src/page/warehouseAreas/WarehouseAreasList.jsx
+++ b/rsf-admin/src/page/warehouseAreas/WarehouseAreasList.jsx
@@ -60,7 +60,7 @@
 
 const filters = [
     <SearchInput source="condition" alwaysOn />,
-
+    <TextField source="warehouseId" label="table.field.warehouseAreas.wareId" alwaysOn />,
     <TextInput source="uuid" label="table.field.warehouseAreas.uuid" />,
     <TextInput source="name" label="table.field.warehouseAreas.name" />,
     <TextInput source="code" label="table.field.warehouseAreas.code" />,
diff --git a/rsf-admin/src/page/warehouseAreasItem/WarehouseAreasItemList.jsx b/rsf-admin/src/page/warehouseAreasItem/WarehouseAreasItemList.jsx
index 9b03b48..999b8d4 100644
--- a/rsf-admin/src/page/warehouseAreasItem/WarehouseAreasItemList.jsx
+++ b/rsf-admin/src/page/warehouseAreasItem/WarehouseAreasItemList.jsx
@@ -127,8 +127,6 @@
                     preferenceKey='warehouseAreasItem'
                     bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />}
                     rowClick={(id, resource, record) => false}
-                    expand={() => <WarehouseAreasItemPanel />}
-                    expandSingle={true}
                     omit={['id', 'createTime', 'createBy', 'memo']}
                 >
                     <NumberField source="id" />

--
Gitblit v1.9.1