From 36e6c98d9e34fd8e90ae803e7de2eef0a4d0741b Mon Sep 17 00:00:00 2001
From: skyouc
Date: 星期二, 18 二月 2025 16:45:57 +0800
Subject: [PATCH] #新增 1. 添加仓库信息 2. 添加库区信息表

---
 rsf-server/src/main/resources/mapper/manager/WarehouseAreasMapper.xml                               |    5 
 rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/WarehouseAreas.java                  |  281 +++++++
 rsf-server/src/main/java/com/vincent/rsf/server/manager/mapper/WarehouseMapper.java                 |   12 
 rsf-admin/src/page/warehouse/WarehouseCreate.jsx                                                    |  171 ++++
 rsf-admin/src/page/warehouseAreas/index.jsx                                                         |   18 
 rsf-server/src/main/java/com/vincent/rsf/server/common/CodeBuilder.java                             |    8 
 rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/WarehouseAreasServiceImpl.java |   12 
 rsf-admin/src/page/warehouseAreas/WarehouseAreasEdit.jsx                                            |  155 ++++
 rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/WarehouseAreasController.java    |  110 ++
 rsf-admin/src/i18n/zh.js                                                                            |   24 
 rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/Warehouse.java                       |  242 ++++++
 rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/WarehouseServiceImpl.java      |   12 
 rsf-admin/src/i18n/en.js                                                                            |   24 
 rsf-admin/src/page/ResourceContent.js                                                               |    6 
 rsf-admin/src/page/warehouse/WarehouseEdit.jsx                                                      |  143 +++
 rsf-admin/src/page/warehouse/WarehousePanel.jsx                                                     |  105 ++
 rsf-server/src/main/java/com/vincent/rsf/server/manager/mapper/WarehouseAreasMapper.java            |   12 
 rsf-server/src/main/java/com/vincent/rsf/server/manager/service/WarehouseAreasService.java          |    8 
 rsf-admin/src/page/warehouse/WarehouseList.jsx                                                      |  168 ++++
 rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/WarehouseController.java         |  110 ++
 rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/Matnr.java                           |   21 
 rsf-admin/src/page/warehouse/index.jsx                                                              |   18 
 rsf-server/src/main/java/com/vincent/rsf/server/manager/service/WarehouseService.java               |    8 
 rsf-server/src/main/java/warehouseAreas.sql                                                         |   29 
 rsf-admin/src/page/warehouseAreas/WarehouseAreasCreate.jsx                                          |  180 ++++
 rsf-admin/src/page/warehouseAreas/WarehouseAreasList.jsx                                            |  185 +++++
 rsf-server/src/main/java/warehouse.sql                                                              |   30 
 rsf-admin/src/page/warehouseAreas/WarehouseAreasPanel.jsx                                           |   99 ++
 rsf-server/src/main/resources/mapper/manager/WarehouseMapper.xml                                    |    5 
 29 files changed, 2,189 insertions(+), 12 deletions(-)

diff --git a/rsf-admin/src/i18n/en.js b/rsf-admin/src/i18n/en.js
index 01d776a..ee05142 100644
--- a/rsf-admin/src/i18n/en.js
+++ b/rsf-admin/src/i18n/en.js
@@ -106,6 +106,7 @@
     },
     menu: {
         dashboard: 'Dashboard',
+        basicInfo: 'BasicInfo',
         settings: 'Settings',
         system: 'System',
         user: 'User',
@@ -122,6 +123,8 @@
         shipper: 'shipper',
         matnr: 'Matnr',
         matnrGroup: 'MatnrGroup',
+        warehouse: 'Warehouse',
+        warehouseAreas: 'WarehouseAreas',
 
     },
     table: {
@@ -263,6 +266,27 @@
                 code: "code",
                 parentId: "parentId",
             },
+            warehouse: {
+                name: "name",
+                code: "code",
+                factory: "factory",
+                address: "address",
+                longitude: "longitude",
+                latgitude: "latgitude",
+                length: "length",
+                width: "width",
+                height: "height",
+            },
+            warehouseAreas: {
+                uuid: "uuid",
+                name: "name",
+                code: "code",
+                shipperId: "shipperId",
+                supplierId: "supplierId",
+                flagMinus: "flagMinus",
+                flagLabelMange: "flagLabelMange",
+                flagMix: "flagMix",
+            },
         }
     },
     page: {
diff --git a/rsf-admin/src/i18n/zh.js b/rsf-admin/src/i18n/zh.js
index 53667aa..c87f20f 100644
--- a/rsf-admin/src/i18n/zh.js
+++ b/rsf-admin/src/i18n/zh.js
@@ -123,6 +123,9 @@
         shipper: '璐т富淇℃伅',
         matnr: '鐗╂枡琛�',
         matnrGroup: '鐗╂枡鍒嗙粍',
+        warehouse: '浠撳簱淇℃伅',
+        warehouseAreas: '浠撳簱搴撳尯',
+
 
     },
     table: {
@@ -264,6 +267,27 @@
                 code: "缂栫爜",
                 parentId: "鐖剁被鏍囪瘑",
             },
+            warehouse: {
+                name: "鍚嶇О",
+                code: "缂栫爜",
+                factory: "宸ュ巶",
+                address: "鍦板潃",
+                longitude: "缁忓害",
+                latgitude: "绾害",
+                length: "闀�",
+                width: "瀹�",
+                height: "楂�",
+            },
+            warehouseAreas: {
+                uuid: "鍞竴缂栫爜",
+                name: "鍚嶇О",
+                code: "缂栫爜",
+                shipperId: "璐т富",
+                supplierId: "渚涘簲鍟�",
+                flagMinus: "鍏佽璐熷簱瀛�",
+                flagLabelMange: "鏍囩绠$悊",
+                flagMix: "娣锋斁",
+            },
         }
     },
     page: {
diff --git a/rsf-admin/src/page/ResourceContent.js b/rsf-admin/src/page/ResourceContent.js
index 0f54345..f2e8798 100644
--- a/rsf-admin/src/page/ResourceContent.js
+++ b/rsf-admin/src/page/ResourceContent.js
@@ -17,6 +17,8 @@
 import shipper from './shipper';
 import matnr from './matnr';
 import matnrGroup from './matnrGroup';
+import warehouse from './warehouse';
+import warehouseAreas from './warehouseAreas';
 
 
 const ResourceContent = (node) => {
@@ -47,6 +49,10 @@
             return matnr;
         case 'matnrGroup':
             return matnrGroup;
+        case 'warehouse':
+            return warehouse;
+        case 'warehouseAreas':
+            return warehouseAreas;
         default:
             return {
                 list: ListGuesser,
diff --git a/rsf-admin/src/page/warehouse/WarehouseCreate.jsx b/rsf-admin/src/page/warehouse/WarehouseCreate.jsx
new file mode 100644
index 0000000..5eb2bf9
--- /dev/null
+++ b/rsf-admin/src/page/warehouse/WarehouseCreate.jsx
@@ -0,0 +1,171 @@
+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 WarehouseCreate = (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.warehouse.name"
+                                        source="name"
+                                        parse={v => v}
+                                        autoFocus
+                                    />
+                                </Grid>
+                                <Grid item xs={6} display="flex" gap={1}>
+                                    <TextInput
+                                        label="table.field.warehouse.code"
+                                        source="code"
+                                        parse={v => v}
+                                    />
+                                </Grid>
+                                <Grid item xs={6} display="flex" gap={1}>
+                                    <TextInput
+                                        label="table.field.warehouse.factory"
+                                        source="factory"
+                                        parse={v => v}
+                                    />
+                                </Grid>
+                                <Grid item xs={6} display="flex" gap={1}>
+                                    <TextInput
+                                        label="table.field.warehouse.address"
+                                        source="address"
+                                        parse={v => v}
+                                    />
+                                </Grid>
+                                <Grid item xs={6} display="flex" gap={1}>
+                                    <TextInput
+                                        label="table.field.warehouse.longitude"
+                                        source="longitude"
+                                        parse={v => v}
+                                    />
+                                </Grid>
+                                <Grid item xs={6} display="flex" gap={1}>
+                                    <TextInput
+                                        label="table.field.warehouse.latgitude"
+                                        source="latgitude"
+                                        parse={v => v}
+                                    />
+                                </Grid>
+                                <Grid item xs={6} display="flex" gap={1}>
+                                    <NumberInput
+                                        label="table.field.warehouse.length"
+                                        source="length"
+                                    />
+                                </Grid>
+                                <Grid item xs={6} display="flex" gap={1}>
+                                    <NumberInput
+                                        label="table.field.warehouse.width"
+                                        source="width"
+                                    />
+                                </Grid>
+                                <Grid item xs={6} display="flex" gap={1}>
+                                    <NumberInput
+                                        label="table.field.warehouse.height"
+                                        source="height"
+                                    />
+                                </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 WarehouseCreate;
diff --git a/rsf-admin/src/page/warehouse/WarehouseEdit.jsx b/rsf-admin/src/page/warehouse/WarehouseEdit.jsx
new file mode 100644
index 0000000..7c53724
--- /dev/null
+++ b/rsf-admin/src/page/warehouse/WarehouseEdit.jsx
@@ -0,0 +1,143 @@
+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 WarehouseEdit = () => {
+    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.warehouse.name"
+                                source="name"
+                                parse={v => v}
+                                autoFocus
+                            />
+                        </Stack>
+                        <Stack direction='row' gap={2}>
+                            <TextInput
+                                label="table.field.warehouse.code"
+                                source="code"
+                                parse={v => v}
+                            />
+                        </Stack>
+                        <Stack direction='row' gap={2}>
+                            <TextInput
+                                label="table.field.warehouse.factory"
+                                source="factory"
+                                parse={v => v}
+                            />
+                        </Stack>
+                        <Stack direction='row' gap={2}>
+                            <TextInput
+                                label="table.field.warehouse.address"
+                                source="address"
+                                parse={v => v}
+                            />
+                        </Stack>
+                        <Stack direction='row' gap={2}>
+                            <TextInput
+                                label="table.field.warehouse.longitude"
+                                source="longitude"
+                                parse={v => v}
+                            />
+                        </Stack>
+                        <Stack direction='row' gap={2}>
+                            <TextInput
+                                label="table.field.warehouse.latgitude"
+                                source="latgitude"
+                                parse={v => v}
+                            />
+                        </Stack>
+                        <Stack direction='row' gap={2}>
+                            <NumberInput
+                                label="table.field.warehouse.length"
+                                source="length"
+                            />
+                        </Stack>
+                        <Stack direction='row' gap={2}>
+                            <NumberInput
+                                label="table.field.warehouse.width"
+                                source="width"
+                            />
+                        </Stack>
+                        <Stack direction='row' gap={2}>
+                            <NumberInput
+                                label="table.field.warehouse.height"
+                                source="height"
+                            />
+                        </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 WarehouseEdit;
diff --git a/rsf-admin/src/page/warehouse/WarehouseList.jsx b/rsf-admin/src/page/warehouse/WarehouseList.jsx
new file mode 100644
index 0000000..2c902fd
--- /dev/null
+++ b/rsf-admin/src/page/warehouse/WarehouseList.jsx
@@ -0,0 +1,168 @@
+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 WarehouseCreate from "./WarehouseCreate";
+import WarehousePanel from "./WarehousePanel";
+import EmptyData from "../components/EmptyData";
+import MyCreateButton from "../components/MyCreateButton";
+import MyExportButton from '../components/MyExportButton';
+import PageDrawer from "../components/PageDrawer";
+import MyField from "../components/MyField";
+import { 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 />,
+
+    <TextInput source="name" label="table.field.warehouse.name" />,
+    <TextInput source="code" label="table.field.warehouse.code" />,
+    <TextInput source="factory" label="table.field.warehouse.factory" />,
+    <TextInput source="address" label="table.field.warehouse.address" />,
+    <TextInput source="longitude" label="table.field.warehouse.longitude" />,
+    <TextInput source="latgitude" label="table.field.warehouse.latgitude" />,
+    <NumberInput source="length" label="table.field.warehouse.length" />,
+    <NumberInput source="width" label="table.field.warehouse.width" />,
+    <NumberInput source="height" label="table.field.warehouse.height" />,
+
+    <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 WarehouseList = () => {
+    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.warehouse"}
+                empty={<EmptyData onClick={() => { setCreateDialog(true) }} />}
+                filters={filters}
+                sort={{ field: "create_time", order: "desc" }}
+                actions={(
+                    <TopToolbar>
+                        <FilterButton />
+                        <MyCreateButton onClick={() => { setCreateDialog(true) }} />
+                        <SelectColumnsButton preferenceKey='warehouse' />
+                        <MyExportButton />
+                    </TopToolbar>
+                )}
+                perPage={DEFAULT_PAGE_SIZE}
+            >
+                <StyledDatagrid
+                    preferenceKey='warehouse'
+                    bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />}
+                    rowClick={(id, resource, record) => false}
+                    expand={() => <WarehousePanel />}
+                    expandSingle={true}
+                    omit={['id', 'createTime', 'createBy', 'memo']}
+                >
+                    <NumberField source="id" />
+                    <TextField source="name" label="table.field.warehouse.name" />
+                    <TextField source="code" label="table.field.warehouse.code" />
+                    <TextField source="factory" label="table.field.warehouse.factory" />
+                    <TextField source="address" label="table.field.warehouse.address" />
+                    <TextField source="longitude" label="table.field.warehouse.longitude" />
+                    <TextField source="latgitude" label="table.field.warehouse.latgitude" />
+                    <NumberField source="length" label="table.field.warehouse.length" />
+                    <NumberField source="width" label="table.field.warehouse.width" />
+                    <NumberField source="height" label="table.field.warehouse.height" />
+
+                    <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>
+            <WarehouseCreate
+                open={createDialog}
+                setOpen={setCreateDialog}
+            />
+            <PageDrawer
+                title='Warehouse Detail'
+                drawerVal={drawerVal}
+                setDrawerVal={setDrawerVal}
+            >
+            </PageDrawer>
+        </Box>
+    )
+}
+
+export default WarehouseList;
diff --git a/rsf-admin/src/page/warehouse/WarehousePanel.jsx b/rsf-admin/src/page/warehouse/WarehousePanel.jsx
new file mode 100644
index 0000000..acb6e40
--- /dev/null
+++ b/rsf-admin/src/page/warehouse/WarehousePanel.jsx
@@ -0,0 +1,105 @@
+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 WarehousePanel = () => {
+    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.warehouse.name'))}: {record.name}
+                            </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.warehouse.name" 
+                                property={record.name}
+                            />
+                        </Grid>
+                        <Grid item xs={6}>
+                            <PanelTypography
+                                title="table.field.warehouse.code" 
+                                property={record.code}
+                            />
+                        </Grid>
+                        <Grid item xs={6}>
+                            <PanelTypography
+                                title="table.field.warehouse.factory" 
+                                property={record.factory}
+                            />
+                        </Grid>
+                        <Grid item xs={6}>
+                            <PanelTypography
+                                title="table.field.warehouse.address" 
+                                property={record.address}
+                            />
+                        </Grid>
+                        <Grid item xs={6}>
+                            <PanelTypography
+                                title="table.field.warehouse.longitude" 
+                                property={record.longitude}
+                            />
+                        </Grid>
+                        <Grid item xs={6}>
+                            <PanelTypography
+                                title="table.field.warehouse.latgitude" 
+                                property={record.latgitude}
+                            />
+                        </Grid>
+                        <Grid item xs={6}>
+                            <PanelTypography
+                                title="table.field.warehouse.length" 
+                                property={record.length}
+                            />
+                        </Grid>
+                        <Grid item xs={6}>
+                            <PanelTypography
+                                title="table.field.warehouse.width" 
+                                property={record.width}
+                            />
+                        </Grid>
+                        <Grid item xs={6}>
+                            <PanelTypography
+                                title="table.field.warehouse.height" 
+                                property={record.height}
+                            />
+                        </Grid>
+
+                    </Grid>
+                </CardContent>
+            </Card >
+        </>
+    );
+};
+
+export default WarehousePanel;
diff --git a/rsf-admin/src/page/warehouse/index.jsx b/rsf-admin/src/page/warehouse/index.jsx
new file mode 100644
index 0000000..3a862d0
--- /dev/null
+++ b/rsf-admin/src/page/warehouse/index.jsx
@@ -0,0 +1,18 @@
+import React, { useState, useRef, useEffect, useMemo } from "react";
+import {
+    ListGuesser,
+    EditGuesser,
+    ShowGuesser,
+} from "react-admin";
+
+import WarehouseList from "./WarehouseList";
+import WarehouseEdit from "./WarehouseEdit";
+
+export default {
+    list: WarehouseList,
+    edit: WarehouseEdit,
+    show: ShowGuesser,
+    recordRepresentation: (record) => {
+        return `${record.name}`
+    }
+};
diff --git a/rsf-admin/src/page/warehouseAreas/WarehouseAreasCreate.jsx b/rsf-admin/src/page/warehouseAreas/WarehouseAreasCreate.jsx
new file mode 100644
index 0000000..8b57c41
--- /dev/null
+++ b/rsf-admin/src/page/warehouseAreas/WarehouseAreasCreate.jsx
@@ -0,0 +1,180 @@
+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 WarehouseAreasCreate = (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.warehouseAreas.uuid"
+                                        source="uuid"
+                                        parse={v => v}
+                                        autoFocus
+                                    />
+                                </Grid>
+                                <Grid item xs={6} display="flex" gap={1}>
+                                    <TextInput
+                                        label="table.field.warehouseAreas.name"
+                                        source="name"
+                                        parse={v => v}
+                                    />
+                                </Grid>
+                                <Grid item xs={6} display="flex" gap={1}>
+                                    <TextInput
+                                        label="table.field.warehouseAreas.code"
+                                        source="code"
+                                        parse={v => v}
+                                    />
+                                </Grid>
+                                <Grid item xs={6} display="flex" gap={1}>
+                                    <ReferenceInput
+                                        source="shipperId"
+                                        reference="shipper"
+                                    >
+                                        <AutocompleteInput
+                                            label="table.field.warehouseAreas.shipperId"
+                                            optionText="name"
+                                            filterToQuery={(val) => ({ name: val })}
+                                        />
+                                    </ReferenceInput>
+                                </Grid>
+                                <Grid item xs={6} display="flex" gap={1}>
+                                    <NumberInput
+                                        label="table.field.warehouseAreas.supplierId"
+                                        source="supplierId"
+                                    />
+                                </Grid>
+                                <Grid item xs={6} display="flex" gap={1}>
+                                    <SelectInput
+                                        label="table.field.warehouseAreas.flagMinus"
+                                        source="flagMinus"
+                                        choices={[
+                                            { id: 0, name: '鍚�' },
+                                            { id:  1, name: '鏄�' },
+                                        ]}
+                                    />
+                                </Grid>
+                                <Grid item xs={6} display="flex" gap={1}>
+                                    <SelectInput
+                                        label="table.field.warehouseAreas.flagLabelMange"
+                                        source="flagLabelMange"
+                                        choices={[
+                                            { id: 0, name: ' 鍚�' },
+                                            { id:  1, name: ' 鏄�' },
+                                        ]}
+                                    />
+                                </Grid>
+                                <Grid item xs={6} display="flex" gap={1}>
+                                    <SelectInput
+                                        label="table.field.warehouseAreas.flagMix"
+                                        source="flagMix"
+                                        choices={[
+                                            { id: 0, name: '鍚�' },
+                                            { id:  1, name: '鏄�' },
+                                        ]}
+                                    />
+                                </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 WarehouseAreasCreate;
diff --git a/rsf-admin/src/page/warehouseAreas/WarehouseAreasEdit.jsx b/rsf-admin/src/page/warehouseAreas/WarehouseAreasEdit.jsx
new file mode 100644
index 0000000..a9a513e
--- /dev/null
+++ b/rsf-admin/src/page/warehouseAreas/WarehouseAreasEdit.jsx
@@ -0,0 +1,155 @@
+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 WarehouseAreasEdit = () => {
+    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.warehouseAreas.uuid"
+                                source="uuid"
+                                parse={v => v}
+                                autoFocus
+                            />
+                        </Stack>
+                        <Stack direction='row' gap={2}>
+                            <TextInput
+                                label="table.field.warehouseAreas.name"
+                                source="name"
+                                parse={v => v}
+                            />
+                        </Stack>
+                        <Stack direction='row' gap={2}>
+                            <TextInput
+                                label="table.field.warehouseAreas.code"
+                                source="code"
+                                parse={v => v}
+                            />
+                        </Stack>
+                        <Stack direction='row' gap={2}>
+                            <ReferenceInput
+                                source="shipperId"
+                                reference="shipper"
+                                perPage={REFERENCE_INPUT_PAGESIZE}
+                            >
+                                <AutocompleteInput
+                                    label="table.field.warehouseAreas.shipperId"
+                                    optionText="name"
+                                    filterToQuery={(val) => ({ name: val })}
+                                />
+                            </ReferenceInput>
+                        </Stack>
+                        <Stack direction='row' gap={2}>
+                            <NumberInput
+                                label="table.field.warehouseAreas.supplierId"
+                                source="supplierId"
+                            />
+                        </Stack>
+                        <Stack direction='row' gap={2}>
+                            <SelectInput
+                                label="table.field.warehouseAreas.flagMinus"
+                                source="flagMinus"
+                                choices={[
+                                    { id: 0, name: '鍚�' },
+                                    { id:  1, name: '鏄�' },
+                                ]}
+                            />
+                        </Stack>
+                        <Stack direction='row' gap={2}>
+                            <SelectInput
+                                label="table.field.warehouseAreas.flagLabelMange"
+                                source="flagLabelMange"
+                                choices={[
+                                    { id: 0, name: ' 鍚�' },
+                                    { id:  1, name: ' 鏄�' },
+                                ]}
+                                validate={required()}
+                            />
+                        </Stack>
+                        <Stack direction='row' gap={2}>
+                            <SelectInput
+                                label="table.field.warehouseAreas.flagMix"
+                                source="flagMix"
+                                choices={[
+                                    { id: 0, name: '鍚�' },
+                                    { id:  1, name: '鏄�' },
+                                ]}
+                                validate={required()}
+                            />
+                        </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 WarehouseAreasEdit;
diff --git a/rsf-admin/src/page/warehouseAreas/WarehouseAreasList.jsx b/rsf-admin/src/page/warehouseAreas/WarehouseAreasList.jsx
new file mode 100644
index 0000000..f8a68f3
--- /dev/null
+++ b/rsf-admin/src/page/warehouseAreas/WarehouseAreasList.jsx
@@ -0,0 +1,185 @@
+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 WarehouseAreasCreate from "./WarehouseAreasCreate";
+import WarehouseAreasPanel from "./WarehouseAreasPanel";
+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 />,
+
+    <TextInput source="uuid" label="table.field.warehouseAreas.uuid" />,
+    <TextInput source="name" label="table.field.warehouseAreas.name" />,
+    <TextInput source="code" label="table.field.warehouseAreas.code" />,
+    <ReferenceInput source="shipperId" label="table.field.warehouseAreas.shipperId" reference="shipper">
+        <AutocompleteInput label="table.field.warehouseAreas.shipperId" optionText="name" filterToQuery={(val) => ({ name: val })} />
+    </ReferenceInput>,
+    <NumberInput source="supplierId" label="table.field.warehouseAreas.supplierId" />,
+    <SelectInput source="flagMinus" label="table.field.warehouseAreas.flagMinus"
+        choices={[
+            { id: 0, name: '鍚�' },
+            { id:  1, name: '鏄�' },
+        ]}
+    />,
+    <SelectInput source="flagLabelMange" label="table.field.warehouseAreas.flagLabelMange"
+        choices={[
+            { id: 0, name: ' 鍚�' },
+            { id:  1, name: ' 鏄�' },
+        ]}
+    />,
+    <SelectInput source="flagMix" label="table.field.warehouseAreas.flagMix"
+        choices={[
+            { id: 0, name: '鍚�' },
+            { id:  1, name: '鏄�' },
+        ]}
+    />,
+
+    <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 WarehouseAreasList = () => {
+    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.warehouseAreas"}
+                empty={<EmptyData onClick={() => { setCreateDialog(true) }} />}
+                filters={filters}
+                sort={{ field: "create_time", order: "desc" }}
+                actions={(
+                    <TopToolbar>
+                        <FilterButton />
+                        <MyCreateButton onClick={() => { setCreateDialog(true) }} />
+                        <SelectColumnsButton preferenceKey='warehouseAreas' />
+                        <MyExportButton />
+                    </TopToolbar>
+                )}
+                perPage={DEFAULT_PAGE_SIZE}
+            >
+                <StyledDatagrid
+                    preferenceKey='warehouseAreas'
+                    bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />}
+                    rowClick={(id, resource, record) => false}
+                    expand={() => <WarehouseAreasPanel />}
+                    expandSingle={true}
+                    omit={['id', 'createTime', 'createBy', 'memo']}
+                >
+                    <NumberField source="id" />
+                    <TextField source="uuid" label="table.field.warehouseAreas.uuid" />
+                    <TextField source="name" label="table.field.warehouseAreas.name" />
+                    <TextField source="code" label="table.field.warehouseAreas.code" />
+                    <ReferenceField source="shipperId" label="table.field.warehouseAreas.shipperId" reference="shipper" link={false} sortable={false}>
+                        <TextField source="name" />
+                    </ReferenceField>
+                    <NumberField source="supplierId" label="table.field.warehouseAreas.supplierId" />
+                    <TextField source="flagMinus$" label="table.field.warehouseAreas.flagMinus" sortable={false} />
+                    <TextField source="flagLabelMange$" label="table.field.warehouseAreas.flagLabelMange" sortable={false} />
+                    <TextField source="flagMix$" label="table.field.warehouseAreas.flagMix" sortable={false} />
+
+                    <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>
+            <WarehouseAreasCreate
+                open={createDialog}
+                setOpen={setCreateDialog}
+            />
+            <PageDrawer
+                title='WarehouseAreas Detail'
+                drawerVal={drawerVal}
+                setDrawerVal={setDrawerVal}
+            >
+            </PageDrawer>
+        </Box>
+    )
+}
+
+export default WarehouseAreasList;
diff --git a/rsf-admin/src/page/warehouseAreas/WarehouseAreasPanel.jsx b/rsf-admin/src/page/warehouseAreas/WarehouseAreasPanel.jsx
new file mode 100644
index 0000000..a42017e
--- /dev/null
+++ b/rsf-admin/src/page/warehouseAreas/WarehouseAreasPanel.jsx
@@ -0,0 +1,99 @@
+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 WarehouseAreasPanel = () => {
+    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.warehouseAreas.uuid'))}: {record.uuid}
+                            </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.warehouseAreas.uuid" 
+                                property={record.uuid}
+                            />
+                        </Grid>
+                        <Grid item xs={6}>
+                            <PanelTypography
+                                title="table.field.warehouseAreas.name" 
+                                property={record.name}
+                            />
+                        </Grid>
+                        <Grid item xs={6}>
+                            <PanelTypography
+                                title="table.field.warehouseAreas.code" 
+                                property={record.code}
+                            />
+                        </Grid>
+                        <Grid item xs={6}>
+                            <PanelTypography
+                                title="table.field.warehouseAreas.shipperId" 
+                                property={record.shipperId$}
+                            />
+                        </Grid>
+                        <Grid item xs={6}>
+                            <PanelTypography
+                                title="table.field.warehouseAreas.supplierId" 
+                                property={record.supplierId}
+                            />
+                        </Grid>
+                        <Grid item xs={6}>
+                            <PanelTypography
+                                title="table.field.warehouseAreas.flagMinus" 
+                                property={record.flagMinus$}
+                            />
+                        </Grid>
+                        <Grid item xs={6}>
+                            <PanelTypography
+                                title="table.field.warehouseAreas.flagLabelMange" 
+                                property={record.flagLabelMange$}
+                            />
+                        </Grid>
+                        <Grid item xs={6}>
+                            <PanelTypography
+                                title="table.field.warehouseAreas.flagMix" 
+                                property={record.flagMix$}
+                            />
+                        </Grid>
+
+                    </Grid>
+                </CardContent>
+            </Card >
+        </>
+    );
+};
+
+export default WarehouseAreasPanel;
diff --git a/rsf-admin/src/page/warehouseAreas/index.jsx b/rsf-admin/src/page/warehouseAreas/index.jsx
new file mode 100644
index 0000000..6b27709
--- /dev/null
+++ b/rsf-admin/src/page/warehouseAreas/index.jsx
@@ -0,0 +1,18 @@
+import React, { useState, useRef, useEffect, useMemo } from "react";
+import {
+    ListGuesser,
+    EditGuesser,
+    ShowGuesser,
+} from "react-admin";
+
+import WarehouseAreasList from "./WarehouseAreasList";
+import WarehouseAreasEdit from "./WarehouseAreasEdit";
+
+export default {
+    list: WarehouseAreasList,
+    edit: WarehouseAreasEdit,
+    show: ShowGuesser,
+    recordRepresentation: (record) => {
+        return `${record.uuid}`
+    }
+};
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/common/CodeBuilder.java b/rsf-server/src/main/java/com/vincent/rsf/server/common/CodeBuilder.java
index b0983bb..890676e 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/common/CodeBuilder.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/common/CodeBuilder.java
@@ -22,8 +22,8 @@
 //        generator.username="sa";
 //        generator.password="Zoneyung@zy56$";
 
-        generator.table="man_matnr";
-        generator.tableDesc="鐗╂枡淇℃伅琛�";
+        generator.table="man_warehouse_areas";
+        generator.tableDesc="搴撳尯淇℃伅琛�";
         generator.packagePath="com.vincent.rsf.server.manager";
 
         generator.build();
@@ -37,9 +37,9 @@
  `deleted` INT(1) NOT NULL DEFAULT '0' COMMENT '鏄惁鍒犻櫎{1:鏄�,0:鍚',
  `tenant_id` INT(11) DEFAULT NULL COMMENT '绉熸埛[sys_tenant]',
  `create_by` BIGINT(20) DEFAULT NULL COMMENT '娣诲姞浜哄憳[sys_user]',
- `create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '娣诲姞鏃堕棿',
+ `create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '娣诲姞鏃堕棿',
  `update_by` BIGINT(20) DEFAULT NULL COMMENT '淇敼浜哄憳[sys_user]',
- `update_time` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP COMMENT '淇敼鏃堕棿',
+ `update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '淇敼鏃堕棿',
  `memo` VARCHAR(255) DEFAULT NULL COMMENT '澶囨敞',
  PRIMARY KEY (`id`)
  ) ENGINE=INNODB AUTO_INCREMENT=15 DEFAULT CHARSET=utf8;
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/WarehouseAreasController.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/WarehouseAreasController.java
new file mode 100644
index 0000000..83b4c3c
--- /dev/null
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/WarehouseAreasController.java
@@ -0,0 +1,110 @@
+package com.vincent.rsf.server.manager.controller;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.vincent.rsf.framework.common.Cools;
+import com.vincent.rsf.framework.common.R;
+import com.vincent.rsf.server.common.utils.ExcelUtil;
+import com.vincent.rsf.server.common.annotation.OperationLog;
+import com.vincent.rsf.server.common.domain.BaseParam;
+import com.vincent.rsf.server.common.domain.KeyValVo;
+import com.vincent.rsf.server.common.domain.PageParam;
+import com.vincent.rsf.server.manager.entity.WarehouseAreas;
+import com.vincent.rsf.server.manager.service.WarehouseAreasService;
+import com.vincent.rsf.server.system.controller.BaseController;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletResponse;
+import java.util.*;
+
+@RestController
+public class WarehouseAreasController extends BaseController {
+
+    @Autowired
+    private WarehouseAreasService warehouseAreasService;
+
+    @PreAuthorize("hasAuthority('manager:warehouseAreas:list')")
+    @PostMapping("/warehouseAreas/page")
+    public R page(@RequestBody Map<String, Object> map) {
+        BaseParam baseParam = buildParam(map, BaseParam.class);
+        PageParam<WarehouseAreas, BaseParam> pageParam = new PageParam<>(baseParam, WarehouseAreas.class);
+        return R.ok().add(warehouseAreasService.page(pageParam, pageParam.buildWrapper(true)));
+    }
+
+    @PreAuthorize("hasAuthority('manager:warehouseAreas:list')")
+    @PostMapping("/warehouseAreas/list")
+    public R list(@RequestBody Map<String, Object> map) {
+        return R.ok().add(warehouseAreasService.list());
+    }
+
+    @PreAuthorize("hasAuthority('manager:warehouseAreas:list')")
+    @PostMapping({"/warehouseAreas/many/{ids}", "/warehouseAreass/many/{ids}"})
+    public R many(@PathVariable Long[] ids) {
+        return R.ok().add(warehouseAreasService.listByIds(Arrays.asList(ids)));
+    }
+
+    @PreAuthorize("hasAuthority('manager:warehouseAreas:list')")
+    @GetMapping("/warehouseAreas/{id}")
+    public R get(@PathVariable("id") Long id) {
+        return R.ok().add(warehouseAreasService.getById(id));
+    }
+
+    @PreAuthorize("hasAuthority('manager:warehouseAreas:save')")
+    @OperationLog("Create 搴撳尯淇℃伅琛�")
+    @PostMapping("/warehouseAreas/save")
+    public R save(@RequestBody WarehouseAreas warehouseAreas) {
+        warehouseAreas.setCreateBy(getLoginUserId());
+        warehouseAreas.setCreateTime(new Date());
+        warehouseAreas.setUpdateBy(getLoginUserId());
+        warehouseAreas.setUpdateTime(new Date());
+        if (!warehouseAreasService.save(warehouseAreas)) {
+            return R.error("Save Fail");
+        }
+        return R.ok("Save Success").add(warehouseAreas);
+    }
+
+    @PreAuthorize("hasAuthority('manager:warehouseAreas:update')")
+    @OperationLog("Update 搴撳尯淇℃伅琛�")
+    @PostMapping("/warehouseAreas/update")
+    public R update(@RequestBody WarehouseAreas warehouseAreas) {
+        warehouseAreas.setUpdateBy(getLoginUserId());
+        warehouseAreas.setUpdateTime(new Date());
+        if (!warehouseAreasService.updateById(warehouseAreas)) {
+            return R.error("Update Fail");
+        }
+        return R.ok("Update Success").add(warehouseAreas);
+    }
+
+    @PreAuthorize("hasAuthority('manager:warehouseAreas:remove')")
+    @OperationLog("Delete 搴撳尯淇℃伅琛�")
+    @PostMapping("/warehouseAreas/remove/{ids}")
+    public R remove(@PathVariable Long[] ids) {
+        if (!warehouseAreasService.removeByIds(Arrays.asList(ids))) {
+            return R.error("Delete Fail");
+        }
+        return R.ok("Delete Success").add(ids);
+    }
+
+    @PreAuthorize("hasAuthority('manager:warehouseAreas:list')")
+    @PostMapping("/warehouseAreas/query")
+    public R query(@RequestParam(required = false) String condition) {
+        List<KeyValVo> vos = new ArrayList<>();
+        LambdaQueryWrapper<WarehouseAreas> wrapper = new LambdaQueryWrapper<>();
+        if (!Cools.isEmpty(condition)) {
+            wrapper.like(WarehouseAreas::getUuid, condition);
+        }
+        warehouseAreasService.page(new Page<>(1, 30), wrapper).getRecords().forEach(
+                item -> vos.add(new KeyValVo(item.getId(), item.getUuid()))
+        );
+        return R.ok().add(vos);
+    }
+
+    @PreAuthorize("hasAuthority('manager:warehouseAreas:list')")
+    @PostMapping("/warehouseAreas/export")
+    public void export(@RequestBody Map<String, Object> map, HttpServletResponse response) throws Exception {
+        ExcelUtil.build(ExcelUtil.create(warehouseAreasService.list(), WarehouseAreas.class), response);
+    }
+
+}
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/WarehouseController.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/WarehouseController.java
new file mode 100644
index 0000000..c4a638a
--- /dev/null
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/WarehouseController.java
@@ -0,0 +1,110 @@
+package com.vincent.rsf.server.manager.controller;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.vincent.rsf.framework.common.Cools;
+import com.vincent.rsf.framework.common.R;
+import com.vincent.rsf.server.common.utils.ExcelUtil;
+import com.vincent.rsf.server.common.annotation.OperationLog;
+import com.vincent.rsf.server.common.domain.BaseParam;
+import com.vincent.rsf.server.common.domain.KeyValVo;
+import com.vincent.rsf.server.common.domain.PageParam;
+import com.vincent.rsf.server.manager.entity.Warehouse;
+import com.vincent.rsf.server.manager.service.WarehouseService;
+import com.vincent.rsf.server.system.controller.BaseController;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletResponse;
+import java.util.*;
+
+@RestController
+public class WarehouseController extends BaseController {
+
+    @Autowired
+    private WarehouseService warehouseService;
+
+    @PreAuthorize("hasAuthority('manager:warehouse:list')")
+    @PostMapping("/warehouse/page")
+    public R page(@RequestBody Map<String, Object> map) {
+        BaseParam baseParam = buildParam(map, BaseParam.class);
+        PageParam<Warehouse, BaseParam> pageParam = new PageParam<>(baseParam, Warehouse.class);
+        return R.ok().add(warehouseService.page(pageParam, pageParam.buildWrapper(true)));
+    }
+
+    @PreAuthorize("hasAuthority('manager:warehouse:list')")
+    @PostMapping("/warehouse/list")
+    public R list(@RequestBody Map<String, Object> map) {
+        return R.ok().add(warehouseService.list());
+    }
+
+    @PreAuthorize("hasAuthority('manager:warehouse:list')")
+    @PostMapping({"/warehouse/many/{ids}", "/warehouses/many/{ids}"})
+    public R many(@PathVariable Long[] ids) {
+        return R.ok().add(warehouseService.listByIds(Arrays.asList(ids)));
+    }
+
+    @PreAuthorize("hasAuthority('manager:warehouse:list')")
+    @GetMapping("/warehouse/{id}")
+    public R get(@PathVariable("id") Long id) {
+        return R.ok().add(warehouseService.getById(id));
+    }
+
+    @PreAuthorize("hasAuthority('manager:warehouse:save')")
+    @OperationLog("Create 浠撳簱淇℃伅琛�")
+    @PostMapping("/warehouse/save")
+    public R save(@RequestBody Warehouse warehouse) {
+        warehouse.setCreateBy(getLoginUserId());
+        warehouse.setCreateTime(new Date());
+        warehouse.setUpdateBy(getLoginUserId());
+        warehouse.setUpdateTime(new Date());
+        if (!warehouseService.save(warehouse)) {
+            return R.error("Save Fail");
+        }
+        return R.ok("Save Success").add(warehouse);
+    }
+
+    @PreAuthorize("hasAuthority('manager:warehouse:update')")
+    @OperationLog("Update 浠撳簱淇℃伅琛�")
+    @PostMapping("/warehouse/update")
+    public R update(@RequestBody Warehouse warehouse) {
+        warehouse.setUpdateBy(getLoginUserId());
+        warehouse.setUpdateTime(new Date());
+        if (!warehouseService.updateById(warehouse)) {
+            return R.error("Update Fail");
+        }
+        return R.ok("Update Success").add(warehouse);
+    }
+
+    @PreAuthorize("hasAuthority('manager:warehouse:remove')")
+    @OperationLog("Delete 浠撳簱淇℃伅琛�")
+    @PostMapping("/warehouse/remove/{ids}")
+    public R remove(@PathVariable Long[] ids) {
+        if (!warehouseService.removeByIds(Arrays.asList(ids))) {
+            return R.error("Delete Fail");
+        }
+        return R.ok("Delete Success").add(ids);
+    }
+
+    @PreAuthorize("hasAuthority('manager:warehouse:list')")
+    @PostMapping("/warehouse/query")
+    public R query(@RequestParam(required = false) String condition) {
+        List<KeyValVo> vos = new ArrayList<>();
+        LambdaQueryWrapper<Warehouse> wrapper = new LambdaQueryWrapper<>();
+        if (!Cools.isEmpty(condition)) {
+            wrapper.like(Warehouse::getName, condition);
+        }
+        warehouseService.page(new Page<>(1, 30), wrapper).getRecords().forEach(
+                item -> vos.add(new KeyValVo(item.getId(), item.getName()))
+        );
+        return R.ok().add(vos);
+    }
+
+    @PreAuthorize("hasAuthority('manager:warehouse:list')")
+    @PostMapping("/warehouse/export")
+    public void export(@RequestBody Map<String, Object> map, HttpServletResponse response) throws Exception {
+        ExcelUtil.build(ExcelUtil.create(warehouseService.list(), Warehouse.class), response);
+    }
+
+}
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/Matnr.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/Matnr.java
index 20e800b..943da6d 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/Matnr.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/Matnr.java
@@ -144,7 +144,7 @@
      * 鏄惁鏍囩绠$悊(*) 0:  鍚�   1:  鏄�  
      */
     @ApiModelProperty(value= "鏄惁鏍囩绠$悊(*) 0:  鍚�   1:  鏄�  ")
-    private Short isLabelMange;
+    private Short flagLabelMange;
 
     /**
      * 瀹夊叏搴撳瓨
@@ -177,10 +177,15 @@
     private Integer validity;
 
     /**
+     * 鏉″舰鐮�
+     */
+    private String barcode;
+
+    /**
      * 鏁堟湡棰勮闃堝��
      */
     @ApiModelProperty(value= "鏁堟湡棰勮闃堝��")
-    private Integer validityWarr;
+    private Integer validityWarn;
 
     /**
      * 鏄惁鍏嶆
@@ -241,7 +246,7 @@
 
     public Matnr() {}
 
-    public Matnr(String name,String code,Long shipperId,Long groupId,Long batchRegularId,String erpCode,String spec,String model,Double weight,String color,String size,String describle,Integer nromNum,String unit,String purchaseUnit,String stockUnit,Short stockLeval,Short isLabelMange,Double safetyQty,Double minQty,Double maxQty,Integer stagnate,Integer validity,Integer validityWarr,Short flagCheck,Integer status,Integer deleted,Integer tenantId,Long createBy,Date createTime,Long updateBy,Date updateTime,String memo) {
+    public Matnr(String name,String code,Long shipperId,Long groupId,Long batchRegularId,String erpCode,String spec,String model,Double weight,String color,String size,String describle,Integer nromNum,String unit,String purchaseUnit,String stockUnit,Short stockLeval,Short flagLabelMange,Double safetyQty,Double minQty,Double maxQty,Integer stagnate,Integer validity,Integer validityWarn,Short flagCheck,Integer status,Integer deleted,Integer tenantId,Long createBy,Date createTime,Long updateBy,Date updateTime,String memo) {
         this.name = name;
         this.code = code;
         this.shipperId = shipperId;
@@ -259,13 +264,13 @@
         this.purchaseUnit = purchaseUnit;
         this.stockUnit = stockUnit;
         this.stockLeval = stockLeval;
-        this.isLabelMange = isLabelMange;
+        this.flagLabelMange = flagLabelMange;
         this.safetyQty = safetyQty;
         this.minQty = minQty;
         this.maxQty = maxQty;
         this.stagnate = stagnate;
         this.validity = validity;
-        this.validityWarr = validityWarr;
+        this.validityWarn = validityWarn;
         this.flagCheck = flagCheck;
         this.status = status;
         this.deleted = deleted;
@@ -355,14 +360,14 @@
     }
 
     public String getIsLabelMange$(){
-        if (null == this.isLabelMange){ return null; }
-        switch (this.isLabelMange){
+        if (null == this.flagLabelMange){ return null; }
+        switch (this.flagLabelMange){
             case 0:
                 return " 鍚�";
             case  1:
                 return " 鏄�";
             default:
-                return String.valueOf(this.isLabelMange);
+                return String.valueOf(this.flagLabelMange);
         }
     }
 
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/Warehouse.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/Warehouse.java
new file mode 100644
index 0000000..37a8c84
--- /dev/null
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/Warehouse.java
@@ -0,0 +1,242 @@
+package com.vincent.rsf.server.manager.entity;
+
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import org.springframework.format.annotation.DateTimeFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import com.vincent.rsf.framework.common.Cools;
+import com.vincent.rsf.framework.common.SpringUtils;
+import com.vincent.rsf.server.system.service.UserService;
+import com.vincent.rsf.server.system.entity.User;
+import java.io.Serializable;
+import java.util.Date;
+
+@Data
+@TableName("man_warehouse")
+public class Warehouse implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * ID
+     */
+    @ApiModelProperty(value= "ID")
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+
+    /**
+     * 鍚嶇О
+     */
+    @ApiModelProperty(value= "鍚嶇О")
+    private String name;
+
+    /**
+     * 缂栫爜
+     */
+    @ApiModelProperty(value= "缂栫爜")
+    private String code;
+
+    /**
+     * 鎵�灞炲伐鍘�
+     */
+    @ApiModelProperty(value= "鎵�灞炲伐鍘�")
+    private String factory;
+
+    /**
+     * 浠撳簱鍦板潃
+     */
+    @ApiModelProperty(value= "浠撳簱鍦板潃")
+    private String address;
+
+    /**
+     * 缁忓害
+     */
+    @ApiModelProperty(value= "缁忓害")
+    private String longitude;
+
+    /**
+     * 绾害
+     */
+    @ApiModelProperty(value= "绾害")
+    private String latgitude;
+
+    /**
+     * 闀�
+     */
+    @ApiModelProperty(value= "闀�")
+    private Double length;
+
+    /**
+     * 瀹�
+     */
+    @ApiModelProperty(value= "瀹�")
+    private Double width;
+
+    /**
+     * 楂�
+     */
+    @ApiModelProperty(value= "楂�")
+    private Double height;
+
+    /**
+     * 鐘舵�� 1: 姝e父  0: 鍐荤粨  
+     */
+    @ApiModelProperty(value= "鐘舵�� 1: 姝e父  0: 鍐荤粨  ")
+    private Integer status;
+
+    /**
+     * 鏄惁鍒犻櫎 1: 鏄�  0: 鍚�  
+     */
+    @ApiModelProperty(value= "鏄惁鍒犻櫎 1: 鏄�  0: 鍚�  ")
+    @TableLogic
+    private Integer deleted;
+
+    /**
+     * 绉熸埛
+     */
+    @ApiModelProperty(value= "绉熸埛")
+    private Integer tenantId;
+
+    /**
+     * 娣诲姞浜哄憳
+     */
+    @ApiModelProperty(value= "娣诲姞浜哄憳")
+    private Long createBy;
+
+    /**
+     * 娣诲姞鏃堕棿
+     */
+    @ApiModelProperty(value= "娣诲姞鏃堕棿")
+    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
+    private Date createTime;
+
+    /**
+     * 淇敼浜哄憳
+     */
+    @ApiModelProperty(value= "淇敼浜哄憳")
+    private Long updateBy;
+
+    /**
+     * 淇敼鏃堕棿
+     */
+    @ApiModelProperty(value= "淇敼鏃堕棿")
+    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
+    private Date updateTime;
+
+    /**
+     * 澶囨敞
+     */
+    @ApiModelProperty(value= "澶囨敞")
+    private String memo;
+
+    public Warehouse() {}
+
+    public Warehouse(String name,String code,String factory,String address,String longitude,String latgitude,Double length,Double width,Double height,Integer status,Integer deleted,Integer tenantId,Long createBy,Date createTime,Long updateBy,Date updateTime,String memo) {
+        this.name = name;
+        this.code = code;
+        this.factory = factory;
+        this.address = address;
+        this.longitude = longitude;
+        this.latgitude = latgitude;
+        this.length = length;
+        this.width = width;
+        this.height = height;
+        this.status = status;
+        this.deleted = deleted;
+        this.tenantId = tenantId;
+        this.createBy = createBy;
+        this.createTime = createTime;
+        this.updateBy = updateBy;
+        this.updateTime = updateTime;
+        this.memo = memo;
+    }
+
+//    Warehouse warehouse = new Warehouse(
+//            null,    // 鍚嶇О
+//            null,    // 缂栫爜
+//            null,    // 鎵�灞炲伐鍘�
+//            null,    // 浠撳簱鍦板潃
+//            null,    // 缁忓害
+//            null,    // 绾害
+//            null,    // 闀�
+//            null,    // 瀹�
+//            null,    // 楂�
+//            null,    // 鐘舵�乕闈炵┖]
+//            null,    // 鏄惁鍒犻櫎[闈炵┖]
+//            null,    // 绉熸埛
+//            null,    // 娣诲姞浜哄憳
+//            null,    // 娣诲姞鏃堕棿[闈炵┖]
+//            null,    // 淇敼浜哄憳
+//            null,    // 淇敼鏃堕棿
+//            null    // 澶囨敞
+//    );
+
+    public String getStatus$(){
+        if (null == this.status){ return null; }
+        switch (this.status){
+            case 1:
+                return "姝e父";
+            case 0:
+                return "鍐荤粨";
+            default:
+                return String.valueOf(this.status);
+        }
+    }
+
+    public String getCreateBy$(){
+        UserService service = SpringUtils.getBean(UserService.class);
+        User user = service.getById(this.createBy);
+        if (!Cools.isEmpty(user)){
+            return String.valueOf(user.getNickname());
+        }
+        return null;
+    }
+
+    public String getCreateTime$(){
+        if (Cools.isEmpty(this.createTime)){
+            return "";
+        }
+        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.createTime);
+    }
+
+    public String getUpdateBy$(){
+        UserService service = SpringUtils.getBean(UserService.class);
+        User user = service.getById(this.updateBy);
+        if (!Cools.isEmpty(user)){
+            return String.valueOf(user.getNickname());
+        }
+        return null;
+    }
+
+    public String getUpdateTime$(){
+        if (Cools.isEmpty(this.updateTime)){
+            return "";
+        }
+        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.updateTime);
+    }
+
+
+
+    public Boolean getStatusBool(){
+        if (null == this.status){ return null; }
+        switch (this.status){
+            case 1:
+                return true;
+            case 0:
+                return false;
+            default:
+                return null;
+        }
+    }
+
+}
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/WarehouseAreas.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/WarehouseAreas.java
new file mode 100644
index 0000000..5eb0b73
--- /dev/null
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/WarehouseAreas.java
@@ -0,0 +1,281 @@
+package com.vincent.rsf.server.manager.entity;
+
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import com.vincent.rsf.server.manager.service.ShipperService;
+import org.springframework.format.annotation.DateTimeFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import com.vincent.rsf.framework.common.Cools;
+import com.vincent.rsf.framework.common.SpringUtils;
+import com.vincent.rsf.server.system.service.UserService;
+import com.vincent.rsf.server.system.entity.User;
+import java.io.Serializable;
+import java.util.Date;
+
+@Data
+@TableName("man_warehouse_areas")
+public class WarehouseAreas implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * ID
+     */
+    @ApiModelProperty(value= "ID")
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+
+    /**
+     * 缂栧彿
+     */
+    @ApiModelProperty(value= "缂栧彿")
+    private String uuid;
+
+    /**
+     * 鍚嶇О
+     */
+    @ApiModelProperty(value= "鍚嶇О")
+    private String name;
+
+    /**
+     * 缂栫爜
+     */
+    @ApiModelProperty(value= "缂栫爜")
+    private String code;
+
+    /**
+     * 璐т富鏍囪瘑(*)
+     */
+    @ApiModelProperty(value= "璐т富鏍囪瘑(*)")
+    private Long shipperId;
+
+    /**
+     * 渚涘簲鍟嗘爣璇�
+     */
+    @ApiModelProperty(value= "渚涘簲鍟嗘爣璇�")
+    private Short supplierId;
+
+    /**
+     * 鍏佽璐熷簱瀛�(*) 0: 鍚�   1: 鏄�  
+     */
+    @ApiModelProperty(value= "鍏佽璐熷簱瀛�(*) 0: 鍚�   1: 鏄�  ")
+    private Short flagMinus;
+
+    /**
+     * 鏄惁鏍囩绠$悊(*) 0:  鍚�   1:  鏄�  
+     */
+    @ApiModelProperty(value= "鏄惁鏍囩绠$悊(*) 0:  鍚�   1:  鏄�  ")
+    private Short flagLabelMange;
+
+    /**
+     * 鏀寔娣锋斁(*) 0: 鍚�   1: 鏄�  
+     */
+    @ApiModelProperty(value= "鏀寔娣锋斁(*) 0: 鍚�   1: 鏄�  ")
+    private Short flagMix;
+
+    /**
+     * 鐘舵�� 1: 姝e父  0: 鍐荤粨  
+     */
+    @ApiModelProperty(value= "鐘舵�� 1: 姝e父  0: 鍐荤粨  ")
+    private Integer status;
+
+    /**
+     * 鏄惁鍒犻櫎 1: 鏄�  0: 鍚�  
+     */
+    @ApiModelProperty(value= "鏄惁鍒犻櫎 1: 鏄�  0: 鍚�  ")
+    @TableLogic
+    private Integer deleted;
+
+    /**
+     * 绉熸埛
+     */
+    @ApiModelProperty(value= "绉熸埛")
+    private Integer tenantId;
+
+    /**
+     * 娣诲姞浜哄憳
+     */
+    @ApiModelProperty(value= "娣诲姞浜哄憳")
+    private Long createBy;
+
+    /**
+     * 娣诲姞鏃堕棿
+     */
+    @ApiModelProperty(value= "娣诲姞鏃堕棿")
+    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
+    private Date createTime;
+
+    /**
+     * 淇敼浜哄憳
+     */
+    @ApiModelProperty(value= "淇敼浜哄憳")
+    private Long updateBy;
+
+    /**
+     * 淇敼鏃堕棿
+     */
+    @ApiModelProperty(value= "淇敼鏃堕棿")
+    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
+    private Date updateTime;
+
+    /**
+     * 澶囨敞
+     */
+    @ApiModelProperty(value= "澶囨敞")
+    private String memo;
+
+    public WarehouseAreas() {}
+
+    public WarehouseAreas(String uuid,String name,String code,Long shipperId,Short supplierId,Short flagMinus,Short flagLabelMange,Short flagMix,Integer status,Integer deleted,Integer tenantId,Long createBy,Date createTime,Long updateBy,Date updateTime,String memo) {
+        this.uuid = uuid;
+        this.name = name;
+        this.code = code;
+        this.shipperId = shipperId;
+        this.supplierId = supplierId;
+        this.flagMinus = flagMinus;
+        this.flagLabelMange = flagLabelMange;
+        this.flagMix = flagMix;
+        this.status = status;
+        this.deleted = deleted;
+        this.tenantId = tenantId;
+        this.createBy = createBy;
+        this.createTime = createTime;
+        this.updateBy = updateBy;
+        this.updateTime = updateTime;
+        this.memo = memo;
+    }
+
+//    WarehouseAreas warehouseAreas = new WarehouseAreas(
+//            null,    // 缂栧彿
+//            null,    // 鍚嶇О
+//            null,    // 缂栫爜
+//            null,    // 璐т富鏍囪瘑(*)
+//            null,    // 渚涘簲鍟嗘爣璇�
+//            null,    // 鍏佽璐熷簱瀛�(*)
+//            null,    // 鏄惁鏍囩绠$悊(*)[闈炵┖]
+//            null,    // 鏀寔娣锋斁(*)[闈炵┖]
+//            null,    // 鐘舵�乕闈炵┖]
+//            null,    // 鏄惁鍒犻櫎[闈炵┖]
+//            null,    // 绉熸埛
+//            null,    // 娣诲姞浜哄憳
+//            null,    // 娣诲姞鏃堕棿[闈炵┖]
+//            null,    // 淇敼浜哄憳
+//            null,    // 淇敼鏃堕棿[闈炵┖]
+//            null    // 澶囨敞
+//    );
+
+    public String getShipperId$(){
+        ShipperService service = SpringUtils.getBean(ShipperService.class);
+        Shipper shipper = service.getById(this.shipperId);
+        if (!Cools.isEmpty(shipper)){
+            return String.valueOf(shipper.getName());
+        }
+        return null;
+    }
+
+    public String getFlagMinus$(){
+        if (null == this.flagMinus){ return null; }
+        switch (this.flagMinus){
+            case 0:
+                return "鍚�";
+            case  1:
+                return "鏄�";
+            default:
+                return String.valueOf(this.flagMinus);
+        }
+    }
+
+    public String getFlagLabelMange$(){
+        if (null == this.flagLabelMange){ return null; }
+        switch (this.flagLabelMange){
+            case 0:
+                return " 鍚�";
+            case  1:
+                return " 鏄�";
+            default:
+                return String.valueOf(this.flagLabelMange);
+        }
+    }
+
+    public String getFlagMix$(){
+        if (null == this.flagMix){ return null; }
+        switch (this.flagMix){
+            case 0:
+                return "鍚�";
+            case  1:
+                return "鏄�";
+            default:
+                return String.valueOf(this.flagMix);
+        }
+    }
+
+    public String getStatus$(){
+        if (null == this.status){ return null; }
+        switch (this.status){
+            case 1:
+                return "姝e父";
+            case 0:
+                return "鍐荤粨";
+            default:
+                return String.valueOf(this.status);
+        }
+    }
+
+    public String getCreateBy$(){
+        UserService service = SpringUtils.getBean(UserService.class);
+        User user = service.getById(this.createBy);
+        if (!Cools.isEmpty(user)){
+            return String.valueOf(user.getNickname());
+        }
+        return null;
+    }
+
+    public String getCreateTime$(){
+        if (Cools.isEmpty(this.createTime)){
+            return "";
+        }
+        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.createTime);
+    }
+
+    public String getUpdateBy$(){
+        UserService service = SpringUtils.getBean(UserService.class);
+        User user = service.getById(this.updateBy);
+        if (!Cools.isEmpty(user)){
+            return String.valueOf(user.getNickname());
+        }
+        return null;
+    }
+
+    public String getUpdateTime$(){
+        if (Cools.isEmpty(this.updateTime)){
+            return "";
+        }
+        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.updateTime);
+    }
+
+
+
+    public Boolean getStatusBool(){
+        if (null == this.status){ return null; }
+        switch (this.status){
+            case 1:
+                return true;
+            case 0:
+                return false;
+            default:
+                return null;
+        }
+    }
+
+}
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/mapper/WarehouseAreasMapper.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/mapper/WarehouseAreasMapper.java
new file mode 100644
index 0000000..2bb046f
--- /dev/null
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/mapper/WarehouseAreasMapper.java
@@ -0,0 +1,12 @@
+package com.vincent.rsf.server.manager.mapper;
+
+import com.vincent.rsf.server.manager.entity.WarehouseAreas;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+import org.springframework.stereotype.Repository;
+
+@Mapper
+@Repository
+public interface WarehouseAreasMapper extends BaseMapper<WarehouseAreas> {
+
+}
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/mapper/WarehouseMapper.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/mapper/WarehouseMapper.java
new file mode 100644
index 0000000..d1eefd0
--- /dev/null
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/mapper/WarehouseMapper.java
@@ -0,0 +1,12 @@
+package com.vincent.rsf.server.manager.mapper;
+
+import com.vincent.rsf.server.manager.entity.Warehouse;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+import org.springframework.stereotype.Repository;
+
+@Mapper
+@Repository
+public interface WarehouseMapper extends BaseMapper<Warehouse> {
+
+}
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/WarehouseAreasService.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/WarehouseAreasService.java
new file mode 100644
index 0000000..1933788
--- /dev/null
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/WarehouseAreasService.java
@@ -0,0 +1,8 @@
+package com.vincent.rsf.server.manager.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.vincent.rsf.server.manager.entity.WarehouseAreas;
+
+public interface WarehouseAreasService extends IService<WarehouseAreas> {
+
+}
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/WarehouseService.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/WarehouseService.java
new file mode 100644
index 0000000..d58f458
--- /dev/null
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/WarehouseService.java
@@ -0,0 +1,8 @@
+package com.vincent.rsf.server.manager.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.vincent.rsf.server.manager.entity.Warehouse;
+
+public interface WarehouseService extends IService<Warehouse> {
+
+}
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/WarehouseAreasServiceImpl.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/WarehouseAreasServiceImpl.java
new file mode 100644
index 0000000..4ef3c7d
--- /dev/null
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/WarehouseAreasServiceImpl.java
@@ -0,0 +1,12 @@
+package com.vincent.rsf.server.manager.service.impl;
+
+import com.vincent.rsf.server.manager.mapper.WarehouseAreasMapper;
+import com.vincent.rsf.server.manager.entity.WarehouseAreas;
+import com.vincent.rsf.server.manager.service.WarehouseAreasService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+@Service("warehouseAreasService")
+public class WarehouseAreasServiceImpl extends ServiceImpl<WarehouseAreasMapper, WarehouseAreas> implements WarehouseAreasService {
+
+}
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/WarehouseServiceImpl.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/WarehouseServiceImpl.java
new file mode 100644
index 0000000..784116a
--- /dev/null
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/WarehouseServiceImpl.java
@@ -0,0 +1,12 @@
+package com.vincent.rsf.server.manager.service.impl;
+
+import com.vincent.rsf.server.manager.mapper.WarehouseMapper;
+import com.vincent.rsf.server.manager.entity.Warehouse;
+import com.vincent.rsf.server.manager.service.WarehouseService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+@Service("warehouseService")
+public class WarehouseServiceImpl extends ServiceImpl<WarehouseMapper, Warehouse> implements WarehouseService {
+
+}
diff --git a/rsf-server/src/main/java/warehouse.sql b/rsf-server/src/main/java/warehouse.sql
new file mode 100644
index 0000000..61e441d
--- /dev/null
+++ b/rsf-server/src/main/java/warehouse.sql
@@ -0,0 +1,30 @@
+-- save warehouse record
+-- mysql
+insert into `sys_menu` ( `name`, `parent_id`, `route`, `component`, `type`, `sort`, `tenant_id`, `status`) values ( 'menu.warehouse', '0', '/manager/warehouse', 'warehouse', '0' , '0', '1' , '1');
+
+insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Query 浠撳簱淇℃伅琛�', '68', '1', 'manager:warehouse:list', '0', '1', '1');
+insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Create 浠撳簱淇℃伅琛�', '68', '1', 'manager:warehouse:save', '1', '1', '1');
+insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Update 浠撳簱淇℃伅琛�', '68', '1', 'manager:warehouse:update', '2', '1', '1');
+insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Delete 浠撳簱淇℃伅琛�', '68', '1', 'manager:warehouse:remove', '3', '1', '1');
+
+-- locale menu name
+warehouse: 'Warehouse',
+
+-- locale field
+warehouse: {
+    name: "name",
+    code: "code",
+    factory: "factory",
+    address: "address",
+    longitude: "longitude",
+    latgitude: "latgitude",
+    length: "length",
+    width: "width",
+    height: "height",
+},
+
+-- ResourceContent
+import warehouse from './warehouse';
+
+case 'warehouse':
+    return warehouse;
diff --git a/rsf-server/src/main/java/warehouseAreas.sql b/rsf-server/src/main/java/warehouseAreas.sql
new file mode 100644
index 0000000..ec6313e
--- /dev/null
+++ b/rsf-server/src/main/java/warehouseAreas.sql
@@ -0,0 +1,29 @@
+-- save warehouseAreas record
+-- mysql
+insert into `sys_menu` ( `name`, `parent_id`, `route`, `component`, `type`, `sort`, `tenant_id`, `status`) values ( 'menu.warehouseAreas', '0', '/manager/warehouseAreas', 'warehouseAreas', '0' , '0', '1' , '1');
+
+insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Query 搴撳尯淇℃伅琛�', '', '1', 'manager:warehouseAreas:list', '0', '1', '1');
+insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Create 搴撳尯淇℃伅琛�', '', '1', 'manager:warehouseAreas:save', '1', '1', '1');
+insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Update 搴撳尯淇℃伅琛�', '', '1', 'manager:warehouseAreas:update', '2', '1', '1');
+insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Delete 搴撳尯淇℃伅琛�', '', '1', 'manager:warehouseAreas:remove', '3', '1', '1');
+
+-- locale menu name
+warehouseAreas: 'WarehouseAreas',
+
+-- locale field
+warehouseAreas: {
+    uuid: "uuid",
+    name: "name",
+    code: "code",
+    shipperId: "shipperId",
+    supplierId: "supplierId",
+    flagMinus: "flagMinus",
+    flagLabelMange: "flagLabelMange",
+    flagMix: "flagMix",
+},
+
+-- ResourceContent
+import warehouseAreas from './warehouseAreas';
+
+case 'warehouseAreas':
+    return warehouseAreas;
diff --git a/rsf-server/src/main/resources/mapper/manager/WarehouseAreasMapper.xml b/rsf-server/src/main/resources/mapper/manager/WarehouseAreasMapper.xml
new file mode 100644
index 0000000..fc64f91
--- /dev/null
+++ b/rsf-server/src/main/resources/mapper/manager/WarehouseAreasMapper.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.vincent.rsf.server.manager.mapper.WarehouseAreasMapper">
+
+</mapper>
diff --git a/rsf-server/src/main/resources/mapper/manager/WarehouseMapper.xml b/rsf-server/src/main/resources/mapper/manager/WarehouseMapper.xml
new file mode 100644
index 0000000..c1881b9
--- /dev/null
+++ b/rsf-server/src/main/resources/mapper/manager/WarehouseMapper.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.vincent.rsf.server.manager.mapper.WarehouseMapper">
+
+</mapper>

--
Gitblit v1.9.1