verou
2025-03-18 a7e9d0a982fc4e2d8e88d397d259dd3ebcfc2cff
fix:物料导入修改
8个文件已修改
1个文件已添加
416 ■■■■ 已修改文件
rsf-admin/package.json 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/pnpm-lock.yaml 97 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/i18n/en.js 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/i18n/zh.js 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/basicInfo/loc/BatchModal.jsx 164 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/basicInfo/loc/InitButton.jsx 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/basicInfo/loc/InitModal.jsx 56 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/basicInfo/loc/LocList.jsx 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/basicInfo/matnr/MatnrList.jsx 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/package.json
@@ -29,7 +29,7 @@
    "ra-i18n-polyglot": "^5.6.2",
    "ra-language-english": "^5.6.2",
    "react": "^18.3.0",
    "react-admin": "^5.1.0",
    "react-admin": "^5.6.3",
    "react-dom": "^18.3.0",
    "react-hook-form": "^7.53.0",
    "react-router": "^6.22.0",
rsf-admin/pnpm-lock.yaml
@@ -66,8 +66,8 @@
        specifier: ^18.3.0
        version: 18.3.1
      react-admin:
        specifier: ^5.1.0
        version: 5.6.2(@mui/utils@6.4.6(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react-is@19.0.0)(react@18.3.1)
        specifier: ^5.6.3
        version: 5.6.3(@mui/utils@6.4.6(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react-is@19.0.0)(react@18.3.1)
      react-dom:
        specifier: ^18.3.0
        version: 18.3.1(react@18.3.1)
@@ -971,8 +971,16 @@
  '@tanstack/query-core@5.67.1':
    resolution: {integrity: sha512-AkFmuukVejyqVIjEQoFhLb3q+xHl7JG8G9cANWTMe3s8iKzD9j1VBSYXgCjy6vm6xM8cUCR9zP2yqWxY9pTWOA==}
  '@tanstack/query-core@5.68.0':
    resolution: {integrity: sha512-r8rFYYo8/sY/LNaOqX84h12w7EQev4abFXDWy4UoDVUJzJ5d9Fbmb8ayTi7ScG+V0ap44SF3vNs/45mkzDGyGw==}
  '@tanstack/react-query@5.67.1':
    resolution: {integrity: sha512-fH5u4JLwB6A+wLFdi8wWBWAYoJV5deYif2OveJ26ktAWjU499uvVFS1wPWnyEyq5LvZX1MZInvv9QRaIZANRaQ==}
    peerDependencies:
      react: ^18 || ^19
  '@tanstack/react-query@5.68.0':
    resolution: {integrity: sha512-mMOdGDKlwTP/WV72QqSNf4PAMeoBp/DqBHQ222wBfb51Looi8QUqnCnb9O98ZgvNISmy6fzxRGBJdZ+9IBvX2Q==}
    peerDependencies:
      react: ^18 || ^19
@@ -2102,14 +2110,29 @@
      react-router: ^6.28.1 || ^7.1.1
      react-router-dom: ^6.28.1 || ^7.1.1
  ra-core@5.6.3:
    resolution: {integrity: sha512-Z22rKk+CXnTFvCIeKzCf6ic9I48WQotx4EzX16PS47IgrD/Wq/PH+J8YLlTzakoGyEqyxnp+KI/SveLx0QBmww==}
    peerDependencies:
      react: ^18.0.0 || ^19.0.0
      react-dom: ^18.0.0 || ^19.0.0
      react-hook-form: ^7.53.0
      react-router: ^6.28.1 || ^7.1.1
      react-router-dom: ^6.28.1 || ^7.1.1
  ra-i18n-polyglot@5.6.2:
    resolution: {integrity: sha512-+idoJxh815IIZYqZZ1UwC5hIPiBxGqhYn1C5tszpiwRcYToP3DfPunO1g7XwpQicgOOmzzaldpJvoczIJQjPfg==}
  ra-i18n-polyglot@5.6.3:
    resolution: {integrity: sha512-tuzq//7wVA6+A1gsQB+WXhVCNS622YdkHDGNEFjp9sXezFhNdeak1zh7vWGuny6ssrbiWn2ItgjEGgw9dItYRQ==}
  ra-language-english@5.6.2:
    resolution: {integrity: sha512-afLZFHNnk3JEZUhZQSSv2nk4Rg69NiUiRiFuMnnImjWFKxICBN8Z1hKJhUauXrZdtyZslXl7nGYhVsuqxTOuQg==}
  ra-ui-materialui@5.6.2:
    resolution: {integrity: sha512-i2Tsq8xCfdYTv/vlIZY+dEdSrcO9DzF44/fqcWkmcj79+Cxe3pLiFx7orhyQQXpnExLm5LjEXR/5ayD1CDFgAQ==}
  ra-language-english@5.6.3:
    resolution: {integrity: sha512-pmtcOP94QS61QuXVLF4uusBe08h47Td4rQbcEiJ7o/ZoUG/VHcY52nJBXheURFyKM7LXwV4mbIBeyoT58x7MdQ==}
  ra-ui-materialui@5.6.3:
    resolution: {integrity: sha512-3KOCo0JWBJ5BeqVb8g1cdnw00+GMnpI7jlX1VqX7YIyDT3TwDbFx1sDGUOvNiLrN7qZA5dIrZWfdYlutjZT/2Q==}
    peerDependencies:
      '@mui/icons-material': ^5.16.12 || ^6.0.0
      '@mui/material': ^5.16.12 || ^6.0.0
@@ -2125,8 +2148,8 @@
  raf-schd@4.0.3:
    resolution: {integrity: sha512-tQkJl2GRWh83ui2DiPTJz9wEiMN20syf+5oKfB03yYP7ioZcJwsIK8FjrtLwH1m7C7e+Tt2yYBlrOpdT+dyeIQ==}
  react-admin@5.6.2:
    resolution: {integrity: sha512-9tMBUgNxXOPAPGorrasuxLvGIsgAcENXNUoyGdWMne05c7jUDRuhpIW7AYiJOCqJAT9qnL0MfoBb7TeY5c08Ow==}
  react-admin@5.6.3:
    resolution: {integrity: sha512-nZAlX1uRKgQKAQcOxMwugkjbDL7CPuU799lxoaxLK59O7AbkQl161uVqWLNUo4eaZRCpXCVqIe2an4lGlxs10g==}
    peerDependencies:
      react: ^18.0.0 || ^19.0.0
      react-dom: ^18.0.0 || ^19.0.0
@@ -3340,9 +3363,16 @@
  '@tanstack/query-core@5.67.1': {}
  '@tanstack/query-core@5.68.0': {}
  '@tanstack/react-query@5.67.1(react@18.3.1)':
    dependencies:
      '@tanstack/query-core': 5.67.1
      react: 18.3.1
  '@tanstack/react-query@5.68.0(react@18.3.1)':
    dependencies:
      '@tanstack/query-core': 5.68.0
      react: 18.3.1
  '@tweenjs/tween.js@21.1.1': {}
@@ -4689,10 +4719,39 @@
      react-router: 6.30.0(react@18.3.1)
      react-router-dom: 6.30.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
  ra-core@5.6.3(react-dom@18.3.1(react@18.3.1))(react-hook-form@7.54.2(react@18.3.1))(react-router-dom@6.30.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-router@6.30.0(react@18.3.1))(react@18.3.1):
    dependencies:
      '@tanstack/react-query': 5.68.0(react@18.3.1)
      clsx: 2.1.1
      date-fns: 3.6.0
      eventemitter3: 5.0.1
      inflection: 3.0.2
      jsonexport: 3.2.0
      lodash: 4.17.21
      query-string: 7.1.3
      react: 18.3.1
      react-dom: 18.3.1(react@18.3.1)
      react-error-boundary: 4.1.2(react@18.3.1)
      react-hook-form: 7.54.2(react@18.3.1)
      react-is: 19.0.0
      react-router: 6.30.0(react@18.3.1)
      react-router-dom: 6.30.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
  ra-i18n-polyglot@5.6.2(react-dom@18.3.1(react@18.3.1))(react-hook-form@7.54.2(react@18.3.1))(react-router-dom@6.30.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-router@6.30.0(react@18.3.1))(react@18.3.1):
    dependencies:
      node-polyglot: 2.6.0
      ra-core: 5.6.2(react-dom@18.3.1(react@18.3.1))(react-hook-form@7.54.2(react@18.3.1))(react-router-dom@6.30.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-router@6.30.0(react@18.3.1))(react@18.3.1)
    transitivePeerDependencies:
      - react
      - react-dom
      - react-hook-form
      - react-router
      - react-router-dom
  ra-i18n-polyglot@5.6.3(react-dom@18.3.1(react@18.3.1))(react-hook-form@7.54.2(react@18.3.1))(react-router-dom@6.30.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-router@6.30.0(react@18.3.1))(react@18.3.1):
    dependencies:
      node-polyglot: 2.6.0
      ra-core: 5.6.3(react-dom@18.3.1(react@18.3.1))(react-hook-form@7.54.2(react@18.3.1))(react-router-dom@6.30.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-router@6.30.0(react@18.3.1))(react@18.3.1)
    transitivePeerDependencies:
      - react
      - react-dom
@@ -4710,12 +4769,22 @@
      - react-router
      - react-router-dom
  ra-ui-materialui@5.6.2(sklympau2jg2ojs7i27mlhc7wq):
  ra-language-english@5.6.3(react-dom@18.3.1(react@18.3.1))(react-hook-form@7.54.2(react@18.3.1))(react-router-dom@6.30.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-router@6.30.0(react@18.3.1))(react@18.3.1):
    dependencies:
      ra-core: 5.6.3(react-dom@18.3.1(react@18.3.1))(react-hook-form@7.54.2(react@18.3.1))(react-router-dom@6.30.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-router@6.30.0(react@18.3.1))(react@18.3.1)
    transitivePeerDependencies:
      - react
      - react-dom
      - react-hook-form
      - react-router
      - react-router-dom
  ra-ui-materialui@5.6.3(muilruxmeryhubct6qeex4xh4y):
    dependencies:
      '@mui/icons-material': 5.16.14(@mui/material@5.16.14(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.18)(react@18.3.1)
      '@mui/material': 5.16.14(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
      '@mui/utils': 6.4.6(@types/react@18.3.18)(react@18.3.1)
      '@tanstack/react-query': 5.67.1(react@18.3.1)
      '@tanstack/react-query': 5.68.0(react@18.3.1)
      autosuggest-highlight: 3.3.4
      clsx: 2.1.1
      css-mediaquery: 0.1.2
@@ -4724,7 +4793,7 @@
      jsonexport: 3.2.0
      lodash: 4.17.21
      query-string: 7.1.3
      ra-core: 5.6.2(react-dom@18.3.1(react@18.3.1))(react-hook-form@7.54.2(react@18.3.1))(react-router-dom@6.30.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-router@6.30.0(react@18.3.1))(react@18.3.1)
      ra-core: 5.6.3(react-dom@18.3.1(react@18.3.1))(react-hook-form@7.54.2(react@18.3.1))(react-router-dom@6.30.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-router@6.30.0(react@18.3.1))(react@18.3.1)
      react: 18.3.1
      react-dom: 18.3.1(react@18.3.1)
      react-dropzone: 14.3.8(react@18.3.1)
@@ -4737,16 +4806,16 @@
  raf-schd@4.0.3: {}
  react-admin@5.6.2(@mui/utils@6.4.6(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react-is@19.0.0)(react@18.3.1):
  react-admin@5.6.3(@mui/utils@6.4.6(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react-is@19.0.0)(react@18.3.1):
    dependencies:
      '@emotion/react': 11.14.0(@types/react@18.3.18)(react@18.3.1)
      '@emotion/styled': 11.14.0(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1)
      '@mui/icons-material': 5.16.14(@mui/material@5.16.14(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.18)(react@18.3.1)
      '@mui/material': 5.16.14(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
      ra-core: 5.6.2(react-dom@18.3.1(react@18.3.1))(react-hook-form@7.54.2(react@18.3.1))(react-router-dom@6.30.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-router@6.30.0(react@18.3.1))(react@18.3.1)
      ra-i18n-polyglot: 5.6.2(react-dom@18.3.1(react@18.3.1))(react-hook-form@7.54.2(react@18.3.1))(react-router-dom@6.30.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-router@6.30.0(react@18.3.1))(react@18.3.1)
      ra-language-english: 5.6.2(react-dom@18.3.1(react@18.3.1))(react-hook-form@7.54.2(react@18.3.1))(react-router-dom@6.30.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-router@6.30.0(react@18.3.1))(react@18.3.1)
      ra-ui-materialui: 5.6.2(sklympau2jg2ojs7i27mlhc7wq)
      ra-core: 5.6.3(react-dom@18.3.1(react@18.3.1))(react-hook-form@7.54.2(react@18.3.1))(react-router-dom@6.30.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-router@6.30.0(react@18.3.1))(react@18.3.1)
      ra-i18n-polyglot: 5.6.3(react-dom@18.3.1(react@18.3.1))(react-hook-form@7.54.2(react@18.3.1))(react-router-dom@6.30.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-router@6.30.0(react@18.3.1))(react@18.3.1)
      ra-language-english: 5.6.3(react-dom@18.3.1(react@18.3.1))(react-hook-form@7.54.2(react@18.3.1))(react-router-dom@6.30.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-router@6.30.0(react@18.3.1))(react@18.3.1)
      ra-ui-materialui: 5.6.3(muilruxmeryhubct6qeex4xh4y)
      react: 18.3.1
      react-dom: 18.3.1(react@18.3.1)
      react-hook-form: 7.54.2(react@18.3.1)
rsf-admin/src/i18n/en.js
@@ -609,7 +609,8 @@
        print: "print",
        enable: 'enable',
        unenable: 'unenable',
        locInit: 'loc init'
        locInit: 'loc init',
        batch: 'batch',
    },
};
rsf-admin/src/i18n/zh.js
@@ -611,7 +611,8 @@
        print: "打印",
        enable: '启用',
        unenable: '禁用',
        locInit: ' 库位初始化'
        locInit: ' 库位初始化',
        batch: '批量操作',
    },
};
rsf-admin/src/page/basicInfo/loc/BatchModal.jsx
New file
@@ -0,0 +1,164 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import {
    CreateBase,
    useTranslate,
    TextInput,
    NumberInput,
    BooleanInput,
    DateInput,
    SaveButton,
    SelectInput,
    ReferenceInput,
    ReferenceArrayInput,
    AutocompleteInput,
    Toolbar,
    required,
    useDataProvider,
    useNotify,
    Form,
    useCreateController,
    useListContext,
    useRefresh,
} from 'react-admin';
import {
    Dialog,
    DialogActions,
    DialogContent,
    DialogTitle,
    Grid,
    TextField,
    Box,
    Button,
    Paper,
    TableContainer,
    Table,
    TableHead,
    TableBody,
    TableRow,
    TableCell,
    Tooltip,
    IconButton,
    styled
} from '@mui/material';
import DialogCloseButton from "../../components/DialogCloseButton";
import DictionarySelect from "../../components/DictionarySelect";
import { useForm, Controller, useWatch, FormProvider, useFormContext } from "react-hook-form";
import SaveIcon from '@mui/icons-material/Save';
import request from '@/utils/request';
import { Add, Edit, Delete } from '@mui/icons-material';
import _ from 'lodash';
import { DataGrid } from '@mui/x-data-grid';
const InitModal = ({ open, setOpen }) => {
    const refresh = useRefresh();
    const translate = useTranslate();
    const notify = useNotify();
    const [formData, setFormData] = useState({
        "areaId": undefined,
        "locType": "",
        "type": ""
    });
    const handleClose = (event, reason) => {
        if (reason !== "backdropClick") {
            setOpen(false);
        }
    };
    const handleReset = (e) => {
        e.preventDefault();
    };
    const handleChange = (value, name) => {
        setFormData((prevData) => ({
            ...prevData,
            [name]: ['locType', 'type'].includes(name) ? value : +value
        }));
    };
    const handleSubmit = async () => {
        const res = await request.post(`/loc/init`, formData);
        if (res?.data?.code === 200) {
            setOpen(false);
            refresh();
        } else {
            notify(res.data.msg);
        }
    }
    return (
        <Dialog open={open} maxWidth="md" fullWidth>
            <Form onSubmit={handleSubmit}>
                <DialogCloseButton onClose={handleClose} />
                <DialogTitle>{translate('toolbar.batch')}</DialogTitle>
                <DialogContent sx={{ mt: 2 }}>
                    <Box sx={{ display: 'flex', flexDirection: 'column', gap: 3 }}>
                        <Grid container spacing={2}>
                            <Grid item xs={4}>
                                <ReferenceInput
                                    source="areaId"
                                    reference="warehouseAreas"
                                >
                                    <AutocompleteInput
                                        label="table.field.loc.areaId"
                                        optionText="name"
                                        onChange={(value) => handleChange(value, 'areaId')}
                                        value={formData.areaId}
                                        validate={[required()]}
                                        filterToQuery={(val) => ({ name: val })}
                                    />
                                </ReferenceInput>
                            </Grid>
                            <Grid item xs={4}>
                                <DictionarySelect
                                    label={translate("table.field.loc.locType")}
                                    name="locType"
                                    value={formData.locType}
                                    onChange={(e) => handleChange(e.target.value, 'locType')}
                                    size="small"
                                    validate={[required()]}
                                    dictTypeCode="sys_width_type"
                                />
                            </Grid>
                            <Grid item xs={4}>
                                <DictionarySelect
                                    label={translate("table.field.loc.type")}
                                    name="type"
                                    value={formData.type}
                                    onChange={(e) => handleChange(e.target.value, 'type')}
                                    size="small"
                                    validate={[required()]}
                                    dictTypeCode="sys_loc_type"
                                />
                            </Grid>
                        </Grid>
                    </Box>
                </DialogContent>
                <DialogActions sx={{ position: 'sticky', bottom: 0, backgroundColor: 'background.paper', zIndex: 1000 }}>
                    <Box sx={{ width: '100%', display: 'flex', justifyContent: 'space-between' }}>
                        <Button type="submit" variant="contained" startIcon={<SaveIcon />}>
                            确认
                        </Button>
                    </Box>
                </DialogActions>
            </Form>
        </Dialog>
    );
}
export default InitModal;
rsf-admin/src/page/basicInfo/loc/InitButton.jsx
@@ -56,17 +56,17 @@
    const refresh = useRefresh();
    const [createDialog, setCreateDialog] = useState(false);
    // console.log(record)
    return (<>
        <Button onClick={() => setCreateDialog(true)} label={"toolbar.locInit"}>
            <CabinIcon />
        </Button>
        <InitModal
            open={createDialog}
            setOpen={setCreateDialog}
        />
    </>
    return (
        <>
            <Button onClick={() => setCreateDialog(true)} label={"toolbar.locInit"}>
                <CabinIcon />
            </Button>
            <InitModal
                open={createDialog}
                setOpen={setCreateDialog}
            />
        </>
    )
}
rsf-admin/src/page/basicInfo/loc/InitModal.jsx
@@ -103,12 +103,11 @@
    return (
        <Dialog open={open} maxWidth="md" fullWidth>
            <DialogCloseButton onClose={handleClose} />
            <DialogTitle>{translate('toolbar.locInit')}</DialogTitle>
            <DialogContent sx={{ mt: 2 }}>
                <Box sx={{ display: 'flex', flexDirection: 'column', gap: 3 }}>
                    <Form>
            <Form onSubmit={handleSubmit}>
                <DialogCloseButton onClose={handleClose} />
                <DialogTitle>{translate('toolbar.locInit')}</DialogTitle>
                <DialogContent sx={{ mt: 2 }}>
                    <Box sx={{ display: 'flex', flexDirection: 'column', gap: 3 }}>
                        <Grid container spacing={2}>
                            <Grid item xs={4}>
                                <ReferenceInput
@@ -152,88 +151,89 @@
                            </Grid>
                            <Grid item xs={4}>
                                <TextField
                                <TextInput
                                    label={translate("table.field.loc.startBay")}
                                    name="startBay"
                                    value={formData.startBay}
                                    onChange={(e) => handleChange(e.target.value, 'startBay')}
                                    size="small"
                                    type="number"
                                    required
                                    validate={[required()]}
                                />
                            </Grid>
                            <Grid item xs={4}>
                                <TextField
                                <TextInput
                                    label={translate("table.field.loc.startLev")}
                                    name="startLev"
                                    value={formData.startLev}
                                    onChange={(e) => handleChange(e.target.value, 'startLev')}
                                    size="small"
                                    type="number"
                                    required
                                    validate={[required()]}
                                />
                            </Grid>
                            <Grid item xs={4}>
                                <TextField
                                <TextInput
                                    label={translate("table.field.loc.startRow")}
                                    name="startRow"
                                    value={formData.startRow}
                                    onChange={(e) => handleChange(e.target.value, 'startRow')}
                                    size="small"
                                    type="number"
                                    required
                                    validate={[required()]}
                                />
                            </Grid>
                            <Grid item xs={4}>
                                <TextField
                                <TextInput
                                    label={translate("table.field.loc.endBay")}
                                    name="endBay"
                                    value={formData.endBay}
                                    onChange={(e) => handleChange(e.target.value, 'endBay')}
                                    size="small"
                                    type="number"
                                    required
                                    validate={[required()]}
                                />
                            </Grid>
                            <Grid item xs={4}>
                                <TextField
                                <TextInput
                                    label={translate("table.field.loc.endLev")}
                                    name="endLev"
                                    value={formData.endLev}
                                    onChange={(e) => handleChange(e.target.value, 'endLev')}
                                    size="small"
                                    type="number"
                                    required
                                    validate={[required()]}
                                />
                            </Grid>
                            <Grid item xs={4}>
                                <TextField
                                <TextInput
                                    label={translate("table.field.loc.endRow")}
                                    name="endRow"
                                    value={formData.endRow}
                                    onChange={(e) => handleChange(e.target.value, 'endRow')}
                                    size="small"
                                    type="number"
                                    required
                                    validate={[required()]}
                                />
                            </Grid>
                        </Grid>
                    </Form>
                </Box>
            </DialogContent>
            <DialogActions sx={{ position: 'sticky', bottom: 0, backgroundColor: 'background.paper', zIndex: 1000 }}>
                <Box sx={{ width: '100%', display: 'flex', justifyContent: 'space-between' }}>
                    <Button onClick={handleSubmit} variant="contained" startIcon={<SaveIcon />}>
                        确认
                    </Button>
                </Box>
            </DialogActions>
                    </Box>
                </DialogContent>
                <DialogActions sx={{ position: 'sticky', bottom: 0, backgroundColor: 'background.paper', zIndex: 1000 }}>
                    <Box sx={{ width: '100%', display: 'flex', justifyContent: 'space-between' }}>
                        <Button type="submit" variant="contained" startIcon={<SaveIcon />}>
                            确认
                        </Button>
                    </Box>
                </DialogActions>
            </Form>
        </Dialog>
    );
}
rsf-admin/src/page/basicInfo/loc/LocList.jsx
@@ -42,11 +42,13 @@
import MyCreateButton from "../../components/MyCreateButton";
import MyExportButton from '../../components/MyExportButton';
import InitButton from './InitButton';
import BatchModal from './BatchModal';
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';
import DashboardIcon from '@mui/icons-material/Dashboard';
import EditIcon from '@mui/icons-material/Edit';
import request from '@/utils/request';
const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({
@@ -132,10 +134,14 @@
            >
                <StyledDatagrid
                    preferenceKey='loc'
                    bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />}
                    rowClick={(id, resource, record) => false}
                    bulkActionButtons={
                        <>
                            <BatchButton />
                            <BulkDeleteButton />
                        </>
                    }
                    rowClick={() => false}
                    expand={() => <LocPanel />}
                    expandSingle={true}
                    omit={['id', 'createTime', 'createBy', 'memo']}
                >
                    <NumberField source="id" />
@@ -217,3 +223,58 @@
    )
}
const BatchButton = () => {
    const record = useRecordContext();
    const notify = useNotify();
    const refresh = useRefresh();
    const { selectedIds } = useListContext();
    console.log(selectedIds)
    const [createDialog, setCreateDialog] = useState(false);
    return (
        <>
            <Button onClick={() => setCreateDialog(true)} label={"toolbar.batch"}>
                <EditIcon />
            </Button>
            <BatchModal
                open={createDialog}
                setOpen={setCreateDialog}
            />
        </>
    )
}
const CustomBulkActionButton = () => {
    const { selectedIds } = useListContext();
    const notify = useNotify();
    const refresh = useRefresh();
    const handleCustomBulkAction = async () => {
        if (selectedIds.length === 0) {
            notify('请选择要操作的记录');
            return;
        }
        // 这里写具体的批量操作逻辑,例如向服务器发送请求
        try {
            const res = await request.post('/loc/bulk-action', { ids: selectedIds });
            if (res?.data?.code === 200) {
                refresh();
                notify('批量操作成功');
            } else {
                notify(res.data.msg);
            }
        } catch (error) {
            notify('批量操作失败,请稍后重试');
        }
    };
    return (
        <Button onClick={handleCustomBulkAction} label="自定义批量操作">
            {/* 可以添加自定义图标 */}
            <EditIcon />
        </Button>
    );
};
rsf-admin/src/page/basicInfo/matnr/MatnrList.jsx
@@ -253,9 +253,7 @@
                        <FilterButton />
                        <MyCreateButton onClick={() => { setCreateDialog(true) }} />
                        <SelectColumnsButton preferenceKey='matnr' />
                        <MatnrList.Context.Provider value={'matnr'}>
                            <ImportButton />
                        </MatnrList.Context.Provider>
                        <ImportButton value={'matnr'} parmas={{}} />
                        <MyExportButton />
                    </TopToolbar>
                )}