From bcf39531dcfaea85297312405fbecc7eebccf7d0 Mon Sep 17 00:00:00 2001 From: skyouc Date: 星期五, 25 四月 2025 09:33:21 +0800 Subject: [PATCH] #新增 1. 新增波次列表及详情 2. 新增立库站点绑定 --- rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/OutStockServiceImpl.java | 63 + rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/WaveItem.java | 291 +++++ rsf-admin/src/page/wave/WaveEdit.jsx | 130 ++ rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/DeviceBindServiceImpl.java | 12 rsf-server/src/main/java/com/vincent/rsf/server/common/CodeBuilder.java | 6 rsf-server/src/main/java/com/vincent/rsf/server/manager/service/DeviceBindService.java | 8 rsf-admin/src/page/orders/outStock/OutOrderModal.jsx | 34 rsf-admin/src/page/deviceBind/DeviceBindEdit.jsx | 146 ++ rsf-server/src/main/java/waveItem.sql | 35 rsf-admin/src/page/orders/outStock/OutOrderList.jsx | 32 rsf-admin/src/i18n/en.js | 17 rsf-admin/src/page/ResourceContent.js | 3 rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/WaveServiceImpl.java | 12 rsf-server/src/main/java/com/vincent/rsf/server/manager/service/OutStockService.java | 2 rsf-server/src/main/resources/mapper/manager/WaveMapper.xml | 5 rsf-admin/src/page/wave/WavePanel.jsx | 87 + rsf-admin/src/page/waveItem/WaveItemPanel.jsx | 135 ++ rsf-admin/src/page/wave/WaveCreate.jsx | 158 ++ rsf-server/src/main/resources/mapper/manager/DeviceBindMapper.xml | 5 rsf-admin/src/page/basicInfo/deviceSite/DeviceSiteList.jsx | 5 rsf-admin/src/page/basicInfo/deviceSite/InitModal.jsx | 26 rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/OutStockController.java | 11 rsf-admin/src/page/waveItem/index.jsx | 18 rsf-server/src/main/java/com/vincent/rsf/server/manager/service/WaveItemService.java | 8 rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/DeviceSiteServiceImpl.java | 25 rsf-admin/src/page/waveItem/WaveItemList.jsx | 178 +++ rsf-admin/src/page/deviceBind/DeviceBindCreate.jsx | 174 +++ rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/DeviceBind.java | 133 ++ rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/DeviceSite.java | 6 rsf-server/src/main/java/com/vincent/rsf/server/manager/service/WaveService.java | 8 rsf-server/src/main/resources/mapper/manager/WaveItemMapper.xml | 5 rsf-admin/src/i18n/zh.js | 27 rsf-admin/src/page/deviceBind/DeviceBindPanel.jsx | 111 + rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/Wave.java | 249 ++++ rsf-server/src/main/java/com/vincent/rsf/server/manager/mapper/WaveMapper.java | 12 rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/WaveController.java | 108 + rsf-admin/src/page/wave/index.jsx | 18 rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/WaveItemController.java | 110 + rsf-admin/src/page/wave/WaveList.jsx | 174 +++ rsf-server/src/main/java/com/vincent/rsf/server/manager/mapper/WaveItemMapper.java | 12 rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/params/DeviceSiteParame.java | 5 rsf-server/src/main/java/com/vincent/rsf/server/system/constant/SerialRuleCode.java | 5 rsf-server/src/main/java/wave.sql | 27 rsf-server/src/main/java/com/vincent/rsf/server/manager/enums/WaveExceStatus.java | 27 rsf-admin/src/page/basicInfo/loc/LocList.jsx | 16 rsf-server/src/main/java/deviceBind.sql | 31 rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/WaveItemServiceImpl.java | 12 rsf-admin/src/page/deviceBind/DeviceBindList.jsx | 170 ++ rsf-server/src/main/java/com/vincent/rsf/server/manager/mapper/DeviceBindMapper.java | 12 rsf-admin/src/page/deviceBind/index.jsx | 18 rsf-admin/src/page/waveItem/WaveItemEdit.jsx | 176 +++ rsf-admin/src/page/waveItem/WaveItemCreate.jsx | 204 +++ rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/DeviceBindController.java | 110 + 53 files changed, 3,350 insertions(+), 62 deletions(-) diff --git a/rsf-admin/src/i18n/en.js b/rsf-admin/src/i18n/en.js index 0f29dff..d81da4f 100644 --- a/rsf-admin/src/i18n/en.js +++ b/rsf-admin/src/i18n/en.js @@ -70,6 +70,7 @@ loadMore: 'Load More Data', complete: 'Complete', deprecate: 'Deprecate', + inputPlaceholder: 'Use commas to separate', resend: 'RESEND', selected: 'selected', batch: 'batch' @@ -175,6 +176,7 @@ outStockItem: 'Out Stock Item', inStockPoces: 'In Stock Pocess', outStockPoces: 'Out Stock Pocess', + deviceBind: 'Device Bind', }, table: { field: { @@ -616,6 +618,7 @@ }, deliveryItem: { deliveryId: "deliveryId", + deliveryCode: "Delivery Code", platItemId: "platItemId", matnrCode: "matnrCode", matnrName: "matnrName", @@ -667,7 +670,6 @@ deviceCode: "deviceCode", deviceSite: "deviceSite", flagInit: "flagInit", - sites: "sites", }, waitPakin: { code: "code", @@ -833,6 +835,18 @@ model: "model", fieldsIndex: "fieldsIndex", }, + deviceBind: { + currentRow: "currentRow", + startRow: "startRow", + endRow: "endRow", + deviceQty: "deviceQty", + startDeviceNo: "startDeviceNo", + endDeviceNo: "endDeviceNo", + staList: "staList", + typeId: "typeId", + beSimilar: "beSimilar", + emptySimilar: "emptySimilar", + }, } }, page: { @@ -944,6 +958,7 @@ asnCreate: "Create By Order", createTask: "createTask", recover: "recover", + createWave: "Create Wave", order: 'Orders', }, diff --git a/rsf-admin/src/i18n/zh.js b/rsf-admin/src/i18n/zh.js index 44b724e..82b5bb0 100644 --- a/rsf-admin/src/i18n/zh.js +++ b/rsf-admin/src/i18n/zh.js @@ -58,6 +58,7 @@ collapse: '鎶樺彔', collapseAll: '鍏ㄩ儴鎶樺彔', scope: '鏉冮檺', + inputPlaceholder: '绔欑偣鍙~澶氫釜锛屼腑闂翠互鑻辨枃閫楀彿鍖哄垎锛�,锛�', import: { title: '瀵煎叆', stop: '鍋滄瀵煎叆', @@ -176,6 +177,7 @@ outStockItem: '鍑哄簱鍗曟槑缁�', inStockPoces: '鍏ュ簱娴佺▼', outStockPoces: '鍑哄簱娴佺▼', + deviceBind: '璁惧缁戝畾', }, table: { field: { @@ -361,8 +363,8 @@ loc: { warehouseId: "鎵�灞炰粨搴�", areaId: "鎵�灞炲簱鍖�", - code: "搴撲綅缂栫爜", - type: "搴撲綅绫诲瀷", + code: "缂栫爜", + type: "绫诲瀷", name: "鍚嶇О", flagLogic: "铏氭嫙搴撲綅", fucAtrrs: "鍔熻兘灞炴��", @@ -661,6 +663,7 @@ }, deliveryItem: { deliveryId: "涓诲崟ID", + deliveryCode: "鍗曞彿", platItemId: "琛屽彿", matnrCode: "鐗╂枡缂栫爜", matnrName: "鐗╂枡鍚嶇О", @@ -704,15 +707,14 @@ }, deviceSite: { type: "鍏ュ嚭搴撶被鍨�", - site: "绔欑偣缂栧彿", + site: "浣滀笟绔欑偣", name: "鍚嶇О", - wcsCode: "wcs绔欑偣缂栧彿", + target: "鐩爣绔欑偣", label: "绔欑偣鏍囩", device: "绔嬪簱绫诲瀷", deviceCode: "璁惧缂栧彿", deviceSite: "璁惧绔欑偣", flagInit: "鏄惁鍒濆鍖�", - sites: "浣滀笟绔欑偣", }, waitPakin: { code: "缂栫爜", @@ -878,6 +880,18 @@ model: "鍨嬪彿", fieldsIndex: "鍔ㄦ�佺储寮�", }, + deviceBind: { + currentRow: "褰撳墠鎺掑彿", + startRow: "璧峰鎺掑彿", + endRow: "缁堟鎺掑彿", + deviceQty: "璁惧鏁伴噺", + startDeviceNo: "璧峰璁惧鍙�", + endDeviceNo: "缁堟璁惧鍙�", + staList: "绔欑偣闆�", + typeId: "搴撳尯绫诲瀷", + beSimilar: "鐩镐技寮�鍏�", + emptySimilar: "绌烘澘闈犺繎寮�鍏�", + }, } }, page: { @@ -991,7 +1005,8 @@ complete: "瀹屾垚", close: "鍏抽棴", asnCreate: "閫氳繃鍗曟嵁鍒涘缓", - createTask: "鐢熸垚浠诲姟", + createTask: "涓嬪彂浠诲姟", + createWave: "鐢熸垚娉㈡", recover: "缁х画鏀惰揣", }, }; diff --git a/rsf-admin/src/page/ResourceContent.js b/rsf-admin/src/page/ResourceContent.js index 5dd2787..b3271cf 100644 --- a/rsf-admin/src/page/ResourceContent.js +++ b/rsf-admin/src/page/ResourceContent.js @@ -43,6 +43,7 @@ import stock from './orders/stock'; import delivery from './orders/delivery'; import outStock from './orders/outStock'; +import deviceBind from './deviceBind'; const ResourceContent = (node) => { @@ -125,6 +126,8 @@ return delivery; case 'outStock': return outStock; + case 'deviceBind': + return deviceBind; default: return { list: ListGuesser, diff --git a/rsf-admin/src/page/basicInfo/deviceSite/DeviceSiteList.jsx b/rsf-admin/src/page/basicInfo/deviceSite/DeviceSiteList.jsx index 21321b5..706513c 100644 --- a/rsf-admin/src/page/basicInfo/deviceSite/DeviceSiteList.jsx +++ b/rsf-admin/src/page/basicInfo/deviceSite/DeviceSiteList.jsx @@ -148,18 +148,17 @@ preferenceKey='deviceSite' bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />} rowClick={(id, resource, record) => false} - omit={['id', 'createTime', 'createBy', 'memo']} + omit={['id', 'createTime', 'createBy', 'memo', 'label']} > <NumberField source="id" /> <TextField source="name" label="table.field.deviceSite.name" /> <NumberField source="type$" label="table.field.deviceSite.type" /> <TextField source="site" label="table.field.deviceSite.site" /> - <TextField source="wcsCode" label="table.field.deviceSite.wcsCode" /> + <TextField source="target" label="table.field.deviceSite.target" /> <TextField source="label" label="table.field.deviceSite.label" /> <TextField source="device$" label="table.field.deviceSite.device" /> <TextField source="deviceCode" label="table.field.deviceSite.deviceCode" /> <TextField source="deviceSite" label="table.field.deviceSite.deviceSite" /> - <ReferenceField source="updateBy" label="common.field.updateBy" reference="user" link={false} sortable={false}> <TextField source="nickname" /> </ReferenceField> diff --git a/rsf-admin/src/page/basicInfo/deviceSite/InitModal.jsx b/rsf-admin/src/page/basicInfo/deviceSite/InitModal.jsx index fbd1634..163c261 100644 --- a/rsf-admin/src/page/basicInfo/deviceSite/InitModal.jsx +++ b/rsf-admin/src/page/basicInfo/deviceSite/InitModal.jsx @@ -95,7 +95,7 @@ return ( - <Dialog open={open} maxWidth="md" fullWidth> + <Dialog open={open} maxWidth="lg" fullWidth> <Form onSubmit={handleSubmit}> <DialogCloseButton onClose={handleClose} /> <DialogTitle>{translate('toolbar.siteInit')}</DialogTitle> @@ -119,8 +119,6 @@ dictTypeCode="sys_device_type" /> </Grid> - - <Grid item xs={4}> <TextInput label={translate("table.field.deviceSite.deviceCode")} @@ -129,25 +127,33 @@ type="number" /> </Grid> - <Grid item xs={4}> <TextInput label={translate("table.field.deviceSite.deviceSite")} name="deviceSites" + placeholder={translate('common.action.inputPlaceholder')} size="small" - type="number" + // type="number" /> </Grid> - <Grid item xs={4}> <TextInput - label={translate("table.field.deviceSite.sites")} - name="sites" + label={translate("table.field.deviceSite.site")} + name="site" + placeholder={translate('common.action.inputPlaceholder')} size="small" - type="number" + // type="number" /> </Grid> - + <Grid item xs={4}> + <TextInput + label={translate("table.field.deviceSite.target")} + name="target" + placeholder={translate('common.action.inputPlaceholder')} + size="small" + // type="number" + /> + </Grid> <Grid item xs={4}> <SelectInput label="table.field.deviceSite.flagInit" diff --git a/rsf-admin/src/page/basicInfo/loc/LocList.jsx b/rsf-admin/src/page/basicInfo/loc/LocList.jsx index 3484d69..ef686d0 100644 --- a/rsf-admin/src/page/basicInfo/loc/LocList.jsx +++ b/rsf-admin/src/page/basicInfo/loc/LocList.jsx @@ -66,20 +66,20 @@ '& .column-name': { }, '& .opt': { - width: 200 + width: 180 }, - '& .RaDatagrid-headerCell': { - textAlign: 'left' - }, - '& .RaDatagrid-rowCell': { - textAlign: 'left' - }, + // '& .RaDatagrid-headerCell': { + // textAlign: 'left' + // }, + // '& .RaDatagrid-rowCell': { + // textAlign: 'left' + // }, '& .type .MuiTypography-root': { whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis', display: 'block', - width: '200px', + width: 'auto', }, })); diff --git a/rsf-admin/src/page/deviceBind/DeviceBindCreate.jsx b/rsf-admin/src/page/deviceBind/DeviceBindCreate.jsx new file mode 100644 index 0000000..101d8d4 --- /dev/null +++ b/rsf-admin/src/page/deviceBind/DeviceBindCreate.jsx @@ -0,0 +1,174 @@ +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 DeviceBindCreate = (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.deviceBind.currentRow" + source="currentRow" + autoFocus + /> + </Grid> + <Grid item xs={6} display="flex" gap={1}> + <NumberInput + label="table.field.deviceBind.startRow" + source="startRow" + /> + </Grid> + <Grid item xs={6} display="flex" gap={1}> + <NumberInput + label="table.field.deviceBind.endRow" + source="endRow" + /> + </Grid> + <Grid item xs={6} display="flex" gap={1}> + <NumberInput + label="table.field.deviceBind.deviceQty" + source="deviceQty" + /> + </Grid> + <Grid item xs={6} display="flex" gap={1}> + <NumberInput + label="table.field.deviceBind.startDeviceNo" + source="startDeviceNo" + /> + </Grid> + <Grid item xs={6} display="flex" gap={1}> + <NumberInput + label="table.field.deviceBind.endDeviceNo" + source="endDeviceNo" + /> + </Grid> + <Grid item xs={6} display="flex" gap={1}> + <TextInput + label="table.field.deviceBind.staList" + source="staList" + parse={v => v} + /> + </Grid> + <Grid item xs={6} display="flex" gap={1}> + <NumberInput + label="table.field.deviceBind.typeId" + source="typeId" + /> + </Grid> + <Grid item xs={6} display="flex" gap={1}> + <TextInput + label="table.field.deviceBind.beSimilar" + source="beSimilar" + parse={v => v} + /> + </Grid> + <Grid item xs={6} display="flex" gap={1}> + <TextInput + label="table.field.deviceBind.emptySimilar" + source="emptySimilar" + parse={v => v} + /> + </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 DeviceBindCreate; diff --git a/rsf-admin/src/page/deviceBind/DeviceBindEdit.jsx b/rsf-admin/src/page/deviceBind/DeviceBindEdit.jsx new file mode 100644 index 0000000..9bd771b --- /dev/null +++ b/rsf-admin/src/page/deviceBind/DeviceBindEdit.jsx @@ -0,0 +1,146 @@ +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 DeviceBindEdit = () => { + 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}> + <NumberInput + label="table.field.deviceBind.currentRow" + source="currentRow" + autoFocus + /> + </Stack> + <Stack direction='row' gap={2}> + <NumberInput + label="table.field.deviceBind.startRow" + source="startRow" + /> + </Stack> + <Stack direction='row' gap={2}> + <NumberInput + label="table.field.deviceBind.endRow" + source="endRow" + /> + </Stack> + <Stack direction='row' gap={2}> + <NumberInput + label="table.field.deviceBind.deviceQty" + source="deviceQty" + /> + </Stack> + <Stack direction='row' gap={2}> + <NumberInput + label="table.field.deviceBind.startDeviceNo" + source="startDeviceNo" + /> + </Stack> + <Stack direction='row' gap={2}> + <NumberInput + label="table.field.deviceBind.endDeviceNo" + source="endDeviceNo" + /> + </Stack> + <Stack direction='row' gap={2}> + <TextInput + label="table.field.deviceBind.staList" + source="staList" + parse={v => v} + /> + </Stack> + <Stack direction='row' gap={2}> + <NumberInput + label="table.field.deviceBind.typeId" + source="typeId" + /> + </Stack> + <Stack direction='row' gap={2}> + <TextInput + label="table.field.deviceBind.beSimilar" + source="beSimilar" + parse={v => v} + /> + </Stack> + <Stack direction='row' gap={2}> + <TextInput + label="table.field.deviceBind.emptySimilar" + source="emptySimilar" + parse={v => v} + /> + </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 DeviceBindEdit; diff --git a/rsf-admin/src/page/deviceBind/DeviceBindList.jsx b/rsf-admin/src/page/deviceBind/DeviceBindList.jsx new file mode 100644 index 0000000..7b47945 --- /dev/null +++ b/rsf-admin/src/page/deviceBind/DeviceBindList.jsx @@ -0,0 +1,170 @@ +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, +} from 'react-admin'; +import { Box, Typography, Card, Stack } from '@mui/material'; +import { styled } from '@mui/material/styles'; +import DeviceBindCreate from "./DeviceBindCreate"; +import DeviceBindPanel from "./DeviceBindPanel"; +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 { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting'; +import * as Common from '@/utils/common'; + +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="currentRow" label="table.field.deviceBind.currentRow" />, + <NumberInput source="startRow" label="table.field.deviceBind.startRow" />, + <NumberInput source="endRow" label="table.field.deviceBind.endRow" />, + <NumberInput source="deviceQty" label="table.field.deviceBind.deviceQty" />, + <NumberInput source="startDeviceNo" label="table.field.deviceBind.startDeviceNo" />, + <NumberInput source="endDeviceNo" label="table.field.deviceBind.endDeviceNo" />, + <TextInput source="staList" label="table.field.deviceBind.staList" />, + <NumberInput source="typeId" label="table.field.deviceBind.typeId" />, + <TextInput source="beSimilar" label="table.field.deviceBind.beSimilar" />, + <TextInput source="emptySimilar" label="table.field.deviceBind.emptySimilar" />, + + <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 DeviceBindList = () => { + const translate = useTranslate(); + + const [createDialog, setCreateDialog] = useState(false); + const [drawerVal, setDrawerVal] = useState(false); + + return ( + <Box display="flex"> + <List + sx={{ + flexGrow: 1, + transition: (theme) => + theme.transitions.create(['all'], { + duration: theme.transitions.duration.enteringScreen, + }), + marginRight: !!drawerVal ? `${PAGE_DRAWER_WIDTH}px` : 0, + }} + title={"menu.deviceBind"} + empty={<EmptyData onClick={() => { setCreateDialog(true) }} />} + filters={filters} + sort={{ field: "create_time", order: "desc" }} + actions={( + <TopToolbar> + <FilterButton /> + <MyCreateButton onClick={() => { setCreateDialog(true) }} /> + <SelectColumnsButton preferenceKey='deviceBind' /> + <MyExportButton /> + </TopToolbar> + )} + perPage={DEFAULT_PAGE_SIZE} + > + <StyledDatagrid + preferenceKey='deviceBind' + bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />} + rowClick={(id, resource, record) => false} + expand={() => <DeviceBindPanel />} + expandSingle={true} + omit={['id', 'createTime', 'createBy', 'memo']} + > + <NumberField source="id" /> + <NumberField source="currentRow" label="table.field.deviceBind.currentRow" /> + <NumberField source="startRow" label="table.field.deviceBind.startRow" /> + <NumberField source="endRow" label="table.field.deviceBind.endRow" /> + <NumberField source="deviceQty" label="table.field.deviceBind.deviceQty" /> + <NumberField source="startDeviceNo" label="table.field.deviceBind.startDeviceNo" /> + <NumberField source="endDeviceNo" label="table.field.deviceBind.endDeviceNo" /> + <TextField source="staList" label="table.field.deviceBind.staList" /> + <NumberField source="typeId" label="table.field.deviceBind.typeId" /> + <TextField source="beSimilar" label="table.field.deviceBind.beSimilar" /> + <TextField source="emptySimilar" label="table.field.deviceBind.emptySimilar" /> + + <ReferenceField source="updateBy" label="common.field.updateBy" reference="user" link={false} sortable={false}> + <TextField source="nickname" /> + </ReferenceField> + <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> + <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} /> + <WrapperField cellClassName="opt" label="common.field.opt"> + <EditButton sx={{ padding: '1px', fontSize: '.75rem' }} /> + <DeleteButton sx={{ padding: '1px', fontSize: '.75rem' }} mutationMode={OPERATE_MODE} /> + </WrapperField> + </StyledDatagrid> + </List> + <DeviceBindCreate + open={createDialog} + setOpen={setCreateDialog} + /> + <PageDrawer + title='DeviceBind Detail' + drawerVal={drawerVal} + setDrawerVal={setDrawerVal} + > + </PageDrawer> + </Box> + ) +} + +export default DeviceBindList; diff --git a/rsf-admin/src/page/deviceBind/DeviceBindPanel.jsx b/rsf-admin/src/page/deviceBind/DeviceBindPanel.jsx new file mode 100644 index 0000000..fa74506 --- /dev/null +++ b/rsf-admin/src/page/deviceBind/DeviceBindPanel.jsx @@ -0,0 +1,111 @@ +import React, { useState, useRef, useEffect, useMemo } from "react"; +import { Box, Card, CardContent, Grid, Typography, Tooltip } from '@mui/material'; +import { + useTranslate, + useRecordContext, +} from 'react-admin'; +import PanelTypography from "../components/PanelTypography"; +import * as Common from '@/utils/common' + +const DeviceBindPanel = () => { + const record = useRecordContext(); + if (!record) return null; + const translate = useTranslate(); + return ( + <> + <Card sx={{ width: { xs: 300, sm: 500, md: 600, lg: 800 }, margin: 'auto' }}> + <CardContent> + <Grid container spacing={2}> + <Grid item xs={12} sx={{ display: 'flex', justifyContent: 'space-between' }}> + <Typography variant="h6" gutterBottom align="left" sx={{ + maxWidth: { xs: '100px', sm: '180px', md: '260px', lg: '360px' }, + whiteSpace: 'nowrap', + overflow: 'hidden', + textOverflow: 'ellipsis', + }}> + {Common.camelToPascalWithSpaces(translate('table.field.deviceBind.id'))}: {record.id} + </Typography> + {/* inherit, primary, secondary, textPrimary, textSecondary, error */} + <Typography variant="h6" gutterBottom align="right" > + ID: {record.id} + </Typography> + </Grid> + </Grid> + <Grid container spacing={2}> + <Grid item xs={12} container alignContent="flex-end"> + <Typography variant="caption" color="textSecondary" sx={{ wordWrap: 'break-word', wordBreak: 'break-all' }}> + {Common.camelToPascalWithSpaces(translate('common.field.memo'))}:{record.memo} + </Typography> + </Grid> + </Grid> + <Box height={20}> </Box> + <Grid container spacing={2}> + <Grid item xs={6}> + <PanelTypography + title="table.field.deviceBind.currentRow" + property={record.currentRow} + /> + </Grid> + <Grid item xs={6}> + <PanelTypography + title="table.field.deviceBind.startRow" + property={record.startRow} + /> + </Grid> + <Grid item xs={6}> + <PanelTypography + title="table.field.deviceBind.endRow" + property={record.endRow} + /> + </Grid> + <Grid item xs={6}> + <PanelTypography + title="table.field.deviceBind.deviceQty" + property={record.deviceQty} + /> + </Grid> + <Grid item xs={6}> + <PanelTypography + title="table.field.deviceBind.startDeviceNo" + property={record.startDeviceNo} + /> + </Grid> + <Grid item xs={6}> + <PanelTypography + title="table.field.deviceBind.endDeviceNo" + property={record.endDeviceNo} + /> + </Grid> + <Grid item xs={6}> + <PanelTypography + title="table.field.deviceBind.staList" + property={record.staList} + /> + </Grid> + <Grid item xs={6}> + <PanelTypography + title="table.field.deviceBind.typeId" + property={record.typeId} + /> + </Grid> + <Grid item xs={6}> + <PanelTypography + title="table.field.deviceBind.beSimilar" + property={record.beSimilar} + /> + </Grid> + <Grid item xs={6}> + <PanelTypography + title="table.field.deviceBind.emptySimilar" + property={record.emptySimilar} + /> + </Grid> + + </Grid> + </CardContent> + </Card > + </> + ); +}; + +export default DeviceBindPanel; diff --git a/rsf-admin/src/page/deviceBind/index.jsx b/rsf-admin/src/page/deviceBind/index.jsx new file mode 100644 index 0000000..08c2f9e --- /dev/null +++ b/rsf-admin/src/page/deviceBind/index.jsx @@ -0,0 +1,18 @@ +import React, { useState, useRef, useEffect, useMemo } from "react"; +import { + ListGuesser, + EditGuesser, + ShowGuesser, +} from "react-admin"; + +import DeviceBindList from "./DeviceBindList"; +import DeviceBindEdit from "./DeviceBindEdit"; + +export default { + list: DeviceBindList, + edit: DeviceBindEdit, + show: ShowGuesser, + recordRepresentation: (record) => { + return `${record.id}` + } +}; diff --git a/rsf-admin/src/page/orders/outStock/OutOrderList.jsx b/rsf-admin/src/page/orders/outStock/OutOrderList.jsx index 8c1bb08..58bb153 100644 --- a/rsf-admin/src/page/orders/outStock/OutOrderList.jsx +++ b/rsf-admin/src/page/orders/outStock/OutOrderList.jsx @@ -55,6 +55,7 @@ import OutOrderCreate from "./OutOrderCreate"; import AddIcon from '@mui/icons-material/Add'; import OutOrderModal from "./OutOrderModal"; +import PublicIcon from '@mui/icons-material/Public'; const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({ '& .css-1vooibu-MuiSvgIcon-root': { @@ -141,7 +142,7 @@ <MyCreateButton onClick={() => { setManualDialog(true) }} /> <SelectColumnsButton preferenceKey='outStock' /> <ImportButton value={'asnOrderItem'} /> - <MyExportButton /> + {/* <MyExportButton /> */} </TopToolbar> )} perPage={DEFAULT_PAGE_SIZE} @@ -151,6 +152,7 @@ preferenceKey='outStock' bulkActionButtons={ <> + <PublicTaskButton /> <MyExportButton /> <BulkDeleteButton mutationMode={OPERATE_MODE} /> @@ -201,6 +203,25 @@ } export default OutOrderList; + +const PublicTaskButton = () => { + const record = useRecordContext(); + const { selectedIds, onUnselectItems } = useListContext(); + + const pubClick = (event) => { + event.stopPropagation(); + onUnselectItems(); + + } + + return ( + <Button + onClick={pubClick} + label={"toolbar.createWave"} + startIcon={<PublicIcon />} + />); +} + const MyButton = ({ setCreateDialog, setmodalType }) => { const record = useRecordContext(); const handleEditClick = (btn) => { @@ -227,8 +248,16 @@ 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 ( @@ -241,7 +270,6 @@ const record = useRecordContext(); const notify = useNotify(); const refresh = useRefresh(); - console.log(record); const cancelOrder = async () => { const { data: { code, data, msg } } = await request.get(`/outStock/cancel/${record?.id}`); diff --git a/rsf-admin/src/page/orders/outStock/OutOrderModal.jsx b/rsf-admin/src/page/orders/outStock/OutOrderModal.jsx index 95b48a6..5bc8cc3 100644 --- a/rsf-admin/src/page/orders/outStock/OutOrderModal.jsx +++ b/rsf-admin/src/page/orders/outStock/OutOrderModal.jsx @@ -54,14 +54,6 @@ '& .RaDatagrid-row': { cursor: 'auto' }, - '& .column-name': { - }, - '& .opt': { - width: 220 - }, - '& .wkType': { - width: 110 - }, '& .status': { width: 90 }, @@ -102,9 +94,10 @@ const { filterValues, setFilters, refetch } = useListContext('deliveryItem'); const [formValues, setFormValues] = useState(filterValues); const handleChange = (event) => { + if (event.target == undefined || event.target == null) {return} setFormValues(formValues => ({ ...formValues, - [event.target.name]: event.target.value + [event.target.name]: event.target.value })); }; @@ -125,10 +118,22 @@ </Stack> <Stack> <TextInput + source="deliveryCode" + label="table.field.deliveryItem.deliveryCode" + defaultValue={params?.matnrName} + onChange={handleChange} + resettable + + /> + </Stack> + <Stack> + <TextInput source="matnrName" label="table.field.deliveryItem.matnrName" defaultValue={params?.matnrName} onChange={handleChange} + resettable + /> </Stack> <Stack> @@ -136,6 +141,7 @@ source="matnrCode" label="table.field.deliveryItem.matnrCode" defaultValue={params?.matnrCode} + resettable onChange={handleChange} /> </Stack> <Stack> @@ -143,6 +149,7 @@ source="splrName" label="table.field.deliveryItem.splrName" defaultValue={params?.splrName} + resettable onChange={handleChange} /> </Stack> </Grid> @@ -162,7 +169,7 @@ aria-hidden fullWidth disableRestoreFocus - maxWidth="lg" + maxWidth="xl" > <DialogTitle id="form-dialog-title" sx={{ position: 'sticky', @@ -200,14 +207,16 @@ perPage={DEFAULT_PAGE_SIZE} > <StyledDatagrid + sx={{ height: '400' }} preferenceKey='deliveryItem' - bulkActionButtons={<AddOutStockButton setOpen={setOpen}/>} + bulkActionButtons={<AddOutStockButton setOpen={setOpen} />} rowClick={(id, resource, record) => false} expand={false} expandSingle={true} omit={['id', 'createTime', 'createBy', 'memo', 'workQty', 'startTime', 'endTime', 'updateBy', 'createTime']} > <NumberField source="id" /> + <TextField source="deliveryCode" label="table.field.deliveryItem.deliveryCode" /> <TextField source="matnrCode" label="table.field.deliveryItem.matnrCode" /> <TextField source="matnrName" label="table.field.deliveryItem.matnrName" /> <TextField source="unit" label="table.field.deliveryItem.unit" /> @@ -236,8 +245,7 @@ const { selectedIds, onUnselectItems } = useListContext(); const notify = useNotify(); const confirm = async (event) => { - console.log(selectedIds); - const res = await request.post(`/outStock/generate/orders`, {ids: selectedIds}); + const res = await request.post(`/outStock/generate/orders`, { ids: selectedIds }); if (res?.data?.code === 200) { notify(res.data.msg); } else { diff --git a/rsf-admin/src/page/wave/WaveCreate.jsx b/rsf-admin/src/page/wave/WaveCreate.jsx new file mode 100644 index 0000000..ad26794 --- /dev/null +++ b/rsf-admin/src/page/wave/WaveCreate.jsx @@ -0,0 +1,158 @@ +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 WaveCreate = (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}> + <TextInput + label="table.field.wave.code" + source="code" + parse={v => v} + autoFocus + /> + </Grid> + <Grid item xs={6} display="flex" gap={1}> + <SelectInput + label="table.field.wave.type" + source="type" + choices={[ + { id: 0, name: '鎵嬪姩' }, + { id: 1, name: '鑷姩' }, + ]} + /> + </Grid> + <Grid item xs={6} display="flex" gap={1}> + <SelectInput + label="table.field.wave.exceStatus" + source="exceStatus" + choices={[ + { id: 0, name: '鍒濆鍖�' }, + { id: 1, name: '鐢熸垚浠诲姟' }, + { id: 2, name: '浠诲姟鎾' }, + { id: 3, name: '瀹屾垚' }, + ]} + /> + </Grid> + <Grid item xs={6} display="flex" gap={1}> + <NumberInput + label="table.field.wave.anfme" + source="anfme" + /> + </Grid> + <Grid item xs={6} display="flex" gap={1}> + <NumberInput + label="table.field.wave.qty" + source="qty" + /> + </Grid> + <Grid item xs={6} display="flex" gap={1}> + <NumberInput + label="table.field.wave.orderNum" + source="orderNum" + /> + </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 WaveCreate; diff --git a/rsf-admin/src/page/wave/WaveEdit.jsx b/rsf-admin/src/page/wave/WaveEdit.jsx new file mode 100644 index 0000000..b26cc70 --- /dev/null +++ b/rsf-admin/src/page/wave/WaveEdit.jsx @@ -0,0 +1,130 @@ +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-admin/src/page/wave/WaveList.jsx b/rsf-admin/src/page/wave/WaveList.jsx new file mode 100644 index 0000000..1ee5b56 --- /dev/null +++ b/rsf-admin/src/page/wave/WaveList.jsx @@ -0,0 +1,174 @@ +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, +} 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 { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting'; +import * as Common from '@/utils/common'; + +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 />, + + <TextInput source="code" label="table.field.wave.code" />, + <SelectInput source="type" label="table.field.wave.type" + choices={[ + { id: 0, name: '鎵嬪姩' }, + { id: 1, name: '鑷姩' }, + ]} + />, + <SelectInput source="exceStatus" label="table.field.wave.exceStatus" + choices={[ + { id: 0, name: '鍒濆鍖�' }, + { id: 1, name: '鐢熸垚浠诲姟' }, + { id: 2, name: '浠诲姟鎾' }, + { id: 3, name: '瀹屾垚' }, + ]} + />, + <NumberInput source="anfme" label="table.field.wave.anfme" />, + <NumberInput source="qty" label="table.field.wave.qty" />, + <NumberInput source="orderNum" label="table.field.wave.orderNum" />, + + <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 WaveList = () => { + const translate = useTranslate(); + + const [createDialog, setCreateDialog] = useState(false); + const [drawerVal, setDrawerVal] = useState(false); + + return ( + <Box display="flex"> + <List + sx={{ + flexGrow: 1, + transition: (theme) => + theme.transitions.create(['all'], { + duration: theme.transitions.duration.enteringScreen, + }), + marginRight: !!drawerVal ? `${PAGE_DRAWER_WIDTH}px` : 0, + }} + title={"menu.wave"} + empty={<EmptyData onClick={() => { setCreateDialog(true) }} />} + 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} />} + rowClick={(id, resource, record) => false} + expand={() => <WavePanel />} + expandSingle={true} + omit={['id', 'createTime', 'createBy', 'memo']} + > + <NumberField source="id" /> + <TextField source="code" label="table.field.wave.code" /> + <TextField source="type$" label="table.field.wave.type" sortable={false} /> + <TextField source="exceStatus$" label="table.field.wave.exceStatus" sortable={false} /> + <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> + <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> + <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} /> + <WrapperField cellClassName="opt" label="common.field.opt"> + <EditButton sx={{ padding: '1px', fontSize: '.75rem' }} /> + <DeleteButton sx={{ padding: '1px', fontSize: '.75rem' }} mutationMode={OPERATE_MODE} /> + </WrapperField> + </StyledDatagrid> + </List> + <WaveCreate + open={createDialog} + setOpen={setCreateDialog} + /> + <PageDrawer + title='Wave Detail' + drawerVal={drawerVal} + setDrawerVal={setDrawerVal} + > + </PageDrawer> + </Box> + ) +} + +export default WaveList; diff --git a/rsf-admin/src/page/wave/WavePanel.jsx b/rsf-admin/src/page/wave/WavePanel.jsx new file mode 100644 index 0000000..311f963 --- /dev/null +++ b/rsf-admin/src/page/wave/WavePanel.jsx @@ -0,0 +1,87 @@ +import React, { useState, useRef, useEffect, useMemo } from "react"; +import { Box, Card, CardContent, Grid, Typography, Tooltip } from '@mui/material'; +import { + useTranslate, + useRecordContext, +} from 'react-admin'; +import PanelTypography from "../components/PanelTypography"; +import * as Common from '@/utils/common' + +const WavePanel = () => { + const record = useRecordContext(); + if (!record) return null; + const translate = useTranslate(); + return ( + <> + <Card sx={{ width: { xs: 300, sm: 500, md: 600, lg: 800 }, margin: 'auto' }}> + <CardContent> + <Grid container spacing={2}> + <Grid item xs={12} sx={{ display: 'flex', justifyContent: 'space-between' }}> + <Typography variant="h6" gutterBottom align="left" sx={{ + maxWidth: { xs: '100px', sm: '180px', md: '260px', lg: '360px' }, + whiteSpace: 'nowrap', + overflow: 'hidden', + textOverflow: 'ellipsis', + }}> + {Common.camelToPascalWithSpaces(translate('table.field.wave.id'))}: {record.id} + </Typography> + {/* inherit, primary, secondary, textPrimary, textSecondary, error */} + <Typography variant="h6" gutterBottom align="right" > + ID: {record.id} + </Typography> + </Grid> + </Grid> + <Grid container spacing={2}> + <Grid item xs={12} container alignContent="flex-end"> + <Typography variant="caption" color="textSecondary" sx={{ wordWrap: 'break-word', wordBreak: 'break-all' }}> + {Common.camelToPascalWithSpaces(translate('common.field.memo'))}:{record.memo} + </Typography> + </Grid> + </Grid> + <Box height={20}> </Box> + <Grid container spacing={2}> + <Grid item xs={6}> + <PanelTypography + title="table.field.wave.code" + property={record.code} + /> + </Grid> + <Grid item xs={6}> + <PanelTypography + title="table.field.wave.type" + property={record.type$} + /> + </Grid> + <Grid item xs={6}> + <PanelTypography + title="table.field.wave.exceStatus" + property={record.exceStatus$} + /> + </Grid> + <Grid item xs={6}> + <PanelTypography + title="table.field.wave.anfme" + property={record.anfme} + /> + </Grid> + <Grid item xs={6}> + <PanelTypography + title="table.field.wave.qty" + property={record.qty} + /> + </Grid> + <Grid item xs={6}> + <PanelTypography + title="table.field.wave.orderNum" + property={record.orderNum} + /> + </Grid> + + </Grid> + </CardContent> + </Card > + </> + ); +}; + +export default WavePanel; diff --git a/rsf-admin/src/page/wave/index.jsx b/rsf-admin/src/page/wave/index.jsx new file mode 100644 index 0000000..c5e4655 --- /dev/null +++ b/rsf-admin/src/page/wave/index.jsx @@ -0,0 +1,18 @@ +import React, { useState, useRef, useEffect, useMemo } from "react"; +import { + ListGuesser, + EditGuesser, + ShowGuesser, +} from "react-admin"; + +import WaveList from "./WaveList"; +import WaveEdit from "./WaveEdit"; + +export default { + list: WaveList, + edit: WaveEdit, + show: ShowGuesser, + recordRepresentation: (record) => { + return `${record.id}` + } +}; diff --git a/rsf-admin/src/page/waveItem/WaveItemCreate.jsx b/rsf-admin/src/page/waveItem/WaveItemCreate.jsx new file mode 100644 index 0000000..7e2c428 --- /dev/null +++ b/rsf-admin/src/page/waveItem/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/waveItem/WaveItemEdit.jsx b/rsf-admin/src/page/waveItem/WaveItemEdit.jsx new file mode 100644 index 0000000..a79b3ec --- /dev/null +++ b/rsf-admin/src/page/waveItem/WaveItemEdit.jsx @@ -0,0 +1,176 @@ +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 WaveItemEdit = () => { + 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}> + <NumberInput + label="table.field.waveItem.waveId" + source="waveId" + autoFocus + /> + </Stack> + <Stack direction='row' gap={2}> + <TextInput + label="table.field.waveItem.waveCode" + source="waveCode" + parse={v => v} + /> + </Stack> + <Stack direction='row' gap={2}> + <NumberInput + label="table.field.waveItem.matnrId" + source="matnrId" + /> + </Stack> + <Stack direction='row' gap={2}> + <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} + /> + </Stack> + <Stack direction='row' gap={2}> + <TextInput + label="table.field.waveItem.batch" + source="batch" + parse={v => v} + /> + </Stack> + <Stack direction='row' gap={2}> + <TextInput + label="table.field.waveItem.splrBatch" + source="splrBatch" + parse={v => v} + /> + </Stack> + <Stack direction='row' gap={2}> + <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" + /> + </Stack> + <Stack direction='row' gap={2}> + <TextInput + label="table.field.waveItem.unit" + source="unit" + parse={v => v} + /> + </Stack> + <Stack direction='row' gap={2}> + <TextInput + label="table.field.waveItem.trackCode" + source="trackCode" + parse={v => v} + /> + </Stack> + <Stack direction='row' gap={2}> + <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" + /> + </Stack> + <Stack direction='row' gap={2}> + <NumberInput + label="table.field.waveItem.workQty" + source="workQty" + /> + </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 WaveItemEdit; diff --git a/rsf-admin/src/page/waveItem/WaveItemList.jsx b/rsf-admin/src/page/waveItem/WaveItemList.jsx new file mode 100644 index 0000000..07d87f0 --- /dev/null +++ b/rsf-admin/src/page/waveItem/WaveItemList.jsx @@ -0,0 +1,178 @@ +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, +} from 'react-admin'; +import { Box, Typography, Card, Stack } from '@mui/material'; +import { styled } from '@mui/material/styles'; +import WaveItemCreate from "./WaveItemCreate"; +import WaveItemPanel from "./WaveItemPanel"; +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 { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting'; +import * as Common from '@/utils/common'; + +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="matnrName" 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 [createDialog, setCreateDialog] = useState(false); + const [drawerVal, setDrawerVal] = useState(false); + + return ( + <Box display="flex"> + <List + 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={<EmptyData onClick={() => { setCreateDialog(true) }} />} + filters={filters} + sort={{ field: "create_time", order: "desc" }} + actions={( + <TopToolbar> + <FilterButton /> + <MyCreateButton onClick={() => { setCreateDialog(true) }} /> + <SelectColumnsButton preferenceKey='waveItem' /> + <MyExportButton /> + </TopToolbar> + )} + perPage={DEFAULT_PAGE_SIZE} + > + <StyledDatagrid + preferenceKey='waveItem' + bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />} + rowClick={(id, resource, record) => false} + expand={() => <WaveItemPanel />} + expandSingle={true} + omit={['id', 'createTime', '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="matnrName" 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" /> + + <ReferenceField source="updateBy" label="common.field.updateBy" reference="user" link={false} sortable={false}> + <TextField source="nickname" /> + </ReferenceField> + <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> + <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} /> + <WrapperField cellClassName="opt" label="common.field.opt"> + <EditButton sx={{ padding: '1px', fontSize: '.75rem' }} /> + <DeleteButton sx={{ padding: '1px', fontSize: '.75rem' }} mutationMode={OPERATE_MODE} /> + </WrapperField> + </StyledDatagrid> + </List> + <WaveItemCreate + open={createDialog} + setOpen={setCreateDialog} + /> + <PageDrawer + title='WaveItem Detail' + drawerVal={drawerVal} + setDrawerVal={setDrawerVal} + > + </PageDrawer> + </Box> + ) +} + +export default WaveItemList; diff --git a/rsf-admin/src/page/waveItem/WaveItemPanel.jsx b/rsf-admin/src/page/waveItem/WaveItemPanel.jsx new file mode 100644 index 0000000..ebea3a1 --- /dev/null +++ b/rsf-admin/src/page/waveItem/WaveItemPanel.jsx @@ -0,0 +1,135 @@ +import React, { useState, useRef, useEffect, useMemo } from "react"; +import { Box, Card, CardContent, Grid, Typography, Tooltip } from '@mui/material'; +import { + useTranslate, + useRecordContext, +} from 'react-admin'; +import PanelTypography from "../components/PanelTypography"; +import * as Common from '@/utils/common' + +const WaveItemPanel = () => { + const record = useRecordContext(); + if (!record) return null; + const translate = useTranslate(); + return ( + <> + <Card sx={{ width: { xs: 300, sm: 500, md: 600, lg: 800 }, margin: 'auto' }}> + <CardContent> + <Grid container spacing={2}> + <Grid item xs={12} sx={{ display: 'flex', justifyContent: 'space-between' }}> + <Typography variant="h6" gutterBottom align="left" sx={{ + maxWidth: { xs: '100px', sm: '180px', md: '260px', lg: '360px' }, + whiteSpace: 'nowrap', + overflow: 'hidden', + textOverflow: 'ellipsis', + }}> + {Common.camelToPascalWithSpaces(translate('table.field.waveItem.id'))}: {record.id} + </Typography> + {/* inherit, primary, secondary, textPrimary, textSecondary, error */} + <Typography variant="h6" gutterBottom align="right" > + ID: {record.id} + </Typography> + </Grid> + </Grid> + <Grid container spacing={2}> + <Grid item xs={12} container alignContent="flex-end"> + <Typography variant="caption" color="textSecondary" sx={{ wordWrap: 'break-word', wordBreak: 'break-all' }}> + {Common.camelToPascalWithSpaces(translate('common.field.memo'))}:{record.memo} + </Typography> + </Grid> + </Grid> + <Box height={20}> </Box> + <Grid container spacing={2}> + <Grid item xs={6}> + <PanelTypography + title="table.field.waveItem.waveId" + property={record.waveId} + /> + </Grid> + <Grid item xs={6}> + <PanelTypography + title="table.field.waveItem.waveCode" + property={record.waveCode} + /> + </Grid> + <Grid item xs={6}> + <PanelTypography + title="table.field.waveItem.matnrId" + property={record.matnrId} + /> + </Grid> + <Grid item xs={6}> + <PanelTypography + title="table.field.waveItem.matnrName" + property={record.matnrName} + /> + </Grid> + <Grid item xs={6}> + <PanelTypography + title="table.field.waveItem.matnrCode" + property={record.matnrCode} + /> + </Grid> + <Grid item xs={6}> + <PanelTypography + title="table.field.waveItem.batch" + property={record.batch} + /> + </Grid> + <Grid item xs={6}> + <PanelTypography + title="table.field.waveItem.splrBatch" + property={record.splrBatch} + /> + </Grid> + <Grid item xs={6}> + <PanelTypography + title="table.field.waveItem.orderCode" + property={record.orderCode} + /> + </Grid> + <Grid item xs={6}> + <PanelTypography + title="table.field.waveItem.orderItemId" + property={record.orderItemId} + /> + </Grid> + <Grid item xs={6}> + <PanelTypography + title="table.field.waveItem.unit" + property={record.unit} + /> + </Grid> + <Grid item xs={6}> + <PanelTypography + title="table.field.waveItem.trackCode" + property={record.trackCode} + /> + </Grid> + <Grid item xs={6}> + <PanelTypography + title="table.field.waveItem.fieldsIndex" + property={record.fieldsIndex} + /> + </Grid> + <Grid item xs={6}> + <PanelTypography + title="table.field.waveItem.anfme" + property={record.anfme} + /> + </Grid> + <Grid item xs={6}> + <PanelTypography + title="table.field.waveItem.workQty" + property={record.workQty} + /> + </Grid> + + </Grid> + </CardContent> + </Card > + </> + ); +}; + +export default WaveItemPanel; diff --git a/rsf-admin/src/page/waveItem/index.jsx b/rsf-admin/src/page/waveItem/index.jsx new file mode 100644 index 0000000..a64a352 --- /dev/null +++ b/rsf-admin/src/page/waveItem/index.jsx @@ -0,0 +1,18 @@ +import React, { useState, useRef, useEffect, useMemo } from "react"; +import { + ListGuesser, + EditGuesser, + ShowGuesser, +} from "react-admin"; + +import WaveItemList from "./WaveItemList"; +import WaveItemEdit from "./WaveItemEdit"; + +export default { + list: WaveItemList, + edit: WaveItemEdit, + show: ShowGuesser, + recordRepresentation: (record) => { + return `${record.id}` + } +}; 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 cb213f0..18e29b0 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,15 +15,15 @@ generator.frontendPrefixPath = "rsf-admin/"; generator.sqlOsType = SqlOsType.MYSQL; - generator.url="192.168.4.24:3306/rsf"; + 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_delivery_item"; - generator.tableDesc="缁煎悎鍗曟嵁鏄庣粏"; + 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 new file mode 100644 index 0000000..73b3473 --- /dev/null +++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/DeviceBindController.java @@ -0,0 +1,110 @@ +package com.vincent.rsf.server.manager.controller; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +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.server.common.utils.ExcelUtil; +import com.vincent.rsf.server.common.annotation.OperationLog; +import com.vincent.rsf.server.common.domain.BaseParam; +import com.vincent.rsf.server.common.domain.KeyValVo; +import com.vincent.rsf.server.common.domain.PageParam; +import com.vincent.rsf.server.manager.entity.DeviceBind; +import com.vincent.rsf.server.manager.service.DeviceBindService; +import com.vincent.rsf.server.system.controller.BaseController; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletResponse; +import java.util.*; + +@RestController +public class DeviceBindController extends BaseController { + + @Autowired + private DeviceBindService deviceBindService; + + @PreAuthorize("hasAuthority('manager:deviceBind:list')") + @PostMapping("/deviceBind/page") + public R page(@RequestBody Map<String, Object> map) { + BaseParam baseParam = buildParam(map, BaseParam.class); + PageParam<DeviceBind, BaseParam> pageParam = new PageParam<>(baseParam, DeviceBind.class); + return R.ok().add(deviceBindService.page(pageParam, pageParam.buildWrapper(true))); + } + + @PreAuthorize("hasAuthority('manager:deviceBind:list')") + @PostMapping("/deviceBind/list") + public R list(@RequestBody Map<String, Object> map) { + return R.ok().add(deviceBindService.list()); + } + + @PreAuthorize("hasAuthority('manager:deviceBind:list')") + @PostMapping({"/deviceBind/many/{ids}", "/deviceBinds/many/{ids}"}) + public R many(@PathVariable Long[] ids) { + return R.ok().add(deviceBindService.listByIds(Arrays.asList(ids))); + } + + @PreAuthorize("hasAuthority('manager:deviceBind:list')") + @GetMapping("/deviceBind/{id}") + public R get(@PathVariable("id") Long id) { + return R.ok().add(deviceBindService.getById(id)); + } + + @PreAuthorize("hasAuthority('manager:deviceBind:save')") + @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()); + if (!deviceBindService.save(deviceBind)) { + return R.error("Save Fail"); + } + return R.ok("Save Success").add(deviceBind); + } + + @PreAuthorize("hasAuthority('manager:deviceBind:update')") + @OperationLog("Update 绔嬩綋搴撶珯鐐圭粦瀹�") + @PostMapping("/deviceBind/update") + public R update(@RequestBody DeviceBind deviceBind) { + deviceBind.setUpdateBy(getLoginUserId()); + deviceBind.setUpdateTime(new Date()); + if (!deviceBindService.updateById(deviceBind)) { + return R.error("Update Fail"); + } + return R.ok("Update Success").add(deviceBind); + } + + @PreAuthorize("hasAuthority('manager:deviceBind:remove')") + @OperationLog("Delete 绔嬩綋搴撶珯鐐圭粦瀹�") + @PostMapping("/deviceBind/remove/{ids}") + public R remove(@PathVariable Long[] ids) { + if (!deviceBindService.removeByIds(Arrays.asList(ids))) { + return R.error("Delete Fail"); + } + return R.ok("Delete Success").add(ids); + } + + @PreAuthorize("hasAuthority('manager:deviceBind:list')") + @PostMapping("/deviceBind/query") + public R query(@RequestParam(required = false) String condition) { + List<KeyValVo> vos = new ArrayList<>(); + LambdaQueryWrapper<DeviceBind> wrapper = new LambdaQueryWrapper<>(); + if (!Cools.isEmpty(condition)) { + wrapper.like(DeviceBind::getId, condition); + } + deviceBindService.page(new Page<>(1, 30), wrapper).getRecords().forEach( + item -> vos.add(new KeyValVo(item.getId(), item.getId())) + ); + return R.ok().add(vos); + } + + @PreAuthorize("hasAuthority('manager:deviceBind:list')") + @PostMapping("/deviceBind/export") + public void export(@RequestBody Map<String, Object> map, HttpServletResponse response) throws Exception { + ExcelUtil.build(ExcelUtil.create(deviceBindService.list(), DeviceBind.class), response); + } + +} 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 3149703..ac580c4 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 @@ -203,5 +203,16 @@ return outStockService.genOutStock(ids); } + @PreAuthorize("hasAuthority('manager:outStock:update')") + @ApiOperation("鍑哄簱鍗曠敓鎴愭尝娆�") + @PostMapping("/outStock/generate/wave") + public R generateWave(@RequestBody Map<String, Object> params) { + if (Objects.isNull(params)) { + return R.error("鍙傛暟涓嶈兘涓虹┖锛侊紒"); + } + 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 new file mode 100644 index 0000000..989b5d2 --- /dev/null +++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/WaveController.java @@ -0,0 +1,108 @@ +package com.vincent.rsf.server.manager.controller; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +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.server.common.utils.ExcelUtil; +import com.vincent.rsf.server.common.annotation.OperationLog; +import com.vincent.rsf.server.common.domain.BaseParam; +import com.vincent.rsf.server.common.domain.KeyValVo; +import com.vincent.rsf.server.common.domain.PageParam; +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 org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletResponse; +import java.util.*; + +@RestController +public class WaveController extends BaseController { + + @Autowired + private WaveService waveService; + + @PreAuthorize("hasAuthority('manager:wave:list')") + @PostMapping("/wave/page") + public R page(@RequestBody Map<String, Object> map) { + BaseParam baseParam = buildParam(map, BaseParam.class); + PageParam<Wave, BaseParam> pageParam = new PageParam<>(baseParam, Wave.class); + return R.ok().add(waveService.page(pageParam, pageParam.buildWrapper(true))); + } + + @PreAuthorize("hasAuthority('manager:wave:list')") + @PostMapping("/wave/list") + public R list(@RequestBody Map<String, Object> map) { + return R.ok().add(waveService.list()); + } + + @PreAuthorize("hasAuthority('manager:wave:list')") + @PostMapping({"/wave/many/{ids}", "/waves/many/{ids}"}) + public R many(@PathVariable Long[] ids) { + return R.ok().add(waveService.listByIds(Arrays.asList(ids))); + } + + @PreAuthorize("hasAuthority('manager:wave:list')") + @GetMapping("/wave/{id}") + public R get(@PathVariable("id") Long id) { + return R.ok().add(waveService.getById(id)); + } + + @PreAuthorize("hasAuthority('manager:wave:save')") + @OperationLog("Create 娉㈡鍗曟嵁") + @PostMapping("/wave/save") + public R save(@RequestBody Wave wave) { + wave.setCreateBy(getLoginUserId()); + wave.setUpdateBy(getLoginUserId()); + if (!waveService.save(wave)) { + return R.error("Save Fail"); + } + return R.ok("Save Success").add(wave); + } + + @PreAuthorize("hasAuthority('manager:wave:update')") + @OperationLog("Update 娉㈡鍗曟嵁") + @PostMapping("/wave/update") + public R update(@RequestBody Wave wave) { + wave.setUpdateBy(getLoginUserId()); + wave.setUpdateTime(new Date()); + if (!waveService.updateById(wave)) { + return R.error("Update Fail"); + } + return R.ok("Update Success").add(wave); + } + + @PreAuthorize("hasAuthority('manager:wave:remove')") + @OperationLog("Delete 娉㈡鍗曟嵁") + @PostMapping("/wave/remove/{ids}") + public R remove(@PathVariable Long[] ids) { + if (!waveService.removeByIds(Arrays.asList(ids))) { + return R.error("Delete Fail"); + } + return R.ok("Delete Success").add(ids); + } + + @PreAuthorize("hasAuthority('manager:wave:list')") + @PostMapping("/wave/query") + public R query(@RequestParam(required = false) String condition) { + List<KeyValVo> vos = new ArrayList<>(); + LambdaQueryWrapper<Wave> wrapper = new LambdaQueryWrapper<>(); + if (!Cools.isEmpty(condition)) { + wrapper.like(Wave::getId, condition); + } + waveService.page(new Page<>(1, 30), wrapper).getRecords().forEach( + item -> vos.add(new KeyValVo(item.getId(), item.getId())) + ); + return R.ok().add(vos); + } + + @PreAuthorize("hasAuthority('manager:wave:list')") + @PostMapping("/wave/export") + public void export(@RequestBody Map<String, Object> map, HttpServletResponse response) throws Exception { + ExcelUtil.build(ExcelUtil.create(waveService.list(), Wave.class), response); + } + +} diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/WaveItemController.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/WaveItemController.java new file mode 100644 index 0000000..758f03e --- /dev/null +++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/WaveItemController.java @@ -0,0 +1,110 @@ +package com.vincent.rsf.server.manager.controller; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +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.server.common.utils.ExcelUtil; +import com.vincent.rsf.server.common.annotation.OperationLog; +import com.vincent.rsf.server.common.domain.BaseParam; +import com.vincent.rsf.server.common.domain.KeyValVo; +import com.vincent.rsf.server.common.domain.PageParam; +import com.vincent.rsf.server.manager.entity.WaveItem; +import com.vincent.rsf.server.manager.service.WaveItemService; +import com.vincent.rsf.server.system.controller.BaseController; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletResponse; +import java.util.*; + +@RestController +public class WaveItemController extends BaseController { + + @Autowired + private WaveItemService waveItemService; + + @PreAuthorize("hasAuthority('manager:waveItem:list')") + @PostMapping("/waveItem/page") + public R page(@RequestBody Map<String, Object> map) { + BaseParam baseParam = buildParam(map, BaseParam.class); + PageParam<WaveItem, BaseParam> pageParam = new PageParam<>(baseParam, WaveItem.class); + return R.ok().add(waveItemService.page(pageParam, pageParam.buildWrapper(true))); + } + + @PreAuthorize("hasAuthority('manager:waveItem:list')") + @PostMapping("/waveItem/list") + public R list(@RequestBody Map<String, Object> map) { + return R.ok().add(waveItemService.list()); + } + + @PreAuthorize("hasAuthority('manager:waveItem:list')") + @PostMapping({"/waveItem/many/{ids}", "/waveItems/many/{ids}"}) + public R many(@PathVariable Long[] ids) { + return R.ok().add(waveItemService.listByIds(Arrays.asList(ids))); + } + + @PreAuthorize("hasAuthority('manager:waveItem:list')") + @GetMapping("/waveItem/{id}") + public R get(@PathVariable("id") Long id) { + return R.ok().add(waveItemService.getById(id)); + } + + @PreAuthorize("hasAuthority('manager:waveItem:save')") + @OperationLog("Create 娉㈡鏄庣粏") + @PostMapping("/waveItem/save") + public R save(@RequestBody WaveItem waveItem) { + waveItem.setCreateBy(getLoginUserId()); + waveItem.setCreateTime(new Date()); + waveItem.setUpdateBy(getLoginUserId()); + waveItem.setUpdateTime(new Date()); + if (!waveItemService.save(waveItem)) { + return R.error("Save Fail"); + } + return R.ok("Save Success").add(waveItem); + } + + @PreAuthorize("hasAuthority('manager:waveItem:update')") + @OperationLog("Update 娉㈡鏄庣粏") + @PostMapping("/waveItem/update") + public R update(@RequestBody WaveItem waveItem) { + waveItem.setUpdateBy(getLoginUserId()); + waveItem.setUpdateTime(new Date()); + if (!waveItemService.updateById(waveItem)) { + return R.error("Update Fail"); + } + return R.ok("Update Success").add(waveItem); + } + + @PreAuthorize("hasAuthority('manager:waveItem:remove')") + @OperationLog("Delete 娉㈡鏄庣粏") + @PostMapping("/waveItem/remove/{ids}") + public R remove(@PathVariable Long[] ids) { + if (!waveItemService.removeByIds(Arrays.asList(ids))) { + return R.error("Delete Fail"); + } + return R.ok("Delete Success").add(ids); + } + + @PreAuthorize("hasAuthority('manager:waveItem:list')") + @PostMapping("/waveItem/query") + public R query(@RequestParam(required = false) String condition) { + List<KeyValVo> vos = new ArrayList<>(); + LambdaQueryWrapper<WaveItem> wrapper = new LambdaQueryWrapper<>(); + if (!Cools.isEmpty(condition)) { + wrapper.like(WaveItem::getId, condition); + } + waveItemService.page(new Page<>(1, 30), wrapper).getRecords().forEach( + item -> vos.add(new KeyValVo(item.getId(), item.getId())) + ); + return R.ok().add(vos); + } + + @PreAuthorize("hasAuthority('manager:waveItem:list')") + @PostMapping("/waveItem/export") + public void export(@RequestBody Map<String, Object> map, HttpServletResponse response) throws Exception { + ExcelUtil.build(ExcelUtil.create(waveItemService.list(), WaveItem.class), response); + } + +} diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/params/DeviceSiteParame.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/params/DeviceSiteParame.java index 6b915c8..68b6a76 100644 --- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/params/DeviceSiteParame.java +++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/params/DeviceSiteParame.java @@ -20,7 +20,7 @@ private List<Long> typeIds; @ApiModelProperty("浣滀笟绔欑偣") - private String sites; + private String site; @ApiModelProperty("璁惧缂栧彿") private String deviceCode; @@ -28,4 +28,7 @@ @ApiModelProperty("璁惧浣滀笟绔欑偣") private String deviceSites; + @ApiModelProperty("鐩爣绔欑偣") + private String target; + } 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 new file mode 100644 index 0000000..dc98990 --- /dev/null +++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/DeviceBind.java @@ -0,0 +1,133 @@ +package com.vincent.rsf.server.manager.entity; + + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableLogic; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import com.vincent.rsf.framework.common.Cools; +import com.vincent.rsf.framework.common.SpringUtils; +import com.vincent.rsf.server.system.service.UserService; +import com.vincent.rsf.server.system.entity.User; +import java.io.Serializable; +import java.util.Date; + +@Data +@TableName("man_device_bind") +public class DeviceBind implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * id + */ + @ApiModelProperty(value= "id") + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + /** + * 褰撳墠鎺掑彿 + */ + @ApiModelProperty(value= "褰撳墠鎺掑彿") + private Integer currentRow; + + /** + * 璧峰鎺掑彿 + */ + @ApiModelProperty(value= "璧峰鎺掑彿") + private Integer startRow; + + /** + * 缁堟鎺掑彿 + */ + @ApiModelProperty(value= "缁堟鎺掑彿") + private Integer endRow; + + /** + * 璁惧鏁伴噺 + */ + @ApiModelProperty(value= "璁惧鏁伴噺") + private Integer deviceQty; + + /** + * 璧峰璁惧鍙� + */ + @ApiModelProperty(value= "璧峰璁惧鍙�") + private Integer startDeviceNo; + + /** + * 缁堟璁惧鍙� + */ + @ApiModelProperty(value= "缁堟璁惧鍙�") + private Integer endDeviceNo; + + /** + * 绔欑偣list + */ + @ApiModelProperty(value= "绔欑偣list") + private String staList; + + /** + * 搴撳尯绫诲瀷 + */ + @ApiModelProperty(value= "搴撳尯绫诲瀷") + private Integer typeId; + + /** + * 鐗╂枡鐩镐技寮�鍏� + */ + @ApiModelProperty(value= "鐗╂枡鐩镐技寮�鍏�") + private String beSimilar; + + /** + * 绌烘澘闈犺繎寮�鍏� + */ + @ApiModelProperty(value= "绌烘澘闈犺繎寮�鍏�") + private String emptySimilar; + + public DeviceBind() {} + + public DeviceBind(Integer currentRow,Integer startRow,Integer endRow,Integer deviceQty,Integer startDeviceNo,Integer endDeviceNo,String staList,Integer typeId,String beSimilar,String emptySimilar) { + this.currentRow = currentRow; + this.startRow = startRow; + this.endRow = endRow; + this.deviceQty = deviceQty; + this.startDeviceNo = startDeviceNo; + this.endDeviceNo = endDeviceNo; + this.staList = staList; + this.typeId = typeId; + this.beSimilar = beSimilar; + this.emptySimilar = emptySimilar; + } + +// DeviceBind deviceBind = new DeviceBind( +// null, // 褰撳墠鎺掑彿 +// null, // 璧峰鎺掑彿 +// null, // 缁堟鎺掑彿 +// null, // 璁惧鏁伴噺 +// null, // 璧峰璁惧鍙� +// null, // 缁堟璁惧鍙� +// null, // 绔欑偣list +// null, // 搴撳尯绫诲瀷 +// null, // 鐗╂枡鐩镐技寮�鍏� +// 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/DeviceSite.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/DeviceSite.java index 5293829..2bca82a 100644 --- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/DeviceSite.java +++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/DeviceSite.java @@ -64,8 +64,8 @@ /** * wcs绔欑偣缂栧彿 */ - @ApiModelProperty(value= "wcs绔欑偣缂栧彿") - private String wcsCode; + @ApiModelProperty(value= "鐩爣浣嶇疆") + private String target; /** * 绔欑偣鏍囩 @@ -154,7 +154,7 @@ this.type = type; this.site = site; this.name = name; - this.wcsCode = wcsCode; + this.target = wcsCode; this.label = label; this.device = device; this.deviceCode = deviceCode; diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/Wave.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/Wave.java new file mode 100644 index 0000000..c9dadf0 --- /dev/null +++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/Wave.java @@ -0,0 +1,249 @@ +package com.vincent.rsf.server.manager.entity; + +import java.text.SimpleDateFormat; +import java.util.Date; + +import lombok.experimental.Accessors; +import org.springframework.format.annotation.DateTimeFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import com.baomidou.mybatisplus.annotation.TableLogic; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableLogic; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import com.vincent.rsf.framework.common.Cools; +import com.vincent.rsf.framework.common.SpringUtils; +import com.vincent.rsf.server.system.service.UserService; +import com.vincent.rsf.server.system.entity.User; +import java.io.Serializable; +import java.util.Date; + +@Data +@TableName("man_wave") +@Accessors(chain = true) +public class Wave implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * ID + */ + @ApiModelProperty(value= "ID") + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + /** + * 娉㈡鍙� + */ + @ApiModelProperty(value= "娉㈡鍙�") + private String code; + + /** + * 娉㈡绫诲瀷 0: 鎵嬪姩 1: 鑷姩 + */ + @ApiModelProperty(value= "娉㈡绫诲瀷 0: 鎵嬪姩 1: 鑷姩 ") + private Short type; + + /** + * 娉㈡鐘舵�� 0: 鍒濆鍖� 1: 鐢熸垚浠诲姟 2: 浠诲姟鎾 3: 瀹屾垚 + */ + @ApiModelProperty(value= "娉㈡鐘舵�� 0: 鍒濆鍖� 1: 鐢熸垚浠诲姟 2: 浠诲姟鎾 3: 瀹屾垚 ") + private Short exceStatus; + + /** + * 鍗曟嵁鏁伴噺 + */ + @ApiModelProperty(value= "鍗曟嵁鏁伴噺") + private Double anfme; + + /** + * 宸插畬鎴愭暟閲� + */ + @ApiModelProperty(value= "宸插畬鎴愭暟閲�") + private Double qty; + + /** + * 鍗曟嵁鏁伴噺 + */ + @ApiModelProperty(value= "鍗曟嵁鏁伴噺") + private Integer orderNum; + + /** + * 鐘舵�� 1: 姝e父 0: 绂佺敤 + */ + @ApiModelProperty(value= "鐘舵�� 1: 姝e父 0: 绂佺敤 ") + private Integer status; + + /** + * 鎵�灞炴満鏋� + */ + @ApiModelProperty(value= "鎵�灞炴満鏋�") + private Long tenantId; + + /** + * 娣诲姞鏃堕棿 + */ + @ApiModelProperty(value= "娣诲姞鏃堕棿") + @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") + private Date createTime; + + /** + * 娣诲姞浜哄憳 + */ + @ApiModelProperty(value= "娣诲姞浜哄憳") + private Long createBy; + + /** + * 淇敼鏃堕棿 + */ + @ApiModelProperty(value= "淇敼鏃堕棿") + @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") + private Date updateTime; + + /** + * 淇敼浜哄憳 + */ + @ApiModelProperty(value= "淇敼浜哄憳") + private Long updateBy; + + /** + * 鏄惁鍒犻櫎 1: 鏄� 0: 鍚� + */ + @ApiModelProperty(value= "鏄惁鍒犻櫎 1: 鏄� 0: 鍚� ") + @TableLogic + private Integer deleted; + + /** + * 澶囨敞 + */ + @ApiModelProperty(value= "澶囨敞") + private String memo; + + public Wave() {} + + public Wave(String code,Short type,Short exceStatus,Double anfme,Double qty,Integer orderNum,Integer status,Long tenantId,Date createTime,Long createBy,Date updateTime,Long updateBy,Integer deleted,String memo) { + this.code = code; + this.type = type; + this.exceStatus = exceStatus; + this.anfme = anfme; + this.qty = qty; + this.orderNum = orderNum; + this.status = status; + this.tenantId = tenantId; + this.createTime = createTime; + this.createBy = createBy; + this.updateTime = updateTime; + this.updateBy = updateBy; + this.deleted = deleted; + this.memo = memo; + } + +// Wave wave = new Wave( +// null, // 娉㈡鍙� +// null, // 娉㈡绫诲瀷 +// null, // 娉㈡鐘舵�� +// null, // 鍗曟嵁鏁伴噺 +// null, // 宸插畬鎴愭暟閲� +// null, // 鍗曟嵁鏁伴噺 +// null, // 鐘舵�� +// null, // 鎵�灞炴満鏋� +// null, // 娣诲姞鏃堕棿 +// null, // 娣诲姞浜哄憳 +// null, // 淇敼鏃堕棿 +// null, // 淇敼浜哄憳 +// null, // 鏄惁鍒犻櫎 +// null // 澶囨敞 +// ); + + public String getType$(){ + if (null == this.type){ return null; } + switch (this.type){ + case 0: + return "鎵嬪姩"; + case 1: + return "鑷姩"; + default: + return String.valueOf(this.type); + } + } + + public String getExceStatus$(){ + if (null == this.exceStatus){ return null; } + switch (this.exceStatus){ + case 0: + return "鍒濆鍖�"; + case 1: + return "鐢熸垚浠诲姟"; + case 2: + return "浠诲姟鎾"; + case 3: + return "瀹屾垚"; + default: + return String.valueOf(this.exceStatus); + } + } + + public String getStatus$(){ + if (null == this.status){ return null; } + switch (this.status){ + case 1: + return "姝e父"; + case 0: + return "绂佺敤"; + default: + return String.valueOf(this.status); + } + } + + public String getCreateTime$(){ + if (Cools.isEmpty(this.createTime)){ + return ""; + } + return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.createTime); + } + + public String getCreateBy$(){ + UserService service = SpringUtils.getBean(UserService.class); + User user = service.getById(this.createBy); + if (!Cools.isEmpty(user)){ + return String.valueOf(user.getNickname()); + } + return null; + } + + public String getUpdateTime$(){ + if (Cools.isEmpty(this.updateTime)){ + return ""; + } + return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.updateTime); + } + + public String getUpdateBy$(){ + UserService service = SpringUtils.getBean(UserService.class); + User user = service.getById(this.updateBy); + if (!Cools.isEmpty(user)){ + return String.valueOf(user.getNickname()); + } + 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/WaveItem.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/WaveItem.java new file mode 100644 index 0000000..36d7e30 --- /dev/null +++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/WaveItem.java @@ -0,0 +1,291 @@ +package com.vincent.rsf.server.manager.entity; + +import com.baomidou.mybatisplus.annotation.TableLogic; +import java.text.SimpleDateFormat; +import java.util.Date; + +import lombok.experimental.Accessors; +import org.springframework.format.annotation.DateTimeFormat; +import java.text.SimpleDateFormat; +import java.util.Date; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableLogic; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import com.vincent.rsf.framework.common.Cools; +import com.vincent.rsf.framework.common.SpringUtils; +import com.vincent.rsf.server.system.service.UserService; +import com.vincent.rsf.server.system.entity.User; +import java.io.Serializable; +import java.util.Date; + +@Data +@Accessors(chain = true) +@TableName("man_wave_item") +public class WaveItem implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * ID + */ + @ApiModelProperty(value= "ID") + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + /** + * 娉㈡ID + */ + @ApiModelProperty(value= "娉㈡ID") + private Long waveId; + + /** + * 娉㈡鍙� + */ + @ApiModelProperty(value= "娉㈡鍙�") + private String waveCode; + + /** + * 鍟嗗搧ID + */ + @ApiModelProperty(value= "鍟嗗搧ID") + private Long matnrId; + + /** + * 鐗╂枡鍚嶇О + */ + @ApiModelProperty(value= "鐗╂枡鍚嶇О") + private String matnrName; + + /** + * 鍟嗗搧缂栧彿 + */ + @ApiModelProperty(value= "鍟嗗搧缂栧彿") + private String matnrCode; + + /** + * 鎵瑰彿 + */ + @ApiModelProperty(value= "鎵瑰彿") + private String batch; + + /** + * 渚涘簲鍟嗘壒娆� + */ + @ApiModelProperty(value= "渚涘簲鍟嗘壒娆�") + private String splrBatch; + + /** + * 鍗曟嵁缂栫爜 + */ + @ApiModelProperty(value= "鍗曟嵁缂栫爜") + private String orderCode; + + /** + * 鍗曟嵁ID + */ + @ApiModelProperty(value= "鍗曟嵁ID") + private Long orderItemId; + + @ApiModelProperty("璁㈠崟ID") + private Long orderId; + + /** + * 鍗曚綅 + */ + @ApiModelProperty(value= "鍗曚綅") + private String unit; + + /** + * 璺熻釜鐮� + */ + @ApiModelProperty(value= "璺熻釜鐮�") + private String trackCode; + + /** + * 鍟嗗搧搴撳瓨绱㈠紩 + */ + @ApiModelProperty(value= "鍟嗗搧搴撳瓨绱㈠紩") + private String fieldsIndex; + + /** + * 鏁伴噺 + */ + @ApiModelProperty(value= "鏁伴噺") + private Double anfme; + + @ApiModelProperty("宸插畬鎴愭暟閲�") + private Double qty; + + /** + * 宸ヤ綔鏁伴噺 + */ + @ApiModelProperty(value= "宸ヤ綔鏁伴噺") + private Double workQty; + + /** + * 鎵�灞炴満鏋� + */ + @ApiModelProperty(value= "鎵�灞炴満鏋�") + private Long tenantId; + + /** + * 鐘舵�� 1: 姝e父 0: 绂佺敤 + */ + @ApiModelProperty(value= "鐘舵�� 1: 姝e父 0: 绂佺敤 ") + private Integer status; + + /** + * 鏄惁鍒犻櫎 1: 鏄� 0: 鍚� + */ + @ApiModelProperty(value= "鏄惁鍒犻櫎 1: 鏄� 0: 鍚� ") + @TableLogic + private Integer deleted; + + /** + * 娣诲姞鏃堕棿 + */ + @ApiModelProperty(value= "娣诲姞鏃堕棿") + @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") + private Date createTime; + + /** + * 娣诲姞浜哄憳 + */ + @ApiModelProperty(value= "娣诲姞浜哄憳") + private Long createBy; + + /** + * 淇敼鏃堕棿 + */ + @ApiModelProperty(value= "淇敼鏃堕棿") + @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") + private Date updateTime; + + /** + * 淇敼浜哄憳 + */ + @ApiModelProperty(value= "淇敼浜哄憳") + private Long updateBy; + + /** + * 澶囨敞 + */ + @ApiModelProperty(value= "澶囨敞") + private String memo; + + 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) { + this.waveId = waveId; + this.waveCode = waveCode; + this.matnrId = matnrId; + this.matnrName = matnrName; + this.matnrCode = matnrCode; + this.batch = batch; + this.splrBatch = splrBatch; + this.orderCode = orderCode; + this.orderItemId = orderItemId; + this.unit = unit; + this.trackCode = trackCode; + this.fieldsIndex = fieldsIndex; + this.anfme = anfme; + this.workQty = workQty; + this.tenantId = tenantId; + this.status = status; + this.deleted = deleted; + this.createTime = createTime; + this.createBy = createBy; + this.updateTime = updateTime; + this.updateBy = updateBy; + this.memo = memo; + } + +// WaveItem waveItem = new WaveItem( +// null, // 娉㈡ID +// null, // 娉㈡鍙� +// null, // 鍟嗗搧ID +// null, // 鐗╂枡鍚嶇О +// null, // 鍟嗗搧缂栧彿 +// null, // 鎵瑰彿 +// null, // 渚涘簲鍟嗘壒娆� +// null, // 鍗曟嵁缂栫爜 +// null, // 鍗曟嵁ID +// null, // 鍗曚綅 +// null, // 璺熻釜鐮� +// null, // 鍟嗗搧搴撳瓨绱㈠紩 +// null, // 鏁伴噺 +// null, // 宸ヤ綔鏁伴噺 +// null, // 鎵�灞炴満鏋� +// null, // 鐘舵�� +// null, // 鏄惁鍒犻櫎 +// null, // 娣诲姞鏃堕棿 +// null, // 娣诲姞浜哄憳 +// null, // 淇敼鏃堕棿 +// null, // 淇敼浜哄憳 +// null // 澶囨敞 +// ); + + public String getStatus$(){ + if (null == this.status){ return null; } + switch (this.status){ + case 1: + return "姝e父"; + case 0: + return "绂佺敤"; + default: + return String.valueOf(this.status); + } + } + + public String getCreateTime$(){ + if (Cools.isEmpty(this.createTime)){ + return ""; + } + return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.createTime); + } + + public String getCreateBy$(){ + UserService service = SpringUtils.getBean(UserService.class); + User user = service.getById(this.createBy); + if (!Cools.isEmpty(user)){ + return String.valueOf(user.getNickname()); + } + return null; + } + + public String getUpdateTime$(){ + if (Cools.isEmpty(this.updateTime)){ + return ""; + } + return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.updateTime); + } + + public String getUpdateBy$(){ + UserService service = SpringUtils.getBean(UserService.class); + User user = service.getById(this.updateBy); + if (!Cools.isEmpty(user)){ + return String.valueOf(user.getNickname()); + } + 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/enums/WaveExceStatus.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/enums/WaveExceStatus.java new file mode 100644 index 0000000..a590c90 --- /dev/null +++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/enums/WaveExceStatus.java @@ -0,0 +1,27 @@ +package com.vincent.rsf.server.manager.enums; + +/** + * @author Ryan + * @version 1.0 + * @title WaveExceStatus + * @description + * @create 2025/4/24 17:56 + */ +public enum WaveExceStatus { + + //娉㈡鎵ц鐘舵�� + WAVE_EXCE_STATUS_INIT("0", "鍒濆鍖�"), + WAVE_EXCE_STATUS_TASK("1", "鐢熸垚浠诲姟"), + WAVE_EXCE_STATUS_SPEED("2", "鎾浠诲姟"), + WAVE_EXCE_STATUS_DONE("3", "瀹屾垚"), + ; + + WaveExceStatus(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/mapper/DeviceBindMapper.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/mapper/DeviceBindMapper.java new file mode 100644 index 0000000..528719d --- /dev/null +++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/mapper/DeviceBindMapper.java @@ -0,0 +1,12 @@ +package com.vincent.rsf.server.manager.mapper; + +import com.vincent.rsf.server.manager.entity.DeviceBind; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; +import org.springframework.stereotype.Repository; + +@Mapper +@Repository +public interface DeviceBindMapper extends BaseMapper<DeviceBind> { + +} diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/mapper/WaveItemMapper.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/mapper/WaveItemMapper.java new file mode 100644 index 0000000..a1017cb --- /dev/null +++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/mapper/WaveItemMapper.java @@ -0,0 +1,12 @@ +package com.vincent.rsf.server.manager.mapper; + +import com.vincent.rsf.server.manager.entity.WaveItem; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; +import org.springframework.stereotype.Repository; + +@Mapper +@Repository +public interface WaveItemMapper extends BaseMapper<WaveItem> { + +} diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/mapper/WaveMapper.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/mapper/WaveMapper.java new file mode 100644 index 0000000..4d4bf1f --- /dev/null +++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/mapper/WaveMapper.java @@ -0,0 +1,12 @@ +package com.vincent.rsf.server.manager.mapper; + +import com.vincent.rsf.server.manager.entity.Wave; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; +import org.springframework.stereotype.Repository; + +@Mapper +@Repository +public interface WaveMapper extends BaseMapper<Wave> { + +} diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/DeviceBindService.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/DeviceBindService.java new file mode 100644 index 0000000..91fae2b --- /dev/null +++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/DeviceBindService.java @@ -0,0 +1,8 @@ +package com.vincent.rsf.server.manager.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.vincent.rsf.server.manager.entity.DeviceBind; + +public interface DeviceBindService extends IService<DeviceBind> { + +} diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/OutStockService.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/OutStockService.java index 90450e4..22fcc64 100644 --- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/OutStockService.java +++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/OutStockService.java @@ -14,4 +14,6 @@ R cancelOutOrder(String id); R genOutStock(List<Long> ids); + + R generateWaves(List<Long> ids); } diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/WaveItemService.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/WaveItemService.java new file mode 100644 index 0000000..bd9a838 --- /dev/null +++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/WaveItemService.java @@ -0,0 +1,8 @@ +package com.vincent.rsf.server.manager.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.vincent.rsf.server.manager.entity.WaveItem; + +public interface WaveItemService extends IService<WaveItem> { + +} 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 new file mode 100644 index 0000000..0005369 --- /dev/null +++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/WaveService.java @@ -0,0 +1,8 @@ +package com.vincent.rsf.server.manager.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.vincent.rsf.server.manager.entity.Wave; + +public interface WaveService extends IService<Wave> { + +} diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/DeviceBindServiceImpl.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/DeviceBindServiceImpl.java new file mode 100644 index 0000000..b5a861b --- /dev/null +++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/DeviceBindServiceImpl.java @@ -0,0 +1,12 @@ +package com.vincent.rsf.server.manager.service.impl; + +import com.vincent.rsf.server.manager.mapper.DeviceBindMapper; +import com.vincent.rsf.server.manager.entity.DeviceBind; +import com.vincent.rsf.server.manager.service.DeviceBindService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +@Service("deviceBindService") +public class DeviceBindServiceImpl extends ServiceImpl<DeviceBindMapper, DeviceBind> implements DeviceBindService { + +} diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/DeviceSiteServiceImpl.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/DeviceSiteServiceImpl.java index 2a1a189..9f28a03 100644 --- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/DeviceSiteServiceImpl.java +++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/DeviceSiteServiceImpl.java @@ -37,25 +37,32 @@ if (Objects.isNull(param.getDeviceSites()) || StringUtils.isBlank(param.getDeviceSites())) { throw new CoolException("鍒濆鍖栧け璐ワ細 璁惧浣滀笟绔欑偣涓嶈兘涓虹┖锛侊紒"); } - if (Objects.isNull(param.getSites()) || StringUtils.isBlank(param.getSites())) { + if (Objects.isNull(param.getSite()) || StringUtils.isBlank(param.getSite())) { throw new CoolException("鍒濆鍖栧け璐�: 浣滀笟绔欑偣涓嶈兘涓虹┖锛侊紒"); } if (Objects.isNull(param.getTypeIds()) || param.getTypeIds().isEmpty()) { throw new CoolException("鍒濆鍖栧け璐ワ細 浣滀笟绫诲瀷涓嶈兘涓虹┖锛侊紒"); } - List<String> sites = Arrays.asList(StringUtils.split(param.getSites(), ",")); + if (Objects.isNull(param.getTarget()) || param.getTarget().isEmpty()) { + throw new CoolException("鍒濆鍖栧け璐ワ細 鐩爣绔欑偣涓嶈兘涓虹┖锛侊紒"); + } + List<String> sites = Arrays.asList(StringUtils.split(param.getSite(), ",")); List<String> dvSites = Arrays.asList(StringUtils.split(param.getDeviceSites(), ",")); + List<String> targets = Arrays.asList(StringUtils.split(param.getTarget(), ",")); List<DeviceSite> deviceSites = new ArrayList<>(); for (String site : sites) { for (String deviceSite : dvSites) { for (Long id : param.getTypeIds()) { - DeviceSite site1 = new DeviceSite(); - site1.setType(id + "") - .setSite(site) - .setDevice(param.getDeviceType()) - .setDeviceSite(deviceSite) - .setDeviceCode(param.getDeviceCode()); - deviceSites.add(site1); + for (String target : targets) { + DeviceSite site1 = new DeviceSite(); + site1.setType(id + "") + .setSite(site) + .setDevice(param.getDeviceType()) + .setDeviceSite(deviceSite) + .setTarget(target) + .setDeviceCode(param.getDeviceCode()); + deviceSites.add(site1); + } } } } 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 3b19c58..af8c2d1 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 @@ -13,6 +13,7 @@ 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.*; @@ -45,15 +46,16 @@ private AsnOrderLogService asnOrderLogService; @Autowired private AsnOrderItemLogService asnOrderItemLogService; - @Autowired private DeliveryItemService deliveryItemService; - @Autowired private DeliveryService deliveryService; @Autowired private MatnrService matnrService; - + @Autowired + private WaveService waveService; + @Autowired + private WaveItemService waveItemService; /** @@ -157,6 +159,7 @@ @Override @Transactional(rollbackFor = Exception.class) public R cancelOutOrder(String id) { + //TODO 鍑哄簱鍗曞彇娑堟祦绋嬶紝QMS锛堝崟鎹彇娑堬級->DO鍗�->鍑哄簱鍗�->娉㈡->鍒ゆ柇鏄惁鍏ㄥ崟鎹�->鍏ㄥ崟鎹笅鍙戝彇娑堜换鍔¤嚦WCS,闈炲叏鍗曟暟鎹彇娑堝垹闄ゆ祦绋嬫墍鏈夊叧鑱旀暟鎹� if (Cools.isEmpty(id)) { throw new CoolException("鍙傛暟涓嶈兘涓虹┖锛侊紒"); } @@ -238,4 +241,58 @@ }); return R.ok(); } + + /** + * @param + * @return + * @author Ryan + * @description 鐢熸垚娉㈡ + * @time 2025/4/24 15:04 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public R generateWaves(List<Long> ids) { + if (Objects.isNull(ids) || ids.isEmpty()) { + throw new CoolException("鍙傛暟涓嶈兘涓虹┖锛侊紒"); + } + List<AsnOrder> orders = this.listByIds(ids); + if (orders.isEmpty()) { + throw new CoolException("鍗曟嵁涓嶅瓨鍦紒锛�"); + } + double sum = orders.stream().mapToDouble(AsnOrder::getAnfme).sum(); + Wave wave = new Wave(); + String ruleCode = SerialRuleUtils.generateRuleCode(SerialRuleCode.SYS_WAVE_TYPE, null); + if (Objects.isNull(ruleCode) || StringUtils.isBlank(ruleCode)) { + throw new CoolException("缂栫爜瑙勫垯閿欒锛氳瑕佹煡鐪嬨�孲YS_WAVE_TYPE銆嶆槸鍚﹁缃垚鍔燂紒锛�"); + } + wave.setOrderNum(ids.size()) + .setType(Short.parseShort("1")) + .setCode(ruleCode) + .setExceStatus(WaveExceStatus.WAVE_EXCE_STATUS_INIT.val) + .setAnfme(sum); + if (!waveService.save(wave)) { + 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 (!waveItemService.saveBatch(items)) { + throw new CoolException("娉㈡鏄庣粏淇濆瓨澶辫触锛侊紒"); + } + return R.ok("鎿嶄綔瀹屾垚锛侊紒"); + } } diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/WaveItemServiceImpl.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/WaveItemServiceImpl.java new file mode 100644 index 0000000..a18d44b --- /dev/null +++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/WaveItemServiceImpl.java @@ -0,0 +1,12 @@ +package com.vincent.rsf.server.manager.service.impl; + +import com.vincent.rsf.server.manager.mapper.WaveItemMapper; +import com.vincent.rsf.server.manager.entity.WaveItem; +import com.vincent.rsf.server.manager.service.WaveItemService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +@Service("waveItemService") +public class WaveItemServiceImpl extends ServiceImpl<WaveItemMapper, WaveItem> implements WaveItemService { + +} 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 new file mode 100644 index 0000000..d323911 --- /dev/null +++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/WaveServiceImpl.java @@ -0,0 +1,12 @@ +package com.vincent.rsf.server.manager.service.impl; + +import com.vincent.rsf.server.manager.mapper.WaveMapper; +import com.vincent.rsf.server.manager.entity.Wave; +import com.vincent.rsf.server.manager.service.WaveService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +@Service("waveService") +public class WaveServiceImpl extends ServiceImpl<WaveMapper, Wave> implements WaveService { + +} diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/system/constant/SerialRuleCode.java b/rsf-server/src/main/java/com/vincent/rsf/server/system/constant/SerialRuleCode.java index d0ad509..3546c5c 100644 --- a/rsf-server/src/main/java/com/vincent/rsf/server/system/constant/SerialRuleCode.java +++ b/rsf-server/src/main/java/com/vincent/rsf/server/system/constant/SerialRuleCode.java @@ -69,4 +69,9 @@ */ public final static String SYS_OUT_STOCK_CODE = "sys_out_stock_code"; + /** + * 娉㈡绫诲瀷 + */ + public final static String SYS_WAVE_TYPE = "sys_wave_type"; + } diff --git a/rsf-server/src/main/java/deviceBind.sql b/rsf-server/src/main/java/deviceBind.sql new file mode 100644 index 0000000..6ef331b --- /dev/null +++ b/rsf-server/src/main/java/deviceBind.sql @@ -0,0 +1,31 @@ +-- save deviceBind record +-- mysql +insert into `sys_menu` ( `name`, `parent_id`, `route`, `component`, `type`, `sort`, `tenant_id`, `status`) values ( 'menu.deviceBind', '0', '/manager/deviceBind', 'deviceBind', '0' , '0', '1' , '1'); + +insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Query 绔嬩綋搴撶珯鐐圭粦瀹�', '', '1', 'manager:deviceBind:list', '0', '1', '1'); +insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Create 绔嬩綋搴撶珯鐐圭粦瀹�', '', '1', 'manager:deviceBind:save', '1', '1', '1'); +insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Update 绔嬩綋搴撶珯鐐圭粦瀹�', '', '1', 'manager:deviceBind:update', '2', '1', '1'); +insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Delete 绔嬩綋搴撶珯鐐圭粦瀹�', '', '1', 'manager:deviceBind:remove', '3', '1', '1'); + +-- locale menu name +deviceBind: 'DeviceBind', + +-- locale field +deviceBind: { + currentRow: "currentRow", + startRow: "startRow", + endRow: "endRow", + deviceQty: "deviceQty", + startDeviceNo: "startDeviceNo", + endDeviceNo: "endDeviceNo", + staList: "staList", + typeId: "typeId", + beSimilar: "beSimilar", + emptySimilar: "emptySimilar", +}, + +-- ResourceContent +import deviceBind from './deviceBind'; + +case 'deviceBind': + return deviceBind; diff --git a/rsf-server/src/main/java/wave.sql b/rsf-server/src/main/java/wave.sql new file mode 100644 index 0000000..4fcff71 --- /dev/null +++ b/rsf-server/src/main/java/wave.sql @@ -0,0 +1,27 @@ +-- save wave record +-- mysql +insert into `sys_menu` ( `name`, `parent_id`, `route`, `component`, `type`, `sort`, `tenant_id`, `status`) values ( 'menu.wave', '0', '/manager/wave', 'wave', '0' , '0', '1' , '1'); + +insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Query 娉㈡鍗曟嵁', '', '1', 'manager:wave:list', '0', '1', '1'); +insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Create 娉㈡鍗曟嵁', '', '1', 'manager:wave:save', '1', '1', '1'); +insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Update 娉㈡鍗曟嵁', '', '1', 'manager:wave:update', '2', '1', '1'); +insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Delete 娉㈡鍗曟嵁', '', '1', 'manager:wave:remove', '3', '1', '1'); + +-- locale menu name +wave: 'Wave', + +-- locale field +wave: { + code: "code", + type: "type", + exceStatus: "exceStatus", + anfme: "anfme", + qty: "qty", + orderNum: "orderNum", +}, + +-- ResourceContent +import wave from './wave'; + +case 'wave': + return wave; diff --git a/rsf-server/src/main/java/waveItem.sql b/rsf-server/src/main/java/waveItem.sql new file mode 100644 index 0000000..48f35e9 --- /dev/null +++ b/rsf-server/src/main/java/waveItem.sql @@ -0,0 +1,35 @@ +-- save waveItem record +-- mysql +insert into `sys_menu` ( `name`, `parent_id`, `route`, `component`, `type`, `sort`, `tenant_id`, `status`) values ( 'menu.waveItem', '0', '/manager/waveItem', 'waveItem', '0' , '0', '1' , '1'); + +insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Query 娉㈡鏄庣粏', '', '1', 'manager:waveItem:list', '0', '1', '1'); +insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Create 娉㈡鏄庣粏', '', '1', 'manager:waveItem:save', '1', '1', '1'); +insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Update 娉㈡鏄庣粏', '', '1', 'manager:waveItem:update', '2', '1', '1'); +insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Delete 娉㈡鏄庣粏', '', '1', 'manager:waveItem:remove', '3', '1', '1'); + +-- locale menu name +waveItem: 'WaveItem', + +-- locale field +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", +}, + +-- ResourceContent +import waveItem from './waveItem'; + +case 'waveItem': + return waveItem; diff --git a/rsf-server/src/main/resources/mapper/manager/DeviceBindMapper.xml b/rsf-server/src/main/resources/mapper/manager/DeviceBindMapper.xml new file mode 100644 index 0000000..510e068 --- /dev/null +++ b/rsf-server/src/main/resources/mapper/manager/DeviceBindMapper.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> +<mapper namespace="com.vincent.rsf.server.manager.mapper.DeviceBindMapper"> + +</mapper> diff --git a/rsf-server/src/main/resources/mapper/manager/WaveItemMapper.xml b/rsf-server/src/main/resources/mapper/manager/WaveItemMapper.xml new file mode 100644 index 0000000..0d37cfe --- /dev/null +++ b/rsf-server/src/main/resources/mapper/manager/WaveItemMapper.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> +<mapper namespace="com.vincent.rsf.server.manager.mapper.WaveItemMapper"> + +</mapper> diff --git a/rsf-server/src/main/resources/mapper/manager/WaveMapper.xml b/rsf-server/src/main/resources/mapper/manager/WaveMapper.xml new file mode 100644 index 0000000..6a4849e --- /dev/null +++ b/rsf-server/src/main/resources/mapper/manager/WaveMapper.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> +<mapper namespace="com.vincent.rsf.server.manager.mapper.WaveMapper"> + +</mapper> -- Gitblit v1.9.1