From d40c85778470a7e8341f0fae023c41dec981f384 Mon Sep 17 00:00:00 2001
From: skyouc
Date: 星期二, 13 五月 2025 20:41:25 +0800
Subject: [PATCH] 新增PO单生成收货单功能

---
 rsf-admin/src/page/orders/asnOrder/POItemModal.jsx |  405 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 405 insertions(+), 0 deletions(-)

diff --git a/rsf-admin/src/page/orders/asnOrder/POItemModal.jsx b/rsf-admin/src/page/orders/asnOrder/POItemModal.jsx
new file mode 100644
index 0000000..0e9ccc3
--- /dev/null
+++ b/rsf-admin/src/page/orders/asnOrder/POItemModal.jsx
@@ -0,0 +1,405 @@
+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,
+    Select,
+    MenuItem
+
+} from '@mui/material';
+import DialogCloseButton from "../../components/DialogCloseButton";
+import StatusSelectInput from "../../components/StatusSelectInput";
+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, GRID_DATE_COL_DEF, GRID_DATETIME_COL_DEF, getGridDateOperators, useGridApiContext } from '@mui/x-data-grid';
+import { LocalizationProvider, DatePicker, DateTimePicker } from '@mui/x-date-pickers';
+import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
+import DictionarySelect from "../../components/DictionarySelect";
+import DictSelect from "../../components/DictSelect";
+import "./asnOrder.css";
+import { 'zhCN' as locale } from 'date-fns/locale';
+import { format, } from 'date-fns';
+import { DemoContainer } from '@mui/x-date-pickers/internals/demo';
+
+const POItemModal = (props) => {
+    const { open, setOpen, billReload, record } = 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 && record !== 0) {
+            requestGetBody()
+        }
+        setDisabled(false)
+    }, [open])
+
+    const handleClose = (event, reason) => {
+        if (reason !== "backdropClick") {
+            setOpen(false);
+            refresh();
+            setTableData([])
+        }
+    };
+
+
+    const [tabelData, setTableData] = useState([]);
+
+    const resetData = () => {
+        setTableData([])
+    }
+
+    const setFinally = () => {
+        const rows = tableRef.current.state.editRows;
+        for (const key in rows) {
+            const find = tabelData.find(item => item.id === +key);
+            find.anfme = rows[key].anfme.value;
+        }
+        setTableData([...tabelData]);
+    }
+
+    const handleSubmit = async () => {
+        setFinally()
+        setDisabled(true)
+        setOpen(false)
+        const parmas = {
+            "purchaseId": record,
+            "items": tabelData,
+        }
+        console.log('--------->');
+        console.log(parmas);
+        // const res = await request.post(`/asnOrder/purchases/save`, parmas);
+        // if (res?.data?.code === 200) {
+        //     setOpen(false);
+        //     refresh();
+        //     resetData()
+        // } else {
+        //     notify(res.data.msg);
+        // }
+        setDisabled(false)
+    };
+
+    const requestGetBody = async () => {
+        const res = await request.post(`/purchaseItem/page`, { purchaseId: record });
+        if (res?.data?.code === 200) {
+            setTableData(res.data.data.records)
+        } else {
+            notify(res.data.msg);
+        }
+    }
+
+    const [selectedRows, setSelectedRows] = useState([]);
+
+    return (
+        <>
+            <Dialog
+                open={open}
+                onClose={handleClose}
+                aria-labelledby="form-dialog-title"
+                aria-hidden
+                fullWidth
+                disableRestoreFocus
+                maxWidth="xl"   // '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={{ mt: 2 }}>
+                        <AsnOrderModalTable tabelData={tabelData}
+                            setTableData={setTableData}
+                            record={record}
+                            selectedRows={selectedRows}
+                            setSelectedRows={setSelectedRows}
+                            tableRef={tableRef} />
+                    </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>
+        </>
+    )
+}
+
+export default POItemModal;
+
+const SelectInputSplrNameEditCell = (params) => {
+    const [formData, setFormData] = useState([{}])
+    useEffect(() => {
+        getOptions();
+    }, []);
+    const getOptions = async () => {
+        const parmas = {
+            "type": "supplier"
+        }
+        const {
+            data: { code, data, msg },
+        } = await request.post("companys/page", parmas);
+        if (code === 200) {
+            setFormData(data.records)
+        } else {
+            notify(msg);
+        }
+    }
+
+    return (
+        <Select
+            value={params.value}
+            onChange={(e) => {
+                params.api.setEditCellValue({
+                    id: params.id,
+                    field: params.field,
+                    value: e.target.value,
+                })
+                // 鎵惧埌閫変腑鐨勪緵搴斿晢璁板綍
+                const selectedSupplier = formData.find(supplier => supplier.name === e.target.value);
+
+                // 濡傛灉鎵惧埌瀵瑰簲鐨勪緵搴斿晢璁板綍锛屽悓鏃舵洿鏂皊plrCode瀛楁
+                if (selectedSupplier) {
+                    params.api.setEditCellValue({
+                        id: params.id,
+                        field: 'splrCode',
+                        value: selectedSupplier.id,
+                    });
+                }
+            }
+
+            }
+            fullWidth
+
+        >
+            {formData.map(e => {
+                return (
+                    <MenuItem value={e.name} children={e.name} key={e.id} />
+                );
+
+            })}
+
+        </Select>
+    );
+};
+
+const AsnOrderModalTable = ({ tabelData, setTableData, record, selectedRows, setSelectedRows, tableRef }) => {
+    const translate = useTranslate();
+    const notify = useNotify();
+
+    const [columns, setColumns] = useState([
+        {
+            field: 'matnrCode',
+            headerName: translate('table.field.asnOrderItem.matnrCode'),
+            width: 130,
+            editable: false,
+        },
+        {
+            field: 'matnrName',
+            headerName: translate('table.field.asnOrderItem.maktx'),
+            width: 250,
+            editable: false,
+        },
+        {
+            field: 'splrName',
+            headerName: translate('table.field.asnOrderItem.splrName') + "*",
+            minWidth: 150,
+            flex: 1,
+            editable: true,
+            renderEditCell: (params) => (
+                <SelectInputSplrNameEditCell {...params} />
+            ),
+            headerClassName: "custom",
+        },
+        {
+            field: 'platItemId',
+            headerName: translate('table.field.asnOrderItem.platItemId') + "*",
+            minWidth: 100,
+            flex: 1,
+            editable: true,
+            headerClassName: "custom",
+        },
+        {
+            field: 'anfme',
+            headerName: translate('table.field.asnOrderItem.anfme') + "*",
+            type: 'number',
+            minWidth: 100,
+            flex: 1,
+            editable: true,
+            valueFormatter: (val) => val < 0 ? 0 : val,
+            headerClassName: "custom",
+        },
+        {
+            field: 'unit',
+            headerName: translate('table.field.asnOrderItem.stockUnit'),
+            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,
+                valueGetter: (value, row) => {
+                    if (value != null && value != undefined) {
+                        return value;
+                    }
+                    if (row.extendFields == null || row.extendFields[el.fields] == null) {
+                        return ''
+                    } else {
+                        return `${row.extendFields[el.fields] == null ? '' : row.extendFields[el.fields]}`;
+                    }
+                },
+                headerName: el.fieldsAlise,
+                minWidth: 100,
+                flex: 1,
+                editable: true
+            }))
+            setColumns([...columns, ...cols, action])
+        } else {
+            notify(msg);
+        }
+    }
+
+    const handleDelete = (row) => {
+        const newData = _.filter(cdata.current, (item) => item.id !== row.id);
+        setTableData(newData);
+    };
+
+
+    const processRowUpdate = (newRow, oldRow) => {
+        const rows = tabelData.map((r) =>
+            r.id === newRow.id ? { ...newRow } : r
+        )
+        setTableData(rows)
+
+        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.id}
+                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>
+    );
+};
+

--
Gitblit v1.9.1