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