skyouc
2025-03-20 210988b56322931b9e0c91194f5c50f84b007688
Merge branch 'front' into devlop
21个文件已修改
12个文件已添加
1501 ■■■■ 已修改文件
rsf-admin/src/i18n/en.js 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/i18n/zh.js 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/ResourceContent.js 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/basicInfo/companys/CompanysList.jsx 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/basicInfo/loc/LocCreate.jsx 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/basicInfo/loc/LocEdit.jsx 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/basicInfo/loc/LocList.jsx 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/basicInfo/locArea/LocAreaCreate.jsx 143 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/basicInfo/locArea/LocAreaEdit.jsx 116 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/basicInfo/locArea/LocAreaList.jsx 162 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/basicInfo/locArea/LocAreaPanel.jsx 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/basicInfo/locArea/index.jsx 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/basicInfo/locType/LocTypeCreate.jsx 132 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/basicInfo/locType/LocTypeEdit.jsx 104 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/basicInfo/locType/LocTypeList.jsx 151 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/basicInfo/locType/LocTypePanel.jsx 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/basicInfo/locType/index.jsx 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/basicInfo/matnr/MatnrCreate.jsx 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/basicInfo/matnr/MatnrEdit.jsx 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/basicInfo/matnr/MatnrList.jsx 129 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/basicInfo/matnrGroup/MatnrGroupList.jsx 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/basicInfo/warehouse/WarehouseList.jsx 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/components/DictField.jsx 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/components/DynamicField.jsx 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/components/ImportModal.jsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/components/TreeSelectInput.jsx 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/container/ContainerList.jsx 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/contract/ContractList.jsx 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/login/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/warehouseAreas/WarehouseAreasCreate.jsx 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/warehouseAreas/WarehouseAreasEdit.jsx 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/warehouseAreas/WarehouseAreasList.jsx 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/vite.config.js 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/i18n/en.js
@@ -107,7 +107,6 @@
    },
    menu: {
        dashboard: 'Dashboard',
        basicInfo: 'BasicInfo',
        settings: 'Settings',
        basicInfo: 'BasicInfo',
        system: 'System',
@@ -128,6 +127,7 @@
        warehouse: 'Warehouse',
        warehouseAreas: 'WarehouseAreas',
        loc: 'Loc',
        locType: 'LocType',
        container: 'Container',
        contract: 'Contract',
        qlyInspect: 'QlyInspect',
@@ -147,7 +147,6 @@
        endBay: "endBay",
        endLev: "endLev",
        endRow: "endRow",
        locType: "locType",
        startBay: "startBay",
        startLev: "startLev",
        startRow: "startRow",
@@ -305,6 +304,7 @@
            warehouseAreas: {
                uuid: "uuid",
                name: "name",
                wareId: "ware",
                code: "code",
                shipperId: "shipperId",
                supplierId: "supplierId",
@@ -355,6 +355,17 @@
                locAttrs: "LocAttrs",
                useStatus: 'useStatus'
            },
            locType: {
                uuid: "uuid",
                name: "name",
                regex: "regex",
            },
            locArea: {
                name: "name",
                code: "code",
                areaId: "areaId",
                locId: "locId",
            },
            container: {
                code: "Code",
                name: "Name",
rsf-admin/src/i18n/zh.js
@@ -127,6 +127,7 @@
        warehouse: '仓库信息',
        warehouseAreas: '仓库库区',
        loc: '基础库位',
        locType: '库位类型',
        container: '容器管理',
        contract: '合同信息',
        qlyInspect: '质检信息',
@@ -297,6 +298,7 @@
            warehouseAreas: {
                uuid: "唯一编码",
                name: "名称",
                wareId: "仓库",
                code: "编码",
                shipperId: "货主",
                supplierId: "供应商",
@@ -354,7 +356,16 @@
                startRow: "起始排",
                useStatus: '库位状态'
            },
            locType: {
                name: "库位类型",
                regex: "规则表达式",
            },
            locArea: {
                name: "名称",
                code: "编码",
                areaId: "库区",
                locId: "库位",
            },
            container: {
                code: "编码",
                name: "名称",
rsf-admin/src/page/ResourceContent.js
@@ -25,6 +25,8 @@
import dictType from './system/dicts/dictType';
import dictData from './system/dicts/dictData';
import companys from './basicInfo/companys';
import locType from './basicInfo/locType';
import locArea from './basicInfo//locArea';
import serialRuleItem from './system/serialRuleItem';
import serialRule from './system/serialRule';
import whMat from './basicInfo/whMat';
@@ -100,6 +102,11 @@
            return fields;
        case 'fieldsItem':
            return fieldsItem;
        case 'locType':
            return locType;
        case 'locArea':
            return locArea;
        default:
            return {
                list: ListGuesser,
rsf-admin/src/page/basicInfo/companys/CompanysList.jsx
@@ -40,7 +40,7 @@
import MyCreateButton from "../../components/MyCreateButton";
import MyExportButton from '../../components/MyExportButton';
import PageDrawer from "../../components/PageDrawer";
import MyField from "../../components/MyField";
import DictField from "../../components/DictField";
import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting';
import * as Common from '@/utils/common';
@@ -121,8 +121,6 @@
                    preferenceKey='companys'
                    bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />}
                    rowClick={(id, resource, record) => false}
                    expand={() => <CompanysPanel />}
                    expandSingle={true}
                    omit={['id', 'createTime', 'createBy', 'memo']}
                >
                    <NumberField source="id" />
@@ -130,7 +128,7 @@
                    <TextField source="name" label="table.field.companys.name" />
                    <TextField source="nameEn" label="table.field.companys.nameEn" />
                    <TextField source="breifCode" label="table.field.companys.breifCode" />
                    <TextField source="type" label="table.field.companys.type" />
                    <DictField source="type" label="table.field.companys.type" dictTypeCode={'sys_companys_type'} />
                    <TextField source="contact" label="table.field.companys.contact" />
                    <TextField source="tel" label="table.field.companys.tel" />
                    <TextField source="email" label="table.field.companys.email" />
rsf-admin/src/page/basicInfo/loc/LocCreate.jsx
@@ -16,6 +16,7 @@
    useDataProvider,
    useNotify,
    Form,
    SelectArrayInput,
    useCreateController,
} from 'react-admin';
import {
@@ -30,6 +31,7 @@
import DialogCloseButton from "../../components/DialogCloseButton";
import StatusSelectInput from "../../components/StatusSelectInput";
import MemoInput from "../../components/MemoInput";
import request from '@/utils/request';
const LocCreate = (props) => {
    const { open, setOpen } = props;
@@ -37,7 +39,6 @@
    const translate = useTranslate();
    const notify = useNotify();
    const handleClose = (event, reason) => {
        if (reason !== "backdropClick") {
            setOpen(false);
@@ -52,6 +53,9 @@
    const handleError = async (error) => {
        notify(error.message || 'common.response.fail', { type: 'error', messageArgs: { _: error.message } });
    };
    return (
        <>
@@ -87,7 +91,7 @@
                            <Grid container rowSpacing={2} columnSpacing={2}>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <ReferenceInput
                                        source="warehouseId$"
                                        source="warehouseId"
                                        reference="warehouse"
                                    >
                                        <AutocompleteInput
@@ -133,7 +137,7 @@
                                            validate={[required()]}
                                        />
                                    </ReferenceInput> */}
                                    <AutocompleteInput
                                    {/* <AutocompleteInput
                                        choices={dicts}
                                        source="type"
                                        optionText="label"
@@ -141,7 +145,10 @@
                                        optionValue="value"
                                        parse={v => v}
                                        validate={[required()]}
                                    />
                                    /> */}
                                    <ReferenceArrayInput source="typeIds" reference="locType" >
                                        <SelectArrayInput label="table.field.loc.type" />
                                    </ReferenceArrayInput>
                                </Grid>
                                {/* <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
@@ -150,7 +157,7 @@
                                        parse={v => v}
                                    />
                                </Grid> */}
                                <Grid item xs={6} display="flex" gap={1}>
                                {/* <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.loc.flagLogic"
                                        source="flagLogic"
@@ -169,7 +176,7 @@
                                        source="barcode"
                                        parse={v => v}
                                    />
                                </Grid>
                                </Grid> */}
                                {/* <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.loc.unit"
@@ -218,7 +225,7 @@
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                {/* <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.loc.channel"
                                        source="channel"
@@ -250,7 +257,10 @@
                                        parse={v => v}
                                        validate={required()}
                                    />
                                </Grid>
                                </Grid> */}
                                <Grid item xs={6} display="flex" gap={1}>
                                    <StatusSelectInput />
rsf-admin/src/page/basicInfo/loc/LocEdit.jsx
@@ -10,6 +10,7 @@
    DateInput,
    SelectInput,
    ReferenceInput,
    SelectArrayInput,
    ReferenceArrayInput,
    AutocompleteInput,
    SaveButton,
@@ -19,6 +20,7 @@
    required,
    useRecordContext,
    DeleteButton,
    useNotify,
} from 'react-admin';
import { useWatch, useFormContext } from "react-hook-form";
import { Stack, Grid, Box, Typography } from '@mui/material';
@@ -28,6 +30,7 @@
import CustomerTopToolBar from "../../components/EditTopToolBar";
import MemoInput from "../../components/MemoInput";
import StatusSelectInput from "../../components/StatusSelectInput";
import request from '@/utils/request';
const FormToolbar = () => {
    const { getValues } = useFormContext();
@@ -43,6 +46,8 @@
const LocEdit = () => {
    const translate = useTranslate();
    const dicts = JSON.parse(localStorage.getItem('sys_dicts'))?.filter(dict => (dict.dictTypeCode == 'sys_loc_type')) || [];
    return (
        <Edit
            redirect="list"
@@ -99,7 +104,7 @@
                                />
                            </Grid>
                            <Grid item xs={6} display="flex" gap={1}>
                                <AutocompleteInput
                                {/* <AutocompleteInput
                                    choices={dicts}
                                    source="type"
                                    optionText="label"
@@ -107,7 +112,10 @@
                                    optionValue="value"
                                    parse={v => v}
                                    validate={[required()]}
                                />
                                /> */}
                                <ReferenceArrayInput source="typeIds" reference="locType" >
                                    <SelectArrayInput label="table.field.loc.type" />
                                </ReferenceArrayInput>
                            </Grid>
                            <Grid item xs={6} display="flex" gap={1}>
                                <TextInput
@@ -158,6 +166,8 @@
                                    validate={required()}
                                />
                            </Grid>
                        </Grid>
                    </Grid>
                    <Grid item xs={12} md={2}>
rsf-admin/src/page/basicInfo/loc/LocList.jsx
@@ -32,13 +32,15 @@
    AutocompleteInput,
    DeleteButton,
    useRefresh,
    Button
    Button,
    useList
} from 'react-admin';
import { Box, Typography, Card, Stack } from '@mui/material';
import { styled } from '@mui/material/styles';
import LocCreate from "./LocCreate";
import LocPanel from "./LocPanel";
import EmptyData from "../../components/EmptyData";
import DynamicField from "../../components/DynamicField";
import MyCreateButton from "../../components/MyCreateButton";
import MyExportButton from '../../components/MyExportButton';
import InitButton from './InitButton';
@@ -50,6 +52,7 @@
import DashboardIcon from '@mui/icons-material/Dashboard';
import EditIcon from '@mui/icons-material/Edit';
import request from '@/utils/request';
const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({
    '& .css-1vooibu-MuiSvgIcon-root': {
@@ -101,6 +104,8 @@
const LocList = () => {
    const translate = useTranslate();
    const notify = useNotify();
    const refresh = useRefresh();
    const [createDialog, setCreateDialog] = useState(false);
    const [drawerVal, setDrawerVal] = useState(false);
@@ -141,30 +146,29 @@
                        </>
                    }
                    rowClick={() => false}
                    expand={() => <LocPanel />}
                    omit={['id', 'createTime', 'createBy', 'memo', 'updateTime', 'updateBy']}
                >
                    <NumberField source="id" />
                    <NumberField source="warehouseId$" label="table.field.loc.warehouseId" />
                    <NumberField source="areaId$" label="table.field.loc.areaId" />
                    <TextField source="code" label="table.field.loc.code" />
                    <TextField source="type$" label="table.field.loc.type" />
                    <TextField source="typeIds$" label="table.field.loc.type" />
                    {/* <TextField source="name" label="table.field.loc.name" /> */}
                    <NumberField source="flagLogic" label="table.field.loc.flagLogic" />
                    {/* <NumberField source="flagLogic" label="table.field.loc.flagLogic" />
                    <TextField source="fucAtrrs" label="table.field.loc.fucAtrrs" />
                    <TextField source="barcode" label="table.field.loc.barcode" />
                    <TextField source="unit" label="table.field.loc.unit" />
                    <TextField source="barcode" label="table.field.loc.barcode" /> */}
                    {/* <TextField source="unit" label="table.field.loc.unit" /> */}
                    <TextField source="length" label="table.field.loc.length" />
                    <TextField source="width" label="table.field.loc.width" />
                    <TextField source="height" label="table.field.loc.height" />
                    <NumberField source="row" label="table.field.loc.row" />
                    <NumberField source="col" label="table.field.loc.col" />
                    <NumberField source="lev" label="table.field.loc.lev" />
                    <NumberField source="channel" label="table.field.loc.channel" />
                    {/* <NumberField source="channel" label="table.field.loc.channel" />
                    <NumberField source="maxParts" label="table.field.loc.maxParts" />
                    <NumberField source="maxPack" label="table.field.loc.maxPack" />
                    <NumberField source="flagLabelMange" label="table.field.loc.flagLabelMange" />
                    <TextField source="locAttrs" label="table.field.loc.locAttrs" />
                    <TextField source="locAttrs" label="table.field.loc.locAttrs" /> */}
                    <TextField source="useStatus$" label="table.field.loc.useStatus" />
                    <ReferenceField source="updateBy" label="common.field.updateBy" reference="user" link={false} sortable={false}>
                        <TextField source="nickname" />
@@ -176,11 +180,13 @@
                    <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} /> */}
                        <EnableButton />
                    </WrapperField>
                </StyledDatagrid>
            </List>
            <LocCreate
rsf-admin/src/page/basicInfo/locArea/LocAreaCreate.jsx
New file
@@ -0,0 +1,143 @@
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 LocAreaCreate = (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.locArea.name"
                                        source="name"
                                        parse={v => v}
                                        autoFocus
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.locArea.code"
                                        source="code"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.locArea.areaId"
                                        source="areaId"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <ReferenceInput
                                        source="locId"
                                        reference="loc"
                                    >
                                        <AutocompleteInput
                                            label="table.field.locArea.locId"
                                            optionText="warehouseId"
                                            filterToQuery={(val) => ({ warehouseId: val })}
                                        />
                                    </ReferenceInput>
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <StatusSelectInput />
                                </Grid>
                                <Grid item xs={12} display="flex" gap={1}>
                                    <Stack direction="column" spacing={1} width={'100%'}>
                                        <MemoInput />
                                    </Stack>
                                </Grid>
                            </Grid>
                        </DialogContent>
                        <DialogActions sx={{ position: 'sticky', bottom: 0, backgroundColor: 'background.paper', zIndex: 1000 }}>
                            <Toolbar sx={{ width: '100%', justifyContent: 'space-between' }}  >
                                <SaveButton />
                            </Toolbar>
                        </DialogActions>
                    </Form>
                </Dialog>
            </CreateBase>
        </>
    )
}
export default LocAreaCreate;
rsf-admin/src/page/basicInfo/locArea/LocAreaEdit.jsx
New file
@@ -0,0 +1,116 @@
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 LocAreaEdit = () => {
    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.locArea.name"
                                source="name"
                                parse={v => v}
                                autoFocus
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.locArea.code"
                                source="code"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.locArea.areaId"
                                source="areaId"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <ReferenceInput
                                source="locId"
                                reference="loc"
                                perPage={REFERENCE_INPUT_PAGESIZE}
                            >
                                <AutocompleteInput
                                    label="table.field.locArea.locId"
                                    optionText="warehouseId"
                                    filterToQuery={(val) => ({ warehouseId: val })}
                                />
                            </ReferenceInput>
                        </Stack>
                    </Grid>
                    <Grid item xs={12} md={4}>
                        <Typography variant="h6" gutterBottom>
                            {translate('common.edit.title.common')}
                        </Typography>
                        <StatusSelectInput />
                        <Box mt="2em" />
                        <MemoInput />
                    </Grid>
                </Grid>
            </SimpleForm>
        </Edit >
    )
}
export default LocAreaEdit;
rsf-admin/src/page/basicInfo/locArea/LocAreaList.jsx
New file
@@ -0,0 +1,162 @@
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 LocAreaCreate from "./LocAreaCreate";
import LocAreaPanel from "./LocAreaPanel";
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.locArea.name" />,
    <TextInput source="code" label="table.field.locArea.code" />,
    <NumberInput source="areaId" label="table.field.locArea.areaId" />,
    <ReferenceInput source="locId" label="table.field.locArea.locId" reference="loc">
        <AutocompleteInput label="table.field.locArea.locId" optionText="warehouseId" filterToQuery={(val) => ({ warehouseId: val })} />
    </ReferenceInput>,
    <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 LocAreaList = () => {
    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.locArea"}
                empty={<EmptyData onClick={() => { setCreateDialog(true) }} />}
                filters={filters}
                sort={{ field: "create_time", order: "desc" }}
                actions={(
                    <TopToolbar>
                        <FilterButton />
                        <MyCreateButton onClick={() => { setCreateDialog(true) }} />
                        <SelectColumnsButton preferenceKey='locArea' />
                        <MyExportButton />
                    </TopToolbar>
                )}
                perPage={DEFAULT_PAGE_SIZE}
            >
                <StyledDatagrid
                    preferenceKey='locArea'
                    bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />}
                    rowClick={(id, resource, record) => false}
                    expand={() => <LocAreaPanel />}
                    expandSingle={true}
                    omit={['id', 'createTime', 'createBy', 'memo']}
                >
                    <NumberField source="id" />
                    <TextField source="name" label="table.field.locArea.name" />
                    <TextField source="code" label="table.field.locArea.code" />
                    <NumberField source="areaId" label="table.field.locArea.areaId" />
                    <ReferenceField source="locId" label="table.field.locArea.locId" reference="loc" link={false} sortable={false}>
                        <TextField source="warehouseId" />
                    </ReferenceField>
                    <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>
            <LocAreaCreate
                open={createDialog}
                setOpen={setCreateDialog}
            />
            <PageDrawer
                title='LocArea Detail'
                drawerVal={drawerVal}
                setDrawerVal={setDrawerVal}
            >
            </PageDrawer>
        </Box>
    )
}
export default LocAreaList;
rsf-admin/src/page/basicInfo/locArea/LocAreaPanel.jsx
New file
@@ -0,0 +1,75 @@
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 LocAreaPanel = () => {
    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.locArea.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.locArea.name"
                                property={record.name}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.locArea.code"
                                property={record.code}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.locArea.areaId"
                                property={record.areaId}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.locArea.locId"
                                property={record.locId$}
                            />
                        </Grid>
                    </Grid>
                </CardContent>
            </Card >
        </>
    );
};
export default LocAreaPanel;
rsf-admin/src/page/basicInfo/locArea/index.jsx
New file
@@ -0,0 +1,18 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import {
    ListGuesser,
    EditGuesser,
    ShowGuesser,
} from "react-admin";
import LocAreaList from "./LocAreaList";
import LocAreaEdit from "./LocAreaEdit";
export default {
    list: LocAreaList,
    edit: LocAreaEdit,
    show: ShowGuesser,
    recordRepresentation: (record) => {
        return `${record.name}`
    }
};
rsf-admin/src/page/basicInfo/locType/LocTypeCreate.jsx
New file
@@ -0,0 +1,132 @@
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 LocTypeCreate = (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.locType.uuid"
                                        source="uuid"
                                        parse={v => v}
                                        autoFocus
                                    />
                                </Grid> */}
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.locType.name"
                                        source="name"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.locType.regex"
                                        source="regex"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <StatusSelectInput />
                                </Grid>
                                <Grid item xs={12} display="flex" gap={1}>
                                    <Stack direction="column" spacing={1} width={'100%'}>
                                        <MemoInput />
                                    </Stack>
                                </Grid>
                            </Grid>
                        </DialogContent>
                        <DialogActions sx={{ position: 'sticky', bottom: 0, backgroundColor: 'background.paper', zIndex: 1000 }}>
                            <Toolbar sx={{ width: '100%', justifyContent: 'space-between' }}  >
                                <SaveButton />
                            </Toolbar>
                        </DialogActions>
                    </Form>
                </Dialog>
            </CreateBase>
        </>
    )
}
export default LocTypeCreate;
rsf-admin/src/page/basicInfo/locType/LocTypeEdit.jsx
New file
@@ -0,0 +1,104 @@
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 LocTypeEdit = () => {
    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.locType.uuid"
                                source="uuid"
                                parse={v => v}
                                autoFocus
                            />
                        </Stack> */}
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.locType.name"
                                source="name"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.locType.regex"
                                source="regex"
                                parse={v => v}
                            />
                        </Stack>
                    </Grid>
                    <Grid item xs={12} md={4}>
                        <Typography variant="h6" gutterBottom>
                            {translate('common.edit.title.common')}
                        </Typography>
                        <StatusSelectInput />
                        <Box mt="2em" />
                        <MemoInput />
                    </Grid>
                </Grid>
            </SimpleForm>
        </Edit >
    )
}
export default LocTypeEdit;
rsf-admin/src/page/basicInfo/locType/LocTypeList.jsx
New file
@@ -0,0 +1,151 @@
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 LocTypeCreate from "./LocTypeCreate";
import LocTypePanel from "./LocTypePanel";
import EmptyData from "../../components/EmptyData";
import MyCreateButton from "../../components/MyCreateButton";
import MyExportButton from '../../components/MyExportButton';
import PageDrawer from "../../components/PageDrawer";
import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting';
import * as Common from '@/utils/common';
const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({
    '& .css-1vooibu-MuiSvgIcon-root': {
        height: '.9em'
    },
    '& .RaDatagrid-row': {
        cursor: 'auto'
    },
    '& .column-name': {
    },
    '& .opt': {
        width: 200
    },
}));
const filters = [
    <SearchInput source="condition" alwaysOn />,
    <TextInput source="uuid" label="table.field.locType.uuid" />,
    <TextInput source="name" label="table.field.locType.name" />,
    <TextInput source="regex" label="table.field.locType.regex" />,
    <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 LocTypeList = () => {
    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.locType"}
                empty={<EmptyData onClick={() => { setCreateDialog(true) }} />}
                filters={filters}
                sort={{ field: "create_time", order: "desc" }}
                actions={(
                    <TopToolbar>
                        <FilterButton />
                        <MyCreateButton onClick={() => { setCreateDialog(true) }} />
                        <SelectColumnsButton preferenceKey='locType' />
                        <MyExportButton />
                    </TopToolbar>
                )}
                perPage={DEFAULT_PAGE_SIZE}
            >
                <StyledDatagrid
                    preferenceKey='locType'
                    bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />}
                    rowClick={(id, resource, record) => false}
                    omit={['id', 'createTime', 'createBy', 'memo']}
                >
                    <NumberField source="id" />
                    {/* <TextField source="uuid" label="table.field.locType.uuid" /> */}
                    <TextField source="name" label="table.field.locType.name" />
                    <TextField source="regex" label="table.field.locType.regex" />
                    <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>
            <LocTypeCreate
                open={createDialog}
                setOpen={setCreateDialog}
            />
            <PageDrawer
                title='LocType Detail'
                drawerVal={drawerVal}
                setDrawerVal={setDrawerVal}
            >
            </PageDrawer>
        </Box>
    )
}
export default LocTypeList;
rsf-admin/src/page/basicInfo/locType/LocTypePanel.jsx
New file
@@ -0,0 +1,69 @@
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 LocTypePanel = () => {
    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.locType.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.locType.uuid"
                                property={record.uuid}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.locType.name"
                                property={record.name}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.locType.regex"
                                property={record.regex}
                            />
                        </Grid>
                    </Grid>
                </CardContent>
            </Card >
        </>
    );
};
export default LocTypePanel;
rsf-admin/src/page/basicInfo/locType/index.jsx
New file
@@ -0,0 +1,18 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import {
    ListGuesser,
    EditGuesser,
    ShowGuesser,
} from "react-admin";
import LocTypeList from "./LocTypeList";
import LocTypeEdit from "./LocTypeEdit";
export default {
    list: LocTypeList,
    edit: LocTypeEdit,
    show: ShowGuesser,
    recordRepresentation: (record) => {
        return `${record.name}`
    }
};
rsf-admin/src/page/basicInfo/matnr/MatnrCreate.jsx
@@ -33,8 +33,8 @@
import DialogCloseButton from "@/page/components/DialogCloseButton";
import StatusSelectInput from "@/page/components/StatusSelectInput";
import MemoInput from "@/page/components/MemoInput";
import { tr } from "date-fns/locale";
import TreeSelectInput from "@/page/components/TreeSelectInput";
import request from '@/utils/request';
function CustomTabPanel(props) {
    const { children, value, index, ...other } = props;
@@ -69,7 +69,21 @@
    const translate = useTranslate();
    const notify = useNotify();
    const [value, setValue] = React.useState(0);
    const [dynamicFields, setDynamicFields] = useState([]);
    useEffect(() => {
        getDynamicFields();
    }, []);
    const getDynamicFields = async () => {
        const {
            data: { code, data, msg },
        } = await request.get("/fields/enable/list");
        if (code === 200) {
            setDynamicFields(data || [])
        } else {
            notify(msg);
        }
    };
    const handleChange = (event, newValue) => {
        setValue(newValue);
    };
@@ -154,10 +168,7 @@
                                        />
                                    </Grid>
                                    <Grid item xs={6} display="flex" gap={1}>
                                        <ReferenceInput
                                            source="shipperId"
                                            reference="shipper"
                                        >
                                        <ReferenceInput source="shipperId" reference="companys" filter={{ type: 'shipper' }}>
                                            <AutocompleteInput
                                                label="table.field.matnr.shipperId"
                                                optionText="name"
@@ -167,17 +178,11 @@
                                        </ReferenceInput>
                                    </Grid>
                                    <Grid item xs={6} display="flex" gap={1}>
                                        <ReferenceInput
                                        <TreeSelectInput
                                            label="table.field.matnr.groupId"
                                            resource={'matnrGroup'}
                                            source="groupId"
                                            reference="matnrGroup"
                                        >
                                            <AutocompleteInput
                                                label="table.field.matnr.groupId"
                                                optionText="name"
                                                validate={[required()]}
                                                filterToQuery={(val) => ({ name: val })}
                                            />
                                        </ReferenceInput>
                                        />
                                    </Grid>
                                    <Grid item xs={6} display="flex" gap={1}>
                                        <TextInput
@@ -277,6 +282,16 @@
                                        />
                                    </Grid>
                                    {dynamicFields.map((item) => {
                                        return (
                                            <Grid key={item.id} item xs={6} display="flex" gap={1}>
                                                <TextInput
                                                    label={item.fieldsAlise}
                                                    source={item.fields}
                                                />
                                            </Grid>
                                        )
                                    })}
                                    <Grid item xs={6} display="flex" gap={1}>
                                        <StatusSelectInput />
@@ -342,13 +357,13 @@
                                <Grid container rowSpacing={2} columnSpacing={2}>
                                    <Grid item xs={6} display="flex" gap={1}>
                                        <ReferenceInput
                                            source="rglarId"
                                            reference="batchRegular"
                                            source="rglar_id"
                                            reference="serialRule"
                                        >
                                            <AutocompleteInput
                                                label="table.field.matnr.rglarId"
                                                optionText="code"
                                                filterToQuery={(val) => ({ code: val })}
                                                optionText="name"
                                                filterToQuery={(val) => ({ name: val })}
                                            />
                                        </ReferenceInput>
                                    </Grid>
rsf-admin/src/page/basicInfo/matnr/MatnrEdit.jsx
@@ -19,6 +19,7 @@
    required,
    useRecordContext,
    DeleteButton,
    useNotify,
} from 'react-admin';
import PropTypes from 'prop-types';
import { useWatch, useFormContext } from "react-hook-form";
@@ -29,7 +30,8 @@
import CustomerTopToolBar from "@/page/components/EditTopToolBar";
import MemoInput from "@/page/components/MemoInput";
import StatusSelectInput from "@/page/components/StatusSelectInput";
import TreeSelectInput from "@/page/components/TreeSelectInput";
import request from '@/utils/request';
const FormToolbar = () => {
    const { getValues } = useFormContext();
    return (
@@ -72,6 +74,24 @@
const MatnrEdit = () => {
    const translate = useTranslate();
    const [value, setValue] = React.useState(0);
    const notify = useNotify();
    const [dynamicFields, setDynamicFields] = useState([]);
    useEffect(() => {
        getDynamicFields();
    }, []);
    const getDynamicFields = async () => {
        const {
            data: { code, data, msg },
        } = await request.get("/fields/enable/list");
        if (code === 200) {
            setDynamicFields(data || [])
        } else {
            notify(msg);
        }
    };
    const handleChange = (event, newValue) => {
        setValue(newValue);
    };
@@ -122,11 +142,7 @@
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <ReferenceInput
                                        source="shipperId"
                                        reference="shipper"
                                        perPage={REFERENCE_INPUT_PAGESIZE}
                                    >
                                    <ReferenceInput source="shipperId" reference="companys" filter={{ type: 'shipper' }}>
                                        <AutocompleteInput
                                            validate={[required()]}
                                            label="table.field.matnr.shipperId"
@@ -136,32 +152,26 @@
                                    </ReferenceInput>
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <ReferenceInput
                                    {/* <ReferenceInput
                                        source="groupId"
                                        reference="matnrGroup"
                                        perPage={REFERENCE_INPUT_PAGESIZE}
                                    >
                                        <AutocompleteInput
                                            label="table.field.matnr.groupId"
                                            optionText="code"
                                            optionText="label"
                                            validate={[required()]}
                                            filterToQuery={(val) => ({ code: val })}
                                        />
                                    </ReferenceInput>
                                    </ReferenceInput> */}
                                    <TreeSelectInput
                                        label="table.field.matnr.groupId"
                                        resource={'matnrGroup'}
                                        source="groupId"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <ReferenceInput
                                        source="rglarId"
                                        reference="batchRegular"
                                        perPage={REFERENCE_INPUT_PAGESIZE}
                                    >
                                        <AutocompleteInput
                                            label="table.field.matnr.rglarId"
                                            optionText="code"
                                            filterToQuery={(val) => ({ code: val })}
                                        />
                                    </ReferenceInput>
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.matnr.platCode"
@@ -254,6 +264,17 @@
                                    />
                                </Grid>
                                {dynamicFields.map((item) => {
                                    return (
                                        <Grid key={item.id} item xs={6} display="flex" gap={1}>
                                            <TextInput
                                                label={item.fieldsAlise}
                                                source={item.fields}
                                            />
                                        </Grid>
                                    )
                                })}
                            </Grid>
@@ -302,10 +323,17 @@
                        <CustomTabPanel value={value} index={2}>
                            <Grid container rowSpacing={2} columnSpacing={2}>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.matnr.flagCheck"
                                        source="flagCheck"
                                    />
                                    <ReferenceInput
                                        source="rglar_id"
                                        reference="serialRule"
                                        perPage={REFERENCE_INPUT_PAGESIZE}
                                    >
                                        <AutocompleteInput
                                            label="table.field.matnr.rglarId"
                                            optionText="name"
                                            filterToQuery={(val) => ({ name: val })}
                                        />
                                    </ReferenceInput>
                                </Grid>
                            </Grid>
                        </CustomTabPanel>
rsf-admin/src/page/basicInfo/matnr/MatnrList.jsx
@@ -48,7 +48,7 @@
import * as Common from '@/utils/common';
import ImportButton from "../../components/ImportButton";
import MatListAside from './MatnrListAside';
import { display, height } from "@mui/system";
import { display, height, width } from "@mui/system";
import DashboardIcon from '@mui/icons-material/Dashboard';
import EditIcon from '@mui/icons-material/Edit';
import request from '@/utils/request';
@@ -83,6 +83,9 @@
        textOverflow: 'ellipsis',
        display: 'block',
        width: '100px',
    },
    '& .RaDatagrid-table': {
        width: '100%'
    }
}));
@@ -146,7 +149,73 @@
const MatnrListContent = (props) => {
    const translate = useTranslate();
    const notify = useNotify();
    const { isLoading } = useListContext();
    const [dynamicFields, setDynamicFields] = useState([]);
    const refresh = useRefresh();
    const { refetch } = useListContext();
    useEffect(() => {
        getDynamicFields();
    }, []);
    const getDynamicFields = async () => {
        try {
            const {
                data: { code, data, msg },
            } = await request.get("/fields/enable/list");
            if (code === 200) {
                setDynamicFields(data);
                refresh();
            } else {
                notify(msg);
            }
        } catch (error) {
            notify('请求出错');
        }
    };
    const columns = [
        <NumberField key="id" source="id" />,
        <TooltipField key="name" source="name" label="table.field.matnr.name" cellClassName="name" />,
        <TextField key="code" source="code" label="table.field.matnr.code" />,
        <TextField key="shipperId$" source="shipperId$" label="table.field.matnr.shipperId" />,
        <ReferenceField key="groupId" source="groupId" label="table.field.matnr.groupId" reference="matnrGroup" link={false} sortable={false}>
            <TextField source="name" />
        </ReferenceField>,
        <TextField key="platCode" source="platCode" label="table.field.matnr.platCode" />,
        <TextField key="spec" source="spec" label="table.field.matnr.spec" />,
        <TextField key="model" source="model" label="table.field.matnr.model" />,
        <NumberField key="weight" source="weight" label="table.field.matnr.weight" />,
        <TextField key="describle" source="describle" label="table.field.matnr.describle" />,
        <NumberField key="nromNum" source="nromNum" label="table.field.matnr.nromNum" />,
        <TextField key="unit" source="unit" label="table.field.matnr.unit" />,
        <TextField key="purchaseUnit" source="purchaseUnit" label="table.field.matnr.purUnit" />,
        <TextField key="stockUnit" source="stockUnit" label="table.field.matnr.stockUnit" />,
        <TextField key="stockLeval$" source="stockLeval$" label="table.field.matnr.stockLevel" sortable={false} />,
        <TextField key="isLabelMange$" source="isLabelMange$" label="table.field.matnr.isLabelMange" sortable={false} />,
        <NumberField key="safeQty" source="safeQty" label="table.field.matnr.safeQty" />,
        <NumberField key="minQty" source="minQty" label="table.field.matnr.minQty" />,
        <NumberField key="maxQty" source="maxQty" label="table.field.matnr.maxQty" />,
        <NumberField key="stagn" source="stagn" label="table.field.matnr.stagn" />,
        <NumberField key="valid" source="valid" label="table.field.matnr.valid" />,
        <NumberField key="validWarn" source="validWarn" label="table.field.matnr.validWarn" />,
        <NumberField key="flagCheck" source="flagCheck" label="table.field.matnr.flagCheck" />,
        <ReferenceField key="updateBy" source="updateBy" label="common.field.updateBy" reference="user" link={false} sortable={false}>
            <TextField source="nickname" />
        </ReferenceField>,
        <DateField key="updateTime" source="updateTime" label="common.field.updateTime" showTime />,
        <ReferenceField key="createBy" source="createBy" label="common.field.createBy" reference="user" link={false} sortable={false}>
            <TextField source="nickname" />
        </ReferenceField>,
        <DateField key="createTime" source="createTime" label="common.field.createTime" showTime />,
        <BooleanField key="statusBool" source="statusBool" label="common.field.status" sortable={false} />,
        <TextField key="memo" source="memo" label="common.field.memo" sortable={false} />,
        <WrapperField key="opt" cellClassName="opt" label="common.field.opt">
            <EditButton sx={{ padding: '1px', fontSize: '.75rem' }} />
            <EnableButton />
        </WrapperField>
    ];
    return (
        <Box sx={{ position: 'relative', minHeight: "60vh", }}>
@@ -166,74 +235,24 @@
                preferenceKey='matnr'
                bulkActionButtons={<> <BatchButton /><BulkDeleteButton mutationMode={OPERATE_MODE} /></>}
                rowClick={(id, resource, record) => false}
                expand={() => <MatnrPanel />}
                expandSingle={true}
                omit={['id', 'shipperId', 'platCode', 'spec', 'model', 'weight', 'color', 'size', 'describle'
                omit={['id', 'shipperId', 'platCode', 'spec', 'model', 'weight', 'color', 'describle'
                    , 'nromNum', 'unit', 'purchaseUnit', 'stockUnit', 'stockLeval', 'isLabelMange', 'safeQty'
                    , 'minQty', 'maxQty', 'stagn', 'valid', 'validWarn', 'flagCheck', 'updateTime', 'updateBy'
                    , 'createTime', 'createBy', 'memo', 'rglarId', 'groupId', 'stockLevel', 'isLabelMange']}
            >
                <NumberField source="id" />
                <TooltipField source="name" label="table.field.matnr.name" cellClassName="name" />
                <TextField source="code" label="table.field.matnr.code" />
                <ReferenceField source="shipperId" label="table.field.matnr.shipperId" reference="shipper" link={false} sortable={false}>
                    <TextField source="name" />
                </ReferenceField>
                <ReferenceField source="groupId" label="table.field.matnr.groupId" reference="matnrGroup" link={false} sortable={false}>
                    <TextField source="name" />
                </ReferenceField>
                <ReferenceField source="rglarId" label="table.field.matnr.rglarId" reference="batchRegular" link={false} sortable={false}>
                    <TextField source="code" />
                </ReferenceField>
                <TextField source="platCode" label="table.field.matnr.platCode" />
                <TextField source="spec" label="table.field.matnr.spec" />
                <TextField source="model" label="table.field.matnr.model" />
                <NumberField source="weight" label="table.field.matnr.weight" />
                <TextField source="color" label="table.field.matnr.color" />
                <TextField source="size" label="table.field.matnr.size" />
                <TextField source="describle" label="table.field.matnr.describle" />
                <NumberField source="nromNum" label="table.field.matnr.nromNum" />
                <TextField source="unit" label="table.field.matnr.unit" />
                <TextField source="purchaseUnit" label="table.field.matnr.purUnit" />
                <TextField source="stockUnit" label="table.field.matnr.stockUnit" />
                <TextField source="stockLeval$" label="table.field.matnr.stockLevel" sortable={false} />
                <TextField source="isLabelMange$" label="table.field.matnr.isLabelMange" sortable={false} />
                <NumberField source="safeQty" label="table.field.matnr.safeQty" />
                <NumberField source="minQty" label="table.field.matnr.minQty" />
                <NumberField source="maxQty" label="table.field.matnr.maxQty" />
                <NumberField source="stagn" label="table.field.matnr.stagn" />
                <NumberField source="valid" label="table.field.matnr.valid" />
                <NumberField source="validWarn" label="table.field.matnr.validWarn" />
                <NumberField source="flagCheck" label="table.field.matnr.flagCheck" />
                <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} /> */}
                    <EnableButton />
                </WrapperField>
                {columns.map((column) => column)}
            </StyledDatagrid>
        </Box>
    );
}
const MatnrList = () => {
    const translate = useTranslate();
    const [createDialog, setCreateDialog] = useState(false);
    const [drawerVal, setDrawerVal] = useState(false);
    const notify = useNotify();
    return (
        <Box display="flex">
rsf-admin/src/page/basicInfo/matnrGroup/MatnrGroupList.jsx
@@ -39,17 +39,18 @@
const TITLE = 'menu.matnrGroup';
const columns = [
    {
        id: 'name',
        label: 'table.field.matnrGroup.name',
        minWidth: 200,
    },
    {
        id: 'code',
        label: 'table.field.matnrGroup.code',
        minWidth: 80,
    },
    {
        id: 'name',
        label: 'table.field.matnrGroup.name',
        Width: 100,
    },
    {
        id: 'parentId',
        label: 'table.field.matnrGroup.parentId',
        minWidth: 100,
rsf-admin/src/page/basicInfo/warehouse/WarehouseList.jsx
@@ -118,8 +118,6 @@
                    preferenceKey='warehouse'
                    bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />}
                    rowClick={(id, resource, record) => false}
                    expand={() => <WarehousePanel />}
                    expandSingle={true}
                    omit={['id', 'createTime', 'createBy', 'memo']}
                >
                    <NumberField source="id" />
rsf-admin/src/page/components/DictField.jsx
New file
@@ -0,0 +1,24 @@
import React, { useState, useRef, useEffect, useMemo, useCallback } from "react";
import {
    useRecordContext,
} from 'react-admin';
import { Box, Typography, Card, Stack } from '@mui/material';
import { useTheme } from '@mui/material/styles';
const DictField = ({ source }) => {
    const record = useRecordContext();
    const theme = useTheme();
    const value = JSON.parse(localStorage.getItem('sys_dicts'))?.find(dict => (dict.value == record[source])).label;
    return record ? (
        <Typography
            variant="body2"
        >
            {value}
        </Typography >
    ) : null;
}
export default DictField;
rsf-admin/src/page/components/DynamicField.jsx
New file
@@ -0,0 +1,44 @@
import React, { Fragment } from 'react';
import {
    TextField,
    NumberField,
    DateField,
    BooleanField,
    ReferenceField
} from 'react-admin';
const DynamicField = ({ fields }) => {
    return (
        <>
            {fields.map((field, index) => {
                switch (field.type) {
                    case 'text':
                        return <TextField key={index} source={field.source} label={field.label} />;
                    case 'number':
                        return <NumberField key={index} source={field.source} label={field.label} />;
                    case 'date':
                        return <DateField key={index} source={field.source} label={field.label} showTime={field.showTime} />;
                    case 'boolean':
                        return <BooleanField key={index} source={field.source} label={field.label} />;
                    case 'reference':
                        return (
                            <ReferenceField
                                key={index}
                                source={field.source}
                                label={field.label}
                                reference={field.reference}
                                link={field.link}
                                sortable={field.sortable}
                            >
                                <TextField source={field.referenceSource} />
                            </ReferenceField>
                        );
                    default:
                        return null;
                }
            })}
        </>
    );
};
export default DynamicField;
rsf-admin/src/page/components/ImportModal.jsx
@@ -79,6 +79,19 @@
        reset();
    };
    const downloadTemplate = async (type) => {
        const res = await request.post(`/${value}/template/download`, {})
        const url = window.URL.createObjectURL(
            new Blob([res.data], { type: res.headers["content-type"] }),
        );
        const link = document.createElement("a");
        link.href = url;
        link.setAttribute("download", `${value}.xlsx`);
        document.body.appendChild(link);
        link.click();
        link.remove();
    }
    return (
        <Dialog open={open} maxWidth="md" fullWidth>
            <DialogCloseButton onClose={handleClose} />
@@ -230,14 +243,7 @@
    );
}
{/**下载打印模板,传入type类型,调用下载模板接口 */ }
const downloadTemplate = (type) => {
    // 下载物料模板
    if (type != undefined && type == 'matnr') {
    }
    console.log('======>');
    console.log(type);
}
function millisecondsToTime(ms) {
    var seconds = Math.floor((ms / 1000) % 60);
rsf-admin/src/page/components/TreeSelectInput.jsx
@@ -1,5 +1,5 @@
import React, { useState, useEffect } from 'react';
import { useCreateContext, useTranslate } from 'react-admin'
import { useCreateContext, useTranslate, useRecordContext } from 'react-admin'
import { MenuItem, Select, FormControl, InputLabel, Typography } from '@mui/material';
import request from '@/utils/request';
import * as Common from '@/utils/common';
@@ -13,6 +13,9 @@
    const [proxyVal, setProxyVal] = React.useState('');
    const record = useRecordContext()
    const val = value || record[source];
    useEffect(() => {
        const http = async (resource) => {
            const res = await request.post(resource + '/tree', {
@@ -20,7 +23,7 @@
            });
            if (res?.data?.code === 200) {
                setTreeData(Common.flattenTree(res.data.data));
                setProxyVal(value);
                setProxyVal(val);
            } else {
                notify(res.data.msg);
            }
rsf-admin/src/page/container/ContainerList.jsx
@@ -134,8 +134,6 @@
                    preferenceKey='container'
                    bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />}
                    rowClick={(id, resource, record) => false}
                    expand={() => <ContainerPanel />}
                    expandSingle={true}
                    omit={['id', 'createTime', 'createBy', 'memo']}
                >
                    <NumberField source="id" />
rsf-admin/src/page/contract/ContractList.jsx
@@ -112,8 +112,6 @@
                    preferenceKey='contract'
                    bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />}
                    rowClick={(id, resource, record) => false}
                    expand={() => <ContractPanel />}
                    expandSingle={true}
                    omit={['id', 'createTime', 'createBy', 'memo']}
                >
                    <NumberField source="id" />
rsf-admin/src/page/login/index.jsx
@@ -113,9 +113,9 @@
                    <Login systemInfo={systemInfo} tenantList={tenantList} />
                )}
                <Box mb={1} sx={{ textAlign: 'center' }}>
                {/* <Box mb={1} sx={{ textAlign: 'center' }}>
                    <Typography variant="caption" align="center">{translate("page.login.footer")}</Typography>
                </Box>
                </Box> */}
            </Card>
        </Box >
    );
rsf-admin/src/page/warehouseAreas/WarehouseAreasCreate.jsx
@@ -117,6 +117,18 @@
                  />
                </Grid>
                <Grid item xs={6} display="flex" gap={1}>
                  <ReferenceInput
                    source="wareId"
                    reference="warehouse"
                  >
                    <AutocompleteInput
                      label="table.field.warehouseAreas.wareId"
                      optionText="name"
                      filterToQuery={(val) => ({ name: val })}
                    />
                  </ReferenceInput>
                </Grid>
                <Grid item xs={6} display="flex" gap={1}>
                  <ReferenceInput source="shipperId" reference="companys" filter={{ type: 'shipper' }}>
                    <AutocompleteInput
                      label="table.field.warehouseAreas.shipperId"
rsf-admin/src/page/warehouseAreas/WarehouseAreasEdit.jsx
@@ -90,9 +90,20 @@
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <ReferenceInput
                                source="wareId"
                                reference="warehouse"
                            >
                                <AutocompleteInput
                                    label="table.field.warehouseAreas.wareId"
                                    optionText="name"
                                    filterToQuery={(val) => ({ name: val })}
                                />
                            </ReferenceInput>
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <ReferenceInput
                                source="shipperId"
                                reference="companys"
                                perPage={REFERENCE_INPUT_PAGESIZE}
                                filter={{ type: 'shipper' }}
                            >
                                <AutocompleteInput
rsf-admin/src/page/warehouseAreas/WarehouseAreasList.jsx
@@ -134,8 +134,6 @@
                    preferenceKey='warehouseAreas'
                    bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />}
                    rowClick={(id, resource, record) => false}
                    expand={() => <WarehouseAreasPanel />}
                    expandSingle={true}
                    omit={['id', 'createTime', 'createBy', 'memo']}
                >
                    <NumberField source="id" />
@@ -145,6 +143,7 @@
                    {/* <ReferenceField source="shipperId" label="table.field.warehouseAreas.shipperId" reference="shipper" link={false} sortable={false}>
                        <TextField source="name" />
                    </ReferenceField> */}
                    <TextField source="warehouseId$" label="table.field.warehouseAreas.wareId" />
                    <TextField source="shipperId$" label="table.field.warehouseAreas.shipperId" />
                    <NumberField source="supplierId" label="table.field.warehouseAreas.supplierId" />
                    <TextField source="flagMinus$" label="table.field.warehouseAreas.flagMinus" sortable={false} />
rsf-admin/vite.config.js
@@ -35,5 +35,7 @@
    },
    base: './',
    envPrefix: 'VITE_',
    open: true,
    cors: true,
  };
});