verou
2025-03-15 1e06ec3b91e1bca46f9f2a5b9718bbc346a30073
feat:新增asn单据
5个文件已修改
353 ■■■■■ 已修改文件
rsf-admin/.env 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/asnOrder/AsnOrderList.jsx 39 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/asnOrder/AsnOrderModal.jsx 281 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/asnOrder/AsnOrderPanel.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/asnOrder/AsnWareModal.jsx 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/.env
@@ -1,2 +1,3 @@
VITE_BASE_IP=47.76.147.249
VITE_BASE_IP=192.168.4.24
# VITE_BASE_IP=47.76.147.249
VITE_BASE_PORT=8080
rsf-admin/src/page/asnOrder/AsnOrderList.jsx
@@ -49,6 +49,7 @@
import EditIcon from '@mui/icons-material/Edit';
const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({
  '& .css-1vooibu-MuiSvgIcon-root': {
    height: '.9em'
@@ -99,11 +100,13 @@
  const [createDialog, setCreateDialog] = useState(false);
  const [drawerVal, setDrawerVal] = useState(false);
  const [modalType, setmodalType] = useState(0);
  const navigate = useNavigate();
  const assign = (record) => {
    navigate(`/asnOrderItem?asnId=${record.id}`);
  };
  const inspection = () => { };
  const print = () => { };
@@ -121,7 +124,7 @@
          marginRight: drawerVal ? `${PAGE_DRAWER_WIDTH}px` : 0,
        }}
        title={"menu.asnOrder"}
        empty={<EmptyData onClick={() => { setCreateDialog(true) }} />}
        empty={<EmptyData onClick={() => { setCreateDialog(true); setmodalType(0) }} />}
        filters={filters}
        sort={{ field: "create_time", order: "desc" }}
        actions={(
@@ -131,7 +134,7 @@
              <ConstructionIcon />
            </Button>
            <FilterButton />
            <MyCreateButton onClick={() => { setCreateDialog(true) }} />
            <MyCreateButton onClick={() => { setCreateDialog(true); setmodalType(0) }} />
            <SelectColumnsButton preferenceKey='asnOrder' />
            <MyExportButton />
@@ -143,7 +146,7 @@
          preferenceKey='asnOrder'
          bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />}
          rowClick={(id, resource, record) => false}
          expand={() => <AsnOrderPanel />}
          expand={(e) => <AsnOrderPanel key={Math.floor(Math.random() * 100)} />}
          expandSingle={true}
          omit={['id', 'createTime', 'createBy', 'memo']}
        >
@@ -176,19 +179,20 @@
          <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">
          <WrapperField cellClassName="opt" label="common.field.opt" >
            <Button label="toolbar.print" onClick={print}>
              <FileDownloadIcon />
            </Button>
            {/* <EditButton sx={{ padding: '1px', fontSize: '.75rem' }} /> */}
            <Button
            <MyButton setCreateDialog={setCreateDialog} setmodalType={setmodalType} />
            {/* <Button
              color="primary"
              startIcon={<EditIcon />}
              onClick={() => { setCreateDialog(true) }}
              onClick={(event, record) => handleEditClick(record)}
              sx={{ ml: 1 }}
              label={'ra.action.edit'}
            >
            </Button>
            </Button> */}
            <DeleteButton sx={{ padding: '1px', fontSize: '.75rem' }} mutationMode={OPERATE_MODE} />
          </WrapperField>
        </StyledDatagrid>
@@ -196,6 +200,7 @@
      <AsnOrderModal
        open={createDialog}
        setOpen={setCreateDialog}
        asnId={modalType}
      />
      <PageDrawer
        title='AsnOrder Detail'
@@ -207,3 +212,23 @@
  )
}
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>
  )
}
rsf-admin/src/page/asnOrder/AsnOrderModal.jsx
@@ -17,6 +17,7 @@
    useNotify,
    Form,
    useCreateController,
    useListContext,
    useRefresh,
} from 'react-admin';
import {
@@ -36,6 +37,8 @@
    TableBody,
    TableRow,
    TableCell,
    Tooltip,
    IconButton,
    styled
@@ -47,25 +50,38 @@
import { useForm, Controller, useWatch, FormProvider, useFormContext } from "react-hook-form";
import SaveIcon from '@mui/icons-material/Save';
import request from '@/utils/request';
import { Add, Edit, Delete } from '@mui/icons-material';
import _ from 'lodash';
import { DataGrid } from '@mui/x-data-grid';
const AsnOrderModal = (props) => {
    const { open, setOpen } = props;
    const { open, setOpen, asnId } = props;
    const translate = useTranslate();
    const notify = useNotify();
    const refresh = useRefresh();
    const [createDialog, setCreateDialog] = useState(false);
    const asnId = ''
    useEffect(() => {
        if (open && asnId !== 0) {
            requestGetHead()
            requestGetBody()
        }
    }, [open])
    const handleClose = (event, reason) => {
        if (reason !== "backdropClick") {
            setOpen(false);
            refresh();
            setFormData({ type: '' })
            setTableData([])
        }
    };
    const [formData, setFormData] = useState({
        type: '',
        wkType: ''
    });
    const [tabelData, setTableData] = useState([]);
@@ -78,20 +94,48 @@
        }));
    };
    const handleSubmit = () => {
        console.log(formData);
    const handleSubmit = async () => {
        const parmas = {
            "orders": formData,
            "items": tabelData,
        }
        const res = await request.post(`/asnOrder/items/save`, parmas);
        if (res?.data?.code === 200) {
            setOpen(false);
        } else {
            notify(res.data.msg);
        }
    };
    const handleDelete = async () => {
        const res = await request.post(`/asnOrder/remove/${asnId}`, {});
        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);
        }
    }
    return (
@@ -100,6 +144,7 @@
                open={open}
                onClose={handleClose}
                aria-labelledby="form-dialog-title"
                aria-hidden
                fullWidth
                disableRestoreFocus
                maxWidth="md"   // 'xs' | 'sm' | 'md' | 'lg' | 'xl'
@@ -116,20 +161,22 @@
                    </Box>
                </DialogTitle>
                <DialogContent sx={{ mt: 2 }}>
                    <Box component="form" onSubmit={handleSubmit} sx={{ display: 'flex', flexDirection: 'column', gap: 3 }}>
                        <Grid container spacing={2}>
                            <Grid item xs={4}>
                                <TextField
                                    label={translate('table.field.asnOrder.type')}
                                    name="type"
                                    value={formData.type}
                                    onChange={handleChange}
                                    variant="outlined"
                                    size="small"
                                />
                            </Grid>
                    <Box component="form" sx={{ display: 'flex', flexDirection: 'column', gap: 3 }}>
                        <form>
                            <Grid container spacing={2}>
                                <Grid item xs={4}>
                                    <TextField
                                        label={translate('table.field.asnOrder.type')}
                                        name="type"
                                        value={formData.type}
                                        onChange={handleChange}
                                        variant="outlined"
                                        size="small"
                                        validate={required()}
                                    />
                                </Grid>
                            <Grid item xs={4}>
                                {/* <Grid item xs={4}>
                                <TextField
                                    label={translate('table.field.asnOrder.wkType')}
                                    name="wkType"
@@ -138,8 +185,9 @@
                                    variant="outlined"
                                    size="small"
                                />
                            </Grid> */}
                            </Grid>
                        </Grid>
                        </form>
                    </Box>
                    <Box sx={{ mt: 2 }}>
@@ -178,137 +226,150 @@
const AsnOrderModalTable = ({ tabelData, setTableData }) => {
    const translate = useTranslate();
    const notify = useNotify();
    const refresh = useRefresh();
    const columns = [
        {
            id: 'matnrId',
            label: 'table.field.asnOrderItem.matnrId',
            field: 'action',
            headerName: '操作',
            minWidth: 100,
            sticky: 'right',
            flex: 1,
            renderCell: (params) => (
                <Tooltip title="Delete">
                    <IconButton onClick={() => handleDelete(params.row)}>
                        <Delete />
                    </IconButton>
                </Tooltip>
            ),
        },
        {
            id: 'matnk',
            label: 'table.field.asnOrderItem.matnk',
            field: 'matnrId',
            headerName: translate('table.field.asnOrderItem.matnrId'),
            minWidth: 100,
            flex: 1,
            editable: false, // 假设 matnrId 不可编辑
        },
        {
            id: 'poDetlId',
            label: 'table.field.asnOrderItem.poDetlId',
            field: 'matnk',
            headerName: translate('table.field.asnOrderItem.matnk'),
            minWidth: 100,
            flex: 1,
            editable: true,
        },
        {
            id: 'poDetlCode',
            label: 'table.field.asnOrderItem.poDetlCode',
            field: 'poDetlId',
            headerName: translate('table.field.asnOrderItem.poDetlId'),
            minWidth: 100,
            flex: 1,
            editable: true,
        },
        {
            id: 'anfme',
            label: 'table.field.asnOrderItem.anfme',
            field: 'poDetlCode',
            headerName: translate('table.field.asnOrderItem.poDetlCode'),
            minWidth: 100,
            flex: 1,
            editable: true,
        },
        {
            id: 'stockUnit',
            label: 'table.field.asnOrderItem.stockUnit',
            field: 'anfme',
            headerName: translate('table.field.asnOrderItem.anfme'),
            minWidth: 100,
            flex: 1,
            editable: true,
        },
        {
            id: 'purQty',
            label: 'table.field.asnOrderItem.purQty',
            field: 'stockUnit',
            headerName: translate('table.field.asnOrderItem.stockUnit'),
            minWidth: 100,
            flex: 1,
            editable: true,
        },
        {
            id: 'purUnit',
            label: 'table.field.asnOrderItem.purUnit',
            field: 'purQty',
            headerName: translate('table.field.asnOrderItem.purQty'),
            minWidth: 100,
            flex: 1,
            editable: true,
        },
        {
            id: 'splrCode',
            label: 'table.field.asnOrderItem.splrCode',
            field: 'purUnit',
            headerName: translate('table.field.asnOrderItem.purUnit'),
            minWidth: 100,
            flex: 1,
            editable: true,
        },
        {
            id: 'splrName',
            label: 'table.field.asnOrderItem.splrName',
            field: 'splrCode',
            headerName: translate('table.field.asnOrderItem.splrCode'),
            minWidth: 100,
            flex: 1,
            editable: true,
        },
        {
            id: 'qrcode',
            label: 'table.field.asnOrderItem.qrcode',
            field: 'splrName',
            headerName: translate('table.field.asnOrderItem.splrName'),
            minWidth: 100,
            flex: 1,
            editable: true,
        },
        {
            id: 'barcode',
            label: 'table.field.asnOrderItem.barcode',
            field: 'qrcode',
            headerName: translate('table.field.asnOrderItem.qrcode'),
            minWidth: 100,
            flex: 1,
            editable: true,
        },
        {
            id: 'packName',
            label: 'table.field.asnOrderItem.packName',
            field: 'barcode',
            headerName: translate('table.field.asnOrderItem.barcode'),
            minWidth: 100,
        }]
            flex: 1,
            editable: true,
        },
        {
            field: 'packName',
            headerName: translate('table.field.asnOrderItem.packName'),
            minWidth: 100,
            flex: 1,
            editable: true,
        },
    const StyledTableRow = styled(TableRow)(({ theme }) => ({
        "& .MuiButtonBase-root.": {
            padding: "0px 0px",
        },
    }));
    ];
    const StyledTableCell = styled(TableCell)(({ theme }) => ({
        "& .MuiButtonBase-root": {
            padding: "0px 0px",
        },
        overflow: "hidden",
        textOverflow: "ellipsis",
        whiteSpace: "nowrap",
        maxWidth: 600,
    }));
    const handleDelete = (row) => {
        const newData = _.filter(tabelData, (item) => item.matnrId !== row.matnrId);
        setTableData(newData);
    };
    const handleEdit = (field, row, value) => {
        setTableData((prevData) =>
            prevData.map((r) =>
                r.matnrId === row.matnrId ? { ...r, [field]: value } : r
            )
        );
    };
    const processRowUpdate = (newRow, oldRow) => {
        const field = Object.keys(newRow).find((key) => newRow[key] !== oldRow[key]);
        handleEdit(field, oldRow, newRow[field]);
        return newRow;
    };
    return (
        <TableContainer component={Paper} >
            <Table size="small" >
                <TableHead>
                    <StyledTableRow key={'head'}>
                        {columns.map((column) => {
                            const value = column.label;
                            return (
                                <StyledTableCell
                                    key={column.id}
                                    align={column.align || "left"}
                                >
                                    {column.format ? column.format(value) : translate(value)}
                                </StyledTableCell>
                            );
        <div style={{ height: 400, width: '100%' }}>
            <DataGrid
                rows={tabelData}
                columns={columns}
                disableRowSelectionOnClick
                getRowId={(row) => row.matnrId}
                disableColumnFilter
                disableColumnSelector
                disableColumnSorting
                disableMultipleColumnsSorting
                processRowUpdate={processRowUpdate}
            />
        </div>
    );
};
                        })}
                    </StyledTableRow>
                </TableHead>
                <TableBody>
                    {tabelData.map((row) => (
                        <StyledTableRow key={row.id || Math.random()}>
                            {columns.map((column) => (
                                <StyledTableCell key={column.id} >
                                    <TextField
                                        key={row.id}
                                        value={row[column.id]}
                                        variant="outlined"
                                        size="small"
                                        sx={{
                                            padding: '2px', '& .MuiOutlinedInput-input': {
                                                padding: '2px 5px',
                                                minWidth: '50px',
                                            }
                                        }}
                                    />
                                </StyledTableCell>
                            ))}
                        </StyledTableRow>
                    ))}
                </TableBody>
            </Table>
        </TableContainer>
    )
}
rsf-admin/src/page/asnOrder/AsnOrderPanel.jsx
@@ -160,7 +160,7 @@
                    <TableBody>
                        {rows.map((row) => (
                            <StyledTableRow key={row.id || Math.random()}>
                            <StyledTableRow key={row.id + Math.random()}>
                                {columns.map((column) => (
                                    <StyledTableCell key={column.id} >
                                        {row[column.id]}
rsf-admin/src/page/asnOrder/AsnWareModal.jsx
@@ -50,15 +50,25 @@
    };
    const handleSubmit = () => {
        setOpen(false);
        refresh();
        const selectedData = selectedRows.map(id => tableData.find(row => row.id === id));
        setData(selectedData);
        const value = selectedData.map((el => {
            return {
                matnrId: el.id,
                matnk: el.name,
                stockUnit: el.stockUnit || '',
                purUnit: el.purchaseUnit || '',
            }
        }))
        setData(value);
        setOpen(false);
        // refresh();
    };
    const getData = async () => {
        const res = await request.post(`/matnr/page`, {
            pageSize: 99
            ...formData,
            pageSize: 199
        });
        if (res?.data?.code === 200) {
            setTableData(res.data.data.records);
@@ -72,7 +82,7 @@
    }, []);
    const handleSearch = () => {
        // 这里可以添加搜索逻辑
        getData()
    };
    return (
@@ -165,10 +175,8 @@
    ];
    const handleSelectionChange = (ids) => {
        const selectedData = ids.map((id) => tableData.find((row) => row.id === id));
        // setSelectedRows(selectedData);
        // setSelectedRows(ids);
        console.log(selectedData)
        setSelectedRows(ids)
    };
    return (
@@ -183,7 +191,7 @@
                disableColumnMenu={true}
                disableColumnSorting
                disableMultipleColumnsSorting
                autoPageSize
                columnBufferPx={100}
            />
        </div>
    );