From 41a0c95f57dfce5373b1c16532451230882c0a5d Mon Sep 17 00:00:00 2001
From: skyouc
Date: 星期五, 13 六月 2025 12:41:30 +0800
Subject: [PATCH] 出库单据预览功能

---
 rsf-admin/src/page/orders/outStock/OutOrderPreview.jsx    |  139 ++++++++++++++++++++++++++++++++++
 rsf-admin/src/page/orders/outStock/OutStockSiteDialog.jsx |   54 +++++++++++++
 2 files changed, 193 insertions(+), 0 deletions(-)

diff --git a/rsf-admin/src/page/orders/outStock/OutOrderPreview.jsx b/rsf-admin/src/page/orders/outStock/OutOrderPreview.jsx
new file mode 100644
index 0000000..f8e91dc
--- /dev/null
+++ b/rsf-admin/src/page/orders/outStock/OutOrderPreview.jsx
@@ -0,0 +1,139 @@
+import { Dialog, DialogActions, DialogContent, DialogTitle, Box, LinearProgress, Grid, } from "@mui/material";
+import React, { useState, useRef, useEffect, useMemo, memo } from "react";
+import {
+    Toolbar,
+    Button,
+    useTranslate,
+    useNotify,
+    useRefresh,
+    useGetList,
+} from 'react-admin';
+import request from '@/utils/request';
+import { styled } from '@mui/material/styles';
+import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting';
+import { DataGrid, useGridApiContext, GridActionsCellItem, useGridApiRef } from '@mui/x-data-grid';
+import DialogCloseButton from "../../components/DialogCloseButton";
+
+
+const OutOrderPreview = (props) => {
+    const { open, setOpen, record, selectedIds } = props;
+    const translate = useTranslate();
+    const gridRef = useGridApiRef();
+    const [rows, setRows] = useState([]);
+    const notify = useNotify();
+    const refresh = useRefresh();
+    const handleClose = async (event, reason) => {
+        if (reason !== "backdropClick") {
+            // const res = await request.get(`/outStock/items/cancel/` + selectedIds);
+            setOpen(false);
+        }
+    };
+
+    if (!selectedIds) { return }
+
+    const { data, isLoading, error } = useGetList('/deliveryItem/edit', {
+        pagination: { page: 1, perPage: 1000 },
+        filter: { deleted: 0, ids: selectedIds }
+    });
+
+    return (
+        <Dialog
+            open={open}
+            onClose={handleClose}
+            aria-labelledby="form-dialog-title"
+            aria-hidden
+            fullWidth
+            maxWidth="lg"
+        >
+            <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>
+                <Grid container xl={12}>
+                    <Grid item xl={12}>
+                        <Box display="flex" sx={{ height: 400, width: '100%', '& .RaConfigurable-root': { width: '100%' } }}>
+                            <LinearProgress sx={{ height: "2px", position: 'absolute', top: 0, left: 0, right: 0, }} />
+                            <OrderPreview rows={data} gridRef={gridRef} />
+                        </Box >
+                    </Grid>
+                </Grid>
+                <Toolbar sx={{ justifyContent: 'end' }}>
+                    <ConfirmButton label="toolbar.confirm" variant="contained" size="large" gridRef={gridRef} setOpen={setOpen} />
+                </Toolbar>
+            </DialogContent>
+        </Dialog>
+    )
+}
+
+export default OutOrderPreview;
+
+const ConfirmButton = ({ gridRef, setOpen }) => {
+    const refresh = useRefresh();
+    const notify = useNotify();
+    const confirm = async () => {
+        const items = gridRef.current?.getSortedRows();
+        const { data: { code, msg } } = await request.post(`/outStock/generate/orders`, { ids: items });
+        if (code === 200) {
+            notify(msg);
+            refresh()
+            setOpen(false)
+        } else {
+            notify(msg);
+        }
+    }
+
+    return (
+        <Button label="toolbar.confirm" variant="contained" size="large" onClick={confirm} />
+    )
+}
+
+const OrderPreview = ({ rows, gridRef }) => {
+    gridRef.current = useGridApiRef();
+
+    const columns = [
+        { field: 'matnrCode', headerName: '鐗╂枡缂栫爜', width: 110 },
+        { field: 'maktx', headerName: '鐗╂枡鍚嶇О', width: 190 },
+        {
+            field: 'anfme', headerName: '鍑哄簱鏁伴噺', width: 110, type: 'number', editable: true,
+            valueGetter: (value, row) => {
+                return row.anfme - row.workQty - row.qty;
+            },
+        },
+        {
+            field: 'workQty', headerName: '鍓╀綑鏁伴噺', width: 110, type: 'number',
+            valueGetter: (value, row) => {
+                return row.anfme - row.workQty - row.qty;
+            },
+        },
+        { field: 'unit', headerName: '鍗曚綅', width: 110 },
+        { field: 'splrBatch', headerName: '鎵规', width: 110 },
+        { field: 'splrName', headerName: '渚涘簲鍟�', width: 110 },
+        { field: 'updateTime', headerName: '鏇存柊鏃堕棿', width: 110 },
+        { field: 'updateBy$', headerName: '鏇存柊浜哄憳', width: 110 },
+    ]
+
+    return (
+        <DataGrid
+            storeKey={"outOrderItemPreview"}
+            rows={rows}
+            columns={columns}
+            apiRef={gridRef}
+            disableRowSelectionOnClick
+            hideFooterPagination={true}  // 闅愯棌鍒嗛〉鎺т欢
+            hideFooter={true}
+            onRowSelectionModelChange={(ids) => {
+                setSelectedIds(ids)
+            }}
+        />
+    )
+}
+
+
diff --git a/rsf-admin/src/page/orders/outStock/OutStockSiteDialog.jsx b/rsf-admin/src/page/orders/outStock/OutStockSiteDialog.jsx
new file mode 100644
index 0000000..e0b0ced
--- /dev/null
+++ b/rsf-admin/src/page/orders/outStock/OutStockSiteDialog.jsx
@@ -0,0 +1,54 @@
+import { Box, Card, Grid, List, LinearProgress, Select, MenuItem, ListItemText, ListItemAvatar, Avatar, ListItemButton, Dialog, DialogTitle, ListItem } from "@mui/material";
+import React, { useState, useRef, useEffect, useMemo } from "react";
+import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE, DEFAULT_ITEM_PAGE_SIZE } from '@/config/setting';
+import { Delete, Edit, Add } from '@mui/icons-material';
+import request from '@/utils/request';
+import { useTranslate } from "react-admin";
+
+const OutStockSiteDialog = (props) => {
+    const translate = useTranslate();
+    const { onClose, selectedValue, open } = props;
+    const [siteNos, setSiteNos] = useState([]);
+
+    const handleClose = () => {
+        onClose(selectedValue);
+    }
+
+    const handleListItemClick = (value) => {
+        onClose(value);
+    }
+
+    useEffect(() => {
+        getSiteNos()
+    }, [open])
+
+
+    const getSiteNos = async () => {
+        const { data: { code, data, msg } } = await request.get('/outStock/tasks/sites');
+        if (code === 200) {
+            setSiteNos(data);
+        } else {
+            notify(msg);
+        }
+    }
+
+    return (
+        <Dialog
+            onClose={handleClose}
+            open={open}
+        >
+            <DialogTitle>{translate("toolbar.modiftySite")}</DialogTitle>
+            <List sx={{ pt: 0 }}>
+                {siteNos.map((site) => (
+                    <ListItem disableGutters key={site?.id}>
+                        <ListItemButton onClick={() => handleListItemClick(site)}>
+                            <ListItemText primary={site.site} />
+                        </ListItemButton>
+                    </ListItem>
+                ))}
+            </List>
+        </Dialog>
+    );
+}
+
+export default OutStockSiteDialog;
\ No newline at end of file

--
Gitblit v1.9.1