DESKTOP-LMJ82IJ\Eno
2025-04-13 fa1bc9ee550d197ef2aa52bf8601dd488cba09cd
#修改
1. 组拖界面优化 2. 质检界面优化
23个文件已添加
4406 ■■■■■ 已修改文件
rsf-admin/src/page/orders/asnOrder/AsnOrderCreate.jsx 184 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/asnOrder/AsnOrderEdit.jsx 114 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/asnOrder/AsnOrderItemCreate.jsx 204 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/asnOrder/AsnOrderItemEdit.jsx 199 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/asnOrder/AsnOrderItemList.jsx 202 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/asnOrder/AsnOrderList.jsx 316 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/asnOrder/AsnOrderModal.jsx 514 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/asnOrder/AsnOrderPanel.jsx 239 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/asnOrder/AsnWareModal.jsx 258 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/asnOrder/PrintModal.jsx 310 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/asnOrder/index.jsx 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/asnOrderLog/AsnOrderItemLogList.jsx 177 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/asnOrderLog/AsnOrderLogCreate.jsx 195 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/asnOrderLog/AsnOrderLogEdit.jsx 144 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/asnOrderLog/AsnOrderLogList.jsx 170 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/asnOrderLog/AsnOrderLogPanel.jsx 143 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/asnOrderLog/index.jsx 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/qlyInspect/QlyIsptItemCreate.jsx 182 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/qlyInspect/QlyIsptItemEdit.jsx 162 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/qlyInspect/QlyIsptItemList.jsx 167 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/waitPakin/WaitPakinItemCreate.jsx 176 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/waitPakin/WaitPakinItemEdit.jsx 148 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/waitPakin/WaitPakinItemList.jsx 166 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/asnOrder/AsnOrderCreate.jsx
New file
@@ -0,0 +1,184 @@
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 AsnOrderCreate = (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.asnOrder.code"
                                        source="code"
                                        parse={v => v}
                                        autoFocus
                                    />
                                </Grid> */}
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.asnOrder.poCode"
                                        source="poCode"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.asnOrder.poId"
                                        source="poId"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.asnOrder.type"
                                        source="type"
                                        parse={v => v}
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.asnOrder.wkType"
                                        source="wkType"
                                        parse={v => v}
                                        validate={required()}
                                    />
                                </Grid>
                                {/* <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.asnOrder.anfme"
                                        source="anfme"
                                        validate={required()}
                                    />
                                </Grid> */}
                                {/* <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.asnOrder.qty"
                                        source="qty"
                                        validate={required()}
                                    />
                                </Grid> */}
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.asnOrder.logisNo"
                                        source="logisNo"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <DateInput
                                        label="table.field.asnOrder.arrTime"
                                        source="arrTime"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <SelectInput
                                        label="table.field.asnOrder.rleStatus"
                                        source="rleStatus"
                                        choices={[
                                            { id: 0, name: ' 正常' },
                                            { id: 1, name: ' 已释放' },
                                        ]}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <StatusSelectInput />
                                </Grid>
                                <Grid item xs={12} display="flex" gap={1}>
                                    <Stack direction="column" spacing={1} width={'100%'}>
                                        <MemoInput />
                                    </Stack>
                                </Grid>
                            </Grid>
                        </DialogContent>
                        <DialogActions sx={{ position: 'sticky', bottom: 0, backgroundColor: 'background.paper', zIndex: 1000 }}>
                            <Toolbar sx={{ width: '100%', justifyContent: 'space-between' }}  >
                                <SaveButton />
                            </Toolbar>
                        </DialogActions>
                    </Form>
                </Dialog>
            </CreateBase>
        </>
    )
}
export default AsnOrderCreate;
rsf-admin/src/page/orders/asnOrder/AsnOrderEdit.jsx
New file
@@ -0,0 +1,114 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import {
    Edit,
    SimpleForm,
    useTranslate,
    TextInput,
    DateInput,
    SelectInput,
    AutocompleteInput,
    SaveButton,
    Toolbar,
    required,
    DeleteButton,
} from 'react-admin';
import { useWatch, useFormContext } from "react-hook-form";
import { Stack, Grid, Box, Typography } from '@mui/material';
import { EDIT_MODE, REFERENCE_INPUT_PAGESIZE } from '@/config/setting';
import EditBaseAside from "../../components/EditBaseAside";
import CustomerTopToolBar from "../../components/EditTopToolBar";
import AsnOrderItemList from "./AsnOrderItemList";
const FormToolbar = () => {
    const { getValues } = useFormContext();
    return (
        <Toolbar sx={{ justifyContent: 'end' }}>
            <SaveButton />
            <DeleteButton mutationMode="optimistic" />
        </Toolbar>
    )
}
const AsnOrderEdit = () => {
    const translate = useTranslate();
    const dicts = JSON.parse(localStorage.getItem('sys_dicts'))?.filter(dict => (dict.dictTypeCode == 'sys_order_type')) || [];
    const business = JSON.parse(localStorage.getItem('sys_dicts'))?.filter(dict => (dict.dictTypeCode == 'sys_business_type')) || [];
    return (
        <>
            <Edit
                redirect="list"
                mutationMode={EDIT_MODE}
                actions={<CustomerTopToolBar />}
                aside={<EditBaseAside />}
            >
                <SimpleForm
                    shouldUnregister
                    warnWhenUnsavedChanges
                    toolbar={<FormToolbar />}
                    mode="onTouched"
                    defaultValues={{}}
                >
                    <Grid container width={{ xs: '100%', xl: '80%' }} rowSpacing={3} columnSpacing={3}>
                        <Grid item xs={24} md={12}>
                            <Typography variant="h6" gutterBottom>
                                {translate('common.edit.title.main')}
                            </Typography>
                            <Stack direction='row' gap={2}>
                                <TextInput
                                    label="table.field.asnOrder.code"
                                    source="code"
                                    readOnly
                                    parse={v => v}
                                />
                                <TextInput
                                    label="table.field.asnOrder.poCode"
                                    source="poCode"
                                    parse={v => v}
                                />
                                <AutocompleteInput
                                    choices={dicts}
                                    optionText="label"
                                    label="table.field.asnOrder.type"
                                    source="type"
                                    optionValue="value"
                                    parse={v => v}
                                />
                                <AutocompleteInput
                                    choices={business}
                                    optionText="label"
                                    label="table.field.asnOrder.wkType"
                                    source="wkType"
                                    optionValue="value"
                                    parse={v => v}
                                />
                                <TextInput
                                    label="table.field.asnOrder.logisNo"
                                    source="logisNo"
                                    parse={v => v}
                                />
                                <DateInput
                                    label="table.field.asnOrder.arrTime"
                                    source="arrTime"
                                />
                                <SelectInput
                                    label="table.field.asnOrder.rleStatus"
                                    source="rleStatus"
                                    choices={[
                                        { id: 0, name: ' 正常' },
                                        { id: 1, name: ' 已释放' },
                                    ]}
                                    validate={required()}
                                />
                            </Stack>
                        </Grid>
                    </Grid>
                </SimpleForm>
            </Edit >
            <AsnOrderItemList />
        </>
    )
}
export default AsnOrderEdit;
rsf-admin/src/page/orders/asnOrder/AsnOrderItemCreate.jsx
New file
@@ -0,0 +1,204 @@
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 AsnOrderItemCreate = (props) => {
    const { open, setOpen, record } = 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
                resource="asnOrderItem"
                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>
                                <Grid item xs={6} display="flex" gap={2}>
                                    <NumberInput
                                        label="table.field.asnOrderItem.asnId"
                                        source="asnId"
                                        readOnly
                                        hidden
                                        defaultValue={record?.id}
                                    />
                                    <TextInput
                                        label="table.field.asnOrderItem.asnCode"
                                        source="asnCode"
                                        readOnly
                                        defaultValue={record?.code}
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={2}>
                                    <TextInput
                                        label="table.field.asnOrderItem.poDetlId"
                                        source="poDetlId"
                                        parse={v => v}
                                    />
                                    <TextInput
                                        label="table.field.asnOrderItem.poDetlCode"
                                        source="poDetlCode"
                                        parse={v => v}
                                    />
                                    <TextInput
                                        label="table.field.asnOrderItem.matnrId"
                                        source="matnrId"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.asnOrderItem.maktx"
                                        source="maktx"
                                        parse={v => v}
                                    />
                                    <NumberInput
                                        label="table.field.asnOrderItem.anfme"
                                        source="anfme"
                                        validate={required()}
                                    />
                                    <TextInput
                                        label="table.field.asnOrderItem.stockUnit"
                                        source="stockUnit"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.asnOrderItem.purQty"
                                        source="purQty"
                                        validate={required()}
                                    />
                                    <TextInput
                                        label="table.field.asnOrderItem.purUnit"
                                        source="purUnit"
                                        parse={v => v}
                                    />
                                    <NumberInput
                                        label="table.field.asnOrderItem.qty"
                                        source="qty"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.asnOrderItem.splrCode"
                                        source="splrCode"
                                        parse={v => v}
                                    />
                                    <TextInput
                                        label="table.field.asnOrderItem.splrName"
                                        source="splrName"
                                        parse={v => v}
                                    />
                                    <TextInput
                                        label="table.field.asnOrderItem.qrcode"
                                        source="qrcode"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.asnOrderItem.barcode"
                                        source="barcode"
                                        parse={v => v}
                                    />
                                    <TextInput
                                        label="table.field.asnOrderItem.packName"
                                        source="packName"
                                        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 AsnOrderItemCreate;
rsf-admin/src/page/orders/asnOrder/AsnOrderItemEdit.jsx
New file
@@ -0,0 +1,199 @@
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,
    Form,
    useRecordContext,
    useGetOne,
    DeleteButton,
    EditBase,
} from 'react-admin';
import { useWatch, useFormContext } from "react-hook-form";
import { Stack, Grid, Box, Typography, Dialog, DialogActions, DialogContent, DialogTitle } from '@mui/material';
import { EDIT_MODE, REFERENCE_INPUT_PAGESIZE } from '@/config/setting';
import DialogCloseButton from "../../components/DialogCloseButton";
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: 'end' }}>
            <SaveButton />
            <DeleteButton mutationMode="optimistic" />
        </Toolbar>
    )
}
const AsnOrderItemEdit = (props) => {
    const { open, setOpen, record } = props;
    const translate = useTranslate();
    const handleClose = (event, reason) => {
        if (reason !== "backdropClick") {
            setOpen(false);
        }
    };
    const { data, isPending, } = useGetOne('asnOrderItem', { id: record?.id });
    if (data == null || data == undefined) { return }
    return (
        <EditBase
            id={record?.id}
            resource="asnOrderItem"
            mutationMode={EDIT_MODE}
            actions={<CustomerTopToolBar />}
        >
            <Dialog
                open={open}
                onClose={handleClose}
                aria-labelledby="form-dialog-title"
                fullWidth
                disableRestoreFocus
                maxWidth="md"
            >
                <DialogTitle id="form-dialog-title" sx={{
                    position: 'sticky',
                    top: 0,
                    backgroundColor: 'background.paper',
                    zIndex: 1000
                }}
                >
                    {translate('update.title')}
                    <Box sx={{ position: 'absolute', top: 8, right: 8, zIndex: 1001 }}>
                        <DialogCloseButton onClose={handleClose} />
                    </Box>
                </DialogTitle>
                <DialogContent sx={{ mt: 2 }}>
                    <Form
                        shouldUnregister
                        warnWhenUnsavedChanges
                        mode="onTouched"
                        defaultValues={{}}
                    >
                        <Grid container width={{ xs: '100%', xl: '100%' }}>
                            <Grid item xs={24} md={14}>
                                <Stack direction='row' gap={2}>
                                    <NumberInput
                                        label="table.field.asnOrderItem.asnId"
                                        source="asnId"
                                        readOnly
                                    />
                                    <TextInput
                                        label="table.field.asnOrderItem.asnCode"
                                        source="asnCode"
                                        readOnly
                                        parse={v => v}
                                    />
                                    <TextInput
                                        label="table.field.asnOrderItem.poDetlId"
                                        source="poDetlId"
                                        parse={v => v}
                                    />
                                    <TextInput
                                        label="table.field.asnOrderItem.poDetlCode"
                                        source="poDetlCode"
                                        parse={v => v}
                                    />
                                </Stack>
                                <Stack direction='row' gap={2}>
                                    <TextInput
                                        label="table.field.asnOrderItem.matnrId"
                                        source="matnrId"
                                        parse={v => v}
                                    />
                                    <TextInput
                                        label="table.field.asnOrderItem.maktx"
                                        source="maktx"
                                        parse={v => v}
                                    />
                                    <NumberInput
                                        label="table.field.asnOrderItem.anfme"
                                        source="anfme"
                                        validate={required()}
                                    />
                                    <TextInput
                                        label="table.field.asnOrderItem.stockUnit"
                                        source="stockUnit"
                                        parse={v => v}
                                    />
                                </Stack>
                                <Stack direction='row' gap={2}>
                                    <NumberInput
                                        label="table.field.asnOrderItem.purQty"
                                        source="purQty"
                                        validate={required()}
                                    />
                                    <TextInput
                                        label="table.field.asnOrderItem.purUnit"
                                        source="purUnit"
                                        parse={v => v}
                                    />
                                    <NumberInput
                                        label="table.field.asnOrderItem.qty"
                                        source="qty"
                                    />
                                    <TextInput
                                        label="table.field.asnOrderItem.splrCode"
                                        source="splrCode"
                                        parse={v => v}
                                    />
                                </Stack>
                                <Stack direction='row' gap={2}>
                                    <TextInput
                                        label="table.field.asnOrderItem.splrName"
                                        source="splrName"
                                        parse={v => v}
                                    />
                                    <TextInput
                                        label="table.field.asnOrderItem.qrcode"
                                        source="qrcode"
                                        parse={v => v}
                                    />
                                    <TextInput
                                        label="table.field.asnOrderItem.barcode"
                                        source="barcode"
                                        parse={v => v}
                                    />
                                    <TextInput
                                        label="table.field.asnOrderItem.packName"
                                        source="packName"
                                        parse={v => v}
                                    />
                                </Stack>
                            </Grid>
                        </Grid>
                        <DialogActions sx={{ position: 'sticky', bottom: 0, backgroundColor: 'background.paper', zIndex: 1000 }}>
                            <Toolbar sx={{ width: '100%', justifyContent: 'end' }}  >
                                <SaveButton type="button" mutationOptions={{
                                    onSuccess: () => {
                                        setOpen(false)
                                    }
                                }} />
                            </Toolbar>
                        </DialogActions>
                    </Form>
                </DialogContent>
            </Dialog>
        </EditBase >
    )
}
export default AsnOrderItemEdit;
rsf-admin/src/page/orders/asnOrder/AsnOrderItemList.jsx
New file
@@ -0,0 +1,202 @@
import React, { useState, useRef, useEffect, useMemo, useCallback } from "react";
import { useNavigate, useLocation } 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,
  Button,
  useEditContext,
  useGetRecordId,
  useGetOne
} from 'react-admin';
import { Box, Typography, Card, Stack, Dialog, DialogActions, DialogTitle } from '@mui/material';
import { styled } from '@mui/material/styles';
import AsnOrderItemCreate from "./AsnOrderItemCreate";
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, DEFAULT_ITEM_PAGE_SIZE } from '@/config/setting';
import AsnOrderItemEdit from "./AsnOrderItemEdit";
import QrCodeIcon from "@mui/icons-material/QrCode";
import ImportButton from "../../components/ImportButton";
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="asnId" label="table.field.asnOrderItem.asnId" />,
  <TextInput source="asnCode" label="table.field.asnOrderItem.asnCode" />,
  <TextInput source="poDetlId" label="table.field.asnOrderItem.poDetlId" />,
  <TextInput source="poDetlCode" label="table.field.asnOrderItem.poDetlCode" />,
  <TextInput source="matnrId" label="table.field.asnOrderItem.matnrId" />,
  <TextInput source="maktx" label="table.field.asnOrderItem.maktx" />,
  <NumberInput source="anfme" label="table.field.asnOrderItem.anfme" />,
  <TextInput source="stockUnit" label="table.field.asnOrderItem.stockUnit" />,
  <NumberInput source="purQty" label="table.field.asnOrderItem.purQty" />,
  <TextInput source="purUnit" label="table.field.asnOrderItem.purUnit" />,
  <NumberInput source="qty" label="table.field.asnOrderItem.qty" />,
  <TextInput source="splrCode" label="table.field.asnOrderItem.splrCode" />,
  <TextInput source="splrName" label="table.field.asnOrderItem.splrName" />,
  <TextInput source="qrcode" label="table.field.asnOrderItem.qrcode" />,
  <TextInput source="barcode" label="table.field.asnOrderItem.barcode" />,
  <TextInput source="packName" label="table.field.asnOrderItem.packName" />,
  <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 AsnOrderItemList = () => {
  const translate = useTranslate();
  const [createDialog, setCreateDialog] = useState(false);
  const [editDialog, setEditDialog] = useState(false);
  const [drawerVal, setDrawerVal] = useState(false);
  const [select, setSelect] = useState({});
  const asnId = useGetRecordId();
  const { data: dicts, isPending, error } = useGetOne('asnOrder', { id: asnId }); const creatCode = () => { };
  return (
    <>
      <Box display="flex">
        <List
          resource="asnOrderItem"
          sx={{
            flexGrow: 1,
            transition: (theme) =>
              theme.transitions.create(['all'], {
                duration: theme.transitions.duration.enteringScreen,
              }),
            marginRight: drawerVal ? `${PAGE_DRAWER_WIDTH}px` : 0,
          }}
          title={"menu.asnOrderItem"}
          empty={<EmptyData onClick={() => { setCreateDialog(true) }} />}
          filter={{ asnId: asnId }}
          filters={filters}
          sort={{ field: "create_time", order: "desc" }}
          actions={(
            <TopToolbar>
              <Button onClick={creatCode} label={"toolbar.creatcode"}>
                <QrCodeIcon />
              </Button>
              <FilterButton />
              <MyCreateButton onClick={() => { setCreateDialog(true) }} />
              <SelectColumnsButton preferenceKey='asnOrderItem' />
              <ImportButton value={'asnOrder'} parmas={{ asnId: asnId }} />
              <MyExportButton />
            </TopToolbar>
          )}
          perPage={DEFAULT_ITEM_PAGE_SIZE}
        >
          <StyledDatagrid
            preferenceKey='asnOrderItem'
            bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />}
            rowClick={(id, resource, record) => {
              setSelect(record)
              setEditDialog(true)
            }}
             omit={['id', 'createTime', 'createBy', 'memo', 'poDetlId', 'matnrId', 'asnId']}
          >
            <NumberField source="id" />
            <NumberField source="asnId" label="table.field.asnOrderItem.asnId" />
            <TextField source="asnCode" label="table.field.asnOrderItem.asnCode" />
            <TextField source="poDetlId" label="table.field.asnOrderItem.poDetlId" />
            <TextField source="poDetlCode" label="table.field.asnOrderItem.poDetlCode" />
            <TextField source="matnrId" label="table.field.asnOrderItem.matnrId" />
            <TextField source="maktx" label="table.field.asnOrderItem.maktx" />
            <NumberField source="anfme" label="table.field.asnOrderItem.anfme" />
            <TextField source="stockUnit" label="table.field.asnOrderItem.stockUnit" />
            <NumberField source="purQty" label="table.field.asnOrderItem.purQty" />
            <TextField source="purUnit" label="table.field.asnOrderItem.purUnit" />
            <NumberField source="qty" label="table.field.asnOrderItem.qty" />
            <TextField source="splrCode" label="table.field.asnOrderItem.splrCode" />
            <TextField source="splrName" label="table.field.asnOrderItem.splrName" />
            <TextField source="qrcode" label="table.field.asnOrderItem.qrcode" />
            <TextField source="barcode" label="table.field.asnOrderItem.barcode" />
            <TextField source="packName" label="table.field.asnOrderItem.packName" />
            <TextField source="updateBy$" label="common.field.updateBy" />
            <DateField source="updateTime" label="common.field.updateTime" showTime />
            <TextField source="createBy$" label="common.field.createBy" />
            <DateField source="createTime" label="common.field.createTime" showTime />
            <BooleanField source="status$" 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' }} /> */}
              <Button label="ra.action.edit" onClick={(id, resource, record) => {
                 setEditDialog(true)
                 setSelect(record) }} />
              <DeleteButton sx={{ padding: '1px', fontSize: '.75rem' }} mutationMode={OPERATE_MODE}   />
            </WrapperField>
          </StyledDatagrid>
        </List>
        <AsnOrderItemCreate
          open={createDialog}
          setOpen={setCreateDialog}
          record={dicts}
        />
        <AsnOrderItemEdit
          open={editDialog}
          setOpen={setEditDialog}
          record={select}
        />
        <PageDrawer
          title='AsnOrderItem Detail'
          drawerVal={drawerVal}
          setDrawerVal={setDrawerVal}
        >
        </PageDrawer>
      </Box>
    </>
  )
}
AsnOrderItemList.Context = React.createContext()
export default AsnOrderItemList;
rsf-admin/src/page/orders/asnOrder/AsnOrderList.jsx
New file
@@ -0,0 +1,316 @@
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,
  useRefresh,
  useListContext,
  FunctionField,
  TextField,
  NumberField,
  DateField,
  BooleanField,
  ReferenceField,
  TextInput,
  DateTimeInput,
  DateInput,
  SelectInput,
  NumberInput,
  ReferenceInput,
  ReferenceArrayInput,
  AutocompleteInput,
  DeleteButton,
  Button,
} from 'react-admin';
import { Box, Typography, Card, Stack } from '@mui/material';
import { styled } from '@mui/material/styles';
import AsnOrderModal from "./AsnOrderModal";
import AsnOrderPanel from "./AsnOrderPanel";
import EmptyData from "../../components/EmptyData";
import MyCreateButton from "../../components/MyCreateButton";
import MyExportButton from '../../components/MyExportButton';
import BillStatusField from '../../components/BillStatusField';
import ConfirmButton from '../../components/ConfirmButton';
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 ConstructionIcon from "@mui/icons-material/Construction";
import FileDownloadIcon from '@mui/icons-material/FileDownload';
import EditIcon from '@mui/icons-material/Edit';
import TaskIcon from '@mui/icons-material/Task';
import CloseIcon from '@mui/icons-material/Close';
import request from '@/utils/request';
import DictionarySelect from "../../components/DictionarySelect";
const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({
  '& .css-1vooibu-MuiSvgIcon-root': {
    height: '.9em'
  },
  '& .RaDatagrid-row': {
    cursor: 'auto'
  },
  '& .column-name': {
  },
  '& .opt': {
    width: 320
  },
  '& .status': {
    width: 100
  },
}));
const filters = [
  <SearchInput source="condition" alwaysOn />,
  <TextInput source="code" label="table.field.asnOrder.code" />,
  <TextInput source="poCode" label="table.field.asnOrder.poCode" />,
  <NumberInput source="poId" label="table.field.asnOrder.poId" />,
  <TextInput source="type" label="table.field.asnOrder.type" />,
  <ReferenceInput source="wkType" reference="dictData" filter={{dictTypeCode: 'sys_business_type'}}  label="table.field.asnOrder.wkType">
    <AutocompleteInput label="table.field.asnOrder.wkType" optionValue="value" />
  </ReferenceInput>,
  <NumberInput source="anfme" label="table.field.asnOrder.anfme" />,
  <NumberInput source="qty" label="table.field.asnOrder.qty" />,
  <TextInput source="logisNo" label="table.field.asnOrder.logisNo" />,
  <DateInput source="arrTime" label="table.field.asnOrder.arrTime" />,
  <SelectInput source="rleStatus" label="table.field.asnOrder.rleStatus"
    choices={[
      { id: 0, name: ' 正常' },
      { id: 1, name: ' 已释放' },
    ]}
  />,
  <TextInput label="common.field.memo" source="memo" />,
  <DictionarySelect
    label='table.field.asnOrder.exceStatus'
    name="exceStatus"
    dictTypeCode="sys_asn_exce_status"
    alwaysOn
  />,
]
const AsnOrderList = () => {
  const translate = useTranslate();
  const [createDialog, setCreateDialog] = useState(false);
  const [drawerVal, setDrawerVal] = useState(false);
  const [modalType, setmodalType] = useState(0);
  const billReload = useRef();
  const navigate = useNavigate();
  const dicts = JSON.parse(localStorage.getItem('sys_dicts'))?.filter(dict => (dict.dictTypeCode == 'sys_business_type')) || [];
  const assign = (record) => {
    navigate(`/asnOrderItem?asnId=${record.id}`);
  };
  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.asnOrder"}
        empty={<EmptyData onClick={() => { setCreateDialog(true); setmodalType(0) }} />}
        filters={filters}
        sort={{ field: "create_time", order: "desc" }}
        actions={(
          <TopToolbar>
            <FilterButton />
            <MyCreateButton onClick={() => { setCreateDialog(true); setmodalType(0) }} />
            <SelectColumnsButton preferenceKey='asnOrder' />
            <MyExportButton />
          </TopToolbar>
        )}
        perPage={DEFAULT_PAGE_SIZE}
      >
        <StyledDatagrid
          sx={{ width: '100%' }}
          preferenceKey='asnOrder'
          bulkActionButtons={<> <InspectionsButton /><BulkDeleteButton mutationMode={OPERATE_MODE} /></>}
          rowClick={() => 'edit'}
          expandSingle={true}
          omit={['id', 'createTime', 'createBy', 'memo', 'poId']}
        >
          <NumberField source="id" />
          <TextField source="code" label="table.field.asnOrder.code" />
          <TextField source="poCode" label="table.field.asnOrder.poCode" />
          <NumberField source="poId" label="table.field.asnOrder.poId" />
          <TextField source="type$" label="table.field.asnOrder.type" />
          <TextField source="wkType$" label="table.field.asnOrder.wkType" />
          <NumberField source="anfme" label="table.field.asnOrder.anfme" />
          <NumberField source="qty" label="table.field.asnOrder.qty" />
          <TextField source="logisNo" label="table.field.asnOrder.logisNo" />
          <DateField source="arrTime" label="table.field.asnOrder.arrTime" showTime />
          <TextField source="rleStatus$" label="table.field.asnOrder.rleStatus" sortable={false} />
          <TextField source="updateBy$" label="common.field.updateBy" />
          <DateField source="updateTime" label="common.field.updateTime" showTime />
          <TextField source="createBy$" label="common.field.createBy" />
          <DateField source="createTime" label="common.field.createTime" showTime />
          <BillStatusField cellClassName="status" source="exceStatus" label="table.field.asnOrder.exceStatus" />
          <TextField source="memo" label="common.field.memo" sortable={false} />
          <WrapperField cellClassName="opt" label="common.field.opt" width={300} >
            <MyButton setCreateDialog={setCreateDialog} setmodalType={setmodalType} />
            <InspectionButton />
            <CompleteButton />
            <CloseButton />
          </WrapperField>
        </StyledDatagrid>
      </List>
      <AsnOrderModal
        open={createDialog}
        setOpen={setCreateDialog}
        asnId={modalType}
        billReload={billReload}
      />
      <PageDrawer
        title='AsnOrder Detail'
        drawerVal={drawerVal}
        setDrawerVal={setDrawerVal}
      >
      </PageDrawer>
    </Box >
  )
}
export default AsnOrderList;
const MyButton = ({ setCreateDialog, setmodalType }) => {
  const record = useRecordContext();
  const handleEditClick = () => {
    const id = record.id;
    setmodalType(id);
    setCreateDialog(true);
  };
  return (
    <Button
      color="primary"
      startIcon={<EditIcon />}
      onClick={() => handleEditClick()}
      sx={{ ml: 1 }}
      label={'ra.action.edit'}
    >
    </Button>
  )
}
const InspectionButton = () => {
  const record = useRecordContext();
  const notify = useNotify();
  const refresh = useRefresh();
  const inspection = () => {
    requestInspect([record])
  };
  const requestInspect = async (rows) => {
    const { data: { code, data, msg } } = await request.post(`/asnOrder/inspect`, rows);
    if (code === 200) {
      notify(msg);
      refresh()
    } else {
      notify(msg);
    }
  }
  return (
    <Button onClick={inspection} label={"toolbar.inspection"}>
      <ConstructionIcon />
    </Button>
  )
}
const InspectionsButton = () => {
  const { selectedIds, onUnselectItems, data } = useListContext();
  const notify = useNotify();
  const refresh = useRefresh();
  const inspection = () => {
    if (selectedIds.length === 0) {
      notify('请选择通知单');
      return;
    } else {
      const rows = data.filter((item) => selectedIds.includes(item.id))
      requestInspect(rows)
    }
  };
  const requestInspect = async (rows) => {
    const { data: { code, data, msg } } = await request.post(`/asnOrder/inspect`, rows);
    if (code === 200) {
      notify(msg);
      refresh()
    } else {
      notify(msg);
    }
  }
  return (
    <Button onClick={inspection} label={"toolbar.inspection"}>
      <ConstructionIcon />
    </Button>
  )
}
const CompleteButton = () => {
  const record = useRecordContext();
  const notify = useNotify();
  const refresh = useRefresh();
  const requestComplete = async () => {
    const { data: { code, data, msg } } = await request.post(`/asnOrder/complete/${record.id}`);
    if (code === 200) {
      notify(msg);
      refresh()
    } else {
      notify(msg);
    }
  }
  return (
    record.exceStatus === 1 && (record.anfme === record.qty ? <Button onClick={requestComplete} label={"toolbar.complete"} color="success">
      <TaskIcon />
    </Button> : <ConfirmButton label={"toolbar.complete"} color="success" data={'当前收货数量小于计划数量,是否确认完成'} startIcon={<TaskIcon />} onConfirm={requestComplete} />)
  )
}
const CloseButton = () => {
  const record = useRecordContext();
  const notify = useNotify();
  const refresh = useRefresh();
  const requestClose = async () => {
    const { data: { code, data, msg } } = await request.post(`/asnOrder/close/${record.id}`);
    if (code === 200) {
      notify(msg);
      refresh()
    } else {
      notify(msg);
    }
  }
  return (
    <ConfirmButton label={"toolbar.close"} color="error" data={'确认是否关闭?'} startIcon={<CloseIcon />} onConfirm={requestClose} />
  )
}
rsf-admin/src/page/orders/asnOrder/AsnOrderModal.jsx
New file
@@ -0,0 +1,514 @@
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,
    Stack,
    Grid,
    TextField,
    Box,
    Button,
    Paper,
    TableContainer,
    Table,
    TableHead,
    TableBody,
    TableRow,
    TableCell,
    Tooltip,
    IconButton,
    styled
} from '@mui/material';
import DialogCloseButton from "../../components/DialogCloseButton";
import StatusSelectInput from "../../components/StatusSelectInput";
import ConfirmButton from "../../components/ConfirmButton";
import AsnWareModal from "./AsnWareModal";
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 _, { set } from 'lodash';
import { DataGrid, useGridApiRef } from '@mui/x-data-grid';
import DictionarySelect from "../../components/DictionarySelect";
import DictSelect from "../../components/DictSelect";
const AsnOrderModal = (props) => {
    const { open, setOpen, asnId, billReload } = props;
    const translate = useTranslate();
    const notify = useNotify();
    const refresh = useRefresh();
    const [disabled, setDisabled] = useState(false)
    const [createDialog, setCreateDialog] = useState(false);
    const tableRef = useRef();
    useEffect(() => {
        if (open && asnId !== 0) {
            requestGetHead()
            requestGetBody()
        }
        setDisabled(false)
    }, [open])
    const handleClose = (event, reason) => {
        if (reason !== "backdropClick") {
            setOpen(false);
            refresh();
            setFormData({ type: '', wkType: '' })
            setTableData([])
        }
    };
    const [formData, setFormData] = useState({
        type: '',
        wkType: '',
        poCode: '',
        logisNo: '',
        arrTime: ''
    });
    const [tabelData, setTableData] = useState([]);
    const handleChange = (value, name) => {
        setFormData((prevData) => ({
            ...prevData,
            [name]: value
        }));
    };
    const resetData = () => {
        setFormData({
            type: '',
            wkType: '',
            poCode: '',
            logisNo: '',
            arrTime: ''
        })
        setTableData([])
    }
    const setFinally = () => {
        const rows = tableRef.current.state.editRows;
        for (const key in rows) {
            const find = tabelData.find(item => item.matnrId === +key);
            find.anfme = rows[key].anfme.value;
        }
        setTableData([...tabelData]);
    }
    const handleSubmit = async () => {
        setFinally()
        setDisabled(true)
        if (asnId === 0) {
            const parmas = {
                "orders": formData,
                "items": tabelData,
            }
            const res = await request.post(`/asnOrder/items/save`, parmas);
            if (res?.data?.code === 200) {
                setOpen(false);
                refresh();
                billReload?.current()
                resetData()
            } else {
                notify(res.data.msg);
            }
        } else {
            const parmas = {
                "orders": formData,
                "items": tabelData,
            }
            const res = await request.post(`/asnOrder/items/update`, parmas);
            if (res?.data?.code === 200) {
                setOpen(false);
                refresh();
                billReload?.current()
                resetData()
            } else {
                notify(res.data.msg);
            }
        }
        setDisabled(false)
    };
    const handleDelete = async () => {
        const res = await request.post(`/asnOrder/remove/${asnId}`);
        if (res?.data?.code === 200) {
            setOpen(false);
            refresh();
        } else {
            notify(res.data.msg);
        }
    };
    const requestGetHead = async () => {
        const res = await request.get(`/asnOrder/${asnId}`);
        if (res?.data?.code === 200) {
            setFormData(res.data.data)
        } else {
            notify(res.data.msg);
        }
    }
    const requestGetBody = async () => {
        const res = await request.post(`/asnOrderItem/page`, { asnId });
        if (res?.data?.code === 200) {
            setTableData(res.data.data.records)
        } else {
            notify(res.data.msg);
        }
    }
    const [selectedRows, setSelectedRows] = useState([]);
    const handleDeleteItem = () => {
        const newTableData = _.filter(tabelData, (item) => !selectedRows.includes(item.matnrId));
        setTableData(newTableData);
    }
    return (
        <>
            <Dialog
                open={open}
                onClose={handleClose}
                aria-labelledby="form-dialog-title"
                aria-hidden
                fullWidth
                disableRestoreFocus
                maxWidth="lg"   // 'xs' | 'sm' | 'md' | 'lg' | 'xl'
            >
                <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 }}>
                    <Box sx={{ display: 'flex', flexDirection: 'column', gap: 3 }}>
                        <Form>
                            <Grid container spacing={2}>
                                <Grid item md={3}>
                                    <DictSelect
                                        label={translate("table.field.asnOrder.type")}
                                        value={formData.type}
                                        onChange={(e) => handleChange(e.target.value, 'type')}
                                        dictTypeCode="sys_order_type"
                                        required
                                    />
                                </Grid>
                                <Grid item md={3}>
                                    <DictSelect
                                        label={translate("table.field.asnOrder.wkType")}
                                        value={formData.wkType}
                                        onChange={(e) => handleChange(e.target.value, 'wkType')}
                                        dictTypeCode="sys_business_type"
                                        required
                                    />
                                </Grid>
                                <Grid item md={3}>
                                    <TextField
                                        label={translate("table.field.asnOrder.poCode")}
                                        value={formData.poCode}
                                        onChange={(e) => handleChange(e.target.value, 'poCode')}
                                    />
                                </Grid>
                                <Grid item md={3}>
                                    <TextField
                                        label={translate("table.field.asnOrder.logisNo")}
                                        value={formData.logisNo}
                                        onChange={(e) => handleChange(e.target.value, 'logisNo')}
                                    />
                                </Grid>
                                <Grid item md={3}>
                                    {/* <TextField
                                        label={translate("table.field.asnOrder.arrTime")}
                                        value={formData.arrTime}
                                        onChange={(e) => handleChange(e.target.value, 'arrTime')}
                                    /> */}
                                    <DateInput
                                        source="arrTime"
                                        label="table.field.asnOrder.arrTime"
                                        value={formData.arrTime}
                                        onChange={(e) => handleChange(e.target.value, 'arrTime')}
                                    />
                                </Grid>
                            </Grid>
                        </Form>
                    </Box>
                    <Box sx={{ mt: 2 }}>
                        <Stack direction="row" spacing={2}>
                            <Button variant="contained" onClick={() => setCreateDialog(true)}>新增物料</Button>
                            {/* {asnId !== '' && <ConfirmButton label={'删除'} variant="outlined" color="error" onConfirm={handleDelete} />} */}
                            <ConfirmButton label={'删除'} variant="outlined" color="error" onConfirm={handleDeleteItem} />
                        </Stack>
                    </Box>
                    <Box sx={{ mt: 2 }}>
                        <AsnOrderModalTable tabelData={tabelData} setTableData={setTableData} asnId={asnId} selectedRows={selectedRows} setSelectedRows={setSelectedRows} tableRef={tableRef}></AsnOrderModalTable>
                    </Box>
                </DialogContent>
                <DialogActions sx={{ position: 'sticky', bottom: 0, backgroundColor: 'background.paper', zIndex: 1000 }}>
                    <Toolbar sx={{ width: '100%', justifyContent: 'space-between' }}  >
                        <Button disabled={disabled} onClick={handleSubmit} variant="contained" startIcon={<SaveIcon />}>
                            {translate('toolbar.confirm')}
                        </Button>
                    </Toolbar>
                </DialogActions>
            </Dialog>
            <AsnWareModal
                open={createDialog}
                setOpen={setCreateDialog}
                data={tabelData}
                setData={setTableData}
            />
        </>
    )
}
export default AsnOrderModal;
const AsnOrderModalTable = ({ tabelData, setTableData, asnId, selectedRows, setSelectedRows, tableRef }) => {
    const translate = useTranslate();
    const notify = useNotify();
    const [columns, setColumns] = useState([
        {
            field: 'maktx',
            headerName: translate('table.field.asnOrderItem.maktx'),
            width: 250,
            editable: false,
        },
        {
            field: 'matnrCode',
            headerName: translate('table.field.asnOrderItem.matnrCode'),
            width: 130,
            editable: false,
        },
        {
            field: 'anfme',
            headerName: translate('table.field.asnOrderItem.purQty'),
            type: 'number',
            minWidth: 100,
            flex: 1,
            editable: true,
            valueFormatter: (val) => val < 0 ? 0 : val
        },
        {
            field: 'splrCode',
            headerName: translate('table.field.asnOrderItem.splrCode'),
            minWidth: 100,
            flex: 1,
            editable: true,
        },
        {
            field: 'splrName',
            headerName: translate('table.field.asnOrderItem.splrName'),
            minWidth: 100,
            flex: 1,
            editable: true,
        },
        // {
        //     field: 'packName',
        //     headerName: translate('table.field.asnOrderItem.packName'),
        //     minWidth: 100,
        //     flex: 1,
        //     editable: true,
        // },
        // {
        //     field: 'poDetlId',
        //     headerName: translate('table.field.asnOrderItem.poDetlId'),
        //     minWidth: 100,
        //     flex: 1,
        // },
        {
            field: 'poCode',
            headerName: translate('table.field.asnOrderItem.poDetlCode'),
            minWidth: 100,
            flex: 1,
            editable: true,
        },
        {
            field: 'stockUnit',
            headerName: translate('table.field.asnOrderItem.stockUnit'),
            minWidth: 100,
            flex: 1,
            editable: false,
        },
        // {
        //     field: 'purQty',
        //     headerName: translate('table.field.asnOrderItem.purQty'),
        //     minWidth: 100,
        //     flex: 1,
        //     editable: true,
        // },
        {
            field: 'purUnit',
            headerName: translate('table.field.asnOrderItem.purUnit'),
            minWidth: 100,
            flex: 1,
            editable: false,
        },
    ])
    const action = {
        field: 'action',
        headerName: '操作',
        width: 70,
        lockPosition: 'left',
        renderCell: (params) => (
            <Tooltip title="Delete">
                <IconButton onClick={() => handleDelete(params.row)}>
                    <Delete />
                </IconButton>
            </Tooltip>
        ),
    }
    let cdata = useRef([]);
    useEffect(() => {
        getDynamicFields();
    }, []);
    useEffect(() => {
        cdata.current = tabelData
    }, [tabelData]);
    const getDynamicFields = async () => {
        const {
            data: { code, data, msg },
        } = await request.get("/fields/enable/list");
        if (code === 200) {
            const cols = data.map(el => ({
                field: el.fields,
                headerName: el.fieldsAlise,
                minWidth: 100,
                flex: 1,
                editable: false
            }))
            setColumns([...columns, ...cols, action])
        } else {
            notify(msg);
        }
    }
    const handleDelete = (row) => {
        const newData = _.filter(cdata.current, (item) => item.matnrId !== row.matnrId);
        setTableData(newData);
    };
    const processRowUpdate = (newRow, oldRow) => {
        const rows = tabelData.map((r) =>
            r.matnrId === newRow.matnrId ? { ...newRow } : r
        )
        setTableData(rows)
        // setTableData((prevData) =>
        //     prevData.map((r) =>
        //         r.matnrId === newRow.matnrId ? { ...newRow } : r
        //     )
        // );
        return newRow;
    };
    const handleSelectionChange = (ids) => {
        setSelectedRows(ids)
    };
    tableRef.current = useGridApiRef();
    return (
        <div style={{ height: 400, width: '100%' }}>
            <DataGrid
                apiRef={tableRef}
                rows={tabelData}
                columns={columns}
                disableRowSelectionOnClick
                getRowId={(row) => row.matnrId}
                disableColumnFilter
                disableColumnSelector
                disableColumnSorting
                disableMultipleColumnsSorting
                processRowUpdate={processRowUpdate}
                initialState={{
                    pagination: {
                        paginationModel: {
                            pageSize: 25,
                        },
                    },
                }}
                pageSizeOptions={[10, 25, 50, 100]}
                editMode="row"
                checkboxSelection
                onRowSelectionModelChange={handleSelectionChange}
                selectionModel={selectedRows}
                sx={{
                    '& .MuiDataGrid-cell input': {
                        border: '1px solid #ccc'
                    },
                }}
            />
        </div>
    );
};
rsf-admin/src/page/orders/asnOrder/AsnOrderPanel.jsx
New file
@@ -0,0 +1,239 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import { Box, Card, CardContent, Grid, Typography, Button, TextField, Tooltip, Paper, TableContainer, Table, TableBody, TableCell, TableHead, TableRow } from '@mui/material';
import {
    useTranslate,
    useRecordContext,
    useNotify,
    useRefresh,
    useListContext,
} from 'react-admin';
import PanelTypography from "../../components/PanelTypography";
import * as Common from '@/utils/common'
import { styled } from "@mui/material/styles";
import request from '@/utils/request';
import debounce from 'lodash/debounce';
import { DataGrid } from '@mui/x-data-grid';
import PrintModal from './PrintModal';
import PrintIcon from '@mui/icons-material/Print';
const AsnOrderPanel = ({ billReload }) => {
    const record = useRecordContext();
    if (!record) return null;
    const translate = useTranslate();
    const notify = useNotify();
    const [rows, setRows] = useState([]);
    const [maktx, setMaktx] = useState('');
    const asnId = record.id;
    useEffect(() => {
        debouncedHttp({ maktx });
    }, [asnId, maktx]);
    const http = async (parmas) => {
        const res = await request.post('/asnOrderItem/page', { ...parmas, asnId });
        if (res?.data?.code === 200) {
            setRows(res.data.data.records)
        } else {
            notify(res.data.msg);
        }
    }
    useEffect(() => {
        billReload.current = http
    }, []);
    const debouncedHttp = useMemo(() => debounce(http, 300), []);
    const columns = [
        {
            field: 'asnId',
            headerName: translate('table.field.asnOrderItem.asnId')
        },
        {
            field: 'asnCode',
            headerName: translate('table.field.asnOrderItem.asnCode'),
            width: 150,
        },
        // {
        //     field: 'poDetlId',
        //     headerName: translate('table.field.asnOrderItem.poDetlId')
        // },
        {
            field: 'poCode',
            headerName: translate('table.field.asnOrderItem.poDetlCode')
        },
        {
            field: 'matnrCode',
            headerName: translate('table.field.asnOrderItem.matnrCode'),
            width: 150,
        },
        {
            field: 'maktx',
            headerName: translate('table.field.asnOrderItem.maktx'),
            width: 200,
        },
        {
            field: 'anfme',
            headerName: translate('table.field.asnOrderItem.purQty')
        },
        {
            field: 'stockUnit',
            headerName: translate('table.field.asnOrderItem.stockUnit')
        },
        // {
        //     field: 'purQty',
        //     headerName: translate('table.field.asnOrderItem.purQty')
        // },
        {
            field: 'purUnit',
            headerName: translate('table.field.asnOrderItem.purUnit')
        },
        {
            field: 'qty',
            headerName: translate('table.field.asnOrderItem.qty')
        },
        {
            field: 'splrBatch',
            headerName: translate('table.field.asnOrderItem.splrBatch')
        },
        {
            field: 'splrCode',
            headerName: translate('table.field.asnOrderItem.splrCode')
        },
        {
            field: 'splrName',
            headerName: translate('table.field.asnOrderItem.splrName')
        },
        {
            field: 'trackCode',
            headerName: translate('table.field.asnOrderItem.barcode'),
            width: 150
        },
        {
            field: 'prodTime',
            headerName: translate('table.field.asnOrderItem.prodTime')
        },
        {
            field: 'packName',
            headerName: translate('table.field.asnOrderItem.packName')
        },
        {
            field: 'action',
            headerName: '操作',
            width: 70,
            lockPosition: 'left',
            renderCell: (params) => (
                <PrintButton rows={[params.row.id]} />
            ),
        },]
    const [selectedRows, setSelectedRows] = useState([]);
    const handleSelectionChange = (ids) => {
        setSelectedRows(ids)
    };
    const maktxChange = (value) => {
        setMaktx(value)
    }
    return (
        <Box sx={{
            position: 'relative',
            padding: '5px 10px'
        }}>
            <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: '4px', alignItems: 'center' }}>
                <TextField value={maktx} onChange={(e) => maktxChange(e.target.value)} label="搜索物料" sx={{ width: '300px' }} size="small" />
                <div style={{ display: 'flex', gap: '10px' }}>
                    <PrintsButton rows={selectedRows} />
                </div>
            </div>
            <DataGrid
                sx={{ width: 'calc(100vw - 280px)' }}
                size="small"
                rows={rows}
                columns={columns}
                disableRowSelectionOnClick
                checkboxSelection
                onRowSelectionModelChange={handleSelectionChange}
                selectionModel={selectedRows}
                disableColumnMenu={true}
                disableColumnSorting
                disableMultipleColumnsSorting
                columnHeaderHeight={40}
                rowHeight={42}
                initialState={{
                    pagination: {
                        paginationModel: {
                            pageSize: 10,
                        },
                    },
                }}
                pageSizeOptions={[10, 25, 50]}
            />
        </Box >
    );
};
export default AsnOrderPanel;
const PrintsButton = ({ rows }) => {
    const record = useRecordContext();
    const { resource, selectedIds } = useListContext();
    const notify = useNotify();
    const refresh = useRefresh();
    const translate = useTranslate();
    const [createDialog, setCreateDialog] = useState(false);
    const modalChange = () => {
        if (rows?.length === 0) {
            notify('请选择物料');
            return;
        } else {
            setCreateDialog(true)
        }
    }
    return (
        <>
            <Button size="small" color="secondary" onClick={modalChange} startIcon={<PrintIcon />}>{translate("toolbar.batchPrint")}</Button>
            <PrintModal
                open={createDialog}
                setOpen={setCreateDialog}
                rows={rows}
            />
        </>
    )
}
const PrintButton = ({ rows }) => {
    const record = useRecordContext();
    const notify = useNotify();
    const refresh = useRefresh();
    const [createDialog, setCreateDialog] = useState(false);
    const translate = useTranslate();
    return (
        <>
            <Button size="small" color="secondary" onClick={() => setCreateDialog(true)} startIcon={<PrintIcon />}>{translate("toolbar.print")}</Button>
            <PrintModal
                open={createDialog}
                setOpen={setCreateDialog}
                rows={rows}
            />
        </>
    )
}
rsf-admin/src/page/orders/asnOrder/AsnWareModal.jsx
New file
@@ -0,0 +1,258 @@
import React, { useState, useEffect } from "react";
import {
    Dialog,
    DialogActions,
    DialogContent,
    DialogTitle,
    Stack,
    Grid,
    TextField,
    Box,
    Button,
    Paper,
    styled
} from '@mui/material';
import DialogCloseButton from "../../components/DialogCloseButton";
import ConfirmButton from "../../components/ConfirmButton";
import { useTranslate, useNotify, useRefresh } from 'react-admin';
import request from '@/utils/request';
import { DataGrid } from '@mui/x-data-grid';
import SaveIcon from '@mui/icons-material/Save';
import TreeSelectInput from "@/page/components/TreeSelectInput";
const AsnWareModal = (props) => {
    const { open, setOpen, data, setData } = props;
    const translate = useTranslate();
    const notify = useNotify();
    const refresh = useRefresh();
    const asnId = '';
    const handleClose = (event, reason) => {
        if (reason !== "backdropClick") {
            setOpen(false);
        }
    };
    const [formData, setFormData] = useState({
        name: '',
        code: '',
        groupId: 0
    });
    const [tableData, setTableData] = useState([]);
    const [dyFields, setDyFields] = useState([]);
    const [selectedRows, setSelectedRows] = useState([]);
    const handleChange = (e) => {
        const { name, value } = e.target;
        setFormData((prevData) => ({
            ...prevData,
            [name]: value
        }));
    };
    const reset = () => {
        setFormData({
            name: '',
            code: '',
            groupId: 0
        })
    }
    const handleSubmit = () => {
        const hasarr = data.map(el => +el.matnrId)
        const selectedData = selectedRows.filter(item => !hasarr.includes(item)).map(id => (tableData.find(row => row.id === id)));
        const value = selectedData.map((el => {
            const dynamicFields = dyFields.reduce((acc, item) => {
                acc[item.fields] = el['extendFields']?.[item.fields] || '';
                return acc;
            }, {});
            return {
                matnrId: el.id,
                maktx: el.name,
                matnrCode: el.code,
                stockUnit: el.stockUnit || '',
                purUnit: el.purchaseUnit || '',
                ...dynamicFields
            }
        }))
        setData([...data, ...value]);
        setOpen(false);
        reset();
    };
    const getData = async () => {
        const res = await request.post(`/matnr/page`, {
            ...formData,
            current: 1,
            pageSize: 100,
            orderBy: "create_time desc"
        });
        if (res?.data?.code === 200) {
            setTableData(res.data.data.records);
        } else {
            notify(res.data.msg);
        }
    };
    useEffect(() => {
        getData();
    }, [open]);
    const handleSearch = () => {
        getData()
    };
    return (
        <Dialog
            open={open}
            onClose={handleClose}
            aria-labelledby="form-dialog-title"
            fullWidth
            disableRestoreFocus
            maxWidth="lg"
        >
            <DialogTitle id="form-dialog-title" sx={{
                position: 'sticky',
                top: 0,
                backgroundColor: 'background.paper',
                zIndex: 1000
            }}>
                选择物料
                <Box sx={{ position: 'absolute', top: 8, right: 8, zIndex: 1001 }}>
                    <DialogCloseButton onClose={handleClose} />
                </Box>
            </DialogTitle>
            <DialogContent sx={{ mt: 2 }}>
                <Box component="form" onSubmit={handleSubmit} sx={{ display: 'flex', flexDirection: 'column', gap: 3 }}>
                    <Grid container spacing={2}>
                        <Grid item md={4}>
                            <TextField
                                label={translate('table.field.matnr.name')}
                                name="name"
                                value={formData.name}
                                onChange={handleChange}
                                size="small"
                            />
                        </Grid>
                        <Grid item md={4}>
                            <TextField
                                label={translate('table.field.matnr.code')}
                                name="code"
                                value={formData.code}
                                onChange={handleChange}
                                size="small"
                            />
                        </Grid>
                        <Grid item md={4}>
                            <TreeSelectInput
                                label="table.field.matnr.groupId"
                                value={formData.groupId}
                                resource={'matnrGroup'}
                                source="groupId"
                                name="groupId"
                                onChange={handleChange}
                            />
                        </Grid>
                    </Grid>
                </Box>
                <Box sx={{ mt: 2 }}>
                    <Stack direction="row" spacing={2}>
                        <Button variant="contained" onClick={handleSearch}>搜索</Button>
                    </Stack>
                </Box>
                <Box sx={{ mt: 2, height: 400, width: '100%' }}>
                    <AsnWareModalTable
                        tableData={tableData}
                        setTableData={setTableData}
                        dyFields={dyFields}
                        setDyFields={setDyFields}
                        selectedRows={selectedRows}
                        setSelectedRows={setSelectedRows}
                    />
                </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 />}>
                        {translate('toolbar.confirm')}
                    </Button>
                </Box>
            </DialogActions>
        </Dialog>
    );
};
export default AsnWareModal;
const AsnWareModalTable = ({ tableData, setTableData, selectedRows, setSelectedRows, dyFields, setDyFields }) => {
    const translate = useTranslate();
    const notify = useNotify();
    const [columns, setColumns] = useState([
        // { field: 'id', headerName: 'ID', width: 100 },
        { field: 'name', headerName: translate('table.field.matnr.name'), width: 300 },
        { field: 'code', headerName: translate('table.field.matnr.code'), width: 200 },
        { field: 'groupId$', headerName: translate('table.field.matnr.groupId'), width: 100 },
        { field: 'spec', headerName: translate('table.field.matnr.spec'), width: 100 },
        { field: 'model', headerName: translate('table.field.matnr.model'), width: 100 },
        { field: 'weight', headerName: translate('table.field.matnr.weight'), width: 100 },
        { field: 'describle', headerName: translate('table.field.matnr.describle'), width: 100 },
        { field: 'nromNum', headerName: translate('table.field.matnr.nromNum'), width: 100 },
        { field: 'unit', headerName: translate('table.field.matnr.unit'), width: 100 },
        { field: 'purchaseUnit', headerName: translate('table.field.matnr.purUnit'), width: 100 },
        { field: 'stockUnit', headerName: translate('table.field.matnr.stockUnit'), width: 100 },
        { field: 'stockLeval$', headerName: translate('table.field.matnr.stockLevel'), width: 100, sortable: false },
    ])
    const handleSelectionChange = (ids) => {
        setSelectedRows(ids)
    };
    useEffect(() => {
        getDynamicFields();
    }, []);
    const getDynamicFields = async () => {
        const {
            data: { code, data, msg },
        } = await request.get("/fields/enable/list");
        if (code === 200) {
            const cols = data.map(el => ({
                field: el.fields,
                headerName: el.fieldsAlise,
                minWidth: 100,
                flex: 1,
                editable: el.unique,
                valueGetter: (value, row) => {
                    return row.extendFields?.[el.fields] || '';
                },
            }))
            setDyFields(data)
            setColumns([...columns, ...cols])
        } else {
            notify(msg);
        }
    }
    return (
        <div style={{ height: 400, width: '100%' }}>
            <DataGrid
                size="small"
                rows={tableData}
                columns={columns}
                checkboxSelection
                onRowSelectionModelChange={handleSelectionChange}
                selectionModel={selectedRows}
                disableColumnMenu={true}
                disableColumnSorting
                disableMultipleColumnsSorting
            />
        </div>
    );
};
rsf-admin/src/page/orders/asnOrder/PrintModal.jsx
New file
@@ -0,0 +1,310 @@
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,
    Radio,
    RadioGroup,
    FormControlLabel,
    FormControl,
    FormLabel,
    TableRow,
    TableCell,
    Tooltip,
    IconButton,
    styled
} from '@mui/material';
import DialogCloseButton from "@/page/components/DialogCloseButton";
import DictionarySelect from "@/page/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 "@/page/components/StatusSelectInput";
import { useReactToPrint } from "react-to-print";
import jsbarcode from 'jsbarcode'
import { el } from "date-fns/locale";
const PrintModal = ({ open, setOpen, rows }) => {
    const refresh = useRefresh();
    const translate = useTranslate();
    const notify = useNotify();
    const contentRef = useRef(null);
    const reactToPrintFn = useReactToPrint({ contentRef });
    const handleClose = (event, reason) => {
        if (reason !== "backdropClick") {
            setOpen(false);
        }
    };
    const [value, setValue] = useState('temp1');
    const handleChange = (event) => {
        setValue(event.target.value);
    };
    const handlePrint = () => {
        // handleClose()
        reactToPrintFn()
    };
    return (
        <Dialog open={open} maxWidth="sm" fullWidth>
            <DialogCloseButton onClose={handleClose} />
            <DialogTitle>{translate('toolbar.print')}</DialogTitle>
            <DialogContent >
                <FormControl >
                    <RadioGroup
                        row
                        aria-labelledby="demo-controlled-radio-buttons-group"
                        name="controlled-radio-buttons-group"
                        value={value}
                        onChange={handleChange}
                        size="small"
                        sx={{ justifyContent: 'center' }}
                    >
                        <FormControlLabel value="temp1" control={<Radio />} label="模板1" size="small" />
                    </RadioGroup>
                </FormControl>
                <Box>
                    <div style={{ textAlign: 'center', display: 'flex', justifyContent: 'center' }}>
                        <table
                            className="contain"
                            style={{
                                overflow: 'hidden',
                                fontSize: 'small',
                                tableLayout: 'fixed',
                                width: '280px',
                                borderCollapse: 'collapse', // 合并边框
                                border: '1px solid black' // 设置表格整体边框
                            }}
                        >
                            <tbody>
                                <tr style={{ height: '74px' }}>
                                    <td
                                        align="center"
                                        colSpan={3}
                                        style={{ border: '1px solid black' }} // 设置单元格边框
                                    >
                                        商品编码
                                    </td>
                                    <td
                                        align="center"
                                        className="barcode"
                                        colSpan={9}
                                        style={{ border: '1px solid black' }}
                                    >
                                        <img className="template-code" src={'/img/barcode.jpeg'} style={{ width: '90%' }} alt="Barcode" />
                                        <div style={{ letterSpacing: '2px', marginTop: '1px', textAlign: 'center' }}>
                                            <span>{'xxxxxx'}</span>
                                        </div>
                                    </td>
                                </tr>
                                <tr style={{ height: '74px' }}>
                                    <td
                                        align="center"
                                        colSpan={3}
                                        style={{ border: '1px solid black' }}
                                    >
                                        商品
                                    </td>
                                    <td
                                        align="center"
                                        colSpan={5}
                                        style={{
                                            overflow: 'hidden',
                                            whiteSpace: 'nowrap',
                                            textOverflow: 'ellipsis',
                                            border: '1px solid black'
                                        }}
                                    >
                                        {'xxxxxxxx'}
                                    </td>
                                    <td
                                        align="center"
                                        colSpan={2}
                                        style={{ border: '1px solid black' }}
                                    >
                                        备注
                                    </td>
                                    <td
                                        align="center"
                                        colSpan={2}
                                        style={{ border: '1px solid black' }}
                                    >
                                        {'xx'}
                                    </td>
                                </tr>
                            </tbody>
                        </table>
                    </div>
                    <style>{`
                    @media print {
                    .print-content {
                            display: block!important;
                        }
                    }`} </style>
                    <div ref={contentRef} className="print-content" style={{ textAlign: 'center', display: 'none' }}>
                        <PrintTemp key={'bb'} rows={rows} />
                    </div>
                </Box>
            </DialogContent>
            <DialogActions sx={{ position: 'sticky', bottom: 0, backgroundColor: 'background.paper', zIndex: 1000 }}>
                <Box sx={{ width: '100%', display: 'flex', justifyContent: 'space-between' }}>
                    <Button onClick={handlePrint} variant="contained" startIcon={<SaveIcon />}>
                        {translate('toolbar.confirm')}
                    </Button>
                </Box>
            </DialogActions>
        </Dialog >
    );
}
export default PrintModal;
const PrintTemp = ({ rows }) => {
    const notify = useNotify();
    const [data, setData] = useState([]);
    const http = async () => {
        const res = await request.post(`/asnOrderItem/many/${rows?.join()}`);
        if (res?.data?.code === 200) {
            let val = res.data.data.map((el => {
                return {
                    barcode: '/img/barcode.jpeg',
                    code: el.trackCode,
                    name: el.maktx,
                    memo: el.memo || ''
                }
            }))
            setData(val)
            setTimeout(() => {
                val.forEach((el) => {
                    jsbarcode(`#barcode${el.code}`, el.code, { height: 30 });
                });
            }, 10);
        } else {
            notify(res.data.msg);
        }
    }
    useEffect(() => {
        if (rows?.length > 0) {
            http();
        }
    }, [rows]);
    return (
        <>
            {data.map((item, index) => (
                <table
                    key={index}
                    className="contain"
                    style={{
                        overflow: 'hidden',
                        fontSize: 'small',
                        tableLayout: 'fixed',
                        width: '520px',
                        borderCollapse: 'collapse',
                        borderSpacing: 0,
                        margin: '0 auto',
                        marginTop: '10px',
                    }}
                >
                    <tbody>
                        <tr style={{ height: '74px' }}>
                            <td align="center" colSpan={3} style={{ border: '1px solid black' }} >
                                商品编码
                            </td>
                            <td
                                align="center"
                                className="barcode"
                                colSpan={9}
                                style={{ border: '1px solid black' }}
                            >
                                <img id={"barcode" + item.code} style={{ width: '70%', verticalAlign: 'middle' }} />
                                {/* <img className="template-code" src={item.barcode} style={{ width: '90%', verticalAlign: 'middle' }} alt="Barcode" /> */}
                                {/* <div style={{ letterSpacing: '2px', marginTop: '1px', textAlign: 'center' }}>
                                    <span>{item.code}</span>
                                </div> */}
                            </td>
                        </tr>
                        <tr style={{ height: '74px' }}>
                            <td
                                align="center"
                                colSpan={3}
                                style={{ border: '1px solid black' }}
                            >
                                商品
                            </td>
                            <td
                                align="center"
                                colSpan={5}
                                style={{
                                    overflow: 'hidden',
                                    whiteSpace: 'nowrap',
                                    textOverflow: 'ellipsis',
                                    border: '1px solid black'
                                }}
                            >
                                {item.name}
                            </td>
                            <td
                                align="center"
                                colSpan={2}
                                style={{ border: '1px solid black' }}
                            >
                                备注
                            </td>
                            <td
                                align="center"
                                colSpan={2}
                                style={{ border: '1px solid black' }}
                            >
                                {item.memo}
                            </td>
                        </tr>
                    </tbody>
                </table>
            ))}
        </>
    )
}
rsf-admin/src/page/orders/asnOrder/index.jsx
New file
@@ -0,0 +1,18 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import {
    ListGuesser,
    EditGuesser,
    ShowGuesser,
} from "react-admin";
import AsnOrderList from "./AsnOrderList";
import AsnOrderEdit from "./AsnOrderEdit";
export default {
    list: AsnOrderList,
    edit: AsnOrderEdit,
    show: ShowGuesser,
    recordRepresentation: (record) => {
        return `${record.name}`
    }
};
rsf-admin/src/page/orders/asnOrderLog/AsnOrderItemLogList.jsx
New file
@@ -0,0 +1,177 @@
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,
    useGetRecordId,
} from 'react-admin';
import { Box, Typography, Card, Stack } from '@mui/material';
import { styled } from '@mui/material/styles';
import EmptyData from "../../components/EmptyData";
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="asnId" label="table.field.asnOrderItemLog.asnId" />,
    <TextInput source="asnCode" label="table.field.asnOrderItemLog.asnCode" />,
    <TextInput source="platItemId" label="table.field.asnOrderItemLog.platItemId" />,
    <NumberInput source="poDetlId" label="table.field.asnOrderItemLog.poDetlId" />,
    <TextInput source="poCode" label="table.field.asnOrderItemLog.poCode" />,
    <TextInput source="fieldsIndex" label="table.field.asnOrderItemLog.fieldsIndex" />,
    <TextInput source="matnrId" label="table.field.asnOrderItemLog.matnrId" />,
    <TextInput source="matnrCode" label="table.field.asnOrderItemLog.matnrCode" />,
    <TextInput source="maktx" label="table.field.asnOrderItemLog.maktx" />,
    <NumberInput source="anfme" label="table.field.asnOrderItemLog.anfme" />,
    <TextInput source="stockUnit" label="table.field.asnOrderItemLog.stockUnit" />,
    <NumberInput source="purQty" label="table.field.asnOrderItemLog.purQty" />,
    <TextInput source="purUnit" label="table.field.asnOrderItemLog.purUnit" />,
    <NumberInput source="qty" label="table.field.asnOrderItemLog.qty" />,
    <TextInput source="splrCode" label="table.field.asnOrderItemLog.splrCode" />,
    <TextInput source="splrBatch" label="table.field.asnOrderItemLog.splrBatch" />,
    <TextInput source="splrName" label="table.field.asnOrderItemLog.splrName" />,
    <TextInput source="qrcode" label="table.field.asnOrderItemLog.qrcode" />,
    <TextInput source="trackCode" label="table.field.asnOrderItemLog.trackCode" />,
    <TextInput source="barcode" label="table.field.asnOrderItemLog.barcode" />,
    <TextInput source="packName" label="table.field.asnOrderItemLog.packName" />,
    <SelectInput source="ntyStatus" label="table.field.asnOrderItemLog.ntyStatus"
        choices={[
            { id: 0, name: ' 未上报' },
            { id: 1, name: ' 已上报' },
        ]}
    />,
    <TextInput label="common.field.memo" source="memo" />,
    <SelectInput
        label="common.field.status"
        source="status"
        choices={[
            { id: '1', name: 'common.enums.statusTrue' },
            { id: '0', name: 'common.enums.statusFalse' },
        ]}
        resettable
    />,
]
const AsnOrderItemLogList = () => {
    const translate = useTranslate();
    const [createDialog, setCreateDialog] = useState(false);
    const [drawerVal, setDrawerVal] = useState(false);
    const recodeId = useGetRecordId();
    return (
        <Box display="flex">
            <List
                resource="asnOrderItemLog"
                sx={{
                    flexGrow: 1,
                    transition: (theme) =>
                        theme.transitions.create(['all'], {
                            duration: theme.transitions.duration.enteringScreen,
                        }),
                    marginRight: drawerVal ? `${PAGE_DRAWER_WIDTH}px` : 0,
                }}
                title={"menu.asnOrderItemLog"}
                empty={false}
                filters={filters}
                filter={{ logId: recodeId }}
                sort={{ field: "create_time", order: "desc" }}
                actions={(
                    <TopToolbar>
                        <FilterButton />
                        <SelectColumnsButton preferenceKey='asnOrderItemLog' />
                        <MyExportButton />
                    </TopToolbar>
                )}
                perPage={DEFAULT_PAGE_SIZE}
            >
                <StyledDatagrid
                    preferenceKey='asnOrderItemLog'
                    bulkActionButtons={false}
                    rowClick={(id, resource, record) => false}
                    omit={['id', 'asnId', 'poDetlId', 'poCode', 'qrcode', 'packName', 'createTime', 'memo', 'fieldsIndex', 'matnrId', 'splrCode', 'status', 'createBy$']}
                >
                    <NumberField source="id" />
                    <NumberField source="asnId" label="table.field.asnOrderItemLog.asnId" />
                    <TextField source="asnCode" label="table.field.asnOrderItemLog.asnCode" />
                    <TextField source="platItemId" label="table.field.asnOrderItemLog.platItemId" />
                    <NumberField source="poDetlId" label="table.field.asnOrderItemLog.poDetlId" />
                    <TextField source="poCode" label="table.field.asnOrderItemLog.poCode" />
                    <TextField source="fieldsIndex" label="table.field.asnOrderItemLog.fieldsIndex" />
                    <TextField source="matnrId" label="table.field.asnOrderItemLog.matnrId" />
                    <TextField source="matnrCode" label="table.field.asnOrderItemLog.matnrCode" />
                    <TextField source="maktx" label="table.field.asnOrderItemLog.maktx" />
                    <NumberField source="anfme" label="table.field.asnOrderItemLog.anfme" />
                    <NumberField source="purQty" label="table.field.asnOrderItemLog.purQty" />
                    <TextField source="purUnit" label="table.field.asnOrderItemLog.purUnit" />
                    <NumberField source="qty" label="table.field.asnOrderItemLog.qty" />
                    <TextField source="splrCode" label="table.field.asnOrderItemLog.splrCode" />
                    <TextField source="splrBatch" label="table.field.asnOrderItemLog.splrBatch" />
                    <TextField source="splrName" label="table.field.asnOrderItemLog.splrName" />
                    <TextField source="qrcode" label="table.field.asnOrderItemLog.qrcode" />
                    <TextField source="trackCode" label="table.field.asnOrderItemLog.trackCode" />
                    <TextField source="packName" label="table.field.asnOrderItemLog.packName" />
                    <TextField source="ntyStatus$" label="table.field.asnOrderItemLog.ntyStatus" sortable={false} />
                    <TextField source="updateBy$" label="common.field.updateBy" />
                    <TextField source="createBy$" label="common.field.createBy" />
                    <DateField source="createTime" label="common.field.createTime" showTime />
                    <TextField source="memo" label="common.field.memo" sortable={false} />
                </StyledDatagrid>
            </List>
            <PageDrawer
                title='AsnOrderItemLog Detail'
                drawerVal={drawerVal}
                setDrawerVal={setDrawerVal}
            >
            </PageDrawer>
        </Box>
    )
}
export default AsnOrderItemLogList;
rsf-admin/src/page/orders/asnOrderLog/AsnOrderLogCreate.jsx
New file
@@ -0,0 +1,195 @@
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 AsnOrderLogCreate = (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.asnOrderLog.code"
                                        source="code"
                                        parse={v => v}
                                        autoFocus
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.asnOrderLog.poCode"
                                        source="poCode"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.asnOrderLog.poId"
                                        source="poId"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.asnOrderLog.type"
                                        source="type"
                                        parse={v => v}
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.asnOrderLog.wkType"
                                        source="wkType"
                                        parse={v => v}
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.asnOrderLog.anfme"
                                        source="anfme"
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.asnOrderLog.qty"
                                        source="qty"
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.asnOrderLog.logisNo"
                                        source="logisNo"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <DateInput
                                        label="table.field.asnOrderLog.arrTime"
                                        source="arrTime"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <SelectInput
                                        label="table.field.asnOrderLog.rleStatus"
                                        source="rleStatus"
                                        choices={[
                                            { id: 0, name: ' 正常' },
                                            { id:  1, name: ' 已释放' },
                                        ]}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <SelectInput
                                        label="table.field.asnOrderLog.ntyStatus"
                                        source="ntyStatus"
                                        choices={[
                                            { id: 0, name: ' 未上报' },
                                            { id:  1, name: ' 已上报' },
                                            { id:  2, name: ' 部分上报' },
                                        ]}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <StatusSelectInput />
                                </Grid>
                                <Grid item xs={12} display="flex" gap={1}>
                                    <Stack direction="column" spacing={1} width={'100%'}>
                                        <MemoInput />
                                    </Stack>
                                </Grid>
                            </Grid>
                        </DialogContent>
                        <DialogActions sx={{ position: 'sticky', bottom: 0, backgroundColor: 'background.paper', zIndex: 1000 }}>
                            <Toolbar sx={{ width: '100%', justifyContent: 'space-between' }}  >
                                <SaveButton />
                            </Toolbar>
                        </DialogActions>
                    </Form>
                </Dialog>
            </CreateBase>
        </>
    )
}
export default AsnOrderLogCreate;
rsf-admin/src/page/orders/asnOrderLog/AsnOrderLogEdit.jsx
New file
@@ -0,0 +1,144 @@
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, Card } from '@mui/material';
import { EDIT_MODE, REFERENCE_INPUT_PAGESIZE } from '@/config/setting';
import EditBaseAside from "../../components/EditBaseAside";
import CustomerTopToolBar from "../../components/EditTopToolBar";
import AsnOrderItemLogList from "./AsnOrderItemLogList"
const FormToolbar = () => {
    return (
        <Toolbar sx={{ justifyContent: 'end' }}>
            <SaveButton />
        </Toolbar>
    )
}
const AsnOrderLogEdit = () => {
    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={24} md={12}>
                            <Typography variant="h6" gutterBottom>
                                {translate('common.edit.title.main')}
                            </Typography>
                            <Stack direction='row' gap={2}>
                                <TextInput
                                    label="table.field.asnOrderLog.code"
                                    source="code"
                                    parse={v => v}
                                    readOnly
                                />
                                <TextInput
                                    label="table.field.asnOrderLog.poCode"
                                    source="poCode"
                                    readOnly
                                    parse={v => v}
                                />
                                <NumberInput
                                    label="table.field.asnOrderLog.poId"
                                    readOnly
                                    source="poId"
                                />
                                <TextInput
                                    label="table.field.asnOrderLog.type"
                                    source="type"
                                    readOnly
                                    parse={v => v}
                                    validate={required()}
                                />
                                <TextInput
                                    label="table.field.asnOrderLog.wkType"
                                    source="wkType"
                                    readOnly
                                    parse={v => v}
                                    validate={required()}
                                />
                            </Stack>
                            <Stack direction='row' gap={2}>
                                <NumberInput
                                    label="table.field.asnOrderLog.anfme"
                                    source="anfme"
                                    readOnly
                                    validate={required()}
                                />
                                <NumberInput
                                    label="table.field.asnOrderLog.qty"
                                    source="qty"
                                    readOnly
                                    validate={required()}
                                />
                                <TextInput
                                    label="table.field.asnOrderLog.logisNo"
                                    source="logisNo"
                                    readOnly
                                    parse={v => v}
                                />
                                <DateInput
                                    label="table.field.asnOrderLog.arrTime"
                                    readOnly
                                    source="arrTime"
                                />
                                <SelectInput
                                    label="table.field.asnOrderLog.ntyStatus"
                                    source="ntyStatus"
                                    readOnly
                                    choices={[
                                        { id: 0, name: ' 未上报' },
                                        { id: 1, name: ' 已上报' },
                                        { id: 2, name: ' 部分上报' },
                                    ]}
                                    validate={required()}
                                />
                            </Stack>
                        </Grid>
                    </Grid>
                </SimpleForm>
            </Edit >
            <Grid item xs={24} md={16} sx={{ marginTop: '1em' }}>
                <Typography variant="h6" gutterBottom >
                    {translate('common.edit.title.common')}
                </Typography>
            </Grid>
            <AsnOrderItemLogList />
        </>
    )
}
export default AsnOrderLogEdit;
rsf-admin/src/page/orders/asnOrderLog/AsnOrderLogList.jsx
New file
@@ -0,0 +1,170 @@
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 AsnOrderLogCreate from "./AsnOrderLogCreate";
import AsnOrderLogPanel from "./AsnOrderLogPanel";
import EmptyData from "../../components/EmptyData";
import MyCreateButton from "../../components/MyCreateButton";
import MyExportButton from '../../components/MyExportButton';
import PageDrawer from "../../components/PageDrawer";
import MyField from "../../components/MyField";
import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting';
import * as Common from '@/utils/common';
const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({
    '& .css-1vooibu-MuiSvgIcon-root': {
        height: '.9em'
    },
    '& .RaDatagrid-row': {
        cursor: 'auto'
    },
    '& .column-name': {
    },
    '& .opt': {
        width: 200
    },
}));
const filters = [
    <SearchInput source="condition" alwaysOn />,
    <TextInput source="code" label="table.field.asnOrderLog.code" />,
    <TextInput source="poCode" label="table.field.asnOrderLog.poCode" />,
    <NumberInput source="poId" label="table.field.asnOrderLog.poId" />,
    <TextInput source="type" label="table.field.asnOrderLog.type" />,
    <TextInput source="wkType" label="table.field.asnOrderLog.wkType" />,
    <NumberInput source="anfme" label="table.field.asnOrderLog.anfme" />,
    <NumberInput source="qty" label="table.field.asnOrderLog.qty" />,
    <TextInput source="logisNo" label="table.field.asnOrderLog.logisNo" />,
    <DateInput source="arrTime" label="table.field.asnOrderLog.arrTime" />,
    <SelectInput source="rleStatus" label="table.field.asnOrderLog.rleStatus"
        choices={[
            { id: 0, name: ' 正常' },
            { id: 1, name: ' 已释放' },
        ]}
    />,
    <SelectInput source="ntyStatus" label="table.field.asnOrderLog.ntyStatus"
        choices={[
            { id: 0, name: ' 未上报' },
            { id: 1, name: ' 已上报' },
            { id: 2, name: ' 部分上报' },
        ]}
    />,
    <TextInput label="common.field.memo" source="memo" />,
    <SelectInput
        label="common.field.status"
        source="status"
        choices={[
            { id: '1', name: 'common.enums.statusTrue' },
            { id: '0', name: 'common.enums.statusFalse' },
        ]}
        resettable
    />,
]
const AsnOrderLogList = () => {
    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.asnOrderLog"}
                empty={<EmptyData onClick={() => { setCreateDialog(true) }} />}
                filters={filters}
                sort={{ field: "create_time", order: "desc" }}
                actions={(
                    <TopToolbar>
                        <FilterButton />
                        {/* <MyCreateButton onClick={() => { setCreateDialog(true) }} /> */}
                        <SelectColumnsButton preferenceKey='asnOrderLog' />
                        <MyExportButton />
                    </TopToolbar>
                )}
                perPage={DEFAULT_PAGE_SIZE}
            >
                <StyledDatagrid
                    preferenceKey='asnOrderLog'
                    bulkActionButtons={false}
                    rowClick={'edit'}
                    expand={false}
                    expandSingle={true}
                    omit={['id', 'createTime', 'createBy', 'memo', 'rleStatus']}
                >
                    <NumberField source="id" />
                    <TextField source="code" label="table.field.asnOrderLog.code" />
                    <TextField source="poCode" label="table.field.asnOrderLog.poCode" />
                    <NumberField source="poId" label="table.field.asnOrderLog.poId" />
                    <TextField source="type$" label="table.field.asnOrderLog.type" />
                    <TextField source="wkType$" label="table.field.asnOrderLog.wkType" />
                    <NumberField source="anfme" label="table.field.asnOrderLog.anfme" />
                    <NumberField source="qty" label="table.field.asnOrderLog.qty" />
                    <TextField source="logisNo" label="table.field.asnOrderLog.logisNo" />
                    <DateField source="arrTime" label="table.field.asnOrderLog.arrTime" showTime />
                    <TextField source="rleStatus$" label="table.field.asnOrderLog.rleStatus" sortable={false} />
                    <TextField source="ntyStatus$" label="table.field.asnOrderLog.ntyStatus" sortable={false} />
                    <TextField source="updateBy$" label="common.field.updateBy"  />
                    <DateField source="updateTime" label="common.field.updateTime" showTime />
                    <TextField source="createBy$" label="common.field.createBy"/>
                    <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} />
                </StyledDatagrid>
            </List>
            <AsnOrderLogCreate
                open={createDialog}
                setOpen={setCreateDialog}
            />
            <PageDrawer
                title='AsnOrderLog Detail'
                drawerVal={drawerVal}
                setDrawerVal={setDrawerVal}
            >
            </PageDrawer>
        </Box>
    )
}
export default AsnOrderLogList;
rsf-admin/src/page/orders/asnOrderLog/AsnOrderLogPanel.jsx
New file
@@ -0,0 +1,143 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import { Box, Card, CardContent, Grid, Typography, Button, TextField, Tooltip, Paper, TableContainer, Table, TableBody, TableCell, TableHead, TableRow } from '@mui/material';
import {
    useTranslate,
    useRecordContext,
    useNotify,
    useRefresh,
    useListContext,
} from 'react-admin';
import PanelTypography from "../../components/PanelTypography";
import * as Common from '@/utils/common'
import { styled } from "@mui/material/styles";
import request from '@/utils/request';
import debounce from 'lodash/debounce';
import { DataGrid } from '@mui/x-data-grid';
const AsnOrderLogPanel = () => {
    const record = useRecordContext();
    if (!record) return null;
    const translate = useTranslate();
    const notify = useNotify();
    const [rows, setRows] = useState([]);
    const [maktx, setMaktx] = useState('');
    const asnId = record.asnId;
    useEffect(() => {
        debouncedHttp({ maktx });
    }, [asnId, maktx]);
    const http = async (parmas) => {
        const res = await request.post('/asnOrderItemLog/page', { ...parmas, asnId });
        if (res?.data?.code === 200) {
            setRows(res.data.data.records)
        } else {
            notify(res.data.msg);
        }
    }
    const debouncedHttp = useMemo(() => debounce(http, 300), []);
    const columns = [
        {
            field: 'asnId',
            headerName: translate('table.field.asnOrderItemLog.asnId')
        },
        {
            field: 'asnCode',
            headerName: translate('table.field.asnOrderItemLog.asnCode')
        },
        {
            field: 'poDetlId',
            headerName: translate('table.field.asnOrderItemLog.poDetlId')
        },
        {
            field: 'poCode',
            headerName: translate('table.field.asnOrderItemLog.poDetlCode')
        },
        {
            field: 'matnrId',
            headerName: translate('table.field.asnOrderItemLog.matnrId')
        },
        {
            field: 'matnrCode',
            headerName: translate('table.field.asnOrderItemLog.matnrCode')
        },
        {
            field: 'maktx',
            headerName: translate('table.field.asnOrderItemLog.maktx')
        },
        {
            field: 'anfme',
            headerName: translate('table.field.asnOrderItemLog.purQty')
        },
        {
            field: 'purUnit',
            headerName: translate('table.field.asnOrderItemLog.purUnit')
        },
        {
            field: 'qty',
            headerName: translate('table.field.asnOrderItemLog.qty')
        },
        {
            field: 'splrBatch',
            headerName: translate('table.field.asnOrderItem.splrBatch')
        },
        {
            field: 'splrCode',
            headerName: translate('table.field.asnOrderItemLog.splrCode')
        },
        {
            field: 'splrName',
            headerName: translate('table.field.asnOrderItemLog.splrName')
        },
        {
            field: 'trackCode',
            headerName: translate('table.field.asnOrderItemLog.barcode')
        },
        {
            field: 'prodTime',
            headerName: translate('table.field.asnOrderItem.prodTime')
        },
        {
            field: 'packName',
            headerName: translate('table.field.asnOrderItemLog.packName')
        },
        {
            field: 'ntyStatus$',
            headerName: translate('table.field.asnOrderItemLog.ntyStatus')
        }]
    const maktxChange = (value) => {
        setMaktx(value)
    }
    return (
        <Box sx={{
            position: 'relative',
            padding: '5px 10px'
        }}>
            <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: '4px', alignItems: 'center' }}>
                <TextField value={maktx} onChange={(e) => maktxChange(e.target.value)} label="搜索物料" variant="outlined" sx={{ width: '300px' }} size="small" />
                <div style={{ display: 'flex', gap: '10px' }}>
                </div>
            </div>
            <DataGrid
                size="small"
                rows={rows}
                columns={columns}
                disableRowSelectionOnClick
                disableColumnMenu={true}
                disableColumnSorting
                disableMultipleColumnsSorting
            />
        </Box >
    );
};
export default AsnOrderLogPanel;
rsf-admin/src/page/orders/asnOrderLog/index.jsx
New file
@@ -0,0 +1,18 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import {
    ListGuesser,
    EditGuesser,
    ShowGuesser,
} from "react-admin";
import AsnOrderLogList from "./AsnOrderLogList";
import AsnOrderLogEdit from "./AsnOrderLogEdit";
export default {
    list: AsnOrderLogList,
    edit: AsnOrderLogEdit,
    show: ShowGuesser,
    recordRepresentation: (record) => {
        return `${record.id}`
    }
};
rsf-admin/src/page/qlyInspect/QlyIsptItemCreate.jsx
New file
@@ -0,0 +1,182 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import {
    CreateBase,
    useTranslate,
    TextInput,
    NumberInput,
    SaveButton,
    Toolbar,
    useNotify,
    Form,
} 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 QlyIsptItemCreate = (props) => {
    const { open, setOpen, record } = 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={{}}
                resource="qlyIsptItem"
                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={2}>
                                    <NumberInput
                                        label="table.field.qlyIsptItem.ispectId"
                                        source="ispectId"
                                        readOnly
                                        defaultValue={record?.id}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.qlyIsptItem.matnrCode"
                                        source="matnrCode"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.qlyIsptItem.maktx"
                                        source="maktx"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.qlyIsptItem.label"
                                        source="label"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.qlyIsptItem.splrName"
                                        source="splrName"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.qlyIsptItem.splrBatch"
                                        source="splrBatch"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.qlyIsptItem.stockBatch"
                                        source="stockBatch"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.qlyIsptItem.rcptQty"
                                        source="rcptQty"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.qlyIsptItem.dlyQty"
                                        source="dlyQty"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.qlyIsptItem.disQty"
                                        source="disQty"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.qlyIsptItem.safeQty"
                                        source="safeQty"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.qlyIsptItem.picPath"
                                        source="picPath"
                                        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 QlyIsptItemCreate;
rsf-admin/src/page/qlyInspect/QlyIsptItemEdit.jsx
New file
@@ -0,0 +1,162 @@
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 QlyIsptItemEdit = () => {
    const translate = useTranslate();
    return (
        <Edit
            redirect="list"
            mutationMode={EDIT_MODE}
            actions={<CustomerTopToolBar />}
            aside={<EditBaseAside />}
        >
            <SimpleForm
                shouldUnregister
                warnWhenUnsavedChanges
                toolbar={<FormToolbar />}
                mode="onTouched"
                defaultValues={{}}
            // validate={(values) => { }}
            >
                <Grid container width={{ xs: '100%', xl: '80%' }} rowSpacing={3} columnSpacing={3}>
                    <Grid item xs={12} md={8}>
                        <Typography variant="h6" gutterBottom>
                            {translate('common.edit.title.main')}
                        </Typography>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.qlyIsptItem.ispectId"
                                source="ispectId"
                                autoFocus
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.qlyIsptItem.matnrCode"
                                source="matnrCode"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.qlyIsptItem.maktx"
                                source="maktx"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.qlyIsptItem.label"
                                source="label"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.qlyIsptItem.splrName"
                                source="splrName"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.qlyIsptItem.splrBatch"
                                source="splrBatch"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.qlyIsptItem.stockBatch"
                                source="stockBatch"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.qlyIsptItem.rcptQty"
                                source="rcptQty"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.qlyIsptItem.dlyQty"
                                source="dlyQty"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.qlyIsptItem.disQty"
                                source="disQty"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.qlyIsptItem.safeQty"
                                source="safeQty"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.qlyIsptItem.picPath"
                                source="picPath"
                                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 QlyIsptItemEdit;
rsf-admin/src/page/qlyInspect/QlyIsptItemList.jsx
New file
@@ -0,0 +1,167 @@
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,
    useGetOne,
    useGetRecordId,
} from 'react-admin';
import { Box, Typography, Card, Stack } from '@mui/material';
import { styled } from '@mui/material/styles';
import QlyIsptItemCreate from "./QlyIsptItemCreate";
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_ITEM_PAGE_SIZE } from '@/config/setting';
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="ispectId" label="table.field.qlyIsptItem.ispectId" />,
    <TextInput source="matnrCode" label="table.field.qlyIsptItem.matnrCode" />,
    <TextInput source="maktx" label="table.field.qlyIsptItem.maktx" />,
    <TextInput source="label" label="table.field.qlyIsptItem.label" />,
    <TextInput source="splrName" label="table.field.qlyIsptItem.splrName" />,
    <TextInput source="splrBatch" label="table.field.qlyIsptItem.splrBatch" />,
    <TextInput source="stockBatch" label="table.field.qlyIsptItem.stockBatch" />,
    <NumberInput source="rcptQty" label="table.field.qlyIsptItem.rcptQty" />,
    <NumberInput source="dlyQty" label="table.field.qlyIsptItem.dlyQty" />,
    <NumberInput source="disQty" label="table.field.qlyIsptItem.disQty" />,
    <NumberInput source="safeQty" label="table.field.qlyIsptItem.safeQty" />,
    <TextInput source="picPath" label="table.field.qlyIsptItem.picPath" />,
    <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 QlyIsptItemList = () => {
    const translate = useTranslate();
    const [createDialog, setCreateDialog] = useState(false);
    const [drawerVal, setDrawerVal] = useState(false);
    const isptId = useGetRecordId();
    const { data: dicts, isPending, error } = useGetOne('qlyInspect', { id: isptId });
    if (dicts == null) {return}
    return (
        <Box display="flex">
            <List
            resource="qlyIsptItem"
            filter={{ispectId: isptId}}
                sx={{
                    flexGrow: 1,
                    transition: (theme) =>
                        theme.transitions.create(['all'], {
                            duration: theme.transitions.duration.enteringScreen,
                        }),
                    marginRight: drawerVal ? `${PAGE_DRAWER_WIDTH}px` : 0,
                }}
                title={"menu.qlyIsptItem"}
                empty={false}
                filters={filters}
                sort={{ field: "create_time", order: "desc" }}
                actions={(
                    <TopToolbar>
                        <FilterButton />
                        {/* <MyCreateButton onClick={() => { setCreateDialog(true) }} /> */}
                        <SelectColumnsButton preferenceKey='qlyIsptItem' />
                        <MyExportButton />
                    </TopToolbar>
                )}
                perPage={DEFAULT_ITEM_PAGE_SIZE}
            >
                <StyledDatagrid
                    preferenceKey='qlyIsptItem'
                    bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />}
                    rowClick={false}
                    omit={['id', 'createTime', 'createBy', 'memo', 'ispectId']}
                >
                    <NumberField source="id" />
                    <NumberField source="ispectId" label="table.field.qlyIsptItem.ispectId" />
                    <TextField source="matnrCode" label="table.field.qlyIsptItem.matnrCode" />
                    <TextField source="maktx" label="table.field.qlyIsptItem.maktx" />
                    <TextField source="label" label="table.field.qlyIsptItem.label" />
                    <TextField source="splrName" label="table.field.qlyIsptItem.splrName" />
                    <TextField source="splrBatch" label="table.field.qlyIsptItem.splrBatch" />
                    <TextField source="stockBatch" label="table.field.qlyIsptItem.stockBatch" />
                    <NumberField source="rcptQty" label="table.field.qlyIsptItem.rcptQty" />
                    <NumberField source="isptResult$" label="table.field.qlyIsptItem.isptResult" />
                    <NumberField source="dlyQty" label="table.field.qlyIsptItem.dlyQty" />
                    <NumberField source="disQty" label="table.field.qlyIsptItem.disQty" />
                    <NumberField source="safeQty" label="table.field.qlyIsptItem.safeQty" />
                    <TextField source="picPath" label="table.field.qlyIsptItem.picPath" />
                    <TextField source="updateBy$" label="common.field.updateBy"  />
                    <DateField source="updateTime" label="common.field.updateTime" showTime />
                    <TextField source="createBy$" label="common.field.createBy"  />
                    <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} />
                </StyledDatagrid>
            </List>
            <QlyIsptItemCreate
                open={createDialog}
                record={dicts}
                setOpen={setCreateDialog}
            />
            <PageDrawer
                title='QlyIsptItem Detail'
                drawerVal={drawerVal}
                setDrawerVal={setDrawerVal}
            >
            </PageDrawer>
        </Box>
    )
}
export default QlyIsptItemList;
rsf-admin/src/page/waitPakin/WaitPakinItemCreate.jsx
New file
@@ -0,0 +1,176 @@
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 WaitPakinItemCreate = (props) => {
    const { open, setOpen } = props;
    const translate = useTranslate();
    const notify = useNotify();
    const handleClose = (event, reason) => {
        if (reason !== "backdropClick") {
            setOpen(false);
        }
    };
    const handleSuccess = async (data) => {
        setOpen(false);
        notify('common.response.success');
    };
    const handleError = async (error) => {
        notify(error.message || 'common.response.fail', { type: 'error', messageArgs: { _: error.message } });
    };
    return (
        <>
            <CreateBase
                record={{}}
                transform={(data) => {
                    return data;
                }}
                mutationOptions={{ onSuccess: handleSuccess, onError: handleError }}
            >
                <Dialog
                    open={open}
                    onClose={handleClose}
                    aria-labelledby="form-dialog-title"
                    fullWidth
                    disableRestoreFocus
                    maxWidth="md"   // 'xs' | 'sm' | 'md' | 'lg' | 'xl'
                >
                    <Form>
                        <DialogTitle id="form-dialog-title" sx={{
                            position: 'sticky',
                            top: 0,
                            backgroundColor: 'background.paper',
                            zIndex: 1000
                        }}
                        >
                            {translate('create.title')}
                            <Box sx={{ position: 'absolute', top: 8, right: 8, zIndex: 1001 }}>
                                <DialogCloseButton onClose={handleClose} />
                            </Box>
                        </DialogTitle>
                        <DialogContent sx={{ mt: 2 }}>
                            <Grid container rowSpacing={2} columnSpacing={2}>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.waitPakinItem.pakinId"
                                        source="pakinId"
                                        autoFocus
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.waitPakinItem.maktx"
                                        source="maktx"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.waitPakinItem.matnrId"
                                        source="matnrId"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.waitPakinItem.matnrCode"
                                        source="matnrCode"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.waitPakinItem.anfme"
                                        source="anfme"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.waitPakinItem.workQty"
                                        source="workQty"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.waitPakinItem.unit"
                                        source="unit"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.waitPakinItem.fieldsIndex"
                                        source="fieldsIndex"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.waitPakinItem.qty"
                                        source="qty"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.waitPakinItem.batch"
                                        source="batch"
                                        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 WaitPakinItemCreate;
rsf-admin/src/page/waitPakin/WaitPakinItemEdit.jsx
New file
@@ -0,0 +1,148 @@
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 WaitPakinItemEdit = () => {
    const translate = useTranslate();
    return (
        <Edit
            redirect="list"
            mutationMode={EDIT_MODE}
            actions={<CustomerTopToolBar />}
            aside={<EditBaseAside />}
        >
            <SimpleForm
                shouldUnregister
                warnWhenUnsavedChanges
                toolbar={<FormToolbar />}
                mode="onTouched"
                defaultValues={{}}
            // validate={(values) => { }}
            >
                <Grid container width={{ xs: '100%', xl: '80%' }} rowSpacing={3} columnSpacing={3}>
                    <Grid item xs={12} md={8}>
                        <Typography variant="h6" gutterBottom>
                            {translate('common.edit.title.main')}
                        </Typography>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.waitPakinItem.pakinId"
                                source="pakinId"
                                autoFocus
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.waitPakinItem.maktx"
                                source="maktx"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.waitPakinItem.matnrId"
                                source="matnrId"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.waitPakinItem.matnrCode"
                                source="matnrCode"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.waitPakinItem.anfme"
                                source="anfme"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.waitPakinItem.workQty"
                                source="workQty"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.waitPakinItem.unit"
                                source="unit"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.waitPakinItem.fieldsIndex"
                                source="fieldsIndex"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.waitPakinItem.qty"
                                source="qty"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.waitPakinItem.batch"
                                source="batch"
                                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 WaitPakinItemEdit;
rsf-admin/src/page/waitPakin/WaitPakinItemList.jsx
New file
@@ -0,0 +1,166 @@
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 WaitPakinItemCreate from "./WaitPakinItemCreate";
import WaitPakinItemPanel from "./WaitPakinItemPanel";
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="pakinId" label="table.field.waitPakinItem.pakinId" />,
    <TextInput source="maktx" label="table.field.waitPakinItem.maktx" />,
    <NumberInput source="matnrId" label="table.field.waitPakinItem.matnrId" />,
    <TextInput source="matnrCode" label="table.field.waitPakinItem.matnrCode" />,
    <NumberInput source="anfme" label="table.field.waitPakinItem.anfme" />,
    <NumberInput source="workQty" label="table.field.waitPakinItem.workQty" />,
    <TextInput source="unit" label="table.field.waitPakinItem.unit" />,
    <TextInput source="fieldsIndex" label="table.field.waitPakinItem.fieldsIndex" />,
    <NumberInput source="qty" label="table.field.waitPakinItem.qty" />,
    <TextInput source="batch" label="table.field.waitPakinItem.batch" />,
    <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 WaitPakinItemList = () => {
    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.waitPakinItem"}
                empty={<EmptyData onClick={() => { setCreateDialog(true) }} />}
                filters={filters}
                sort={{ field: "create_time", order: "desc" }}
                actions={(
                    <TopToolbar>
                        <FilterButton />
                        {/* <MyCreateButton onClick={() => { setCreateDialog(true) }} /> */}
                        <SelectColumnsButton preferenceKey='waitPakinItem' />
                        <MyExportButton />
                    </TopToolbar>
                )}
                perPage={DEFAULT_PAGE_SIZE}
            >
                <StyledDatagrid
                    preferenceKey='waitPakinItem'
                    bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />}
                    rowClick={(id, resource, record) => false}
                    omit={['id', 'createTime', 'createBy', 'memo']}
                >
                    <NumberField source="id" />
                    <NumberField source="pakinId" label="table.field.waitPakinItem.pakinId" />
                    <TextField source="maktx" label="table.field.waitPakinItem.maktx" />
                    <NumberField source="matnrId" label="table.field.waitPakinItem.matnrId" />
                    <TextField source="matnrCode" label="table.field.waitPakinItem.matnrCode" />
                    <NumberField source="anfme" label="table.field.waitPakinItem.anfme" />
                    <NumberField source="workQty" label="table.field.waitPakinItem.workQty" />
                    <TextField source="unit" label="table.field.waitPakinItem.unit" />
                    <TextField source="fieldsIndex" label="table.field.waitPakinItem.fieldsIndex" />
                    <NumberField source="qty" label="table.field.waitPakinItem.qty" />
                    <TextField source="batch" label="table.field.waitPakinItem.batch" />
                    <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>
            <WaitPakinItemCreate
                open={createDialog}
                setOpen={setCreateDialog}
            />
            <PageDrawer
                title='WaitPakinItem Detail'
                drawerVal={drawerVal}
                setDrawerVal={setDrawerVal}
            >
            </PageDrawer>
        </Box>
    )
}
export default WaitPakinItemList;