From 6cfcfa0b4d2d5a5cd28f4486594eb5db16b679c4 Mon Sep 17 00:00:00 2001
From: skyouc
Date: 星期一, 14 七月 2025 19:18:01 +0800
Subject: [PATCH] 盘点单功能优化

---
 rsf-admin/src/page/orders/check/CheckOrderCreate.jsx                                            |    7 
 rsf-admin/src/page/orders/check/SelectMatnrModal.jsx                                            |   45 ----
 rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/CheckOrderController.java    |   11 +
 rsf-server/src/main/java/com/vincent/rsf/server/manager/service/CheckOrderService.java          |    3 
 rsf-server/src/main/java/com/vincent/rsf/server/manager/enums/CheckOrderType.java               |   14 +
 rsf-admin/src/page/orders/check/CheckOrderModal.jsx                                             |    4 
 rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/CheckOrderServiceImpl.java |   81 ++++++++
 rsf-admin/src/page/orders/check/MatnrInfoModal.jsx                                              |  247 +++++++++++++++++++++++++++
 rsf-server/src/main/java/com/vincent/rsf/server/manager/enums/CheckExceStatus.java              |   20 ++
 rsf-admin/src/page/orders/check/CheckOrderList.jsx                                              |   47 ----
 rsf-server/src/main/resources/application-dev.yml                                               |    2 
 11 files changed, 391 insertions(+), 90 deletions(-)

diff --git a/rsf-admin/src/page/orders/check/CheckOrderCreate.jsx b/rsf-admin/src/page/orders/check/CheckOrderCreate.jsx
index 40fba47..7b8b7a1 100644
--- a/rsf-admin/src/page/orders/check/CheckOrderCreate.jsx
+++ b/rsf-admin/src/page/orders/check/CheckOrderCreate.jsx
@@ -42,9 +42,6 @@
 import DialogCloseButton from "../../components/DialogCloseButton";
 import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting';
 import { styled } from '@mui/material/styles';
-import StatusSelectInput from "../../components/StatusSelectInput";
-import OutOrderItemList from "./OutOrderItemList";
-import MemoInput from "../../components/MemoInput";
 import AddIcon from '@mui/icons-material/Add';
 import SelectMatnrModal from "./SelectMatnrModal";
 
@@ -108,7 +105,7 @@
                     maxWidth="xl"   // 'xs' | 'sm' | 'md' | 'lg' | 'xl'
                 >
                     <Form
-                        resource="outStock"
+                        resource="check"
                     >
                         <DialogTitle id="form-dialog-title" sx={{
                             position: 'sticky',
@@ -206,7 +203,7 @@
 export default OutOrderCreate;
 
 
-const AddOutOrderButton = (setMatCreate) => {
+const AddOutOrderButton = ({setMatCreate}) => {
     const record = useRecordContext();
     const addMats = (event) => {
         event.stopPropagation();
diff --git a/rsf-admin/src/page/orders/check/CheckOrderList.jsx b/rsf-admin/src/page/orders/check/CheckOrderList.jsx
index 228316d..3fec11a 100644
--- a/rsf-admin/src/page/orders/check/CheckOrderList.jsx
+++ b/rsf-admin/src/page/orders/check/CheckOrderList.jsx
@@ -38,6 +38,8 @@
 import DetailsIcon from '@mui/icons-material/Details';
 import AddTaskIcon from '@mui/icons-material/AddTask';
 import PublicIcon from '@mui/icons-material/Public';
+import SelectMatnrModal from "./SelectMatnrModal";
+import CheckOrderModal from "./CheckOrderModal";
 import EditIcon from '@mui/icons-material/Edit';
 import AddIcon from '@mui/icons-material/Add';
 import request from '@/utils/request';
@@ -70,7 +72,7 @@
   <ReferenceInput source="type" reference="dictData" filter={{ dictTypeCode: 'sys_order_type', group: '3' }} label="table.field.checkOrder.type" alwaysOn>
     <AutocompleteInput label="table.field.checkOrder.type" optionValue="value" />
   </ReferenceInput>,
-  <ReferenceInput source="wkType" reference="dictData" filter={{ dictTypeCode: 'sys_check_order_type'}} label="table.field.checkOrder.wkType" alwaysOn>
+  <ReferenceInput source="wkType" reference="dictData" filter={{ dictTypeCode: 'sys_check_order_type' }} label="table.field.checkOrder.wkType" alwaysOn>
     <AutocompleteInput label="table.field.checkOrder.wkType" optionValue="value" />
   </ReferenceInput>,
   <NumberInput source="anfme" label="table.field.checkOrder.anfme" />,
@@ -97,7 +99,6 @@
   const translate = useTranslate();
   const refresh = useRefresh();
   const notify = useNotify();
-
   const [createDialog, setCreateDialog] = useState(false);
   const [manualDialog, setManualDialog] = useState(false);
   const [selectIds, setSelectIds] = useState([]);
@@ -140,7 +141,6 @@
         actions={(
           <TopToolbar>
             <FilterButton />
-            <CreateByOrderButton setCreateDialog={setCreateDialog} />
             <MyCreateButton onClick={() => { setManualDialog(true); setmodalType(0) }} />
             <SelectColumnsButton preferenceKey='check' />
             <ImportButton value={'checkItem'} />
@@ -175,27 +175,20 @@
             <MyButton setCreateDialog={setManualDialog} setmodalType={setmodalType} />
             <EditButton label="toolbar.detail" icon={(<DetailsIcon />)}></EditButton>
             <CancelButton />
-            <PublicButton setDrawerVal={setDrawerVal} drawerVal={drawerVal} setSelect={setSelect} />
           </WrapperField>
         </StyledDatagrid>
       </List>
-      {/* <OutOrderCreate
+      {/* <CheckOrderCreate
         open={manualDialog}
         setOpen={setManualDialog}
       /> */}
-      {/* <SelectMatnrModal
+      <SelectMatnrModal
         asnId={modalType}
         billReload={billReload}
         open={manualDialog}
         setOpen={setManualDialog}
       />
-      <OutOrderModal
-        open={createDialog}
-        setOpen={setCreateDialog}
-        preview={preview}
-        setPreview={setPreview}
-      />
-      <OutStockWaveDialog open={waveRule} setOpen={setWaveRule} onClose={closeDialog} />
+      {/* <OutStockWaveDialog open={waveRule} setOpen={setWaveRule} onClose={closeDialog} />
       <OutOrderPreview open={preview} setOpen={setPreview} />
       <PageEditDrawer
         title={"toolbar.publicWorking"}
@@ -251,19 +244,6 @@
   )
 }
 
-const CreateByOrderButton = ({ setCreateDialog }) => {
-  const record = useRecordContext();
-  const notify = useNotify();
-  const refresh = useRefresh();
-  const createByOrder = async (event) => {
-    event.stopPropagation();
-    setCreateDialog(true);
-  }
-
-  return (
-    <Button onClick={createByOrder} label={'toolbar.asnCreate'}> <AddIcon /> </Button>
-  )
-}
 
 const CancelButton = () => {
   const record = useRecordContext();
@@ -281,20 +261,5 @@
 
   return (
     record?.exceStatus == 10 ? <ConfirmButton label={"toolbar.cancel"} startIcon={<CancelOutlinedIcon />} onConfirm={cancelOrder} size={"small"} /> : <></>
-  )
-}
-
-//涓嬪彂鎵ц
-const PublicButton = ({ setDrawerVal, setSelect }) => {
-  const record = useRecordContext();
-  const refresh = useRefresh();
-  const taskEvent = () => {
-    setDrawerVal(true)
-    setSelect(record)
-    refresh();
-  }
-
-  return (
-    record.workQty < record.anfme ? <Button label={"toolbar.publicWorking"} startIcon={<AddTaskIcon />} onClick={taskEvent} size={"small"} /> : <></>
   )
 }
diff --git a/rsf-admin/src/page/orders/check/OutOrderModal.jsx b/rsf-admin/src/page/orders/check/CheckOrderModal.jsx
similarity index 99%
rename from rsf-admin/src/page/orders/check/OutOrderModal.jsx
rename to rsf-admin/src/page/orders/check/CheckOrderModal.jsx
index 6bea1bd..2136fbb 100644
--- a/rsf-admin/src/page/orders/check/OutOrderModal.jsx
+++ b/rsf-admin/src/page/orders/check/CheckOrderModal.jsx
@@ -91,7 +91,7 @@
     />,
 ]
 
-const OutOrderModal = (props) => {
+const CheckOrderModal = (props) => {
     const { open, setOpen, preview, setPreview, record } = props;
     const translate = useTranslate();
     const [params, setParams] = useState({});
@@ -257,7 +257,7 @@
     )
 }
 
-export default OutOrderModal;
+export default CheckOrderModal;
 
 const AddOutStockButton = (props) => {
     const { setOpen, setPreview, setSelect } = props;
diff --git a/rsf-admin/src/page/orders/check/MatnrInfoModal.jsx b/rsf-admin/src/page/orders/check/MatnrInfoModal.jsx
new file mode 100644
index 0000000..37a571f
--- /dev/null
+++ b/rsf-admin/src/page/orders/check/MatnrInfoModal.jsx
@@ -0,0 +1,247 @@
+import React, { useState, useEffect } from "react";
+import {
+    Dialog,
+    DialogActions,
+    DialogContent,
+    DialogTitle,
+    Stack,
+    Grid,
+    TextField,
+    Box,
+    Button,
+    Paper,
+    styled
+} from '@mui/material';
+import DialogCloseButton from "../../components/DialogCloseButton";
+import { useTranslate, useNotify, useRefresh } from 'react-admin';
+import request from '@/utils/request';
+import { DataGrid } from '@mui/x-data-grid';
+import SaveIcon from '@mui/icons-material/Save';
+import TreeSelectInput from "@/page/components/TreeSelectInput";
+const MatnrInfoModal = (props) => {
+    const { open, setOpen, data, setData } = props;
+
+    const translate = useTranslate();
+    const notify = useNotify();
+    const refresh = useRefresh();
+
+    const handleClose = (event, reason) => {
+        if (reason !== "backdropClick") {
+            setOpen(false);
+        }
+    };
+
+    const [formData, setFormData] = useState({});
+    const [tableData, setTableData] = useState([]);
+    const [dyFields, setDyFields] = useState([]);
+    const [selectedRows, setSelectedRows] = useState([]);
+
+    const handleChange = (e) => {
+        const { name, value } = e.target;
+        setFormData(() => ({
+            [name]: value
+        }));
+    };
+
+    const reset = () => {
+        setFormData({
+            name: '',
+            code: '',
+            groupId: 0
+        })
+    }
+
+    const handleSubmit = () => {
+        const hasarr = data.map(el => +el.matnrId)
+        const selectedData = selectedRows.filter(item => !hasarr.includes(item)).map(id => (tableData.find(row => row.id === id)));
+        const value = selectedData.map((el => {
+            const dynamicFields = dyFields.reduce((acc, item) => {
+                acc[item.fields] = el['extendFields']?.[item.fields] || '';
+                return acc;
+            }, {});
+            return {
+                matnrId: el.id,
+                maktx: el.name,
+                matnrCode: el.code,
+                stockUnit: el.stockUnit || '',
+                purUnit: el.purchaseUnit || '',
+                ...dynamicFields
+            }
+        }))
+        setData([...data, ...value]);
+        setOpen(false);
+        reset();
+    };
+
+    const getData = async () => {
+        const res = await request.post(`/matnr/page`, {
+            ...formData,
+            current: 1,
+            pageSize: 100,
+            orderBy: "create_time desc"
+        });
+        if (res?.data?.code === 200) {
+            setTableData(res.data.data.records);
+        } else {
+            notify(res.data.msg);
+        }
+    };
+
+    useEffect(() => {
+        getData();
+    }, [open]);
+
+    const handleSearch = () => {
+        getData()
+    };
+
+    return (
+        <Dialog
+            open={open}
+            onClose={handleClose}
+            aria-labelledby="form-dialog-title"
+            fullWidth
+            disableRestoreFocus
+            maxWidth="lg"
+        >
+            <DialogTitle id="form-dialog-title" sx={{
+                position: 'sticky',
+                top: 0,
+                backgroundColor: 'background.paper',
+                zIndex: 1000
+            }}>
+                {translate("common.action.newAddMats")}
+                <Box sx={{ position: 'absolute', top: 8, right: 8, zIndex: 1001 }}>
+                    <DialogCloseButton onClose={handleClose} />
+                </Box>
+            </DialogTitle>
+            <DialogContent sx={{ mt: 2 }}>
+                <Box component="form" onSubmit={handleSubmit} sx={{ display: 'flex', flexDirection: 'column', gap: 3 }}>
+                    <Grid container spacing={2}>
+                        <Grid item md={4}>
+                            <TextField
+                                label={translate('table.field.matnr.name')}
+                                name="name"
+                                value={formData.name}
+                                onChange={handleChange}
+                                size="small"
+                            />
+                        </Grid>
+                        <Grid item md={4}>
+                            <TextField
+                                label={translate('table.field.matnr.code')}
+                                name="code"
+                                value={formData.code}
+                                onChange={handleChange}
+                                size="small"
+                            />
+                        </Grid>
+                        <Grid item md={4}>
+                            <TreeSelectInput
+                                label="table.field.matnr.groupId"
+                                value={formData.groupId}
+                                resource={'matnrGroup'}
+                                source="groupId"
+                                name="groupId"
+                                onChange={handleChange}
+                            />
+                        </Grid>
+                    </Grid>
+                </Box>
+                <Box sx={{ mt: 2 }}>
+                    <Stack direction="row" spacing={2}>
+                        <Button variant="contained" onClick={handleSearch}>鎼滅储</Button>
+                    </Stack>
+                </Box>
+                <Box sx={{ mt: 2, height: 400, width: '100%' }}>
+                    <AsnWareModalTable
+                        tableData={tableData}
+                        setTableData={setTableData}
+                        dyFields={dyFields}
+                        setDyFields={setDyFields}
+                        selectedRows={selectedRows}
+                        setSelectedRows={setSelectedRows}
+                    />
+                </Box>
+            </DialogContent>
+            <DialogActions sx={{ position: 'sticky', bottom: 0, backgroundColor: 'background.paper', zIndex: 1000 }}>
+                <Box sx={{ width: '100%', display: 'flex', justifyContent: 'space-between' }}>
+                    <Button onClick={handleSubmit} variant="contained" startIcon={<SaveIcon />}>
+                        {translate('toolbar.confirm')}
+                    </Button>
+                </Box>
+            </DialogActions>
+        </Dialog>
+    );
+};
+
+export default MatnrInfoModal;
+
+const AsnWareModalTable = ({ tableData, setTableData, selectedRows, setSelectedRows, dyFields, setDyFields }) => {
+    const translate = useTranslate();
+    const notify = useNotify();
+
+    const [columns, setColumns] = useState([
+        // { field: 'id', headerName: 'ID', width: 100 },
+        { field: 'name', headerName: translate('table.field.matnr.name'), width: 300 },
+        { field: 'code', headerName: translate('table.field.matnr.code'), width: 200 },
+        { field: 'groupId$', headerName: translate('table.field.matnr.groupId'), width: 100 },
+        { field: 'spec', headerName: translate('table.field.matnr.spec'), width: 100 },
+        { field: 'model', headerName: translate('table.field.matnr.model'), width: 100 },
+        { field: 'weight', headerName: translate('table.field.matnr.weight'), width: 100 },
+        { field: 'describle', headerName: translate('table.field.matnr.describle'), width: 100 },
+        { field: 'nromNum', headerName: translate('table.field.matnr.nromNum'), width: 100 },
+        { field: 'unit', headerName: translate('table.field.matnr.unit'), width: 100 },
+        { field: 'purchaseUnit', headerName: translate('table.field.matnr.purUnit'), width: 100 },
+        { field: 'stockUnit', headerName: translate('table.field.matnr.stockUnit'), width: 100 },
+        { field: 'stockLeval$', headerName: translate('table.field.matnr.stockLevel'), width: 100, sortable: false },
+    ])
+
+
+    const handleSelectionChange = (ids) => {
+        setSelectedRows(ids)
+
+    };
+
+    useEffect(() => {
+        getDynamicFields();
+    }, []);
+
+    const getDynamicFields = async () => {
+        const {
+            data: { code, data, msg },
+        } = await request.get("/fields/enable/list");
+        if (code === 200) {
+            const cols = data.map(el => ({
+                field: el.fields,
+                headerName: el.fieldsAlise,
+                minWidth: 100,
+                flex: 1,
+                editable: el.unique,
+                valueGetter: (value, row) => {
+                    return row.extendFields?.[el.fields] || '';
+                },
+            }))
+            setDyFields(data)
+            setColumns([...columns, ...cols])
+        } else {
+            notify(msg);
+        }
+    }
+
+    return (
+        <div style={{ height: 400, width: '100%' }}>
+            <DataGrid
+                size="small"
+                rows={tableData}
+                columns={columns}
+                checkboxSelection
+                onRowSelectionModelChange={handleSelectionChange}
+                selectionModel={selectedRows}
+                disableColumnMenu={true}
+                disableColumnSorting
+                disableMultipleColumnsSorting
+            />
+        </div>
+    );
+};
\ No newline at end of file
diff --git a/rsf-admin/src/page/orders/check/SelectMatnrModal.jsx b/rsf-admin/src/page/orders/check/SelectMatnrModal.jsx
index 08e9a61..bf53f9c 100644
--- a/rsf-admin/src/page/orders/check/SelectMatnrModal.jsx
+++ b/rsf-admin/src/page/orders/check/SelectMatnrModal.jsx
@@ -44,18 +44,14 @@
     MenuItem
 } from '@mui/material';
 import DialogCloseButton from "../../components/DialogCloseButton";
-import StatusSelectInput from "../../components/StatusSelectInput";
 import ConfirmButton from "../../components/ConfirmButton";
 import MatnrInfoModal from "./MatnrInfoModal";
-import { useForm, Controller, useWatch, FormProvider, useFormContext } from "react-hook-form";
 import SaveIcon from '@mui/icons-material/Save';
 import request from '@/utils/request';
 import { Add, Edit, Delete } from '@mui/icons-material';
-import _, { set } from 'lodash';
 import { DataGrid, useGridApiRef } from '@mui/x-data-grid';
 import DictionarySelect from "../../components/DictionarySelect";
 import DictSelect from "../../components/DictSelect";
-import "./asnOrder.css";
 
 const SelectMatnrModal = (props) => {
     const { open, setOpen, asnId, billReload } = props;
@@ -159,7 +155,7 @@
 
 
     const handleDelete = async () => {
-        const res = await request.post(`/outStock/remove/${asnId}`);
+        const res = await request.post(`/check/remove/${asnId}`);
         if (res?.data?.code === 200) {
             setOpen(false);
             refresh();
@@ -169,7 +165,7 @@
     };
 
     const requestGetHead = async () => {
-        const res = await request.get(`/outStock/${asnId}`);
+        const res = await request.get(`/check/${asnId}`);
         if (res?.data?.code === 200) {
             setFormData(res.data.data)
         } else {
@@ -178,7 +174,7 @@
     }
 
     const requestGetBody = async () => {
-        const res = await request.post(`/outStockItem/page`, { asnId });
+        const res = await request.post(`/checkItem/page`, { asnId });
         if (res?.data?.code === 200) {
             setTableData(res.data.data.records)
         } else {
@@ -219,42 +215,14 @@
                     <Box sx={{ display: 'flex', flexDirection: 'column', gap: 3 }}>
                         <Form defaultValues={formData}>
                             <Grid container spacing={2}>
-                                {/* <Grid item md={2}>
-                                    <DictSelect
-                                        label={translate("table.field.asnOrder.type")}
-                                        value={formData.type}
-                                        onChange={(e) => handleChange(e.target.value, 'type')}
-                                        dictTypeCode="sys_order_type"
-                                        required
-                                    />
-                                </Grid> */}
                                 <Grid item md={2}>
                                     <DictSelect
-                                        label={translate("table.field.outStock.wkType")}
+                                        label={translate("table.field.checkOrder.checkType")}
                                         value={formData.wkType}
                                         variant="filled"
-                                        group='2'
                                         onChange={(e) => handleChange(e.target.value, 'wkType')}
-                                        dictTypeCode="sys_business_type"
+                                        dictTypeCode="sys_check_order_type"
                                         required
-                                    />
-                                </Grid>
-                                <Grid item md={2}>
-                                    <TextField
-                                        label={translate("table.field.outStock.poCode")}
-                                        value={formData.poCode}
-                                        variant="filled"
-                                        size='small'
-                                        onChange={(e) => handleChange(e.target.value, 'poCode')}
-                                    />
-                                </Grid>
-                                <Grid item md={2}>
-                                    <TextField
-                                        label={translate("table.field.outStock.logisNo")}
-                                        value={formData.logisNo}
-                                        variant="filled"
-                                        size='small'
-                                        onChange={(e) => handleChange(e.target.value, 'logisNo')}
                                     />
                                 </Grid>
                                 <Grid item md={2}>
@@ -270,11 +238,9 @@
                             </Grid>
                         </Form>
                     </Box>
-
                     <Box sx={{ mt: 2 }}>
                         <Stack direction="row" spacing={2}>
                             <Button variant="contained" onClick={() => setCreateDialog(true)}>鏂板鐗╂枡</Button>
-                            {/* {asnId !== '' && <ConfirmButton label={'鍒犻櫎'} variant="outlined" color="error" onConfirm={handleDelete} />} */}
                             <ConfirmButton label={'鍒犻櫎'} variant="outlined" color="error" onConfirm={handleDeleteItem} />
                         </Stack>
                     </Box>
@@ -516,6 +482,7 @@
         if (code === 200) {
             const cols = data.map(el => ({
                 field: el.fields,
+                key: el.id,
                 headerName: el.fieldsAlise,
                 minWidth: 100,
                 flex: 1,
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/CheckOrderController.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/CheckOrderController.java
index 48ffb18..b6133ac 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/CheckOrderController.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/CheckOrderController.java
@@ -10,6 +10,7 @@
 import com.vincent.rsf.server.common.domain.KeyValVo;
 import com.vincent.rsf.server.common.domain.PageParam;
 import com.vincent.rsf.server.common.utils.ExcelUtil;
+import com.vincent.rsf.server.manager.controller.params.AsnOrderAndItemsParams;
 import com.vincent.rsf.server.manager.entity.AsnOrder;
 import com.vincent.rsf.server.manager.enums.OrderType;
 import com.vincent.rsf.server.manager.service.CheckOrderService;
@@ -124,6 +125,16 @@
         ExcelUtil.build(ExcelUtil.create(orders, AsnOrder.class), response);
     }
 
+    @PostMapping("/check/items/save")
+    @ApiOperation("淇濆瓨涓诲崟鍙婃槑缁�")
+    @PreAuthorize("hasAuthority('manager:check:save')")
+    public R saveOutStock(@RequestBody AsnOrderAndItemsParams params) throws Exception {
+        if (Objects.isNull(params)) {
+            return R.error("鍙傛暟涓嶈兘涓虹┖锛侊紒");
+        }
+        return checkOrderService.saveCheckOrder(params, getLoginUserId());
+    }
+
 
 
     /**
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/enums/CheckExceStatus.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/enums/CheckExceStatus.java
new file mode 100644
index 0000000..7abfd51
--- /dev/null
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/enums/CheckExceStatus.java
@@ -0,0 +1,20 @@
+package com.vincent.rsf.server.manager.enums;
+
+
+public enum CheckExceStatus {
+
+    CHECK_ORDER_STATUS_UN_EXCE("1", "鏈墽琛�"),
+    CHECK_ORDER_STATUS_INIT("2", "鍒濆鍖�"),
+    CHECK_ORDER_STATUS_EXCE_ING("3", "鎵ц涓�"),
+    CHECK_ORDER_STATUS_EXCE_DONE("4", "鎵ц瀹屾垚"),
+
+    ;
+
+    CheckExceStatus(String val, String desc) {
+        this.val = Short.parseShort(val);
+        this.desc = desc;
+    }
+
+    public Short val;
+    public String desc;
+}
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/enums/CheckOrderType.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/enums/CheckOrderType.java
index ad0ab62..701642a 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/enums/CheckOrderType.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/enums/CheckOrderType.java
@@ -7,13 +7,25 @@
  * @version 1.0
  */
 public enum CheckOrderType {
-
+    //鐩樼偣淇℃伅锛�1.涓存椂鐩樼偣锛� 2.鎶芥牱鐩樼偣锛� 3. 鍖哄煙鐩樼偣锛�4. 宸紓鐩樼偣 5. 寰幆鐩樼偣 6. 瀹氭湡鐩樼偣
     CHECK_ORDER_TYPE_TEMP("1", "涓存椂鐩樼偣"),
     CHECK_ORDER_TYPE_ROUND("2", "鎶芥牱鐩樼偣"),
     CHECK_ORDER_TYPE_AREAS("3", "鍖哄煙鐩樼偣"),
     CHECK_ORDER_TYPE_DIFF("4", "宸紓鐩樼偣"),
     CHECK_ORDER_TYPE_CIRCLE("5", "寰幆鐩樼偣"),
+    CHECK_ORDER_TYPE_TIMER("6", "瀹氭湡鐩樼偣"),
+    ;
 
+    CheckOrderType(String type, String desc) {
+        this.type = Integer.parseInt(type);
+        this.desc = desc;
+    }
 
+    public Integer type;
+    public String desc;
+
+    public static String getOrderType() {
+        return null;
+    }
 
 }
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/CheckOrderService.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/CheckOrderService.java
index aee567f..c847096 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/CheckOrderService.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/CheckOrderService.java
@@ -2,6 +2,7 @@
 
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.vincent.rsf.framework.common.R;
+import com.vincent.rsf.server.manager.controller.params.AsnOrderAndItemsParams;
 import com.vincent.rsf.server.manager.entity.AsnOrder;
 import org.springframework.web.multipart.MultipartFile;
 
@@ -10,4 +11,6 @@
 public interface CheckOrderService extends IService<AsnOrder> {
 
     R excelImport(MultipartFile file, HashMap<String, Object> hashMap, Long loginUserId);
+
+    R saveCheckOrder(AsnOrderAndItemsParams params, Long loginUserId);
 }
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/CheckOrderServiceImpl.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/CheckOrderServiceImpl.java
index a481d1f..6c3fd66 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/CheckOrderServiceImpl.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/CheckOrderServiceImpl.java
@@ -8,17 +8,22 @@
 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.manager.controller.params.AsnOrderAndItemsParams;
 import com.vincent.rsf.server.manager.entity.AsnOrder;
 import com.vincent.rsf.server.manager.entity.AsnOrderItem;
 import com.vincent.rsf.server.manager.entity.Matnr;
 import com.vincent.rsf.server.manager.entity.excel.CheckOrderTemplate;
 import com.vincent.rsf.server.manager.enums.AsnExceStatus;
+import com.vincent.rsf.server.manager.enums.CheckExceStatus;
 import com.vincent.rsf.server.manager.enums.OrderType;
 import com.vincent.rsf.server.manager.enums.OrderWorkType;
 import com.vincent.rsf.server.manager.mapper.CheckOrderMapper;
+import com.vincent.rsf.server.manager.service.AsnOrderItemService;
 import com.vincent.rsf.server.manager.service.CheckOrderItemService;
 import com.vincent.rsf.server.manager.service.CheckOrderService;
 import com.vincent.rsf.server.manager.service.MatnrService;
+import com.vincent.rsf.server.system.constant.SerialRuleCode;
+import com.vincent.rsf.server.system.utils.SerialRuleUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -33,9 +38,10 @@
 
     @Autowired
     private MatnrService matnrService;
-
     @Autowired
     private CheckOrderItemService checkOrderItemService;
+    @Autowired
+    private AsnOrderItemService asnOrderItemService;
 
     /**
      * @author Ryan
@@ -109,4 +115,77 @@
 
         return R.ok("鎿嶄綔鎴愬姛锛侊紒");
     }
+
+    /**
+     * @param
+     * @return
+     * @author Ryan
+     * @description 淇濆瓨鍑哄簱涓诲崟鍙婃槑缁�
+     * @time 2025/4/29 13:47
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public R saveCheckOrder(AsnOrderAndItemsParams params, Long loginUserId) {
+        if (Objects.isNull(params.getOrders())) {
+            throw new CoolException("涓诲崟淇℃伅涓嶈兘涓虹┖");
+        }
+        AsnOrder orders = params.getOrders();
+        if (StringUtils.isBlank(orders.getWkType())) {
+            throw new CoolException("涓氬姟绫诲瀷涓嶈兘涓虹┖锛侊紒");
+        }
+
+        String ruleCode = SerialRuleUtils.generateRuleCode(SerialRuleCode.SYS_CHECK_RULE_CODE, orders);
+        if (StringUtils.isBlank(ruleCode)) {
+            throw new CoolException("缂栫爜瑙勫垯閿欒锛氳妫�鏌ャ�孲YS_CHECK_RULE_CODE銆嶆槸鍚﹁缃纭紒锛�");
+        }
+        orders.setCode(ruleCode)
+                .setType(OrderType.ORDER_CHECK.type)
+                .setExceStatus(CheckExceStatus.CHECK_ORDER_STATUS_UN_EXCE.val)
+                .setUpdateBy(loginUserId)
+                .setCreateBy(loginUserId);
+        if (!this.save(orders)) {
+            throw new CoolException("涓诲崟淇濆瓨澶辫触锛侊紒");
+        }
+        if (params.getItems().isEmpty()) {
+            throw new CoolException("鐩樼偣鍗曟槑缁嗕笉鑳戒负绌猴紒锛�");
+        }
+        params.setOrders(orders);
+        try {
+            svaeOrUpdateOrderItem(params, loginUserId);
+        } catch (Exception e) {
+            throw new CoolException(e.getMessage());
+        }
+        return R.ok();
+    }
+
+    /**
+     * @param
+     * @return
+     * @author Ryan
+     * @description 鏇存柊鎴栦繚瀛樻槑缁�
+     * @time 2025/4/7 13:28
+     */
+    @Transactional(rollbackFor = Exception.class)
+    public void svaeOrUpdateOrderItem(AsnOrderAndItemsParams params, Long loginUserId) throws Exception {
+        AsnOrder orders = params.getOrders();
+        params.getItems().forEach(item -> {
+            item.put("asnId", orders.getId());
+            item.put("asnCode", orders.getCode());
+            item.put("poCode", orders.getPoCode());
+            item.put("createBy", loginUserId);
+            item.put("updateBy", loginUserId);
+            if (!asnOrderItemService.fieldsSave(item, loginUserId)) {
+                throw new CoolException("鏄庣粏淇濆瓨澶辫触锛侊紒");
+            }
+        });
+        List<AsnOrderItem> orderItems = checkOrderItemService.list(new LambdaQueryWrapper<AsnOrderItem>()
+                .eq(AsnOrderItem::getAsnId, params.getOrders().getId()));
+        Double sum = orderItems.stream().mapToDouble(AsnOrderItem::getAnfme).sum();
+        orders.setAnfme(sum);
+        if (!this.updateById(orders)) {
+            throw new CoolException("璁″垝鏀惰揣鏁伴噺淇敼澶辫触锛侊紒");
+        }
+    }
+
+
 }
diff --git a/rsf-server/src/main/resources/application-dev.yml b/rsf-server/src/main/resources/application-dev.yml
index cfb08a3..95669f3 100644
--- a/rsf-server/src/main/resources/application-dev.yml
+++ b/rsf-server/src/main/resources/application-dev.yml
@@ -15,7 +15,7 @@
 #    url: jdbc:mysql://47.76.147.249:3306/rsf?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
 #    username: rsf
     username: root
-    url: jdbc:mysql://192.168.4.151:3306/rsf?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
+    url: jdbc:mysql://127.0.0.1:3306/rsf?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
     password: 34821015
     type: com.alibaba.druid.pool.DruidDataSource
     druid:

--
Gitblit v1.9.1