From 27f59f44345d044967e2048f09dbd704f90ce3db Mon Sep 17 00:00:00 2001
From: skyouc
Date: 星期五, 25 四月 2025 17:51:20 +0800
Subject: [PATCH] #新增  1. 新增波次功能  2. 库区新增优化

---
 rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/OutStockServiceImpl.java |  103 ++
 rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/WaveItem.java                  |    8 
 rsf-admin/src/page/orders/wave/WaveList.jsx                                                   |   70 +
 rsf-admin/src/page/orders/wave/index.jsx                                                      |    0 
 rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/WarehouseAreas.java            |   27 
 rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/OutStockController.java    |    5 
 rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/DeviceBind.java                |   22 
 rsf-server/src/main/java/com/vincent/rsf/server/common/CodeBuilder.java                       |   12 
 rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/AsnOrderItem.java              |    3 
 rsf-admin/src/page/orders/wave/WaveItemEdit.jsx                                               |  196 +++++++
 rsf-server/src/main/java/com/vincent/rsf/server/manager/utils/GroupMergeUtil.java             |  154 +++++
 rsf-server/src/main/java/com/vincent/rsf/server/manager/service/WaveService.java              |   11 
 rsf-admin/src/page/orders/wave/WaveCreate.jsx                                                 |    6 
 rsf-admin/src/page/warehouseAreas/WarehouseAreasEdit.jsx                                      |   30 
 rsf-admin/src/i18n/zh.js                                                                      |   27 +
 rsf-admin/src/page/orders/outStock/OutOrderList.jsx                                           |   32 
 rsf-admin/src/i18n/en.js                                                                      |   26 
 rsf-admin/src/page/ResourceContent.js                                                         |    4 
 rsf-admin/src/page/orders/wave/WavePanel.jsx                                                  |    2 
 rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/WaveController.java        |   13 
 rsf-admin/src/page/orders/wave/WaveEdit.jsx                                                   |  145 +++++
 rsf-server/src/main/java/com/vincent/rsf/server/system/constant/DictTypeCode.java             |    5 
 rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/WaveServiceImpl.java     |   52 +
 rsf-admin/src/page/warehouseAreas/WarehouseAreasCreate.jsx                                    |   36 
 rsf-admin/src/page/warehouseAreas/WarehouseAreasList.jsx                                      |    4 
 /dev/null                                                                                     |  130 ----
 rsf-admin/src/page/orders/wave/WaveItemList.jsx                                               |  190 +++++++
 rsf-server/src/main/java/com/vincent/rsf/server/manager/enums/AsnExceStatus.java              |   18 
 rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/DeliveryItem.java              |   25 
 rsf-admin/src/page/orders/wave/WaveItemCreate.jsx                                             |  204 +++++++
 rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/DeviceBindController.java  |   12 
 31 files changed, 1,295 insertions(+), 277 deletions(-)

diff --git a/rsf-admin/src/i18n/en.js b/rsf-admin/src/i18n/en.js
index d81da4f..bdd97fd 100644
--- a/rsf-admin/src/i18n/en.js
+++ b/rsf-admin/src/i18n/en.js
@@ -177,6 +177,8 @@
         inStockPoces: 'In Stock Pocess',
         outStockPoces: 'Out Stock Pocess',
         deviceBind: 'Device Bind',
+        wave: 'Wave Manage',
+
     },
     table: {
         field: {
@@ -720,6 +722,30 @@
                 qty: "qty",
                 batch: "batch",
             },
+            wave: {
+                code: "code",
+                type: "type",
+                exceStatus: "exceStatus",
+                anfme: "anfme",
+                qty: "qty",
+                orderNum: "orderNum",
+            },
+            waveItem: {
+                waveId: "waveId",
+                waveCode: "waveCode",
+                matnrId: "matnrId",
+                matnrName: "matnrName",
+                matnrCode: "matnrCode",
+                batch: "batch",
+                splrBatch: "splrBatch",
+                orderCode: "orderCode",
+                orderItemId: "orderItemId",
+                unit: "unit",
+                trackCode: "trackCode",
+                fieldsIndex: "fieldsIndex",
+                anfme: "anfme",
+                workQty: "workQty",
+            },
             task: {
                 taskCode: "TaskCode",
                 taskStatus: "Status",
diff --git a/rsf-admin/src/i18n/zh.js b/rsf-admin/src/i18n/zh.js
index 82b5bb0..32dc27a 100644
--- a/rsf-admin/src/i18n/zh.js
+++ b/rsf-admin/src/i18n/zh.js
@@ -178,6 +178,8 @@
         inStockPoces: '鍏ュ簱娴佺▼',
         outStockPoces: '鍑哄簱娴佺▼',
         deviceBind: '璁惧缁戝畾',
+        wave: '娉㈡绠$悊',
+
     },
     table: {
         field: {
@@ -333,6 +335,7 @@
             warehouseAreas: {
                 uuid: "鍞竴缂栫爜",
                 name: "搴撳尯鍚嶇О",
+                type: "搴撳尯绫诲瀷",
                 wareId: "鎵�灞炰粨搴�",
                 code: "搴撳尯缂栫爜",
                 shipperId: "璐т富",
@@ -765,6 +768,30 @@
                 qty: "宸插畬鎴�",
                 batch: "鎵规",
             },
+            wave: {
+                code: "娉㈡鍙�",
+                type: "鍗曟嵁绫诲瀷",
+                exceStatus: "鐘舵��",
+                anfme: "鏁伴噺",
+                qty: "瀹屾垚鏁伴噺",
+                orderNum: "鍗曟嵁鏁�",
+            },
+            waveItem: {
+                waveId: "娉㈡ID",
+                waveCode: "娉㈡鍙�",
+                matnrId: "鐗╂枡ID",
+                matnrName: "鐗╂枡鍚嶇О",
+                matnrCode: "鐗╂枡缂栫爜",
+                batch: "鎵规",
+                splrBatch: "渚涘簲鍟嗘壒娆�",
+                orderCode: "婧愬崟鍙�",
+                orderItemId: "婧愬崟鏄庣粏ID",
+                unit: "鍗曚綅",
+                trackCode: "璺熻釜鐮�",
+                fieldsIndex: "鍔ㄦ�佹墿灞�",
+                anfme: "鏁伴噺",
+                workQty: "鎵ц鏁�",
+            },
             task: {
                 taskCode: "浠诲姟鍙�",
                 taskStatus: "鐘舵��",
diff --git a/rsf-admin/src/page/ResourceContent.js b/rsf-admin/src/page/ResourceContent.js
index b3271cf..c44aba5 100644
--- a/rsf-admin/src/page/ResourceContent.js
+++ b/rsf-admin/src/page/ResourceContent.js
@@ -44,6 +44,7 @@
 import delivery from './orders/delivery';
 import outStock from './orders/outStock';
 import deviceBind from './deviceBind';
+import wave from './orders/wave';
 
 
 const ResourceContent = (node) => {
@@ -128,6 +129,9 @@
             return outStock;
         case 'deviceBind':
             return deviceBind;
+        case 'wave':
+            return wave;
+
         default:
             return {
                 list: ListGuesser,
diff --git a/rsf-admin/src/page/orders/outStock/OutOrderList.jsx b/rsf-admin/src/page/orders/outStock/OutOrderList.jsx
index 58bb153..23ed27e 100644
--- a/rsf-admin/src/page/orders/outStock/OutOrderList.jsx
+++ b/rsf-admin/src/page/orders/outStock/OutOrderList.jsx
@@ -151,12 +151,7 @@
           sx={{ width: '100%' }}
           preferenceKey='outStock'
           bulkActionButtons={
-            <>
-              <PublicTaskButton />
-              <MyExportButton />
-              <BulkDeleteButton mutationMode={OPERATE_MODE}
-              />
-            </>}
+            <PublicTaskButton />}
           rowClick={false}
           expandSingle={true}
           omit={['id', 'createTime', 'createBy', 'memo', 'poId', 'rleStatus$']}
@@ -179,8 +174,7 @@
           <TextField source="memo" label="common.field.memo" sortable={false} />
           <WrapperField cellClassName="opt" label="common.field.opt" >
             <EditButton label="toolbar.detail" icon={(<DetailsIcon />)}></EditButton>
-            {/* <MyButton setCreateDialog={setCreateDialog} setmodalType={setmodalType} /> */}
-            <CancelButton></CancelButton>
+            <CancelButton />
           </WrapperField>
         </StyledDatagrid>
       </List>
@@ -207,11 +201,21 @@
 const PublicTaskButton = () => {
   const record = useRecordContext();
   const { selectedIds, onUnselectItems } = useListContext();
+  const notify = useNotify();
+  const refresh = useRefresh();
+  const redirect = useRedirect();
 
-  const pubClick = (event) => {
+  const pubClick = async (event) => {
     event.stopPropagation();
     onUnselectItems();
-
+    const res = await request.post(`/outStock/generate/wave`, { ids: selectedIds });
+    if (res?.data?.code === 200) {
+      notify(res.data.msg);
+      redirect("/wave")
+    } else {
+      notify(res.data.msg);
+    }
+    refresh();
   }
 
   return (
@@ -248,16 +252,8 @@
   const refresh = useRefresh();
 
   const createByOrder = async (event) => {
-    const {selectedIds, onUnselectItems} = useListContext();
     event.stopPropagation();
     setCreateDialog(true);
-    const res = await request.post(`/outStock/generate/wave`, { ids: selectedIds });
-    if (res?.data?.code === 200) {
-      notify(res.data.msg);
-    } else {
-      notify(res.data.msg);
-    }
-
   }
 
   return (
diff --git a/rsf-admin/src/page/wave/WaveCreate.jsx b/rsf-admin/src/page/orders/wave/WaveCreate.jsx
similarity index 96%
rename from rsf-admin/src/page/wave/WaveCreate.jsx
rename to rsf-admin/src/page/orders/wave/WaveCreate.jsx
index ad26794..0da4e8c 100644
--- a/rsf-admin/src/page/wave/WaveCreate.jsx
+++ b/rsf-admin/src/page/orders/wave/WaveCreate.jsx
@@ -27,9 +27,9 @@
     Grid,
     Box,
 } from '@mui/material';
-import DialogCloseButton from "../components/DialogCloseButton";
-import StatusSelectInput from "../components/StatusSelectInput";
-import MemoInput from "../components/MemoInput";
+import DialogCloseButton from "../../components/DialogCloseButton";
+import StatusSelectInput from "../../components/StatusSelectInput";
+import MemoInput from "../../components/MemoInput";
 
 const WaveCreate = (props) => {
     const { open, setOpen } = props;
diff --git a/rsf-admin/src/page/orders/wave/WaveEdit.jsx b/rsf-admin/src/page/orders/wave/WaveEdit.jsx
new file mode 100644
index 0000000..899a39f
--- /dev/null
+++ b/rsf-admin/src/page/orders/wave/WaveEdit.jsx
@@ -0,0 +1,145 @@
+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";
+import WaveItemList from "./WaveItemList";
+
+const FormToolbar = () => {
+    const { getValues } = useFormContext();
+
+    return (
+        <Toolbar sx={{ justifyContent: 'space-between' }}>
+            <SaveButton />
+            <DeleteButton mutationMode="optimistic" />
+        </Toolbar>
+    )
+}
+
+const WaveEdit = () => {
+    const translate = useTranslate();
+
+    return (
+        <Box>
+            <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: '100%' }} rowSpacing={3} columnSpacing={3}>
+                        <Grid item xs={16} md={10} sx={{
+                            "& .MuiFormLabel-root.MuiInputLabel-root.Mui-disabled": {
+                                bgcolor: 'white',
+                                WebkitTextFillColor: "rgba(0, 0, 0)"
+                            },
+
+                            "& .MuiInputBase-input.MuiFilledInput-input.Mui-disabled": {
+                                bgcolor: 'white',
+                                WebkitTextFillColor: "rgba(0, 0, 0)"
+                            },
+                            "& .MuiFilledInput-root.MuiInputBase-sizeSmall": {
+                                bgcolor: 'white',
+                            }
+                        }}>
+                            <Typography variant="h6" gutterBottom>
+                                {translate('common.edit.title.main')}
+                            </Typography>
+                            <Stack direction='row' gap={2}>
+                                <TextInput
+                                    label="table.field.wave.code"
+                                    source="code"
+                                    parse={v => v}
+                                    readOnly
+                                />
+                                <SelectInput
+                                    label="table.field.wave.type"
+                                    source="type"
+                                    readOnly
+                                    choices={[
+                                        { id: 0, name: '鎵嬪姩' },
+                                        { id: 1, name: '鑷姩' },
+                                    ]}
+                                    
+                                />
+                                <SelectInput
+                                    label="table.field.wave.exceStatus"
+                                    source="exceStatus"
+                                    readOnly
+                                    choices={[
+                                        { id: 0, name: '鍒濆鍖�' },
+                                        { id: 1, name: '鐢熸垚浠诲姟' },
+                                        { id: 2, name: '浠诲姟鎾' },
+                                        { id: 3, name: '瀹屾垚' },
+                                    ]}
+                                />
+                            </Stack>
+                            <Stack direction='row' gap={2}>
+                                <NumberInput
+                                    label="table.field.wave.anfme"
+                                    readOnly
+                                    source="anfme"
+                                />
+                                <NumberInput
+                                    label="table.field.wave.qty"
+                                    readOnly
+                                    source="qty"
+                                />
+                                <NumberInput
+                                    label="table.field.wave.orderNum"
+                                    readOnly
+                                    source="orderNum"
+                                />
+                            </Stack>
+
+                        </Grid>
+                        <Grid item xs={8} md={2}>
+                            <Typography variant="h6" gutterBottom>
+                                {translate('common.edit.title.common')}
+                            </Typography>
+                            <StatusSelectInput />
+                            <Box mt="2em" />
+                            <MemoInput />
+                        </Grid>
+                    </Grid>
+                </SimpleForm>
+            </Edit >
+            <WaveItemList />
+        </Box>
+    )
+}
+
+export default WaveEdit;
diff --git a/rsf-admin/src/page/orders/wave/WaveItemCreate.jsx b/rsf-admin/src/page/orders/wave/WaveItemCreate.jsx
new file mode 100644
index 0000000..a23e2c7
--- /dev/null
+++ b/rsf-admin/src/page/orders/wave/WaveItemCreate.jsx
@@ -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 WaveItemCreate = (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.waveItem.waveId"
+                                        source="waveId"
+                                        autoFocus
+                                    />
+                                </Grid>
+                                <Grid item xs={6} display="flex" gap={1}>
+                                    <TextInput
+                                        label="table.field.waveItem.waveCode"
+                                        source="waveCode"
+                                        parse={v => v}
+                                    />
+                                </Grid>
+                                <Grid item xs={6} display="flex" gap={1}>
+                                    <NumberInput
+                                        label="table.field.waveItem.matnrId"
+                                        source="matnrId"
+                                    />
+                                </Grid>
+                                <Grid item xs={6} display="flex" gap={1}>
+                                    <TextInput
+                                        label="table.field.waveItem.matnrName"
+                                        source="matnrName"
+                                        parse={v => v}
+                                    />
+                                </Grid>
+                                <Grid item xs={6} display="flex" gap={1}>
+                                    <TextInput
+                                        label="table.field.waveItem.matnrCode"
+                                        source="matnrCode"
+                                        parse={v => v}
+                                    />
+                                </Grid>
+                                <Grid item xs={6} display="flex" gap={1}>
+                                    <TextInput
+                                        label="table.field.waveItem.batch"
+                                        source="batch"
+                                        parse={v => v}
+                                    />
+                                </Grid>
+                                <Grid item xs={6} display="flex" gap={1}>
+                                    <TextInput
+                                        label="table.field.waveItem.splrBatch"
+                                        source="splrBatch"
+                                        parse={v => v}
+                                    />
+                                </Grid>
+                                <Grid item xs={6} display="flex" gap={1}>
+                                    <TextInput
+                                        label="table.field.waveItem.orderCode"
+                                        source="orderCode"
+                                        parse={v => v}
+                                    />
+                                </Grid>
+                                <Grid item xs={6} display="flex" gap={1}>
+                                    <NumberInput
+                                        label="table.field.waveItem.orderItemId"
+                                        source="orderItemId"
+                                    />
+                                </Grid>
+                                <Grid item xs={6} display="flex" gap={1}>
+                                    <TextInput
+                                        label="table.field.waveItem.unit"
+                                        source="unit"
+                                        parse={v => v}
+                                    />
+                                </Grid>
+                                <Grid item xs={6} display="flex" gap={1}>
+                                    <TextInput
+                                        label="table.field.waveItem.trackCode"
+                                        source="trackCode"
+                                        parse={v => v}
+                                    />
+                                </Grid>
+                                <Grid item xs={6} display="flex" gap={1}>
+                                    <TextInput
+                                        label="table.field.waveItem.fieldsIndex"
+                                        source="fieldsIndex"
+                                        parse={v => v}
+                                    />
+                                </Grid>
+                                <Grid item xs={6} display="flex" gap={1}>
+                                    <NumberInput
+                                        label="table.field.waveItem.anfme"
+                                        source="anfme"
+                                    />
+                                </Grid>
+                                <Grid item xs={6} display="flex" gap={1}>
+                                    <NumberInput
+                                        label="table.field.waveItem.workQty"
+                                        source="workQty"
+                                    />
+                                </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 WaveItemCreate;
diff --git a/rsf-admin/src/page/orders/wave/WaveItemEdit.jsx b/rsf-admin/src/page/orders/wave/WaveItemEdit.jsx
new file mode 100644
index 0000000..8e76025
--- /dev/null
+++ b/rsf-admin/src/page/orders/wave/WaveItemEdit.jsx
@@ -0,0 +1,196 @@
+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,
+    useGetOne,
+    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 WaveItemEdit = (props) => {
+    const { open, setOpen, record } = props;
+    const translate = useTranslate();
+    const handleClose = (event, reason) => {
+        if (reason !== "backdropClick") {
+            setOpen(false);
+        }
+    };
+    const { data, isPending, } = useGetOne('waveItem', { id: record?.id });
+    if (data == null || data == undefined) { return }
+
+    return (
+        <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 }}>
+                <EditBase
+                    id={record?.id}
+                    resource="waveItem"
+                    mutationMode={EDIT_MODE}
+                    actions={<CustomerTopToolBar />}
+                >
+                    <Form
+                        shouldUnregister
+                        warnWhenUnsavedChanges
+                        mode="onTouched"
+                        defaultValues={{}}
+                    >
+                        <Grid container width={{ xs: '100%', xl: '100%' }} rowSpacing={3} columnSpacing={3}>
+                            <Grid item xs={16} md={10}>
+                                <Typography variant="h6" gutterBottom>
+                                    {translate('common.edit.title.main')}
+                                </Typography>
+                                <Stack direction='row' gap={2}>
+                                    <NumberInput
+                                        label="table.field.waveItem.waveId"
+                                        source="waveId"
+                                        autoFocus
+                                    />
+                                    <TextInput
+                                        label="table.field.waveItem.waveCode"
+                                        source="waveCode"
+                                        parse={v => v}
+                                    />
+                                    <NumberInput
+                                        label="table.field.waveItem.matnrId"
+                                        source="matnrId"
+                                    />
+                                    <TextInput
+                                        label="table.field.waveItem.matnrName"
+                                        source="matnrName"
+                                        parse={v => v}
+                                    />
+                                </Stack>
+                                <Stack direction='row' gap={2}>
+                                    <TextInput
+                                        label="table.field.waveItem.matnrCode"
+                                        source="matnrCode"
+                                        parse={v => v}
+                                    />
+                                    <TextInput
+                                        label="table.field.waveItem.batch"
+                                        source="batch"
+                                        parse={v => v}
+                                    />
+                                    <TextInput
+                                        label="table.field.waveItem.splrBatch"
+                                        source="splrBatch"
+                                        parse={v => v}
+                                    />
+                                    <TextInput
+                                        label="table.field.waveItem.orderCode"
+                                        source="orderCode"
+                                        parse={v => v}
+                                    />
+                                </Stack>
+                                <Stack direction='row' gap={2}>
+                                    <NumberInput
+                                        label="table.field.waveItem.orderItemId"
+                                        source="orderItemId"
+                                    />
+
+                                    <TextInput
+                                        label="table.field.waveItem.unit"
+                                        source="unit"
+                                        parse={v => v}
+                                    />
+                                    <TextInput
+                                        label="table.field.waveItem.trackCode"
+                                        source="trackCode"
+                                        parse={v => v}
+                                    />
+                                    <TextInput
+                                        label="table.field.waveItem.fieldsIndex"
+                                        source="fieldsIndex"
+                                        parse={v => v}
+                                    />
+                                </Stack>
+                                <Stack direction='row' gap={2}>
+                                    <NumberInput
+                                        label="table.field.waveItem.anfme"
+                                        source="anfme"
+                                    />
+                                    <NumberInput
+                                        label="table.field.waveItem.workQty"
+                                        source="workQty"
+                                    />
+                                </Stack>
+
+                            </Grid>
+                            <Grid item xs={8} md={2}>
+                                <Typography variant="h6" gutterBottom>
+                                    {translate('common.edit.title.common')}
+                                </Typography>
+                                <StatusSelectInput />
+                                <Box mt="2em" />
+                                <MemoInput />
+                            </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>
+                </EditBase >
+            </DialogContent>
+        </Dialog>
+    )
+}
+
+export default WaveItemEdit;
diff --git a/rsf-admin/src/page/orders/wave/WaveItemList.jsx b/rsf-admin/src/page/orders/wave/WaveItemList.jsx
new file mode 100644
index 0000000..ba3a37d
--- /dev/null
+++ b/rsf-admin/src/page/orders/wave/WaveItemList.jsx
@@ -0,0 +1,190 @@
+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,
+    Button,
+} from 'react-admin';
+import { Box, Typography, Card, Stack } from '@mui/material';
+import { styled } from '@mui/material/styles';
+import WaveItemCreate from "./WaveItemCreate";
+import EmptyData from "../../components/EmptyData";
+import MyCreateButton from "../../components/MyCreateButton";
+import MyExportButton from '../../components/MyExportButton';
+import PageDrawer from "../../components/PageDrawer";
+import WaveItemEdit from "./WaveItemEdit";
+import MyField from "../../components/MyField";
+import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting';
+import * as Common from '@/utils/common';
+import ContentCreate from '@mui/icons-material/Create';
+
+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 />,
+    <DateInput label='common.time.after' source="timeStart" alwaysOn />,
+    <DateInput label='common.time.before' source="timeEnd" alwaysOn />,
+    <NumberInput source="waveId" label="table.field.waveItem.waveId" />,
+    <TextInput source="waveCode" label="table.field.waveItem.waveCode" />,
+    <NumberInput source="matnrId" label="table.field.waveItem.matnrId" />,
+    <TextInput source="maktx" label="table.field.waveItem.matnrName" />,
+    <TextInput source="matnrCode" label="table.field.waveItem.matnrCode" />,
+    <TextInput source="batch" label="table.field.waveItem.batch" />,
+    <TextInput source="splrBatch" label="table.field.waveItem.splrBatch" />,
+    <TextInput source="orderCode" label="table.field.waveItem.orderCode" />,
+    <NumberInput source="orderItemId" label="table.field.waveItem.orderItemId" />,
+    <TextInput source="unit" label="table.field.waveItem.unit" />,
+    <TextInput source="trackCode" label="table.field.waveItem.trackCode" />,
+    <TextInput source="fieldsIndex" label="table.field.waveItem.fieldsIndex" />,
+    <NumberInput source="anfme" label="table.field.waveItem.anfme" />,
+    <NumberInput source="workQty" label="table.field.waveItem.workQty" />,
+    <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 WaveItemList = () => {
+    const translate = useTranslate();
+    const waveId = useGetRecordId();
+    const [createDialog, setCreateDialog] = useState(false);
+    const [editDialog, setEditDialog] = useState(false);
+    const [drawerVal, setDrawerVal] = useState(false);
+
+    return (
+        <Box display="flex">
+            <List
+                resource="waveItem"
+                sx={{
+                    flexGrow: 1,
+                    transition: (theme) =>
+                        theme.transitions.create(['all'], {
+                            duration: theme.transitions.duration.enteringScreen,
+                        }),
+                    marginRight: !!drawerVal ? `${PAGE_DRAWER_WIDTH}px` : 0,
+                }}
+                title={"menu.waveItem"}
+                empty={false}
+                filters={filters}
+                filter={{ waveId: waveId }}
+                sort={{ field: "create_time", order: "desc" }}
+                actions={(
+                    <TopToolbar>
+                        <FilterButton />
+                        <SelectColumnsButton preferenceKey='waveItem' />
+                    </TopToolbar>
+                )}
+                perPage={DEFAULT_PAGE_SIZE}
+            >
+                <StyledDatagrid
+                    preferenceKey='waveItem'
+                    bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />}
+                    rowClick={(id, resource, record) => false}
+                    expand={false}
+                    expandSingle={false}
+                    omit={['id', 'createTime', 'matnrId', 'waveId', 'batch', 'orderItemId', 'batch', 'fieldsIndex', 'createBy', 'memo']}
+                >
+                    <NumberField source="id" />
+                    <NumberField source="waveId" label="table.field.waveItem.waveId" />
+                    <TextField source="waveCode" label="table.field.waveItem.waveCode" />
+                    <NumberField source="matnrId" label="table.field.waveItem.matnrId" />
+                    <TextField source="maktx" label="table.field.waveItem.matnrName" />
+                    <TextField source="matnrCode" label="table.field.waveItem.matnrCode" />
+                    <TextField source="batch" label="table.field.waveItem.batch" />
+                    <TextField source="splrBatch" label="table.field.waveItem.splrBatch" />
+                    <TextField source="orderCode" label="table.field.waveItem.orderCode" />
+                    <NumberField source="orderItemId" label="table.field.waveItem.orderItemId" />
+                    <TextField source="unit" label="table.field.waveItem.unit" />
+                    <TextField source="trackCode" label="table.field.waveItem.trackCode" />
+                    <TextField source="fieldsIndex" label="table.field.waveItem.fieldsIndex" />
+                    <NumberField source="anfme" label="table.field.waveItem.anfme" />
+                    <NumberField source="workQty" label="table.field.waveItem.workQty" />
+                    <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>
+            <WaveItemEdit
+                open={editDialog}
+                setOpen={setEditDialog}
+            />
+            <WaveItemCreate
+                open={createDialog}
+                setOpen={setCreateDialog}
+            />
+            <PageDrawer
+                title='WaveItem Detail'
+                drawerVal={drawerVal}
+                setDrawerVal={setDrawerVal}
+            >
+            </PageDrawer>
+        </Box>
+    )
+}
+
+export default WaveItemList;
+
+const DetailButton = (setEditDialog) => {
+    const record = useRecordContext();
+    const editClick = (event) => {
+        console.log('--========--->');
+        event.stopPropagation()
+        setEditDialog(true)
+    }
+
+    return (
+        <Button  label="ra.action.edit" onClick={editClick} startIcon={<ContentCreate />}/>
+
+    )
+
+}
diff --git a/rsf-admin/src/page/wave/WaveList.jsx b/rsf-admin/src/page/orders/wave/WaveList.jsx
similarity index 77%
rename from rsf-admin/src/page/wave/WaveList.jsx
rename to rsf-admin/src/page/orders/wave/WaveList.jsx
index 1ee5b56..73596e2 100644
--- a/rsf-admin/src/page/wave/WaveList.jsx
+++ b/rsf-admin/src/page/orders/wave/WaveList.jsx
@@ -31,18 +31,24 @@
     ReferenceArrayInput,
     AutocompleteInput,
     DeleteButton,
+    useRefresh,
+    useRedirect,
+    Button,
 } from 'react-admin';
 import { Box, Typography, Card, Stack } from '@mui/material';
 import { styled } from '@mui/material/styles';
 import WaveCreate from "./WaveCreate";
 import WavePanel from "./WavePanel";
-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 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 request from '@/utils/request';
 import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting';
 import * as Common from '@/utils/common';
+import PublicIcon from '@mui/icons-material/Public';
+
 
 const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({
     '& .css-1vooibu-MuiSvgIcon-root': {
@@ -96,7 +102,6 @@
 
 const WaveList = () => {
     const translate = useTranslate();
-
     const [createDialog, setCreateDialog] = useState(false);
     const [drawerVal, setDrawerVal] = useState(false);
 
@@ -112,26 +117,26 @@
                     marginRight: !!drawerVal ? `${PAGE_DRAWER_WIDTH}px` : 0,
                 }}
                 title={"menu.wave"}
-                empty={<EmptyData onClick={() => { setCreateDialog(true) }} />}
+                empty={false}
                 filters={filters}
                 sort={{ field: "create_time", order: "desc" }}
                 actions={(
                     <TopToolbar>
                         <FilterButton />
-                        <MyCreateButton onClick={() => { setCreateDialog(true) }} />
                         <SelectColumnsButton preferenceKey='wave' />
-                        <MyExportButton />
                     </TopToolbar>
                 )}
                 perPage={DEFAULT_PAGE_SIZE}
             >
                 <StyledDatagrid
                     preferenceKey='wave'
-                    bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />}
+                    bulkActionButtons={
+                        <PublicTaskButton />
+                    }
                     rowClick={(id, resource, record) => false}
-                    expand={() => <WavePanel />}
-                    expandSingle={true}
-                    omit={['id', 'createTime', 'createBy', 'memo']}
+                    expand={false}
+                    expandSingle={false}
+                    omit={['id', 'createTime', 'createBy', 'memo', 'createBy$']}
                 >
                     <NumberField source="id" />
                     <TextField source="code" label="table.field.wave.code" />
@@ -140,14 +145,9 @@
                     <NumberField source="anfme" label="table.field.wave.anfme" />
                     <NumberField source="qty" label="table.field.wave.qty" />
                     <NumberField source="orderNum" label="table.field.wave.orderNum" />
-
-                    <ReferenceField source="updateBy" label="common.field.updateBy" reference="user" link={false} sortable={false}>
-                        <TextField source="nickname" />
-                    </ReferenceField>
+                    <TextField source="updateBy$" label="common.field.updateBy" />
                     <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>
+                    <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} />
@@ -172,3 +172,33 @@
 }
 
 export default WaveList;
+
+const PublicTaskButton = () => {
+    const record = useRecordContext();
+    const { selectedIds, onUnselectItems } = useListContext();
+    const notify = useNotify();
+    const refresh = useRefresh();
+    const redirect = useRedirect();
+
+    const pubClick = async (event) => {
+        event.stopPropagation();
+        console.log('=========>');
+        
+        onUnselectItems();
+        const res = await request.post(`/wave/public/task`, { ids: selectedIds });
+        if (res?.data?.code === 200) {
+            notify(res.data.msg);
+            redirect("/task")
+        } else {
+            notify(res.data.msg);
+        }
+        refresh();
+    }
+
+    return (
+        <Button
+            onClick={pubClick}
+            label={"toolbar.createTask"}
+            startIcon={<PublicIcon />}
+        />);
+}
\ No newline at end of file
diff --git a/rsf-admin/src/page/wave/WavePanel.jsx b/rsf-admin/src/page/orders/wave/WavePanel.jsx
similarity index 98%
rename from rsf-admin/src/page/wave/WavePanel.jsx
rename to rsf-admin/src/page/orders/wave/WavePanel.jsx
index 311f963..e64f444 100644
--- a/rsf-admin/src/page/wave/WavePanel.jsx
+++ b/rsf-admin/src/page/orders/wave/WavePanel.jsx
@@ -4,7 +4,7 @@
     useTranslate,
     useRecordContext,
 } from 'react-admin';
-import PanelTypography from "../components/PanelTypography";
+import PanelTypography from "../../components/PanelTypography";
 import * as Common from '@/utils/common'
 
 const WavePanel = () => {
diff --git a/rsf-admin/src/page/wave/index.jsx b/rsf-admin/src/page/orders/wave/index.jsx
similarity index 100%
rename from rsf-admin/src/page/wave/index.jsx
rename to rsf-admin/src/page/orders/wave/index.jsx
diff --git a/rsf-admin/src/page/warehouseAreas/WarehouseAreasCreate.jsx b/rsf-admin/src/page/warehouseAreas/WarehouseAreasCreate.jsx
index ea0d05f..3d0ee89 100644
--- a/rsf-admin/src/page/warehouseAreas/WarehouseAreasCreate.jsx
+++ b/rsf-admin/src/page/warehouseAreas/WarehouseAreasCreate.jsx
@@ -36,7 +36,7 @@
 
   const translate = useTranslate();
   const notify = useNotify();
-
+  const dicts = JSON.parse(localStorage.getItem('sys_dicts'))?.filter(dict => (dict.dictTypeCode == 'sys_ware_areas_type')) || [];
   const handleClose = (event, reason) => {
     if (reason !== "backdropClick") {
       setOpen(false);
@@ -91,32 +91,29 @@
             </DialogTitle>
             <DialogContent sx={{ mt: 2 }}>
               <Grid container rowSpacing={2} columnSpacing={2}>
-                {/* <Grid item xs={6} display="flex" gap={1}>
-                  <TextInput
-                    label="table.field.warehouseAreas.uuid"
-                    source="uuid"
-                    parse={(v) => v}
-                    validate={[required()]}
-                    autoFocus
-                  />
-                </Grid> */}
-                <Grid item xs={6} display="flex" gap={1}>
+                <Grid item xs={12} display="flex" gap={1}>
                   <TextInput
                     label="table.field.warehouseAreas.name"
                     source="name"
                     validate={[required()]}
                     parse={(v) => v}
                   />
-                </Grid>
-                <Grid item xs={6} display="flex" gap={1}>
                   <TextInput
                     label="table.field.warehouseAreas.code"
                     source="code"
                     validate={[required()]}
                     parse={(v) => v}
                   />
+                  <AutocompleteInput
+                    choices={dicts}
+                    optionText="label"
+                    label="table.field.asnOrder.type"
+                    source="type"
+                    optionValue="value"
+                    parse={v => v}
+                  />
                 </Grid>
-                <Grid item xs={6} display="flex" gap={1}>
+                <Grid item xs={12} display="flex" gap={1}>
                   <ReferenceInput
                     source="warehouseId"
                     reference="warehouse"
@@ -128,8 +125,7 @@
                       filterToQuery={(val) => ({ name: val })}
                     />
                   </ReferenceInput>
-                </Grid>
-                <Grid item xs={6} display="flex" gap={1}>
+
                   <ReferenceInput source="shipperId" reference="companys" filter={{ type: 'shipper' }}>
                     <AutocompleteInput
                       label="table.field.warehouseAreas.shipperId"
@@ -137,8 +133,6 @@
                       filterToQuery={(val) => ({ name: val })}
                     />
                   </ReferenceInput>
-                </Grid>
-                <Grid item xs={6} display="flex" gap={1}>
                   <ReferenceInput source="supplierId" reference="companys" filter={{ type: 'supplier' }}>
                     <AutocompleteInput
                       label="table.field.warehouseAreas.supplierId"
@@ -147,7 +141,7 @@
                     />
                   </ReferenceInput>
                 </Grid>
-                <Grid item xs={6} display="flex" gap={1}>
+                <Grid item xs={12} display="flex" gap={1}>
                   <SelectInput
                     label="table.field.warehouseAreas.flagMinus"
                     source="flagMinus"
@@ -157,8 +151,6 @@
                       { id: 1, name: "鏄�" },
                     ]}
                   />
-                </Grid>
-                <Grid item xs={6} display="flex" gap={1}>
                   <SelectInput
                     label="table.field.warehouseAreas.flagLabelMange"
                     source="flagLabelMange"
@@ -168,8 +160,6 @@
                       { id: 1, name: " 鏄�" },
                     ]}
                   />
-                </Grid>
-                <Grid item xs={6} display="flex" gap={1}>
                   <SelectInput
                     label="table.field.warehouseAreas.flagMix"
                     source="flagMix"
diff --git a/rsf-admin/src/page/warehouseAreas/WarehouseAreasEdit.jsx b/rsf-admin/src/page/warehouseAreas/WarehouseAreasEdit.jsx
index e197ebd..cb67494 100644
--- a/rsf-admin/src/page/warehouseAreas/WarehouseAreasEdit.jsx
+++ b/rsf-admin/src/page/warehouseAreas/WarehouseAreasEdit.jsx
@@ -42,6 +42,7 @@
 
 const WarehouseAreasEdit = () => {
     const translate = useTranslate();
+    const dicts = JSON.parse(localStorage.getItem('sys_dicts'))?.filter(dict => (dict.dictTypeCode == 'sys_ware_areas_type')) || [];
 
     return (
         <Edit
@@ -58,8 +59,8 @@
                 defaultValues={{}}
             // validate={(values) => { }}
             >
-                <Grid container width={{ xs: '100%', xl: '80%' }} rowSpacing={3} columnSpacing={3}>
-                    <Grid item xs={12} md={8}>
+                <Grid container width={{ xs: '100%', xl: '100%' }} rowSpacing={3} columnSpacing={3}>
+                    <Grid item xs={16} md={10}>
                         <Typography variant="h6" gutterBottom>
                             {translate('common.edit.title.main')}
                         </Typography>
@@ -72,23 +73,27 @@
                                 autoFocus
                             />
                         </Stack> */}
-                        <Stack direction='row' gap={2}>
+                        <Stack xs={16} direction='row' gap={2}>
                             <TextInput
                                 label="table.field.warehouseAreas.name"
                                 source="name"
                                 validate={[required()]}
                                 parse={v => v}
                             />
-                        </Stack>
-                        <Stack direction='row' gap={2}>
                             <TextInput
                                 label="table.field.warehouseAreas.code"
                                 source="code"
                                 validate={[required()]}
                                 parse={v => v}
                             />
-                        </Stack>
-                        <Stack direction='row' gap={2}>
+                            <AutocompleteInput
+                                choices={dicts}
+                                optionText="label"
+                                label="table.field.asnOrder.type"
+                                source="type"
+                                optionValue="value"
+                                parse={v => v}
+                            />
                             <ReferenceInput
                                 source="warehouseId"
                                 reference="warehouse"
@@ -113,8 +118,6 @@
                                     filterToQuery={(val) => ({ name: val })}
                                 />
                             </ReferenceInput>
-                        </Stack>
-                        <Stack direction='row' gap={2}>
                             <ReferenceInput
                                 source="supplierId"
                                 reference="companys"
@@ -126,8 +129,6 @@
                                     filterToQuery={(val) => ({ name: val })}
                                 />
                             </ReferenceInput>
-                        </Stack>
-                        <Stack direction='row' gap={2}>
                             <SelectInput
                                 label="table.field.warehouseAreas.flagMinus"
                                 source="flagMinus"
@@ -137,8 +138,6 @@
                                     { id: 1, name: '鏄�' },
                                 ]}
                             />
-                        </Stack>
-                        <Stack direction='row' gap={2}>
                             <SelectInput
                                 label="table.field.warehouseAreas.flagLabelMange"
                                 source="flagLabelMange"
@@ -148,8 +147,6 @@
                                     { id: 1, name: ' 鏄�' },
                                 ]}
                             />
-                        </Stack>
-                        <Stack direction='row' gap={2}>
                             <SelectInput
                                 label="table.field.warehouseAreas.flagMix"
                                 source="flagMix"
@@ -160,9 +157,8 @@
                                 ]}
                             />
                         </Stack>
-
                     </Grid>
-                    <Grid item xs={12} md={4}>
+                    <Grid item xs={8} md={2}>
                         <Typography variant="h6" gutterBottom>
                             {translate('common.edit.title.common')}
                         </Typography>
diff --git a/rsf-admin/src/page/warehouseAreas/WarehouseAreasList.jsx b/rsf-admin/src/page/warehouseAreas/WarehouseAreasList.jsx
index c90866a..86a989a 100644
--- a/rsf-admin/src/page/warehouseAreas/WarehouseAreasList.jsx
+++ b/rsf-admin/src/page/warehouseAreas/WarehouseAreasList.jsx
@@ -114,9 +114,9 @@
 
 const WarehouseAreasList = () => {
     const translate = useTranslate();
-
     const [createDialog, setCreateDialog] = useState(false);
     const [drawerVal, setDrawerVal] = useState(false);
+    const dicts = JSON.parse(localStorage.getItem('sys_dicts'))?.filter(dict => (dict.dictTypeCode == 'sys_ware_areas_type')) || [];
 
     return (
         <Box display="flex">
@@ -160,6 +160,7 @@
                     {/* <TextField source="uuid" label="table.field.warehouseAreas.uuid" /> */}
                     <TextField source="name" label="table.field.warehouseAreas.name" />
                     <TextField source="code" label="table.field.warehouseAreas.code" />
+                    <TextField source="type$" label="table.field.warehouseAreas.type"/>
                     {/* <ReferenceField source="shipperId" label="table.field.warehouseAreas.shipperId" reference="shipper" link={false} sortable={false}>
                         <TextField source="name" />
                     </ReferenceField> */}
@@ -169,7 +170,6 @@
                     <TextField source="flagMinus$" label="table.field.warehouseAreas.flagMinus" sortable={false} />
                     <TextField source="flagLabelMange$" label="table.field.warehouseAreas.flagLabelMange" sortable={false} />
                     <TextField source="flagMix$" label="table.field.warehouseAreas.flagMix" sortable={false} />
-
                     <ReferenceField source="updateBy" label="common.field.updateBy" reference="user" link={false} sortable={false}>
                         <TextField source="nickname" />
                     </ReferenceField>
diff --git a/rsf-admin/src/page/wave/WaveEdit.jsx b/rsf-admin/src/page/wave/WaveEdit.jsx
deleted file mode 100644
index b26cc70..0000000
--- a/rsf-admin/src/page/wave/WaveEdit.jsx
+++ /dev/null
@@ -1,130 +0,0 @@
-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 WaveEdit = () => {
-    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}>
-                            <TextInput
-                                label="table.field.wave.code"
-                                source="code"
-                                parse={v => v}
-                                autoFocus
-                            />
-                        </Stack>
-                        <Stack direction='row' gap={2}>
-                            <SelectInput
-                                label="table.field.wave.type"
-                                source="type"
-                                choices={[
-                                    { id: 0, name: '鎵嬪姩' },
-                                    { id: 1, name: '鑷姩' },
-                                ]}
-                            />
-                        </Stack>
-                        <Stack direction='row' gap={2}>
-                            <SelectInput
-                                label="table.field.wave.exceStatus"
-                                source="exceStatus"
-                                choices={[
-                                    { id: 0, name: '鍒濆鍖�' },
-                                    { id: 1, name: '鐢熸垚浠诲姟' },
-                                    { id: 2, name: '浠诲姟鎾' },
-                                    { id: 3, name: '瀹屾垚' },
-                                ]}
-                            />
-                        </Stack>
-                        <Stack direction='row' gap={2}>
-                            <NumberInput
-                                label="table.field.wave.anfme"
-                                source="anfme"
-                            />
-                        </Stack>
-                        <Stack direction='row' gap={2}>
-                            <NumberInput
-                                label="table.field.wave.qty"
-                                source="qty"
-                            />
-                        </Stack>
-                        <Stack direction='row' gap={2}>
-                            <NumberInput
-                                label="table.field.wave.orderNum"
-                                source="orderNum"
-                            />
-                        </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 WaveEdit;
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/common/CodeBuilder.java b/rsf-server/src/main/java/com/vincent/rsf/server/common/CodeBuilder.java
index 18e29b0..2aa629f 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/common/CodeBuilder.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/common/CodeBuilder.java
@@ -15,16 +15,16 @@
         generator.frontendPrefixPath = "rsf-admin/";
 
         generator.sqlOsType = SqlOsType.MYSQL;
-        generator.url="127.0.0.1:3306/rsf";
-        generator.username="root";
-        generator.password="34821015";
+        generator.url = "127.0.0.1:3306/rsf";
+        generator.username = "root";
+        generator.password = "34821015";
 //        generator.url="47.97.1.152:51433;databasename=jkasrs";
 //        generator.username="sa";
 //        generator.password="Zoneyung@zy56$";
 
-        generator.table="man_device_bind";
-        generator.tableDesc="绔嬩綋搴撶珯鐐圭粦瀹�";
-        generator.packagePath="com.vincent.rsf.server.manager";
+        generator.table = "man_device_bind";
+        generator.tableDesc = "绔嬩綋搴撶珯鐐圭粦瀹�";
+        generator.packagePath = "com.vincent.rsf.server.manager";
 
         generator.build();
     }
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/DeviceBindController.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/DeviceBindController.java
index 73b3473..579e7be 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/DeviceBindController.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/DeviceBindController.java
@@ -55,10 +55,10 @@
     @OperationLog("Create 绔嬩綋搴撶珯鐐圭粦瀹�")
     @PostMapping("/deviceBind/save")
     public R save(@RequestBody DeviceBind deviceBind) {
-        deviceBind.setCreateBy(getLoginUserId());
-        deviceBind.setCreateTime(new Date());
-        deviceBind.setUpdateBy(getLoginUserId());
-        deviceBind.setUpdateTime(new Date());
+//        deviceBind.setCreateBy(getLoginUserId());
+//        deviceBind.setCreateTime(new Date());
+//        deviceBind.setUpdateBy(getLoginUserId());
+//        deviceBind.setUpdateTime(new Date());
         if (!deviceBindService.save(deviceBind)) {
             return R.error("Save Fail");
         }
@@ -69,8 +69,8 @@
     @OperationLog("Update 绔嬩綋搴撶珯鐐圭粦瀹�")
     @PostMapping("/deviceBind/update")
     public R update(@RequestBody DeviceBind deviceBind) {
-        deviceBind.setUpdateBy(getLoginUserId());
-        deviceBind.setUpdateTime(new Date());
+//        deviceBind.setUpdateBy(getLoginUserId());
+//        deviceBind.setUpdateTime(new Date());
         if (!deviceBindService.updateById(deviceBind)) {
             return R.error("Update Fail");
         }
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/OutStockController.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/OutStockController.java
index ac580c4..2efff1c 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/OutStockController.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/OutStockController.java
@@ -80,7 +80,8 @@
             if (Objects.isNull(ruleCode) || StringUtils.isBlank(ruleCode)) {
                 return R.error("缂栫爜瑙勫垯閿欒锛氱紪鐮併�孲YS_OUT_STOCK_CODE銆嶆槸鏈缃垚鍔燂紒锛�");
             }
-            asnOrder.setCode(ruleCode);
+            asnOrder.setExceStatus(AsnExceStatus.OUT_STOCK_STATUS_TASK_INIT.val)
+                    .setCode(ruleCode);
         }
         if (!outStockService.save(asnOrder)) {
             return R.error("Save Fail");
@@ -213,6 +214,4 @@
         List<Long> ids = (List<Long>) params.get("ids");
         return outStockService.generateWaves(ids);
     }
-
-
 }
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/WaveController.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/WaveController.java
index 989b5d2..2334f1c 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/WaveController.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/WaveController.java
@@ -4,6 +4,7 @@
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.vincent.rsf.framework.common.Cools;
 import com.vincent.rsf.framework.common.R;
+import com.vincent.rsf.framework.exception.CoolException;
 import com.vincent.rsf.server.common.utils.ExcelUtil;
 import com.vincent.rsf.server.common.annotation.OperationLog;
 import com.vincent.rsf.server.common.domain.BaseParam;
@@ -12,6 +13,7 @@
 import com.vincent.rsf.server.manager.entity.Wave;
 import com.vincent.rsf.server.manager.service.WaveService;
 import com.vincent.rsf.server.system.controller.BaseController;
+import io.swagger.annotations.ApiOperation;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.web.bind.annotation.*;
@@ -105,4 +107,15 @@
         ExcelUtil.build(ExcelUtil.create(waveService.list(), Wave.class), response);
     }
 
+
+    @PreAuthorize("hasAuthority('manager:wave:update')")
+    @ApiOperation("娉㈡涓嬪彂浠诲姟")
+    @PostMapping("/wave/public/task")
+    public R publicTask(@RequestBody Map<String, Object> map) {
+        if (Cools.isEmpty(map)) {
+            throw new CoolException("鍙傛暟涓嶈兘涓虹┖锛侊紒");
+        }
+        return waveService.publicTask(map);
+    }
+
 }
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/AsnOrderItem.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/AsnOrderItem.java
index 572b4d2..4672de4 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/AsnOrderItem.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/AsnOrderItem.java
@@ -55,6 +55,7 @@
     @ApiModelProperty("瀛楁绱㈠紩")
     private String fieldsIndex;
 
+
     @ApiModelProperty("鎵ц鏁伴噺")
     private Double workQty;
 
@@ -229,7 +230,7 @@
      */
     @ApiModelProperty(value= "澶囨敞")
     private String memo;
-
+//
     public AsnOrderItem() {}
 
     public AsnOrderItem(Long asnId,String asnCode,Long poDetlId, String matnrCode, String poCode,Long matnrId,String matnk,Double anfme,String stockUnit,Double purQty,String purUnit,Double qty,String splrCode,String splrName,String qrcode,String barcode,String packName,Integer status, Integer ntyStatus,Integer deleted,Integer tenantId,Long createBy,Date createTime,Long updateBy,Date updateTime,String memo) {
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/DeliveryItem.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/DeliveryItem.java
index d3148b5..7a66332 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/DeliveryItem.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/DeliveryItem.java
@@ -59,10 +59,16 @@
     private String matnrCode;
 
     /**
+     * 鐗╂枡ID
+     */
+    @ApiModelProperty("鐗╂枡ID")
+    private Long matnrId;
+
+    /**
      * 鐗╂枡鍚嶇О
      */
     @ApiModelProperty(value= "鐗╂枡鍚嶇О")
-    private String matnrName;
+    private String maktx;
 
     /**
      * 鍔ㄦ�佸瓧娈电储寮�
@@ -118,6 +124,18 @@
     @ApiModelProperty(value= "渚涘簲鍟嗘壒娆�")
     private String splrBatch;
 
+    @ApiModelProperty("鎵规")
+    private String batch;
+
+    @ApiModelProperty("璺熻釜鐮�")
+    private String trackCode;
+
+    @ApiModelProperty("鐢熶骇鏃ユ湡")
+    private Date prodTime;
+
+    @ApiModelProperty("鍖呰")
+    private String packName;
+
     /**
      * 鐘舵�� 1: 姝e父  0: 鍐荤粨  
      */
@@ -171,11 +189,12 @@
 
     public DeliveryItem() {}
 
-    public DeliveryItem(Long deliveryId,String platItemId,String matnrCode,String matnrName,String fieldsIndex,String unit,Double anfme,Double qty,Double nromQty,Double printQty,String splrName,String splrCode,String splrBatch,Integer status,Integer deleted,Integer tenantId,Long createBy,Date createTime,Long updateBy,Date updateTime,String memo) {
+    public DeliveryItem(Long deliveryId,String platItemId, Long matnrId,String matnrCode,String matnrName,String fieldsIndex,String unit,Double anfme,Double qty,Double nromQty,Double printQty,String splrName,String splrCode,String splrBatch,Integer status,Integer deleted,Integer tenantId,Long createBy,Date createTime,Long updateBy,Date updateTime,String memo) {
         this.deliveryId = deliveryId;
         this.platItemId = platItemId;
+        this.matnrId = matnrId;
         this.matnrCode = matnrCode;
-        this.matnrName = matnrName;
+        this.maktx = matnrName;
         this.fieldsIndex = fieldsIndex;
         this.unit = unit;
         this.anfme = anfme;
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/DeviceBind.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/DeviceBind.java
index dc98990..f65d4de 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/DeviceBind.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/DeviceBind.java
@@ -118,16 +118,16 @@
 
 
 
-    public Boolean getStatusBool(){
-        if (null == this.status){ return null; }
-        switch (this.status){
-            case 1:
-                return true;
-            case 0:
-                return false;
-            default:
-                return null;
-        }
-    }
+//    public Boolean getStatusBool(){
+//        if (null == this.status){ return null; }
+//        switch (this.status){
+//            case 1:
+//                return true;
+//            case 0:
+//                return false;
+//            default:
+//                return null;
+//        }
+//    }
 
 }
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/WarehouseAreas.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/WarehouseAreas.java
index 6efb8c0..c1246aa 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/WarehouseAreas.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/WarehouseAreas.java
@@ -3,13 +3,18 @@
 import com.baomidou.mybatisplus.annotation.*;
 
 import java.text.SimpleDateFormat;
-import java.util.Date;
+import java.util.*;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.fasterxml.jackson.annotation.JsonFormat;
 import com.vincent.rsf.server.manager.service.CompanysService;
 import com.vincent.rsf.server.manager.service.ShipperService;
 import com.vincent.rsf.server.manager.service.WarehouseService;
+import com.vincent.rsf.server.system.constant.DictTypeCode;
+import com.vincent.rsf.server.system.entity.DictData;
+import com.vincent.rsf.server.system.service.DictDataService;
 import io.swagger.annotations.Api;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.format.annotation.DateTimeFormat;
 import java.text.SimpleDateFormat;
 import java.util.Date;
@@ -24,7 +29,7 @@
 import com.vincent.rsf.server.system.entity.User;
 import java.io.Serializable;
 import java.util.Date;
-import java.util.Objects;
+import java.util.stream.Collectors;
 
 @Data
 @TableName("man_warehouse_areas")
@@ -48,7 +53,7 @@
     /**
      * 缂栧彿
      */
-    @ApiModelProperty(value= "缂栧彿")
+    @ApiModelProperty(value= "涓氬姟绫诲瀷")
     private String type;
 
     /**
@@ -156,8 +161,8 @@
 
     public WarehouseAreas() {}
 
-    public WarehouseAreas(String uuid,String name,String code,Long shipperId,Short supplierId,Short flagMinus,Short flagLabelMange,Short flagMix,Integer status,Integer deleted,Integer tenantId,Long createBy,Date createTime,Long updateBy,Date updateTime,String memo) {
-        this.type = uuid;
+    public WarehouseAreas(String type,String name,String code,Long shipperId,Short supplierId,Short flagMinus,Short flagLabelMange,Short flagMix,Integer status,Integer deleted,Integer tenantId,Long createBy,Date createTime,Long updateBy,Date updateTime,String memo) {
+        this.type = type;
         this.name = name;
         this.code = code;
         this.shipperId = shipperId;
@@ -194,6 +199,18 @@
         return null;
     }
 
+    public String getType$() {
+        if (Cools.isEmpty(this.type)){
+            return "";
+        }
+        DictDataService dictDataService = SpringUtils.getBean(DictDataService.class);
+        DictData dictData = dictDataService.getOne(new LambdaQueryWrapper<DictData>().eq(DictData::getDictTypeCode, DictTypeCode.SYS_WARE_AREAS_TYPE).eq(DictData::getValue, this.type));
+        if (Objects.isNull(dictData)) {
+            return null;
+        }
+        return dictData.getLabel();
+    }
+
     public String getSupplierId$() {
         CompanysService service = SpringUtils.getBean(CompanysService.class);
         Companys supplier = service.getById(this.supplierId);
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/WaveItem.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/WaveItem.java
index 36d7e30..392b2ac 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/WaveItem.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/WaveItem.java
@@ -59,7 +59,7 @@
      * 鐗╂枡鍚嶇О
      */
     @ApiModelProperty(value= "鐗╂枡鍚嶇О")
-    private String matnrName;
+    private String maktx;
 
     /**
      * 鍟嗗搧缂栧彿
@@ -180,13 +180,14 @@
 
     public WaveItem() {}
 
-    public WaveItem(Long waveId,String waveCode,Long matnrId,String matnrName,String matnrCode,String batch,String splrBatch,String orderCode,Long orderItemId,String unit,String trackCode,String fieldsIndex,Double anfme,Double workQty,Long tenantId,Integer status,Integer deleted,Date createTime,Long createBy,Date updateTime,Long updateBy,String memo) {
+    public WaveItem(Long waveId,String waveCode,Long matnrId,String matnrName,String matnrCode,String batch,String splrBatch,String orderCode, Long orderId,Long orderItemId,String unit,String trackCode,String fieldsIndex,Double anfme,Double workQty,Long tenantId,Integer status,Integer deleted,Date createTime,Long createBy,Date updateTime,Long updateBy,String memo) {
         this.waveId = waveId;
         this.waveCode = waveCode;
         this.matnrId = matnrId;
-        this.matnrName = matnrName;
+        this.maktx = matnrName;
         this.matnrCode = matnrCode;
         this.batch = batch;
+        this.orderId = orderId;
         this.splrBatch = splrBatch;
         this.orderCode = orderCode;
         this.orderItemId = orderItemId;
@@ -205,6 +206,7 @@
         this.memo = memo;
     }
 
+
 //    WaveItem waveItem = new WaveItem(
 //            null,    // 娉㈡ID
 //            null,    // 娉㈡鍙�
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/enums/AsnExceStatus.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/enums/AsnExceStatus.java
index b272641..c58518d 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/enums/AsnExceStatus.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/enums/AsnExceStatus.java
@@ -14,8 +14,14 @@
     ASN_EXCE_STATUS_EXCE_ING("1", "鎵ц涓�"),
     ASN_EXCE_STATUS_TASK_DONE("2", "宸插畬鎴�"),
     ASN_EXCE_STATUS_TASK_CANCEL("3", "鍙栨秷"),
-    ASN_EXCE_STATUS_TASK_CLOSE("4", "宸插叧闂�")
-            ;
+    ASN_EXCE_STATUS_TASK_CLOSE("4", "宸插叧闂�"),
+    OUT_STOCK_STATUS_TASK_INIT("5", "鍒濆鍖�"),
+    OUT_STOCK_STATUS_TASK_EXCE("6", "寰呭鐞�"),
+
+    OUT_STOCK_STATUS_TASK_WAVE("7", "鐢熸垚娉㈡"),
+
+    OUT_STOCK_STATUS_TASK_WORKING("8", "浣滀笟涓�")
+    ;
     AsnExceStatus(String val, String desc) {
         this.val = Short.parseShort(val);
         this.desc = desc;
@@ -35,6 +41,10 @@
             return AsnExceStatus.ASN_EXCE_STATUS_TASK_CANCEL.desc;
         } else if (val.equals(AsnExceStatus.ASN_EXCE_STATUS_TASK_CLOSE.val)) {
             return AsnExceStatus.ASN_EXCE_STATUS_TASK_CLOSE.desc;
+        } else if (val.equals(AsnExceStatus.OUT_STOCK_STATUS_TASK_INIT.val)) {
+            return AsnExceStatus.OUT_STOCK_STATUS_TASK_INIT.desc;
+        } else if (val.equals(AsnExceStatus.OUT_STOCK_STATUS_TASK_EXCE.val)) {
+            return AsnExceStatus.OUT_STOCK_STATUS_TASK_EXCE.desc;
         } else {
             return null;
         }
@@ -51,6 +61,10 @@
             return AsnExceStatus.ASN_EXCE_STATUS_TASK_CANCEL.val;
         } else if (desc.equals(AsnExceStatus.ASN_EXCE_STATUS_TASK_CLOSE.desc)) {
             return AsnExceStatus.ASN_EXCE_STATUS_TASK_CLOSE.val;
+        }else if (desc.equals(AsnExceStatus.OUT_STOCK_STATUS_TASK_INIT.desc)) {
+            return AsnExceStatus.OUT_STOCK_STATUS_TASK_INIT.val;
+        } else if (desc.equals(AsnExceStatus.OUT_STOCK_STATUS_TASK_EXCE.desc)) {
+            return AsnExceStatus.OUT_STOCK_STATUS_TASK_EXCE.val;
         } else {
             return null;
         }
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/WaveService.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/WaveService.java
index 0005369..b38ff1e 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/WaveService.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/WaveService.java
@@ -1,8 +1,19 @@
 package com.vincent.rsf.server.manager.service;
 
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.vincent.rsf.framework.common.R;
 import com.vincent.rsf.server.manager.entity.Wave;
+
+import java.util.Map;
 
 public interface WaveService extends IService<Wave> {
 
+    /**
+     * @author Ryan
+     * @description 娉㈡浠诲姟涓嬪彂
+     * @param
+     * @return
+     * @time 2025/4/25 16:24
+     */
+    R publicTask(Map<String, Object> map);
 }
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/OutStockServiceImpl.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/OutStockServiceImpl.java
index af8c2d1..17ea75b 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/OutStockServiceImpl.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/OutStockServiceImpl.java
@@ -6,19 +6,14 @@
 import com.vincent.rsf.framework.common.Cools;
 import com.vincent.rsf.framework.common.R;
 import com.vincent.rsf.framework.exception.CoolException;
-import com.vincent.rsf.server.api.entity.dto.PoItemsDto;
-import com.vincent.rsf.server.api.service.ReceiveMsgService;
-import com.vincent.rsf.server.api.service.ReportMsgService;
 import com.vincent.rsf.server.manager.controller.params.AsnOrderAndItemsParams;
-import com.vincent.rsf.server.manager.controller.params.BatchUpdateParam;
 import com.vincent.rsf.server.manager.entity.*;
 import com.vincent.rsf.server.manager.enums.AsnExceStatus;
 import com.vincent.rsf.server.manager.enums.WaveExceStatus;
 import com.vincent.rsf.server.manager.mapper.AsnOrderMapper;
-import com.vincent.rsf.server.manager.mapper.PurchaseMapper;
 import com.vincent.rsf.server.manager.service.*;
+import com.vincent.rsf.server.manager.utils.GroupMergeUtil;
 import com.vincent.rsf.server.system.constant.SerialRuleCode;
-import com.vincent.rsf.server.system.mapper.SerialRuleMapper;
 import com.vincent.rsf.server.system.utils.SerialRuleUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.BeanUtils;
@@ -26,7 +21,6 @@
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
-import javax.annotation.Resource;
 import java.util.*;
 import java.util.stream.Collectors;
 
@@ -208,7 +202,7 @@
             if (Objects.isNull(ruleCode) || StringUtils.isBlank(ruleCode)) {
                 throw new CoolException("缂栫爜瑙勫垯閿欒锛氳妫�鏌� 銆孲YS_OUT_STOCK_CODE銆嶇紪鐮佹槸鍚﹁缃垚鍔�");
             }
-            order.setExceStatus(AsnExceStatus.ASN_EXCE_STATUS_UN_EXCE.val)
+            order.setExceStatus(AsnExceStatus.OUT_STOCK_STATUS_TASK_INIT.val)
                     .setCode(ruleCode)
                     .setPoId(delivery.getId())
                     .setId(null)
@@ -222,6 +216,9 @@
                 BeanUtils.copyProperties(item, orderItem);
                 orderItem.setId(null)
                         .setPoCode(order.getPoCode())
+                        .setMaktx(item.getMaktx())
+                        .setMatnrCode(item.getMatnrCode())
+                        .setFieldsIndex(item.getFieldsIndex())
                         .setAsnId(order.getId())
                         .setAsnCode(order.getCode())
                         .setPlatItemId(item.getPlatItemId())
@@ -255,9 +252,11 @@
         if (Objects.isNull(ids) || ids.isEmpty()) {
             throw new CoolException("鍙傛暟涓嶈兘涓虹┖锛侊紒");
         }
-        List<AsnOrder> orders = this.listByIds(ids);
+        List<AsnOrder> orders = this.list(new LambdaQueryWrapper<AsnOrder>()
+                .in(AsnOrder::getId, ids)
+                .eq(AsnOrder::getExceStatus, AsnExceStatus.OUT_STOCK_STATUS_TASK_INIT.val));
         if (orders.isEmpty()) {
-            throw new CoolException("鍗曟嵁涓嶅瓨鍦紒锛�");
+            throw new CoolException("褰撳墠鍗曟嵁鐘舵�佷笉鑳芥墽琛屾尝娆$敓鎴愭搷浣滐紒锛�");
         }
         double sum = orders.stream().mapToDouble(AsnOrder::getAnfme).sum();
         Wave wave = new Wave();
@@ -274,25 +273,83 @@
             throw new CoolException("娉㈡淇濆瓨澶辫触锛侊紒");
         }
         List<Long> list = orders.stream().map(AsnOrder::getId).collect(Collectors.toList());
-        List<WaveItem> items = new ArrayList<>();
         List<AsnOrderItem> orderItems = asnOrderItemService
                 .list(new LambdaQueryWrapper<AsnOrderItem>()
                         .in(AsnOrderItem::getAsnId, list));
-
-
-        for (AsnOrderItem item : orderItems) {
-            WaveItem waveItem = new WaveItem();
-            BeanUtils.copyProperties(item, waveItem);
-            waveItem.setWaveId(wave.getId())
-                    .setWaveCode(wave.getCode())
-                    .setOrderId(item.getAsnId())
-                    .setOrderCode(item.getAsnCode())
-                    .setOrderItemId(item.getId());
-            items.add(waveItem);
+        if (orderItems.isEmpty()) {
+            throw new CoolException("鍗曟嵁涓嶅瓨鍦紒锛�");
         }
-        if (!waveItemService.saveBatch(items)) {
+
+        List<WaveItem> waveItems = mergeWave(orderItems, wave);
+        if (!waveItemService.saveBatch(waveItems)) {
             throw new CoolException("娉㈡鏄庣粏淇濆瓨澶辫触锛侊紒");
         }
+        double sum1 = waveItems.stream().mapToDouble(WaveItem::getAnfme).sum();
+        wave.setAnfme(sum1);
+        if (!waveService.saveOrUpdate(wave)) {
+            throw new CoolException("涓诲崟淇敼澶辫触锛侊紒");
+        }
+
+        if (!this.update(new LambdaUpdateWrapper<AsnOrder>()
+                .set(AsnOrder::getExceStatus, AsnExceStatus.OUT_STOCK_STATUS_TASK_WAVE.val)
+                .in(AsnOrder::getId, ids))) {
+            throw new CoolException("鎵ц鐘舵�佷慨鏀逛慨鏀瑰け璐ワ紒锛�");
+        }
         return R.ok("鎿嶄綔瀹屾垚锛侊紒");
     }
+
+    /**
+     * @param
+     * @param wave
+     * @return
+     * @author Ryan
+     * @description 鍚堝苟鐢熸垚娉㈡
+     * @time 2025/4/25 10:07
+     */
+    private List<WaveItem> mergeWave(List<AsnOrderItem> orderItems, Wave wave) {
+        List<WaveItem> items = new ArrayList<>();
+        orderItems.forEach(order -> {
+            WaveItem item = new WaveItem();
+            BeanUtils.copyProperties(order, item);
+            item.setOrderItemId(order.getId())
+                    .setId(null)
+                    .setOrderCode(order.getAsnCode())
+                    .setOrderId(order.getAsnId())
+                    .setMatnrId(order.getMatnrId())
+                    .setMaktx(order.getMaktx())
+                    .setWaveId(wave.getId())
+                    .setWaveCode(wave.getCode());
+            items.add(item);
+        });
+        List<WaveItem> waveItems = GroupMergeUtil.groupAndMerge(items,
+                (p1, p2) -> new WaveItem(
+                        p1.getWaveId(),
+                        p1.getWaveCode(),
+                        p1.getMatnrId(),
+                        p1.getMaktx(),
+                        p1.getMatnrCode(),
+                        p1.getBatch(),
+                        p1.getSplrBatch(),
+                        p1.getOrderCode(),
+                        p1.getOrderId(),
+                        p1.getOrderItemId(),
+                        p1.getUnit(),
+                        p1.getTrackCode(),
+                        p1.getFieldsIndex(),
+                        p1.getAnfme() + p2.getAnfme(),
+                        p1.getWorkQty(),
+                        p1.getTenantId(),
+                        p1.getStatus(),
+                        p1.getDeleted(),
+                        p1.getCreateTime(),
+                        p1.getCreateBy(),
+                        p1.getUpdateTime(),
+                        p1.getUpdateBy(),
+                        p1.getMemo()
+                ),
+                WaveItem::getSplrBatch, WaveItem::getMatnrCode, WaveItem::getFieldsIndex
+        );
+
+        return waveItems;
+    }
 }
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/WaveServiceImpl.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/WaveServiceImpl.java
index d323911..d42bfd6 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/WaveServiceImpl.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/WaveServiceImpl.java
@@ -1,12 +1,64 @@
 package com.vincent.rsf.server.manager.service.impl;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.vincent.rsf.framework.common.Cools;
+import com.vincent.rsf.framework.common.R;
+import com.vincent.rsf.framework.exception.CoolException;
+import com.vincent.rsf.server.manager.entity.AsnOrder;
+import com.vincent.rsf.server.manager.entity.AsnOrderItem;
+import com.vincent.rsf.server.manager.enums.WaveExceStatus;
 import com.vincent.rsf.server.manager.mapper.WaveMapper;
 import com.vincent.rsf.server.manager.entity.Wave;
+import com.vincent.rsf.server.manager.service.AsnOrderItemService;
+import com.vincent.rsf.server.manager.service.AsnOrderService;
 import com.vincent.rsf.server.manager.service.WaveService;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
 
 @Service("waveService")
 public class WaveServiceImpl extends ServiceImpl<WaveMapper, Wave> implements WaveService {
 
+    @Autowired
+    private AsnOrderItemService asnOrderItemService;
+
+    @Autowired
+    private AsnOrderService asnOrderService;
+
+    /**
+     * @author Ryan
+     * @description 娉㈡浠诲姟涓嬪彂
+     * @param
+     * @return
+     * @time 2025/4/25 16:24
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public R publicTask(Map<String, Object> map) {
+        List<Long> ids = (List<Long>) map.get("ids");
+        if (Objects.isNull(ids) || ids.isEmpty()) {
+            throw new CoolException("鍙傛暟涓嶈兘涓虹┖锛侊紒");
+        }
+        List<Wave> waves = this.list(new LambdaQueryWrapper<Wave>().in(Wave::getId, ids));
+        if (Objects.isNull(waves) || waves.isEmpty()) {
+            throw new CoolException("娉㈡鏁版嵁涓嶅瓨鍦紒锛�");
+        }
+
+        List<AsnOrder> orders = asnOrderService.list(new LambdaQueryWrapper<AsnOrder>().eq(AsnOrder::getId, ids));
+
+
+        asnOrderItemService.list(new LambdaQueryWrapper<AsnOrderItem>().eq(AsnOrderItem::getAsnId, ids));
+
+        if (!this.update(new LambdaUpdateWrapper<Wave>().set(Wave::getExceStatus, WaveExceStatus.WAVE_EXCE_STATUS_TASK).in(Wave::getId,ids))) {
+            throw new CoolException("娉㈡鐘舵�佷慨鏀瑰け璐ワ紒锛�");
+        }
+
+        return R.ok();
+    }
 }
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/utils/GroupMergeUtil.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/utils/GroupMergeUtil.java
new file mode 100644
index 0000000..5ccb3d3
--- /dev/null
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/utils/GroupMergeUtil.java
@@ -0,0 +1,154 @@
+package com.vincent.rsf.server.manager.utils;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.google.gson.JsonObject;
+import lombok.Data;
+
+import java.util.*;
+import java.util.function.BinaryOperator;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+/**
+ * @author Ryan
+ * @description 鏍规嵁瀵硅薄澶氫釜灞炴�у悎骞跺鐞�
+ * @param
+ * @return
+ * @time 2025/4/25 10:55
+ */
+public class GroupMergeUtil {
+    /**
+     * 鏍规嵁澶氫釜灞炴�у垎缁勫悎骞跺璞″垪琛�
+     *
+     * @param list       寰呭垎缁勭殑瀵硅薄鍒楄〃
+     * @param mergers    鍚堝苟鍑芥暟锛屽畾涔夊浣曞悎骞跺悓涓�缁勪腑鐨勫璞�
+     * @param keyGetters 鍒嗙粍灞炴�х殑getter鏂规硶鏁扮粍
+     * @param <T>        瀵硅薄绫诲瀷
+     * @param <K>        鍒嗙粍閿被鍨�
+     * @return 鍒嗙粍鍚堝苟鍚庣殑瀵硅薄鍒楄〃
+     */
+    @SafeVarargs
+    public static <T, K> List<T> groupAndMerge(
+            List<T> list,
+            BinaryOperator<T> mergers,
+            Function<T, K>... keyGetters) {
+
+        return new ArrayList<>(list.stream()
+                .collect(Collectors.toMap(
+                        item -> new GroupingKeys<>(Arrays.stream(keyGetters)
+                                .map(getter -> getter.apply(item))
+                                .toArray()),
+                        Function.identity(),
+                        mergers))
+                .values());
+    }
+
+    /**
+     * @author Ryan
+     * @description 鐢ㄤ簬瀛樺偍澶氫釜鍒嗙粍閿殑鍐呴儴绫�
+     * @param
+     * @return
+     * @time 2025/4/25 10:56
+     */
+    private static class GroupingKeys<K> {
+        private final Object[] keys;
+        private final int hashCode;
+
+        public GroupingKeys(Object[] keys) {
+            this.keys = keys;
+            this.hashCode = Arrays.deepHashCode(keys);
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) {
+                return true;
+            }
+            if (o == null || getClass() != o.getClass()) {
+                return false;
+            }
+            GroupingKeys<?> that = (GroupingKeys<?>) o;
+            return Arrays.deepEquals(keys, that.keys);
+        }
+
+        @Override
+        public int hashCode() {
+            return hashCode;
+        }
+    }
+
+    // 绀轰緥浣跨敤
+//    public static void main(String[] args) {
+//        // 绀轰緥鏁版嵁绫�
+//        @Data
+//        class Product {
+//         private String category;
+//            private String subCategory;
+//            private String abc;
+//
+//            private String dbc;
+//
+//            private String brand;
+//            private int quantity;
+//            private double price;
+//
+//            public Product(String category, String abc, String dbc, String subCategory, String brand, int quantity, double price) {
+//                this.category = category;
+//                this.subCategory = subCategory;
+//                this.abc = abc;
+//                this.dbc = dbc;
+//                this.brand = brand;
+//                this.quantity = quantity;
+//                this.price = price;
+//            }
+//
+//            // getters...
+////            public String getCategory() { return category; }
+////            public String getSubCategory() { return subCategory; }
+////            public String getBrand() { return brand; }
+////            public int getQuantity() { return quantity; }
+////            public double getPrice() { return price; }
+//
+//            @Override
+//            public String toString() {
+//                return String.format("[%s, %s, %s] - Qty: %d, Price: %.2f",
+//                        category, subCategory, brand, quantity, price);
+//            }
+//        }
+//
+//        // 鍒涘缓娴嬭瘯鏁版嵁
+//        List<Product> products = Arrays.asList(
+//                new Product("Electronics", "Phone", "Apple", 10, 999.99),
+//                new Product("Electronics", "Phone", "Samsung", 15, 899.99),
+//                new Product("Electronics", "Phone", "Apple", 5, 999.99),
+//                new Product("Electronics", "Tablet", "Apple", 8, 799.99),
+//                new Product("Clothing", "Shirt", "Nike", 20, 29.99),
+//                new Product("Clothing", "Shirt", "Nike", 10, 29.99),
+//                new Product("Clothing", "Pants", "Adidas", 12, 49.99)
+//        );
+//
+//        // 鎸� category, subCategory, brand 鍒嗙粍锛屽悎骞� quantity 鐩稿姞锛宲rice 鍙栧钩鍧囧��
+//        List<Product> mergedProducts = groupAndMerge(
+//                products,
+//                (p1, p2) -> new Product(
+//                        p1.category,
+//                        p1.subCategory,
+//                        p1.brand,
+//                        p1.quantity + p2.quantity,
+//                        (p1.price + p2.price) / 2  // 杩欓噷绠�鍗曞钩鍧囷紝瀹為檯涓氬姟鍙兘涓嶅悓
+//                ),
+//                Product::getCategory,
+//                Product::getSubCategory,
+//                Product::getBrand
+//        );
+//
+////        // 鎵撳嵃缁撴灉
+////        System.out.println("鍚堝苟鍚庣殑浜у搧鍒楄〃:");
+////        System.out.println(JSONArray.toJSONString(mergedProducts));
+////        mergedProducts.forEach(item -> {
+////            System.out.println(JSONObject.toJSONString(item));
+////        });
+////        mergedProducts.forEach(System.out::println);
+//    }
+}
\ No newline at end of file
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/system/constant/DictTypeCode.java b/rsf-server/src/main/java/com/vincent/rsf/server/system/constant/DictTypeCode.java
index 3239e46..8ba60d6 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/system/constant/DictTypeCode.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/system/constant/DictTypeCode.java
@@ -54,4 +54,9 @@
      */
     public final static String DICT_ASN_EXCE_STATUS = "sys_asn_exce_status";
 
+    /**
+     * 浠撳簱搴撳尯绫诲瀷
+     */
+    public final static String SYS_WARE_AREAS_TYPE = "sys_ware_areas_type";
+
 }

--
Gitblit v1.9.1