From f00f83d2b2a868e518b78c76d3e11bc01aabffa7 Mon Sep 17 00:00:00 2001 From: skyouc Date: 星期六, 22 三月 2025 15:38:35 +0800 Subject: [PATCH] Merge branch 'front' of http://47.97.1.152:5880/r/wms-master into front --- rsf-admin/src/page/basicInfo/locArea/LocAreaEdit.jsx | 2 rsf-admin/src/page/basicInfo/locArea/LocAreaList.jsx | 2 rsf-admin/src/page/basicInfo/locAreaMatRela/LocAreaMatRelaList.jsx | 160 ++++++ rsf-admin/src/page/basicInfo/locAreaMatRela/LocAreaMatRelaEdit.jsx | 151 ++++++ rsf-admin/src/page/basicInfo/locType/LocTypeList.jsx | 33 + rsf-admin/src/page/basicInfo/locAreaMatRela/LocAreaMatRelaPanel.jsx | 87 +++ rsf-admin/src/page/basicInfo/loc/LocList.jsx | 38 + rsf-admin/src/page/basicInfo/matnr/PrintModal.jsx | 9 rsf-admin/src/page/basicInfo/loc/BindModal.jsx | 199 ++++++++ rsf-admin/src/page/basicInfo/loc/InitModal.jsx | 2 rsf-admin/src/page/basicInfo/loc/LocCreate.jsx | 1 rsf-admin/src/page/basicInfo/locType/BindModal.jsx | 199 ++++++++ rsf-admin/src/page/basicInfo/matnr/BindModal.jsx | 186 +++++++ rsf-admin/src/page/basicInfo/locArea/LocAreaCreate.jsx | 2 rsf-admin/src/page/basicInfo/matnrGroup/MatnrGroupEdit.jsx | 77 +- rsf-admin/src/page/basicInfo/locAreaMatRela/index.jsx | 18 rsf-admin/src/i18n/zh.js | 13 rsf-admin/src/page/basicInfo/loc/LocEdit.jsx | 1 rsf-admin/src/page/basicInfo/matnr/MatnrList.jsx | 26 + rsf-admin/src/i18n/en.js | 13 rsf-admin/src/page/ResourceContent.js | 4 rsf-admin/src/page/basicInfo/matnrGroup/MatnrGroupCreate.jsx | 3 rsf-admin/src/page/basicInfo/locAreaMatRela/LocAreaMatRelaCreate.jsx | 179 +++++++ 23 files changed, 1,350 insertions(+), 55 deletions(-) diff --git a/rsf-admin/src/i18n/en.js b/rsf-admin/src/i18n/en.js index cb54b18..cda7790 100644 --- a/rsf-admin/src/i18n/en.js +++ b/rsf-admin/src/i18n/en.js @@ -129,6 +129,7 @@ loc: 'Loc', locType: 'LocType', locArea: 'locArea', + locAreaMatRela: 'LocAreaMatRela', container: 'Container', contract: 'Contract', qlyInspect: 'QlyInspect', @@ -367,6 +368,14 @@ name: "name", code: "code", areaId: "areaId", + locId: "locId", + }, + locAreaMatRela: { + areaId: "areaId", + code: "code", + matnrId: "matnrId", + groupId: "groupId", + locTypeId: "locTypeId", locId: "locId", }, container: { @@ -627,7 +636,9 @@ locInit: 'loc init', batch: 'batch', confirm: 'confirm', - subzone: 'subzone' + subzone: 'subzone', + bindmatnr: 'bind matnr', + bindloc: 'bind loc', }, }; diff --git a/rsf-admin/src/i18n/zh.js b/rsf-admin/src/i18n/zh.js index 2f2f96b..bec9beb 100644 --- a/rsf-admin/src/i18n/zh.js +++ b/rsf-admin/src/i18n/zh.js @@ -129,6 +129,7 @@ loc: '搴撲綅', locType: '搴撲綅绫诲瀷', locArea: '閫昏緫鍒嗗尯', + locAreaMatRela: '搴撳尯鐗╂枡鍏崇郴', container: '瀹瑰櫒绠$悊', contract: '鍚堝悓淇℃伅', qlyInspect: '璐ㄦ淇℃伅', @@ -367,6 +368,14 @@ name: "鍚嶇О", code: "缂栫爜", areaId: "搴撳尯", + locId: "搴撲綅", + }, + locAreaMatRela: { + areaId: "搴撳尯", + code: "缂栫爜", + matnrId: "鐗╂枡", + groupId: "鐗╂枡鍒嗙粍", + locTypeId: "搴撲綅绫诲瀷", locId: "搴撲綅", }, container: { @@ -629,7 +638,9 @@ locInit: '聽搴撲綅鍒濆鍖�', batch: '鎵归噺鎿嶄綔', confirm: '纭', - subzone: '缁戝畾鍒嗗尯' + subzone: '缁戝畾鍒嗗尯', + bindmatnr: '缁戝畾鐗╂枡', + bindloc: '缁戝畾搴撲綅', }, }; diff --git a/rsf-admin/src/page/ResourceContent.js b/rsf-admin/src/page/ResourceContent.js index b5b46b3..b17dc51 100644 --- a/rsf-admin/src/page/ResourceContent.js +++ b/rsf-admin/src/page/ResourceContent.js @@ -27,6 +27,7 @@ import companys from './basicInfo/companys'; import locType from './basicInfo/locType'; import locArea from './basicInfo//locArea'; +import locAreaMatRela from './basicInfo/locAreaMatRela'; import serialRuleItem from './system/serialRuleItem'; import serialRule from './system/serialRule'; import whMat from './basicInfo/whMat'; @@ -106,6 +107,9 @@ return locType; case 'locArea': return locArea; + case 'locAreaMatRela': + return locAreaMatRela; + default: return { diff --git a/rsf-admin/src/page/basicInfo/loc/BindModal.jsx b/rsf-admin/src/page/basicInfo/loc/BindModal.jsx new file mode 100644 index 0000000..0a8145f --- /dev/null +++ b/rsf-admin/src/page/basicInfo/loc/BindModal.jsx @@ -0,0 +1,199 @@ +import React, { useState, useRef, useEffect, useMemo } from "react"; +import { + CreateBase, + useTranslate, + TextInput, + NumberInput, + BooleanInput, + DateInput, + SaveButton, + SelectInput, + ReferenceInput, + ReferenceArrayInput, + AutocompleteInput, + Toolbar, + required, + useDataProvider, + useNotify, + Form, + useCreateController, + useListContext, + useRefresh, + SelectArrayInput +} from 'react-admin'; +import { + Dialog, + DialogActions, + DialogContent, + DialogTitle, + Grid, + TextField, + Box, + Button, + Paper, + TableContainer, + Table, + TableHead, + TableBody, + TableRow, + TableCell, + Tooltip, + IconButton, + styled, + + + +} from '@mui/material'; +import DialogCloseButton from "../../components/DialogCloseButton"; +import DictionarySelect from "../../components/DictionarySelect"; +import { useForm, Controller, useWatch, FormProvider, useFormContext } from "react-hook-form"; +import SaveIcon from '@mui/icons-material/Save'; +import request from '@/utils/request'; +import { Add, Edit, Delete } from '@mui/icons-material'; +import _ from 'lodash'; +import { DataGrid } from '@mui/x-data-grid'; +import StatusSelectInput from "../../components/StatusSelectInput"; +import TreeSelectInput from "@/page/components/TreeSelectInput"; +const MatnrModal = ({ open, setOpen }) => { + const refresh = useRefresh(); + const translate = useTranslate(); + + + const notify = useNotify(); + + const [formData, setFormData] = useState({ + areaId: null, + groupId: null, + matnrId: null, + }); + + const { selectedIds, onUnselectItems } = useListContext(); + + const handleClose = (event, reason) => { + if (reason !== "backdropClick") { + setOpen(false); + reset() + refresh(); + onUnselectItems() + } + }; + + const reset = () => { + setFormData({ + areaId: null, + groupId: null, + matnrId: null, + }) + } + + const handleReset = (e) => { + e.preventDefault(); + }; + + const handleChange = (value, name) => { + setFormData((prevData) => ({ + ...prevData, + [name]: value + })); + refresh() + }; + + const removeEmptyKeys = (obj) => { + return _.pickBy(obj, (value) => { + if (_.isObject(value)) { + const newObj = removeEmptyKeys(value); + return !_.isEmpty(newObj); + } + return !_.isNil(value) && (_.isNumber(value) ? value !== 0 : !_.isEmpty(value)); + }); + } + + const handleSubmit = async () => { + const parmas = { + locId: selectedIds, + areaId: formData.areaId, + matnrId: formData.matnrId, + } + + const res = await request.post(`/locAreaMatRela/matnr/bind`, parmas); + if (res?.data?.code === 200) { + handleClose() + + } else { + notify(res.data.msg); + } + + + } + + const [groupId, setGroupId] = useState(); + + const warehouseChange = (e) => { + setGroupId(e.target.value) + } + + return ( + <Dialog open={open} maxWidth="md" fullWidth> + <Form onSubmit={handleSubmit}> + <DialogCloseButton onClose={handleClose} /> + <DialogTitle>{translate('toolbar.bindmatnr')}</DialogTitle> + <DialogContent sx={{ mt: 2 }}> + <Box sx={{ display: 'flex', flexDirection: 'column', gap: 3 }}> + <Grid container spacing={2}> + <Grid item xs={4}> + <ReferenceInput + source="areaId" + reference="warehouseAreas" + > + <AutocompleteInput + label="table.field.loc.areaId" + optionText="name" + onChange={(value) => handleChange(value, 'areaId')} + value={formData.areaId} + validate={required()} + filterToQuery={(val) => ({ name: val })} + /> + </ReferenceInput> + + </Grid> + + <Grid item xs={4}> + <TreeSelectInput + label="table.field.locAreaMatRela.groupId" + resource={'matnrGroup'} + source="groupId" + value={formData.groupId} + onChange={(e) => handleChange(e.target.value, 'groupId')} + /> + </Grid> + + + <Grid item xs={4}> + <ReferenceArrayInput source="matnrId" reference="matnr" filter={{ groupId: formData.groupId }}> + <SelectArrayInput + label="table.field.locAreaMatRela.matnrId" + validate={required()} + value={formData.matnrId} + onChange={(e) => handleChange(e.target.value, 'matnrId')} + /> + </ReferenceArrayInput> + + </Grid> + + </Grid> + + </Box> + </DialogContent> + <DialogActions sx={{ position: 'sticky', bottom: 0, backgroundColor: 'background.paper', zIndex: 1000 }}> + <Box sx={{ width: '100%', display: 'flex', justifyContent: 'space-between' }}> + <Button type="submit" variant="contained" startIcon={<SaveIcon />}> + {translate('toolbar.confirm')} + </Button> + </Box> + </DialogActions> + </Form> + </Dialog> + ); +} + +export default MatnrModal; \ No newline at end of file diff --git a/rsf-admin/src/page/basicInfo/loc/InitModal.jsx b/rsf-admin/src/page/basicInfo/loc/InitModal.jsx index 16a287a..931b943 100644 --- a/rsf-admin/src/page/basicInfo/loc/InitModal.jsx +++ b/rsf-admin/src/page/basicInfo/loc/InitModal.jsx @@ -153,7 +153,7 @@ <Grid item xs={4}> <ReferenceArrayInput source="typeIds" reference="locType" > - <SelectArrayInput label="table.field.loc.type" onChange={(e) => handleChange(e.target.value, 'typeIds')} /> + <SelectArrayInput label="table.field.loc.type" onChange={(e) => handleChange(e.target.value, 'typeIds')} validate={[required()]} /> </ReferenceArrayInput> </Grid> diff --git a/rsf-admin/src/page/basicInfo/loc/LocCreate.jsx b/rsf-admin/src/page/basicInfo/loc/LocCreate.jsx index e5eb67a..23465f9 100644 --- a/rsf-admin/src/page/basicInfo/loc/LocCreate.jsx +++ b/rsf-admin/src/page/basicInfo/loc/LocCreate.jsx @@ -270,6 +270,7 @@ label={translate("table.field.loc.useStatus")} name="useStatus" size="small" + validate={[required()]} dictTypeCode="sys_loc_use_stas" /> {/* <ReferenceInput diff --git a/rsf-admin/src/page/basicInfo/loc/LocEdit.jsx b/rsf-admin/src/page/basicInfo/loc/LocEdit.jsx index 5c640c5..3c32e39 100644 --- a/rsf-admin/src/page/basicInfo/loc/LocEdit.jsx +++ b/rsf-admin/src/page/basicInfo/loc/LocEdit.jsx @@ -177,6 +177,7 @@ <DictionarySelect label={translate("table.field.loc.useStatus")} name="useStatus" + validate={[required()]} size="small" dictTypeCode="sys_loc_use_stas" /> diff --git a/rsf-admin/src/page/basicInfo/loc/LocList.jsx b/rsf-admin/src/page/basicInfo/loc/LocList.jsx index d07243d..1053f48 100644 --- a/rsf-admin/src/page/basicInfo/loc/LocList.jsx +++ b/rsf-admin/src/page/basicInfo/loc/LocList.jsx @@ -38,7 +38,7 @@ import { Box, Typography, Card, Stack } from '@mui/material'; import { styled } from '@mui/material/styles'; import LocCreate from "./LocCreate"; -import LocPanel from "./LocPanel"; +import BindModal from "./BindModal"; import EmptyData from "../../components/EmptyData"; import DynamicField from "../../components/DynamicField"; import MyCreateButton from "../../components/MyCreateButton"; @@ -54,7 +54,7 @@ import EditIcon from '@mui/icons-material/Edit'; import request from '@/utils/request'; import DiscountIcon from '@mui/icons-material/Discount'; -import { textAlign } from "@mui/system"; +import LinkIcon from '@mui/icons-material/Link'; const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({ '& .css-1vooibu-MuiSvgIcon-root': { @@ -76,8 +76,8 @@ const filters = [ <SearchInput source="condition" alwaysOn />, - <NumberField source="warehouseId$" label="table.field.loc.warehouseId" />, - <NumberField source="areaId$" label="table.field.loc.areaId" />, + <TextInput source="warehouseId$" label="table.field.loc.warehouseId" />, + <TextInput source="areaId$" label="table.field.loc.areaId" />, <TextInput source="code" label="table.field.loc.code" />, <TextInput source="type" label="table.field.loc.type" />, <TextInput source="name" label="table.field.loc.name" />, @@ -148,6 +148,7 @@ bulkActionButtons={ <> <BatchButton /> + <BindButton /> <SubzoneButton /> <BulkDeleteButton /> </> @@ -157,9 +158,9 @@ > <NumberField source="id" /> <NumberField source="warehouseId$" label="table.field.loc.warehouseId" /> - <NumberField source="areaId$" label="table.field.loc.areaId" align="left" /> - <TextField source="code" label="table.field.loc.code" align="left" /> - <TextField source="typeIds$" label="table.field.loc.type" align="left" /> + <NumberField source="areaId$" label="table.field.loc.areaId" /> + <TextField source="code" label="table.field.loc.code" /> + <TextField source="typeIds$" label="table.field.loc.type" /> {/* <TextField source="name" label="table.field.loc.name" /> */} {/* <NumberField source="flagLogic" label="table.field.loc.flagLogic" /> <TextField source="fucAtrrs" label="table.field.loc.fucAtrrs" /> @@ -282,4 +283,27 @@ </> ) +} + +const BindButton = () => { + const record = useRecordContext(); + const notify = useNotify(); + const refresh = useRefresh(); + + + const [createDialog, setCreateDialog] = useState(false); + + return ( + <> + <Button onClick={() => setCreateDialog(true)} label={"toolbar.bindmatnr"}> + <LinkIcon /> + </Button> + + <BindModal + open={createDialog} + setOpen={setCreateDialog} + /> + </> + + ) } \ No newline at end of file diff --git a/rsf-admin/src/page/basicInfo/locArea/LocAreaCreate.jsx b/rsf-admin/src/page/basicInfo/locArea/LocAreaCreate.jsx index 38ac67a..363386b 100644 --- a/rsf-admin/src/page/basicInfo/locArea/LocAreaCreate.jsx +++ b/rsf-admin/src/page/basicInfo/locArea/LocAreaCreate.jsx @@ -88,6 +88,7 @@ <TextInput label="table.field.locArea.name" source="name" + validate={[required()]} parse={v => v} autoFocus /> @@ -107,6 +108,7 @@ <AutocompleteInput label="table.field.locArea.areaId" optionText="name" + validate={[required()]} filterToQuery={(val) => ({ name: val })} /> </ReferenceInput> diff --git a/rsf-admin/src/page/basicInfo/locArea/LocAreaEdit.jsx b/rsf-admin/src/page/basicInfo/locArea/LocAreaEdit.jsx index afd0a4c..8ddb456 100644 --- a/rsf-admin/src/page/basicInfo/locArea/LocAreaEdit.jsx +++ b/rsf-admin/src/page/basicInfo/locArea/LocAreaEdit.jsx @@ -67,6 +67,7 @@ <TextInput label="table.field.locArea.name" source="name" + validate={[required()]} parse={v => v} autoFocus /> @@ -86,6 +87,7 @@ <AutocompleteInput label="table.field.locArea.areaId" optionText="name" + validate={[required()]} filterToQuery={(val) => ({ name: val })} /> </ReferenceInput> diff --git a/rsf-admin/src/page/basicInfo/locArea/LocAreaList.jsx b/rsf-admin/src/page/basicInfo/locArea/LocAreaList.jsx index 9f92799..faacd4e 100644 --- a/rsf-admin/src/page/basicInfo/locArea/LocAreaList.jsx +++ b/rsf-admin/src/page/basicInfo/locArea/LocAreaList.jsx @@ -115,8 +115,6 @@ preferenceKey='locArea' bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />} rowClick={(id, resource, record) => false} - expand={() => <LocAreaPanel />} - expandSingle={true} omit={['id', 'createTime', 'createBy', 'memo']} > <NumberField source="id" /> diff --git a/rsf-admin/src/page/basicInfo/locAreaMatRela/LocAreaMatRelaCreate.jsx b/rsf-admin/src/page/basicInfo/locAreaMatRela/LocAreaMatRelaCreate.jsx new file mode 100644 index 0000000..c685d20 --- /dev/null +++ b/rsf-admin/src/page/basicInfo/locAreaMatRela/LocAreaMatRelaCreate.jsx @@ -0,0 +1,179 @@ +import React, { useState, useRef, useEffect, useMemo } from "react"; +import { + CreateBase, + useTranslate, + TextInput, + NumberInput, + BooleanInput, + DateInput, + SaveButton, + SelectInput, + ReferenceInput, + ReferenceArrayInput, + AutocompleteInput, + SelectArrayInput, + Toolbar, + required, + useDataProvider, + useNotify, + Form, + useCreateController, +} from 'react-admin'; +import { + Dialog, + DialogActions, + DialogContent, + DialogTitle, + Stack, + Grid, + Box, +} from '@mui/material'; +import DialogCloseButton from "../../components/DialogCloseButton"; +import StatusSelectInput from "../../components/StatusSelectInput"; +import MemoInput from "../../components/MemoInput"; +import TreeSelectInput from "@/page/components/TreeSelectInput"; + +const LocAreaMatRelaCreate = (props) => { + const { open, setOpen } = props; + + const translate = useTranslate(); + const notify = useNotify(); + + const handleClose = (event, reason) => { + if (reason !== "backdropClick") { + setOpen(false); + } + }; + + const handleSuccess = async (data) => { + setOpen(false); + notify('common.response.success'); + }; + + const handleError = async (error) => { + notify(error.message || 'common.response.fail', { type: 'error', messageArgs: { _: error.message } }); + }; + + return ( + <> + <CreateBase + record={{}} + transform={(data) => { + return data; + }} + mutationOptions={{ onSuccess: handleSuccess, onError: handleError }} + > + <Dialog + open={open} + onClose={handleClose} + aria-labelledby="form-dialog-title" + fullWidth + disableRestoreFocus + maxWidth="md" // 'xs' | 'sm' | 'md' | 'lg' | 'xl' + > + <Form> + <DialogTitle id="form-dialog-title" sx={{ + position: 'sticky', + top: 0, + backgroundColor: 'background.paper', + zIndex: 1000 + }} + > + {translate('create.title')} + <Box sx={{ position: 'absolute', top: 8, right: 8, zIndex: 1001 }}> + <DialogCloseButton onClose={handleClose} /> + </Box> + </DialogTitle> + <DialogContent sx={{ mt: 2 }}> + <Grid container rowSpacing={2} columnSpacing={2}> + <Grid item xs={6} display="flex" gap={1}> + <ReferenceInput + source="areaId" + reference="warehouseAreas" + > + <AutocompleteInput + label="table.field.locAreaMatRela.areaId" + optionText="name" + validate={[required()]} + filterToQuery={(val) => ({ name: val })} + /> + </ReferenceInput> + </Grid> + <Grid item xs={6} display="flex" gap={1}> + <TextInput + label="table.field.locAreaMatRela.code" + source="code" + parse={v => v} + /> + </Grid> + <Grid item xs={6} display="flex" gap={1}> + <ReferenceInput + source="matnrId" + reference="matnr" + > + <AutocompleteInput + label="table.field.locAreaMatRela.matnrId" + optionText="name" + filterToQuery={(val) => ({ name: val })} + /> + </ReferenceInput> + </Grid> + <Grid item xs={6} display="flex" gap={1}> + <TreeSelectInput + label="table.field.locAreaMatRela.groupId" + resource={'matnrGroup'} + source="groupId" + /> + </Grid> + <Grid item xs={6} display="flex" gap={1}> + <ReferenceInput + source="locId" + reference="loc" + > + <AutocompleteInput + label="table.field.locAreaMatRela.locId" + optionText="code" + filterToQuery={(val) => ({ code: val })} + /> + </ReferenceInput> + </Grid> + <Grid item xs={6} display="flex" gap={1}> + {/* <ReferenceArrayInput source="locTypeId" reference="locType" > + <SelectArrayInput label="table.field.locAreaMatRela.locTypeId" /> + </ReferenceArrayInput> */} + <ReferenceInput + source="locTypeId" + reference="locType" + > + <AutocompleteInput + label="table.field.locAreaMatRela.locTypeId" + optionText="name" + filterToQuery={(val) => ({ name: val })} + /> + </ReferenceInput> + </Grid> + + + <Grid item xs={6} display="flex" gap={1}> + <StatusSelectInput /> + </Grid> + <Grid item xs={12} display="flex" gap={1}> + <Stack direction="column" spacing={1} width={'100%'}> + <MemoInput /> + </Stack> + </Grid> + </Grid> + </DialogContent> + <DialogActions sx={{ position: 'sticky', bottom: 0, backgroundColor: 'background.paper', zIndex: 1000 }}> + <Toolbar sx={{ width: '100%', justifyContent: 'space-between' }} > + <SaveButton /> + </Toolbar> + </DialogActions> + </Form> + </Dialog> + </CreateBase> + </> + ) +} + +export default LocAreaMatRelaCreate; diff --git a/rsf-admin/src/page/basicInfo/locAreaMatRela/LocAreaMatRelaEdit.jsx b/rsf-admin/src/page/basicInfo/locAreaMatRela/LocAreaMatRelaEdit.jsx new file mode 100644 index 0000000..8a4f76a --- /dev/null +++ b/rsf-admin/src/page/basicInfo/locAreaMatRela/LocAreaMatRelaEdit.jsx @@ -0,0 +1,151 @@ +import React, { useState, useRef, useEffect, useMemo } from "react"; +import { + Edit, + SimpleForm, + FormDataConsumer, + useTranslate, + TextInput, + NumberInput, + BooleanInput, + DateInput, + SelectInput, + ReferenceInput, + ReferenceArrayInput, + AutocompleteInput, + SelectArrayInput, + SaveButton, + Toolbar, + Labeled, + NumberField, + required, + useRecordContext, + DeleteButton, +} from 'react-admin'; +import { useWatch, useFormContext } from "react-hook-form"; +import { Stack, Grid, Box, Typography } from '@mui/material'; +import * as Common from '@/utils/common'; +import { EDIT_MODE, REFERENCE_INPUT_PAGESIZE } from '@/config/setting'; +import EditBaseAside from "../../components/EditBaseAside"; +import CustomerTopToolBar from "../../components/EditTopToolBar"; +import MemoInput from "../../components/MemoInput"; +import StatusSelectInput from "../../components/StatusSelectInput"; +import TreeSelectInput from "@/page/components/TreeSelectInput"; + +const FormToolbar = () => { + const { getValues } = useFormContext(); + + return ( + <Toolbar sx={{ justifyContent: 'space-between' }}> + <SaveButton /> + <DeleteButton mutationMode="optimistic" /> + </Toolbar> + ) +} + +const LocAreaMatRelaEdit = () => { + const translate = useTranslate(); + + return ( + <Edit + redirect="list" + mutationMode={EDIT_MODE} + actions={<CustomerTopToolBar />} + aside={<EditBaseAside />} + > + <SimpleForm + shouldUnregister + warnWhenUnsavedChanges + toolbar={<FormToolbar />} + mode="onTouched" + defaultValues={{}} + // validate={(values) => { }} + > + <Grid container width={{ xs: '100%', xl: '80%' }} rowSpacing={3} columnSpacing={3}> + <Grid item xs={12} md={8}> + <Typography variant="h6" gutterBottom> + {translate('common.edit.title.main')} + </Typography> + <Stack direction='row' gap={2}> + <ReferenceInput + source="areaId" + reference="warehouseAreas" + > + <AutocompleteInput + label="table.field.locAreaMatRela.areaId" + optionText="name" + validate={[required()]} + filterToQuery={(val) => ({ name: val })} + /> + </ReferenceInput> + </Stack> + <Stack direction='row' gap={2}> + <TextInput + label="table.field.locAreaMatRela.code" + source="code" + parse={v => v} + /> + </Stack> + <Stack direction='row' gap={2}> + <ReferenceInput + source="matnrId" + reference="matnr" + > + <AutocompleteInput + label="table.field.locAreaMatRela.matnrId" + optionText="name" + filterToQuery={(val) => ({ name: val })} + /> + </ReferenceInput> + </Stack> + <Stack direction='row' gap={2}> + <TreeSelectInput + label="table.field.locAreaMatRela.groupId" + resource={'matnrGroup'} + source="groupId" + /> + </Stack> + <Stack direction='row' gap={2}> + <ReferenceInput + source="locId" + reference="loc" + > + <AutocompleteInput + label="table.field.locAreaMatRela.locId" + optionText="code" + filterToQuery={(val) => ({ code: val })} + /> + </ReferenceInput> + </Stack> + <Stack direction='row' gap={2}> + {/* <ReferenceArrayInput source="locTypeId" reference="locType" > + <SelectArrayInput label="table.field.locAreaMatRela.locTypeId" /> + </ReferenceArrayInput> */} + <ReferenceInput + source="locTypeId" + reference="locType" + > + <AutocompleteInput + label="table.field.locAreaMatRela.locTypeId" + optionText="name" + filterToQuery={(val) => ({ name: val })} + /> + </ReferenceInput> + </Stack> + + + </Grid> + <Grid item xs={12} md={4}> + <Typography variant="h6" gutterBottom> + {translate('common.edit.title.common')} + </Typography> + <StatusSelectInput /> + <Box mt="2em" /> + <MemoInput /> + </Grid> + </Grid> + </SimpleForm> + </Edit > + ) +} + +export default LocAreaMatRelaEdit; diff --git a/rsf-admin/src/page/basicInfo/locAreaMatRela/LocAreaMatRelaList.jsx b/rsf-admin/src/page/basicInfo/locAreaMatRela/LocAreaMatRelaList.jsx new file mode 100644 index 0000000..c4c916d --- /dev/null +++ b/rsf-admin/src/page/basicInfo/locAreaMatRela/LocAreaMatRelaList.jsx @@ -0,0 +1,160 @@ +import React, { useState, useRef, useEffect, useMemo, useCallback } from "react"; +import { useNavigate } from 'react-router-dom'; +import { + List, + DatagridConfigurable, + SearchInput, + TopToolbar, + SelectColumnsButton, + EditButton, + FilterButton, + CreateButton, + ExportButton, + BulkDeleteButton, + WrapperField, + useRecordContext, + useTranslate, + useNotify, + useListContext, + FunctionField, + TextField, + NumberField, + DateField, + BooleanField, + ReferenceField, + TextInput, + DateTimeInput, + DateInput, + SelectInput, + NumberInput, + ReferenceInput, + ReferenceArrayInput, + AutocompleteInput, + DeleteButton, +} from 'react-admin'; +import { Box, Typography, Card, Stack } from '@mui/material'; +import { styled } from '@mui/material/styles'; +import LocAreaMatRelaCreate from "./LocAreaMatRelaCreate"; +import LocAreaMatRelaPanel from "./LocAreaMatRelaPanel"; +import EmptyData from "../../components/EmptyData"; +import MyCreateButton from "../../components/MyCreateButton"; +import MyExportButton from '../../components/MyExportButton'; +import PageDrawer from "../../components/PageDrawer"; +import MyField from "../../components/MyField"; +import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting'; +import * as Common from '@/utils/common'; + +const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({ + '& .css-1vooibu-MuiSvgIcon-root': { + height: '.9em' + }, + '& .RaDatagrid-row': { + cursor: 'auto' + }, + '& .column-name': { + }, + '& .opt': { + width: 200 + }, +})); + +const filters = [ + <SearchInput source="condition" alwaysOn />, + + <NumberInput source="areaId" label="table.field.locAreaMatRela.areaId" />, + <TextInput source="code" label="table.field.locAreaMatRela.code" />, + <NumberInput source="matnrId" label="table.field.locAreaMatRela.matnrId" />, + <NumberInput source="groupId" label="table.field.locAreaMatRela.groupId" />, + <NumberInput source="locTypeId" label="table.field.locAreaMatRela.locTypeId" />, + <NumberInput source="locId" label="table.field.locAreaMatRela.locId" />, + + <TextInput label="common.field.memo" source="memo" />, + <SelectInput + label="common.field.status" + source="status" + choices={[ + { id: '1', name: 'common.enums.statusTrue' }, + { id: '0', name: 'common.enums.statusFalse' }, + ]} + resettable + />, +] + +const LocAreaMatRelaList = () => { + const translate = useTranslate(); + + const [createDialog, setCreateDialog] = useState(false); + const [drawerVal, setDrawerVal] = useState(false); + + return ( + <Box display="flex"> + <List + sx={{ + flexGrow: 1, + transition: (theme) => + theme.transitions.create(['all'], { + duration: theme.transitions.duration.enteringScreen, + }), + marginRight: drawerVal ? `${PAGE_DRAWER_WIDTH}px` : 0, + }} + title={"menu.locAreaMatRela"} + empty={<EmptyData onClick={() => { setCreateDialog(true) }} />} + filters={filters} + sort={{ field: "create_time", order: "desc" }} + actions={( + <TopToolbar> + <FilterButton /> + <MyCreateButton onClick={() => { setCreateDialog(true) }} /> + <SelectColumnsButton preferenceKey='locAreaMatRela' /> + <MyExportButton /> + </TopToolbar> + )} + perPage={DEFAULT_PAGE_SIZE} + > + <StyledDatagrid + preferenceKey='locAreaMatRela' + bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />} + rowClick={(id, resource, record) => false} + expand={() => <LocAreaMatRelaPanel />} + expandSingle={true} + omit={['id', 'createTime', 'createBy', 'memo']} + > + <NumberField source="id" /> + <NumberField source="areaId$" label="table.field.locAreaMatRela.areaId" /> + <TextField source="code" label="table.field.locAreaMatRela.code" /> + <NumberField source="matnrId$" label="table.field.locAreaMatRela.matnrId" /> + <NumberField source="groupId$" label="table.field.locAreaMatRela.groupId" /> + <NumberField source="locTypeId$" label="table.field.locAreaMatRela.locTypeId" /> + <NumberField source="locId$" label="table.field.locAreaMatRela.locId" /> + + <ReferenceField source="updateBy" label="common.field.updateBy" reference="user" link={false} sortable={false}> + <TextField source="nickname" /> + </ReferenceField> + <DateField source="updateTime" label="common.field.updateTime" showTime /> + <ReferenceField source="createBy" label="common.field.createBy" reference="user" link={false} sortable={false}> + <TextField source="nickname" /> + </ReferenceField> + <DateField source="createTime" label="common.field.createTime" showTime /> + <BooleanField source="statusBool" label="common.field.status" sortable={false} /> + <TextField source="memo" label="common.field.memo" sortable={false} /> + <WrapperField cellClassName="opt" label="common.field.opt"> + <EditButton sx={{ padding: '1px', fontSize: '.75rem' }} /> + <DeleteButton sx={{ padding: '1px', fontSize: '.75rem' }} mutationMode={OPERATE_MODE} /> + </WrapperField> + </StyledDatagrid> + </List> + <LocAreaMatRelaCreate + open={createDialog} + setOpen={setCreateDialog} + /> + <PageDrawer + title='LocAreaMatRela Detail' + drawerVal={drawerVal} + setDrawerVal={setDrawerVal} + > + </PageDrawer> + </Box> + ) +} + +export default LocAreaMatRelaList; diff --git a/rsf-admin/src/page/basicInfo/locAreaMatRela/LocAreaMatRelaPanel.jsx b/rsf-admin/src/page/basicInfo/locAreaMatRela/LocAreaMatRelaPanel.jsx new file mode 100644 index 0000000..3805034 --- /dev/null +++ b/rsf-admin/src/page/basicInfo/locAreaMatRela/LocAreaMatRelaPanel.jsx @@ -0,0 +1,87 @@ +import React, { useState, useRef, useEffect, useMemo } from "react"; +import { Box, Card, CardContent, Grid, Typography, Tooltip } from '@mui/material'; +import { + useTranslate, + useRecordContext, +} from 'react-admin'; +import PanelTypography from "../../components/PanelTypography"; +import * as Common from '@/utils/common' + +const LocAreaMatRelaPanel = () => { + const record = useRecordContext(); + if (!record) return null; + const translate = useTranslate(); + return ( + <> + <Card 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.locAreaMatRela.areaId'))}: {record.areaId} + </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}> </Box> + <Grid container spacing={2}> + <Grid item xs={6}> + <PanelTypography + title="table.field.locAreaMatRela.areaId" + property={record.areaId} + /> + </Grid> + <Grid item xs={6}> + <PanelTypography + title="table.field.locAreaMatRela.code" + property={record.code} + /> + </Grid> + <Grid item xs={6}> + <PanelTypography + title="table.field.locAreaMatRela.matnrId" + property={record.matnrId} + /> + </Grid> + <Grid item xs={6}> + <PanelTypography + title="table.field.locAreaMatRela.groupId" + property={record.groupId} + /> + </Grid> + <Grid item xs={6}> + <PanelTypography + title="table.field.locAreaMatRela.locTypeId" + property={record.locTypeId} + /> + </Grid> + <Grid item xs={6}> + <PanelTypography + title="table.field.locAreaMatRela.locId" + property={record.locId} + /> + </Grid> + + </Grid> + </CardContent> + </Card > + </> + ); +}; + +export default LocAreaMatRelaPanel; diff --git a/rsf-admin/src/page/basicInfo/locAreaMatRela/index.jsx b/rsf-admin/src/page/basicInfo/locAreaMatRela/index.jsx new file mode 100644 index 0000000..87ce528 --- /dev/null +++ b/rsf-admin/src/page/basicInfo/locAreaMatRela/index.jsx @@ -0,0 +1,18 @@ +import React, { useState, useRef, useEffect, useMemo } from "react"; +import { + ListGuesser, + EditGuesser, + ShowGuesser, +} from "react-admin"; + +import LocAreaMatRelaList from "./LocAreaMatRelaList"; +import LocAreaMatRelaEdit from "./LocAreaMatRelaEdit"; + +export default { + list: LocAreaMatRelaList, + edit: LocAreaMatRelaEdit, + show: ShowGuesser, + recordRepresentation: (record) => { + return `${record.areaId}` + } +}; diff --git a/rsf-admin/src/page/basicInfo/locType/BindModal.jsx b/rsf-admin/src/page/basicInfo/locType/BindModal.jsx new file mode 100644 index 0000000..310dd74 --- /dev/null +++ b/rsf-admin/src/page/basicInfo/locType/BindModal.jsx @@ -0,0 +1,199 @@ +import React, { useState, useRef, useEffect, useMemo } from "react"; +import { + CreateBase, + useTranslate, + TextInput, + NumberInput, + BooleanInput, + DateInput, + SaveButton, + SelectInput, + ReferenceInput, + ReferenceArrayInput, + AutocompleteInput, + Toolbar, + required, + useDataProvider, + useNotify, + Form, + useCreateController, + useListContext, + useRefresh, + SelectArrayInput +} from 'react-admin'; +import { + Dialog, + DialogActions, + DialogContent, + DialogTitle, + Grid, + TextField, + Box, + Button, + Paper, + TableContainer, + Table, + TableHead, + TableBody, + TableRow, + TableCell, + Tooltip, + IconButton, + styled, + + + +} from '@mui/material'; +import DialogCloseButton from "../../components/DialogCloseButton"; +import DictionarySelect from "../../components/DictionarySelect"; +import { useForm, Controller, useWatch, FormProvider, useFormContext } from "react-hook-form"; +import SaveIcon from '@mui/icons-material/Save'; +import request from '@/utils/request'; +import { Add, Edit, Delete } from '@mui/icons-material'; +import _ from 'lodash'; +import { DataGrid } from '@mui/x-data-grid'; +import StatusSelectInput from "../../components/StatusSelectInput"; +import TreeSelectInput from "@/page/components/TreeSelectInput"; +const MatnrModal = ({ open, setOpen }) => { + const refresh = useRefresh(); + const translate = useTranslate(); + + + const notify = useNotify(); + + const [formData, setFormData] = useState({ + areaId: null, + groupId: null, + matnrId: null, + }); + + const { selectedIds, onUnselectItems } = useListContext(); + + const handleClose = (event, reason) => { + if (reason !== "backdropClick") { + setOpen(false); + reset() + refresh(); + onUnselectItems() + } + }; + + const reset = () => { + setFormData({ + areaId: null, + groupId: null, + matnrId: null, + }) + } + + const handleReset = (e) => { + e.preventDefault(); + }; + + const handleChange = (value, name) => { + setFormData((prevData) => ({ + ...prevData, + [name]: value + })); + refresh() + }; + + const removeEmptyKeys = (obj) => { + return _.pickBy(obj, (value) => { + if (_.isObject(value)) { + const newObj = removeEmptyKeys(value); + return !_.isEmpty(newObj); + } + return !_.isNil(value) && (_.isNumber(value) ? value !== 0 : !_.isEmpty(value)); + }); + } + + const handleSubmit = async () => { + const parmas = { + typeId: selectedIds, + areaId: formData.areaId, + matnrId: formData.matnrId, + } + + const res = await request.post(`/locAreaMatRela/matnr/bind`, parmas); + if (res?.data?.code === 200) { + handleClose() + + } else { + notify(res.data.msg); + } + + + } + + const [groupId, setGroupId] = useState(); + + const warehouseChange = (e) => { + setGroupId(e.target.value) + } + + return ( + <Dialog open={open} maxWidth="md" fullWidth> + <Form onSubmit={handleSubmit}> + <DialogCloseButton onClose={handleClose} /> + <DialogTitle>{translate('toolbar.bindmatnr')}</DialogTitle> + <DialogContent sx={{ mt: 2 }}> + <Box sx={{ display: 'flex', flexDirection: 'column', gap: 3 }}> + <Grid container spacing={2}> + <Grid item xs={4}> + <ReferenceInput + source="areaId" + reference="warehouseAreas" + > + <AutocompleteInput + label="table.field.loc.areaId" + optionText="name" + onChange={(value) => handleChange(value, 'areaId')} + value={formData.areaId} + validate={required()} + filterToQuery={(val) => ({ name: val })} + /> + </ReferenceInput> + + </Grid> + + <Grid item xs={4}> + <TreeSelectInput + label="table.field.locAreaMatRela.groupId" + resource={'matnrGroup'} + source="groupId" + value={formData.groupId} + onChange={(e) => handleChange(e.target.value, 'groupId')} + /> + </Grid> + + + <Grid item xs={4}> + <ReferenceArrayInput source="matnrId" reference="matnr" filter={{ groupId: formData.groupId }}> + <SelectArrayInput + label="table.field.locAreaMatRela.matnrId" + validate={required()} + value={formData.matnrId} + onChange={(e) => handleChange(e.target.value, 'matnrId')} + /> + </ReferenceArrayInput> + + </Grid> + + </Grid> + + </Box> + </DialogContent> + <DialogActions sx={{ position: 'sticky', bottom: 0, backgroundColor: 'background.paper', zIndex: 1000 }}> + <Box sx={{ width: '100%', display: 'flex', justifyContent: 'space-between' }}> + <Button type="submit" variant="contained" startIcon={<SaveIcon />}> + {translate('toolbar.confirm')} + </Button> + </Box> + </DialogActions> + </Form> + </Dialog> + ); +} + +export default MatnrModal; \ No newline at end of file diff --git a/rsf-admin/src/page/basicInfo/locType/LocTypeList.jsx b/rsf-admin/src/page/basicInfo/locType/LocTypeList.jsx index 45a4e4d..5fd0003 100644 --- a/rsf-admin/src/page/basicInfo/locType/LocTypeList.jsx +++ b/rsf-admin/src/page/basicInfo/locType/LocTypeList.jsx @@ -31,6 +31,9 @@ ReferenceArrayInput, AutocompleteInput, DeleteButton, + useRefresh, + Button, + useList } from 'react-admin'; import { Box, Typography, Card, Stack } from '@mui/material'; import { styled } from '@mui/material/styles'; @@ -42,6 +45,8 @@ import PageDrawer from "../../components/PageDrawer"; import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting'; import * as Common from '@/utils/common'; +import BindModal from "./BindModal"; +import LinkIcon from '@mui/icons-material/Link'; const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({ '& .css-1vooibu-MuiSvgIcon-root': { @@ -109,7 +114,10 @@ > <StyledDatagrid preferenceKey='locType' - bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />} + bulkActionButtons={<> + <BindButton /> + <BulkDeleteButton /> + </>} rowClick={(id, resource, record) => false} omit={['id', 'createTime', 'createBy', 'memo']} > @@ -150,3 +158,26 @@ } export default LocTypeList; + +const BindButton = () => { + const record = useRecordContext(); + const notify = useNotify(); + const refresh = useRefresh(); + + + const [createDialog, setCreateDialog] = useState(false); + + return ( + <> + <Button onClick={() => setCreateDialog(true)} label={"toolbar.bindmatnr"}> + <LinkIcon /> + </Button> + + <BindModal + open={createDialog} + setOpen={setCreateDialog} + /> + </> + + ) +} diff --git a/rsf-admin/src/page/basicInfo/matnr/BindModal.jsx b/rsf-admin/src/page/basicInfo/matnr/BindModal.jsx new file mode 100644 index 0000000..3ada880 --- /dev/null +++ b/rsf-admin/src/page/basicInfo/matnr/BindModal.jsx @@ -0,0 +1,186 @@ +import React, { useState, useRef, useEffect, useMemo } from "react"; +import { + CreateBase, + useTranslate, + TextInput, + NumberInput, + BooleanInput, + DateInput, + SaveButton, + SelectInput, + ReferenceInput, + ReferenceArrayInput, + AutocompleteInput, + Toolbar, + required, + useDataProvider, + useNotify, + Form, + useCreateController, + useListContext, + useRefresh, + SelectArrayInput +} from 'react-admin'; +import { + Dialog, + DialogActions, + DialogContent, + DialogTitle, + Grid, + TextField, + Box, + Button, + Paper, + TableContainer, + Table, + TableHead, + TableBody, + TableRow, + TableCell, + Tooltip, + IconButton, + styled, + +} from '@mui/material'; +import DialogCloseButton from "../../components/DialogCloseButton"; +import DictionarySelect from "../../components/DictionarySelect"; +import { useForm, Controller, useWatch, FormProvider, useFormContext } from "react-hook-form"; +import SaveIcon from '@mui/icons-material/Save'; +import request from '@/utils/request'; +import { Add, Edit, Delete } from '@mui/icons-material'; +import _ from 'lodash'; +import { DataGrid } from '@mui/x-data-grid'; +import StatusSelectInput from "../../components/StatusSelectInput"; +import TreeSelectInput from "@/page/components/TreeSelectInput"; +const MatnrModal = ({ open, setOpen }) => { + const refresh = useRefresh(); + const translate = useTranslate(); + + + const notify = useNotify(); + + const [formData, setFormData] = useState({ + areaId: null, + locId: null, + }); + + const { selectedIds, onUnselectItems } = useListContext(); + + const handleClose = (event, reason) => { + if (reason !== "backdropClick") { + setOpen(false); + reset() + refresh(); + onUnselectItems() + } + }; + + const reset = () => { + setFormData({ + areaId: null, + locId: null, + }) + } + + const handleReset = (e) => { + e.preventDefault(); + }; + + const handleChange = (value, name) => { + setFormData((prevData) => ({ + ...prevData, + [name]: value + })); + refresh() + }; + + const removeEmptyKeys = (obj) => { + return _.pickBy(obj, (value) => { + if (_.isObject(value)) { + const newObj = removeEmptyKeys(value); + return !_.isEmpty(newObj); + } + return !_.isNil(value) && (_.isNumber(value) ? value !== 0 : !_.isEmpty(value)); + }); + } + + const handleSubmit = async () => { + const parmas = { + matnrId: selectedIds, + areaId: formData.areaId, + locId: formData.locId, + } + + const res = await request.post(`/locAreaMatRela/matnr/bind`, parmas); + if (res?.data?.code === 200) { + handleClose() + + } else { + notify(res.data.msg); + } + + + } + + const [groupId, setGroupId] = useState(); + + const warehouseChange = (e) => { + setGroupId(e.target.value) + } + + return ( + <Dialog open={open} maxWidth="md" fullWidth> + <Form onSubmit={handleSubmit}> + <DialogCloseButton onClose={handleClose} /> + <DialogTitle>{translate('toolbar.bindloc')}</DialogTitle> + <DialogContent sx={{ mt: 2 }}> + <Box sx={{ display: 'flex', flexDirection: 'column', gap: 3 }}> + <Grid container spacing={2}> + <Grid item xs={4}> + <ReferenceInput + source="areaId" + reference="warehouseAreas" + > + <AutocompleteInput + label="table.field.loc.areaId" + optionText="name" + onChange={(value) => handleChange(value, 'areaId')} + value={formData.areaId} + validate={required()} + filterToQuery={(val) => ({ name: val })} + /> + </ReferenceInput> + + </Grid> + + + <Grid item xs={4}> + <ReferenceArrayInput source="locId" reference="loc" > + <SelectArrayInput + label="table.field.locAreaMatRela.locId" + validate={required()} + optionText={'code'} + value={formData.locId} + onChange={(e) => handleChange(e.target.value, 'locId')} + /> + </ReferenceArrayInput> + + </Grid> + + </Grid> + + </Box> + </DialogContent> + <DialogActions sx={{ position: 'sticky', bottom: 0, backgroundColor: 'background.paper', zIndex: 1000 }}> + <Box sx={{ width: '100%', display: 'flex', justifyContent: 'space-between' }}> + <Button type="submit" variant="contained" startIcon={<SaveIcon />}> + {translate('toolbar.confirm')} + </Button> + </Box> + </DialogActions> + </Form> + </Dialog> + ); +} + +export default MatnrModal; \ No newline at end of file diff --git a/rsf-admin/src/page/basicInfo/matnr/MatnrList.jsx b/rsf-admin/src/page/basicInfo/matnr/MatnrList.jsx index e27b5e6..23079ee 100644 --- a/rsf-admin/src/page/basicInfo/matnr/MatnrList.jsx +++ b/rsf-admin/src/page/basicInfo/matnr/MatnrList.jsx @@ -55,6 +55,8 @@ import request from '@/utils/request'; import BatchModal from './BatchModal'; import PrintModal from './PrintModal'; +import LinkIcon from '@mui/icons-material/Link'; +import BindModal from './BindModal'; const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({ '& .css-1vooibu-MuiSvgIcon-root': { @@ -238,6 +240,7 @@ preferenceKey='matnr' bulkActionButtons={<> <BatchButton /> + <BindButton /> <PrintButton /> <BulkDeleteButton mutationMode={OPERATE_MODE} /> </>} @@ -379,4 +382,27 @@ </> ) +} + +const BindButton = () => { + const record = useRecordContext(); + const notify = useNotify(); + const refresh = useRefresh(); + + + const [createDialog, setCreateDialog] = useState(false); + + return ( + <> + <Button onClick={() => setCreateDialog(true)} label={"toolbar.bindloc"}> + <LinkIcon /> + </Button> + + <BindModal + open={createDialog} + setOpen={setCreateDialog} + /> + </> + + ) } \ No newline at end of file diff --git a/rsf-admin/src/page/basicInfo/matnr/PrintModal.jsx b/rsf-admin/src/page/basicInfo/matnr/PrintModal.jsx index 7513fbe..f618577 100644 --- a/rsf-admin/src/page/basicInfo/matnr/PrintModal.jsx +++ b/rsf-admin/src/page/basicInfo/matnr/PrintModal.jsx @@ -210,9 +210,12 @@ } })) setData(val) - val.forEach((el) => { - jsbarcode(`#barcode${el.code}`, el.code, { height: 30 }); - }); + setTimeout(() => { + val.forEach((el) => { + jsbarcode(`#barcode${el.code}`, el.code, { height: 30 }); + }); + }, 10); + } else { diff --git a/rsf-admin/src/page/basicInfo/matnrGroup/MatnrGroupCreate.jsx b/rsf-admin/src/page/basicInfo/matnrGroup/MatnrGroupCreate.jsx index 0146f24..4c9aa78 100644 --- a/rsf-admin/src/page/basicInfo/matnrGroup/MatnrGroupCreate.jsx +++ b/rsf-admin/src/page/basicInfo/matnrGroup/MatnrGroupCreate.jsx @@ -84,7 +84,7 @@ </DialogTitle> <DialogContent sx={{ mt: 2 }}> <Grid container rowSpacing={2} columnSpacing={2}> - + <Grid item xs={6} display="flex" gap={1}> <TextInput label="table.field.matnrGroup.name" @@ -104,6 +104,7 @@ <Grid item xs={6} display="flex" gap={1}> <NumberInput label="table.field.matnrGroup.parentId" + validate={[required()]} source="parentId" /> </Grid> diff --git a/rsf-admin/src/page/basicInfo/matnrGroup/MatnrGroupEdit.jsx b/rsf-admin/src/page/basicInfo/matnrGroup/MatnrGroupEdit.jsx index 206a847..1cfd61c 100644 --- a/rsf-admin/src/page/basicInfo/matnrGroup/MatnrGroupEdit.jsx +++ b/rsf-admin/src/page/basicInfo/matnrGroup/MatnrGroupEdit.jsx @@ -50,6 +50,7 @@ <Grid item xs={6} display="flex" gap={1}> <TreeSelectInput label="table.field.matnrGroup.parentId" + validate={[required()]} value={editRecord?.parentId} isTranslate resource={resource} @@ -76,7 +77,7 @@ const MatnrGroupEdit = (props) => { const { editRecord, open, setOpen, callback, resource } = props; - + const translate = useTranslate(); const notify = useNotify(); @@ -138,43 +139,43 @@ }; return ( - <> - <CreateBase> - <Dialog - open={open} - onClose={handleClose} - aria-labelledby="form-dialog-title" - fullWidth - disableRestoreFocus - maxWidth="md" // 'xs' | 'sm' | 'md' | 'lg' | 'xl' - > - <Form record={editRecord} onSubmit={onSubmit}> - <DialogTitle id="form-dialog-title" sx={{ - position: 'sticky', - top: 0, - backgroundColor: 'background.paper', - zIndex: 1000 - }} - > - {editRecord ? translate('update.title') : translate('create.title')} - <Box sx={{ position: 'absolute', top: 8, right: 8, zIndex: 1001 }}> - <DialogCloseButton onClose={handleClose} /> - </Box> - </DialogTitle> - <DialogContent sx={{ mt: 2 }}> - <EditContent - editRecord={editRecord} - /> - </DialogContent> - <DialogActions sx={{ position: 'sticky', bottom: 0, backgroundColor: 'background.paper', zIndex: 1000 }}> - <Toolbar sx={{ width: '100%', justifyContent: 'space-between' }} > - <SaveButton /> - </Toolbar> - </DialogActions> - </Form> - </Dialog> - </CreateBase> - </> + <> + <CreateBase> + <Dialog + open={open} + onClose={handleClose} + aria-labelledby="form-dialog-title" + fullWidth + disableRestoreFocus + maxWidth="md" // 'xs' | 'sm' | 'md' | 'lg' | 'xl' + > + <Form record={editRecord} onSubmit={onSubmit}> + <DialogTitle id="form-dialog-title" sx={{ + position: 'sticky', + top: 0, + backgroundColor: 'background.paper', + zIndex: 1000 + }} + > + {editRecord ? translate('update.title') : translate('create.title')} + <Box sx={{ position: 'absolute', top: 8, right: 8, zIndex: 1001 }}> + <DialogCloseButton onClose={handleClose} /> + </Box> + </DialogTitle> + <DialogContent sx={{ mt: 2 }}> + <EditContent + editRecord={editRecord} + /> + </DialogContent> + <DialogActions sx={{ position: 'sticky', bottom: 0, backgroundColor: 'background.paper', zIndex: 1000 }}> + <Toolbar sx={{ width: '100%', justifyContent: 'space-between' }} > + <SaveButton /> + </Toolbar> + </DialogActions> + </Form> + </Dialog> + </CreateBase> + </> ) } -- Gitblit v1.9.1