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