27个文件已添加
1 文件已重命名
6个文件已删除
6个文件已修改
| | |
| | | VITE_BASE_IP=192.168.4.56 |
| | | VITE_BASE_IP=127.0.0.1 |
| | | # VITE_BASE_IP=47.76.147.249 |
| | | VITE_BASE_PORT=8080 |
New file |
| | |
| | | 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 BasDeviceCreate = (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.basDevice.deviceNo" |
| | | source="deviceNo" |
| | | autoFocus |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6} display="flex" gap={1}> |
| | | <TextInput |
| | | label="table.field.basDevice.inEnable" |
| | | source="inEnable" |
| | | parse={v => v} |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6} display="flex" gap={1}> |
| | | <TextInput |
| | | label="table.field.basDevice.outEnable" |
| | | source="outEnable" |
| | | parse={v => v} |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6} display="flex" gap={1}> |
| | | <TextInput |
| | | label="table.field.basDevice.origin" |
| | | source="origin" |
| | | 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 BasDeviceCreate; |
New file |
| | |
| | | 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 BasDeviceEdit = () => { |
| | | 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.basDevice.deviceNo" |
| | | source="deviceNo" |
| | | autoFocus |
| | | /> |
| | | </Stack> |
| | | <Stack direction='row' gap={2}> |
| | | <TextInput |
| | | label="table.field.basDevice.inEnable" |
| | | source="inEnable" |
| | | parse={v => v} |
| | | /> |
| | | </Stack> |
| | | <Stack direction='row' gap={2}> |
| | | <TextInput |
| | | label="table.field.basDevice.outEnable" |
| | | source="outEnable" |
| | | parse={v => v} |
| | | /> |
| | | </Stack> |
| | | <Stack direction='row' gap={2}> |
| | | <TextInput |
| | | label="table.field.basDevice.origin" |
| | | source="origin" |
| | | 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 BasDeviceEdit; |
New file |
| | |
| | | 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 BasDeviceCreate from "./BasDeviceCreate"; |
| | | import BasDevicePanel from "./BasDevicePanel"; |
| | | 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="deviceNo" label="table.field.basDevice.deviceNo" />, |
| | | <TextInput source="inEnable" label="table.field.basDevice.inEnable" />, |
| | | <TextInput source="outEnable" label="table.field.basDevice.outEnable" />, |
| | | <TextInput source="origin" label="table.field.basDevice.origin" />, |
| | | |
| | | <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 BasDeviceList = () => { |
| | | 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.basDevice"} |
| | | empty={<EmptyData onClick={() => { setCreateDialog(true) }} />} |
| | | filters={filters} |
| | | sort={{ field: "create_time", order: "desc" }} |
| | | actions={( |
| | | <TopToolbar> |
| | | <FilterButton /> |
| | | <MyCreateButton onClick={() => { setCreateDialog(true) }} /> |
| | | <SelectColumnsButton preferenceKey='basDevice' /> |
| | | <MyExportButton /> |
| | | </TopToolbar> |
| | | )} |
| | | perPage={DEFAULT_PAGE_SIZE} |
| | | > |
| | | <StyledDatagrid |
| | | preferenceKey='basDevice' |
| | | bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />} |
| | | rowClick={(id, resource, record) => false} |
| | | expand={() => <BasDevicePanel />} |
| | | expandSingle={true} |
| | | omit={['id', 'createTime', 'createBy', 'memo']} |
| | | > |
| | | <NumberField source="id" /> |
| | | <NumberField source="deviceNo" label="table.field.basDevice.deviceNo" /> |
| | | <TextField source="inEnable" label="table.field.basDevice.inEnable" /> |
| | | <TextField source="outEnable" label="table.field.basDevice.outEnable" /> |
| | | <TextField source="origin" label="table.field.basDevice.origin" /> |
| | | |
| | | <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> |
| | | <BasDeviceCreate |
| | | open={createDialog} |
| | | setOpen={setCreateDialog} |
| | | /> |
| | | <PageDrawer |
| | | title='BasDevice Detail' |
| | | drawerVal={drawerVal} |
| | | setDrawerVal={setDrawerVal} |
| | | > |
| | | </PageDrawer> |
| | | </Box> |
| | | ) |
| | | } |
| | | |
| | | export default BasDeviceList; |
New file |
| | |
| | | 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 BasDevicePanel = () => { |
| | | 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.basDevice.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.basDevice.deviceNo" |
| | | property={record.deviceNo} |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6}> |
| | | <PanelTypography |
| | | title="table.field.basDevice.inEnable" |
| | | property={record.inEnable} |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6}> |
| | | <PanelTypography |
| | | title="table.field.basDevice.outEnable" |
| | | property={record.outEnable} |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6}> |
| | | <PanelTypography |
| | | title="table.field.basDevice.origin" |
| | | property={record.origin} |
| | | /> |
| | | </Grid> |
| | | |
| | | </Grid> |
| | | </CardContent> |
| | | </Card > |
| | | </> |
| | | ); |
| | | }; |
| | | |
| | | export default BasDevicePanel; |
New file |
| | |
| | | import React, { useState, useRef, useEffect, useMemo } from "react"; |
| | | import { |
| | | ListGuesser, |
| | | EditGuesser, |
| | | ShowGuesser, |
| | | } from "react-admin"; |
| | | |
| | | import BasDeviceList from "./BasDeviceList"; |
| | | import BasDeviceEdit from "./BasDeviceEdit"; |
| | | |
| | | export default { |
| | | list: BasDeviceList, |
| | | edit: BasDeviceEdit, |
| | | show: ShowGuesser, |
| | | recordRepresentation: (record) => { |
| | | return `${record.id}` |
| | | } |
| | | }; |
New file |
| | |
| | | -- save basDevice record |
| | | -- mysql |
| | | insert into `sys_menu` ( `name`, `parent_id`, `route`, `component`, `type`, `sort`, `tenant_id`, `status`) values ( 'menu.basDevice', '0', '/manager/basDevice', 'basDevice', '0' , '0', '1' , '1'); |
| | | |
| | | insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Query 基础设备表', '', '1', 'manager:basDevice:list', '0', '1', '1'); |
| | | insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Create 基础设备表', '', '1', 'manager:basDevice:save', '1', '1', '1'); |
| | | insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Update 基础设备表', '', '1', 'manager:basDevice:update', '2', '1', '1'); |
| | | insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Delete 基础设备表', '', '1', 'manager:basDevice:remove', '3', '1', '1'); |
| | | |
| | | -- locale menu name |
| | | basDevice: 'BasDevice', |
| | | |
| | | -- locale field |
| | | basDevice: { |
| | | deviceNo: "deviceNo", |
| | | inEnable: "inEnable", |
| | | outEnable: "outEnable", |
| | | origin: "origin", |
| | | }, |
| | | |
| | | -- ResourceContent |
| | | import basDevice from './basDevice'; |
| | | |
| | | case 'basDevice': |
| | | return basDevice; |
New file |
| | |
| | | package com.vincent.rsf.server.api.controller; |
| | | |
| | | import com.vincent.rsf.framework.common.Cools; |
| | | import com.vincent.rsf.framework.common.R; |
| | | import com.vincent.rsf.server.api.entity.dto.InTaskMsgDto; |
| | | import com.vincent.rsf.server.api.controller.params.TaskInParam; |
| | | import com.vincent.rsf.server.api.entity.enums.TaskType; |
| | | import com.vincent.rsf.server.api.service.WcsService; |
| | | import com.vincent.rsf.server.system.controller.BaseController; |
| | | import io.swagger.annotations.Api; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.web.bind.annotation.PostMapping; |
| | | import org.springframework.web.bind.annotation.RequestBody; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | @RestController |
| | | @RequestMapping("/wcs") |
| | | @Api(tags = "wcs接口对接") |
| | | public class WcsController extends BaseController { |
| | | |
| | | @Autowired |
| | | private WcsService wcsService; |
| | | |
| | | // @ApiOperation(value = "wcs生成入库任务接口") |
| | | @PostMapping("/create/in/task") |
| | | public R createInTask(@RequestBody TaskInParam param) { |
| | | if (Cools.isEmpty(param.getIoType())) { |
| | | return R.error("入出库类型不能为空"); |
| | | } |
| | | if (Cools.isEmpty(param.getSourceStaNo())) { |
| | | return R.error("源站编号不能为空"); |
| | | } |
| | | if (Cools.isEmpty(param.getBarcode()) && param.getIoType().equals(TaskType.TASK_TYPE_IN.type)) { |
| | | return R.error("条码不能为空"); |
| | | } |
| | | if (Cools.isEmpty(param.getLocType1())){ |
| | | return R.error("高低检测信号不能为空"); |
| | | } |
| | | InTaskMsgDto msgDto = wcsService.createInTask(param,getLoginUserId()); |
| | | return R.ok(msgDto); |
| | | |
| | | |
| | | } |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package com.vincent.rsf.server.api.controller.params; |
| | | |
| | | import lombok.Data; |
| | | |
| | | @Data |
| | | public class TaskInParam { |
| | | |
| | | private Integer ioType; //作业类型 |
| | | private Integer sourceStaNo; //作业站点 or 来源站点 |
| | | private String barcode; //容器条码 |
| | | private Integer locType1; //库位类型 |
| | | private Integer area; |
| | | // private Integer locType2; //库位类型 |
| | | // private Integer locType3; //库位类型 |
| | | } |
File was renamed from rsf-server/src/main/java/com/vincent/rsf/server/api/controller/MobileController.java |
| | |
| | | package com.vincent.rsf.server.api.controller; |
| | | package com.vincent.rsf.server.api.controller.pda; |
| | | |
| | | import com.vincent.rsf.framework.common.R; |
| | | import com.vincent.rsf.framework.exception.CoolException; |
New file |
| | |
| | | package com.vincent.rsf.server.api.controller.pda; |
| | | |
| | | import com.vincent.rsf.framework.common.R; |
| | | import com.vincent.rsf.server.api.service.PdaOutStockService; |
| | | import io.swagger.annotations.Api; |
| | | import io.swagger.annotations.ApiOperation; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import java.util.Map; |
| | | |
| | | @Api(tags = "PDA出库操作接口") |
| | | @RequestMapping("/pda") |
| | | @RestController |
| | | public class pdaOutStockController { |
| | | |
| | | @Autowired |
| | | private PdaOutStockService pdaOutStockService; |
| | | |
| | | @PreAuthorize("hasAuthority('manager:task:list')") |
| | | @GetMapping("/outStockTaskItem/{barcode}") |
| | | @ApiOperation("快速拣货查询") |
| | | public R getOutStockTaskItem(@PathVariable String barcode) { |
| | | |
| | | return pdaOutStockService.getOutStockTaskItem(barcode); |
| | | } |
| | | } |
New file |
| | |
| | | package com.vincent.rsf.server.api.entity.dto; |
| | | |
| | | import lombok.Data; |
| | | |
| | | @Data |
| | | public class InTaskMsgDto { |
| | | private Integer sourceStaNo; |
| | | |
| | | private Integer staNo; |
| | | |
| | | private Integer deviceNo; |
| | | |
| | | private String locNo; |
| | | |
| | | private String workNo; |
| | | } |
New file |
| | |
| | | package com.vincent.rsf.server.api.entity.dto; |
| | | |
| | | import com.vincent.rsf.server.api.controller.params.TaskInParam; |
| | | import lombok.Data; |
| | | |
| | | @Data |
| | | public class LocTypeDto { |
| | | // 高低类型{0:未知,1:低库位,2:高库位} |
| | | private Integer locType1; |
| | | |
| | | // 宽窄类型{0:未知,1:窄库位,2:宽库位} |
| | | private Integer locType2; |
| | | |
| | | // 轻重类型{0:未知,1:轻库位,2:重库位} |
| | | private Integer locType3; |
| | | |
| | | public LocTypeDto(TaskInParam param) { |
| | | this.locType1 = param.getLocType1(); // 高库位 |
| | | |
| | | } |
| | | } |
New file |
| | |
| | | package com.vincent.rsf.server.api.service; |
| | | |
| | | import com.vincent.rsf.framework.common.R; |
| | | |
| | | import java.util.Map; |
| | | |
| | | public interface PdaOutStockService { |
| | | R getOutStockTaskItem(String barcode); |
| | | } |
New file |
| | |
| | | package com.vincent.rsf.server.api.service; |
| | | |
| | | import com.vincent.rsf.server.api.entity.dto.InTaskMsgDto; |
| | | import com.vincent.rsf.server.api.controller.params.TaskInParam; |
| | | |
| | | public interface WcsService { |
| | | InTaskMsgDto createInTask(TaskInParam param, Long loginUserId); |
| | | } |
New file |
| | |
| | | package com.vincent.rsf.server.api.service.impl; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.vincent.rsf.framework.common.R; |
| | | import com.vincent.rsf.server.api.service.PdaOutStockService; |
| | | import com.vincent.rsf.server.manager.entity.AsnOrder; |
| | | import com.vincent.rsf.server.manager.entity.Task; |
| | | import com.vincent.rsf.server.manager.entity.TaskItem; |
| | | import com.vincent.rsf.server.manager.service.AsnOrderService; |
| | | import com.vincent.rsf.server.manager.service.OutStockService; |
| | | import com.vincent.rsf.server.manager.service.TaskItemService; |
| | | import com.vincent.rsf.server.manager.service.TaskService; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import javax.annotation.Resource; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.Objects; |
| | | |
| | | @Service |
| | | public class PdaOutStockServiceImpl implements PdaOutStockService { |
| | | |
| | | @Resource |
| | | private TaskService taskService; |
| | | @Resource |
| | | private TaskItemService taskItemService; |
| | | |
| | | @Override |
| | | public R getOutStockTaskItem(String barcode) { |
| | | LambdaQueryWrapper<Task> lambdaQueryWrapper = new LambdaQueryWrapper<>(); |
| | | lambdaQueryWrapper.eq(Task::getBarcode, barcode); |
| | | Task task = taskService.getOne(lambdaQueryWrapper); |
| | | if (null == task){ |
| | | return R.error("未查询到相关任务"); |
| | | } |
| | | List<TaskItem> taskItems = taskItemService.list(new LambdaQueryWrapper<TaskItem>().eq(TaskItem::getTaskId, task.getId())); |
| | | if (null == taskItems || taskItems.size() <= 0){ |
| | | return R.error("任务出错,未查询到相关任务明细"); |
| | | } |
| | | |
| | | |
| | | return R.ok(taskItems); |
| | | } |
| | | } |
New file |
| | |
| | | package com.vincent.rsf.server.api.service.impl; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; |
| | | import com.vincent.rsf.framework.common.Cools; |
| | | import com.vincent.rsf.framework.exception.CoolException; |
| | | import com.vincent.rsf.server.api.entity.dto.InTaskMsgDto; |
| | | import com.vincent.rsf.server.api.entity.dto.LocTypeDto; |
| | | import com.vincent.rsf.server.api.controller.params.TaskInParam; |
| | | import com.vincent.rsf.server.api.entity.enums.OrderType; |
| | | import com.vincent.rsf.server.api.entity.enums.TaskStsType; |
| | | import com.vincent.rsf.server.api.entity.enums.TaskType; |
| | | import com.vincent.rsf.server.api.service.WcsService; |
| | | import com.vincent.rsf.server.api.utils.LocUtils; |
| | | import com.vincent.rsf.server.api.utils.SlaveProperties; |
| | | import com.vincent.rsf.server.manager.entity.*; |
| | | import com.vincent.rsf.server.manager.enums.PakinIOStatus; |
| | | import com.vincent.rsf.server.manager.service.*; |
| | | import com.vincent.rsf.server.manager.service.impl.LocServiceImpl; |
| | | import com.vincent.rsf.server.manager.utils.LocManageUtil; |
| | | import com.vincent.rsf.server.system.constant.SerialRuleCode; |
| | | import com.vincent.rsf.server.system.enums.LocStsType; |
| | | import com.vincent.rsf.server.system.utils.SerialRuleUtils; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.springframework.beans.BeanUtils; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | import java.util.Objects; |
| | | import java.util.stream.Collectors; |
| | | |
| | | @Service |
| | | public class WcsServiceImpl implements WcsService { |
| | | @Autowired |
| | | private DeviceSiteService deviceSiteService; |
| | | @Autowired |
| | | private WaitPakinService waitPakinService; |
| | | @Autowired |
| | | private DeviceBindService deviceBindService; |
| | | @Autowired |
| | | private LocServiceImpl locService; |
| | | @Autowired |
| | | private LocItemService locItemService; |
| | | @Autowired |
| | | private SlaveProperties slaveProperties; |
| | | @Autowired |
| | | private WarehouseAreasService warehouseAreasService; |
| | | @Autowired |
| | | private TaskService taskService; |
| | | @Autowired |
| | | private TaskItemService taskItemService; |
| | | @Autowired |
| | | private WaitPakinItemService waitPakinItemService; |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public InTaskMsgDto createInTask(TaskInParam param, Long loginUserId) { |
| | | // 获取库位号 |
| | | InTaskMsgDto locNo = getLocNo(param); |
| | | |
| | | // 验证设备站点 |
| | | DeviceSite deviceSite = validateDeviceSite(param); |
| | | |
| | | // 验证组拖状态 |
| | | WaitPakin waitPakin = validateWaitPakin(param.getBarcode()); |
| | | |
| | | // 生成任务编码 |
| | | String ruleCode = generateTaskCode(); |
| | | |
| | | // 创建并保存任务 |
| | | Task task = createTask(ruleCode, locNo.getLocNo(), waitPakin.getBarcode(), |
| | | deviceSite.getDeviceSite(), param.getSourceStaNo().toString(), loginUserId); |
| | | |
| | | // 更新库位状态 |
| | | updateLocStatus(task.getTargLoc(), waitPakin.getBarcode()); |
| | | |
| | | // 获取并验证组拖明细 |
| | | List<WaitPakinItem> waitPakinItems = getWaitPakinItems(waitPakin.getId()); |
| | | |
| | | // 创建并保存任务明细 |
| | | saveTaskItems(task.getId(), waitPakinItems, loginUserId); |
| | | |
| | | // 更新组托状态 |
| | | updateWaitPakinStatus(param.getBarcode(), loginUserId); |
| | | |
| | | // 设置工作单号并返回 |
| | | locNo.setWorkNo(ruleCode); |
| | | return locNo; |
| | | } |
| | | |
| | | /** |
| | | * 验证设备站点 |
| | | */ |
| | | private DeviceSite validateDeviceSite(TaskInParam param) { |
| | | DeviceSite deviceSite = deviceSiteService.getOne(new LambdaQueryWrapper<DeviceSite>() |
| | | .eq(DeviceSite::getSite, param.getSourceStaNo()) |
| | | .eq(DeviceSite::getType, param.getIoType())); |
| | | |
| | | if (Objects.isNull(deviceSite)) { |
| | | throw new CoolException("站点不存在!!"); |
| | | } |
| | | return deviceSite; |
| | | } |
| | | |
| | | /** |
| | | * 验证组拖状态 |
| | | */ |
| | | private WaitPakin validateWaitPakin(String barcode) { |
| | | WaitPakin waitPakin = waitPakinService.getOne(new LambdaQueryWrapper<WaitPakin>() |
| | | .eq(WaitPakin::getBarcode, barcode) |
| | | .eq(WaitPakin::getIoStatus, Short.parseShort(PakinIOStatus.PAKIN_IO_STATUS_DONE.val))); |
| | | |
| | | if (Cools.isEmpty(waitPakin)) { |
| | | throw new CoolException("请检查组拖状态是否完成!!"); |
| | | } |
| | | return waitPakin; |
| | | } |
| | | |
| | | /** |
| | | * 生成任务编码 |
| | | */ |
| | | private String generateTaskCode() { |
| | | String ruleCode = SerialRuleUtils.generateRuleCode(SerialRuleCode.SYS_TASK_CODE, null); |
| | | if (StringUtils.isBlank(ruleCode)) { |
| | | throw new CoolException("编码错误:请确认编码「SYS_TASK_CODE」是否已生成!!"); |
| | | } |
| | | return ruleCode; |
| | | } |
| | | |
| | | /** |
| | | * 创建并保存任务 |
| | | */ |
| | | private Task createTask(String ruleCode, String targetLoc, String barcode, |
| | | String targetSite, String sourceSiteNo, Long loginUserId) { |
| | | Task task = new Task(); |
| | | task.setTaskCode(ruleCode) |
| | | .setTaskStatus(TaskStsType.GENERATE_IN.id.shortValue()) |
| | | .setTaskType(TaskType.TASK_TYPE_IN.type.shortValue()) |
| | | .setTargLoc(targetLoc) |
| | | .setBarcode(barcode) |
| | | .setTargSite(targetSite) |
| | | .setCreateBy(loginUserId) |
| | | .setUpdateBy(loginUserId) |
| | | .setOrgSite(sourceSiteNo); |
| | | |
| | | if (!taskService.save(task)) { |
| | | throw new CoolException("任务保存失败!!"); |
| | | } |
| | | return task; |
| | | } |
| | | |
| | | /** |
| | | * 更新库位状态 |
| | | */ |
| | | private void updateLocStatus(String locCode, String barcode) { |
| | | boolean updated = locService.update(new LambdaUpdateWrapper<Loc>() |
| | | .eq(Loc::getCode, locCode) |
| | | .set(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_S.type) |
| | | .set(Loc::getBarcode, barcode)); |
| | | |
| | | if (!updated) { |
| | | throw new CoolException("库位预约失败!!"); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 获取并验证组拖明细 |
| | | */ |
| | | private List<WaitPakinItem> getWaitPakinItems(Long pakinId) { |
| | | List<WaitPakinItem> waitPakinItems = waitPakinItemService.list( |
| | | new LambdaQueryWrapper<WaitPakinItem>().eq(WaitPakinItem::getPakinId, pakinId)); |
| | | |
| | | if (waitPakinItems.isEmpty()) { |
| | | throw new CoolException("数据错误:组拖明细不存在"); |
| | | } |
| | | return waitPakinItems; |
| | | } |
| | | |
| | | /** |
| | | * 创建并保存任务明细 |
| | | */ |
| | | private void saveTaskItems(Long taskId, List<WaitPakinItem> waitPakinItems, Long loginUserId) { |
| | | List<TaskItem> taskItems = waitPakinItems.stream().map(item -> { |
| | | TaskItem taskItem = new TaskItem(); |
| | | BeanUtils.copyProperties(item, taskItem); |
| | | |
| | | return taskItem.setTaskId(taskId) |
| | | .setOrderType(OrderType.ORDER_RECEIPT.type) |
| | | .setSource(item.getId()) |
| | | .setTrackCode(item.getTrackCode()) |
| | | .setCreateBy(loginUserId) |
| | | .setUpdateBy(loginUserId) |
| | | .setOrderId(item.getAsnId()) |
| | | .setOrderItemId(item.getAsnItemId()); |
| | | }).collect(Collectors.toList()); |
| | | |
| | | if (!taskItemService.saveBatch(taskItems)) { |
| | | throw new CoolException("任务明细保存失败!!"); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 更新组托状态 |
| | | */ |
| | | private void updateWaitPakinStatus(String barcode, Long loginUserId) { |
| | | boolean updated = waitPakinService.update(new LambdaUpdateWrapper<WaitPakin>() |
| | | .eq(WaitPakin::getBarcode, barcode) |
| | | .set(WaitPakin::getUpdateBy, loginUserId) |
| | | .set(WaitPakin::getCreateBy, loginUserId) |
| | | .set(WaitPakin::getIoStatus, PakinIOStatus.PAKIN_IO_STATUS_TASK_EXCE.val)); |
| | | |
| | | if (!updated) { |
| | | throw new CoolException("组托状态修改失败!!"); |
| | | } |
| | | } |
| | | |
| | | // @Override |
| | | // public InTaskMsgDto createInTask(TaskInParam param, Long loginUserId) { |
| | | // InTaskMsgDto locNo = getLocNo(param); |
| | | // DeviceSite deviceSite = deviceSiteService.getOne(new LambdaQueryWrapper<DeviceSite>() |
| | | // .eq(DeviceSite::getSite, param.getSourceStaNo()) |
| | | // .eq(DeviceSite::getType,param.getIoType()) |
| | | // ); |
| | | // if (Objects.isNull(deviceSite)) { |
| | | // throw new CoolException("站点不存在!!"); |
| | | // } |
| | | // |
| | | // WaitPakin waitPakin = waitPakinService.getOne(new LambdaQueryWrapper<WaitPakin>() |
| | | // .eq(WaitPakin::getBarcode, param.getBarcode()) |
| | | // .eq(WaitPakin::getIoStatus, Short.parseShort(PakinIOStatus.PAKIN_IO_STATUS_DONE.val))); |
| | | // if (Cools.isEmpty(waitPakin)) { |
| | | // throw new CoolException("请检查组拖状态是否完成!!"); |
| | | // } |
| | | // |
| | | // List<TaskItem> taskItems = new ArrayList<>(); |
| | | // String ruleCode = SerialRuleUtils.generateRuleCode(SerialRuleCode.SYS_TASK_CODE, null); |
| | | // if (StringUtils.isBlank(ruleCode)) { |
| | | // throw new CoolException("编码错误:请确认编码「SYS_TASK_CODE」是否已生成!!"); |
| | | // } |
| | | // Task task = new Task(); |
| | | // task.setTaskCode(ruleCode) |
| | | // .setTaskStatus(TaskStsType.GENERATE_IN.id.shortValue()) |
| | | // .setTaskType(TaskType.TASK_TYPE_IN.type.shortValue()) |
| | | // .setTargLoc(locNo.getLocNo()) |
| | | // .setBarcode(waitPakin.getBarcode()) |
| | | // .setTargSite(deviceSite.getDeviceSite()) |
| | | // .setCreateBy(loginUserId) |
| | | // .setUpdateBy(loginUserId) |
| | | // .setOrgSite(param.getSourceStaNo().toString()); |
| | | // |
| | | // |
| | | // |
| | | // |
| | | // if (!taskService.save(task)) { |
| | | // throw new CoolException("任务保存失败!!"); |
| | | // } |
| | | // if (!locService.update(new LambdaUpdateWrapper<Loc>().eq(Loc::getCode, task.getTargLoc()) |
| | | // .set(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_S.type).set(Loc::getBarcode, waitPakin.getBarcode()))) { |
| | | // throw new CoolException("库位预约失败!!"); |
| | | // } |
| | | // /**获取组拖明细**/ |
| | | // List<WaitPakinItem> waitPakinItems = waitPakinItemService.list(new LambdaQueryWrapper<WaitPakinItem>().eq(WaitPakinItem::getPakinId, waitPakin.getId())); |
| | | // if (waitPakinItems.isEmpty()) { |
| | | // throw new CoolException("数据错误:组拖明细不存在"); |
| | | // } |
| | | // waitPakinItems.forEach(item -> { |
| | | // TaskItem taskItem = new TaskItem(); |
| | | // BeanUtils.copyProperties(item, taskItem); |
| | | //// AsnOrder order = asnOrderService.getOne(new LambdaQueryWrapper<AsnOrder>().eq(AsnOrder::getId, item.getAsnId())); |
| | | //// if (Objects.isNull(order)) { |
| | | //// throw new CoolException("数据错误: 单据不存在!!"); |
| | | //// } |
| | | // taskItem.setTaskId(task.getId()) |
| | | // .setOrderType(OrderType.ORDER_RECEIPT.type) |
| | | // .setSource(item.getId()) |
| | | // .setTrackCode(item.getTrackCode()) |
| | | // .setCreateBy(loginUserId) |
| | | // .setUpdateBy(loginUserId) |
| | | // .setOrderId(item.getAsnId()) |
| | | // .setOrderItemId(item.getAsnItemId()); |
| | | // taskItems.add(taskItem); |
| | | // }); |
| | | // if (!taskItemService.saveBatch(taskItems)) { |
| | | // throw new CoolException("任务明细保存失败!!"); |
| | | // } |
| | | // |
| | | // |
| | | // if (!waitPakinService.update(new LambdaUpdateWrapper<WaitPakin>() |
| | | // .eq(WaitPakin::getBarcode, param.getBarcode()) |
| | | // .set(WaitPakin::getUpdateBy, loginUserId) |
| | | // .set(WaitPakin::getCreateBy, loginUserId) |
| | | // .set(WaitPakin::getIoStatus, PakinIOStatus.PAKIN_IO_STATUS_TASK_EXCE.val))) { |
| | | // throw new CoolException("组托状态修改失败!!"); |
| | | // } |
| | | // locNo.setWorkNo(ruleCode); |
| | | // return locNo; |
| | | // } |
| | | |
| | | public InTaskMsgDto getLocNo(TaskInParam param) { |
| | | String matnr = null; String batch = null; |
| | | List<WaitPakin> waitPakins = waitPakinService.list(new LambdaQueryWrapper<WaitPakin>().eq(WaitPakin::getBarcode, param.getBarcode())); |
| | | if (Cools.isEmpty(waitPakins) && param.getIoType().equals(TaskType.TASK_TYPE_IN.type)) { |
| | | throw new CoolException("未找到组托信息,请组托"); |
| | | }else if (!Cools.isEmpty(waitPakins)) { |
| | | matnr = waitPakins.get(0).getCode(); |
| | | batch = waitPakins.get(0).getCode(); |
| | | } |
| | | List<DeviceSite> deviceSites = deviceSiteService.list(new LambdaQueryWrapper<DeviceSite>() |
| | | .eq(DeviceSite::getSite, param.getSourceStaNo()) |
| | | .eq(DeviceSite::getType,param.getIoType()) |
| | | ); |
| | | if (Cools.isEmpty(deviceSites)) { |
| | | throw new CoolException("未找到站点路径信息"); |
| | | } |
| | | WarehouseAreas warehouseArea = warehouseAreasService.getById(param.getArea()); |
| | | if (Cools.isEmpty(warehouseArea)) { |
| | | throw new CoolException("未找到所属库区信息"); |
| | | } |
| | | LocTypeDto locTypeDto = new LocTypeDto(param); |
| | | InTaskMsgDto dto = null; |
| | | switch (warehouseArea.getType()) { |
| | | case "CRN": //堆垛机 |
| | | dto = getLocNoCrn(param.getArea(), param.getSourceStaNo(), matnr,batch, locTypeDto, 0, param.getIoType()); |
| | | break; |
| | | case "SXC": //四向库 |
| | | break; |
| | | case "CTU": //四向库 |
| | | break; |
| | | } |
| | | return dto; |
| | | } |
| | | |
| | | private InTaskMsgDto getLocNoCrn(Integer area,Integer sourceStaNo, String matnr, String batch,LocTypeDto locTypeDto, int times,Integer ioType){ |
| | | if (Cools.isEmpty(matnr)) { //物料号 |
| | | matnr = ""; |
| | | } |
| | | if (Cools.isEmpty(batch)) { //批次 |
| | | batch = ""; |
| | | } |
| | | // 初始化参数 |
| | | int deviceNo = 0; //堆垛机号 |
| | | int nearRow = 0; //最浅库位排 |
| | | int curRow = 0; //最深库位排 |
| | | int rowCount = 0; //轮询轮次 |
| | | Loc loc = null; // 目标库位 |
| | | |
| | | InTaskMsgDto inTaskMsgDto = new InTaskMsgDto(); |
| | | DeviceBind deviceBind = deviceBindService.getById(LocUtils.getAreaType(sourceStaNo)); |
| | | if (Cools.isEmpty(deviceBind)) { |
| | | throw new CoolException("数据异常,请联系管理员===>库位规则未知"); |
| | | } |
| | | int sRow = deviceBind.getStartRow(); |
| | | int eRow = deviceBind.getEndRow(); |
| | | int deviceQty = deviceBind.getDeviceQty(); |
| | | |
| | | |
| | | // ===============>>>> 开始执行 |
| | | curRow = deviceBind.getCurrentRow(); |
| | | |
| | | //此程序用于优化堆垛机异常时的运行时间 |
| | | for (int i = times; i <= deviceQty * 2; i++) { |
| | | int[] locNecessaryParameters = LocUtils.LocNecessaryParameters(deviceBind, curRow, deviceQty); |
| | | curRow = locNecessaryParameters[1]; |
| | | deviceNo = locNecessaryParameters[2]; |
| | | rowCount = locNecessaryParameters[0]; |
| | | nearRow = locNecessaryParameters[3]; |
| | | break; |
| | | } |
| | | if (nearRow == 0) { |
| | | throw new CoolException("无可用堆垛机"); |
| | | } |
| | | //入库靠近摆放 |
| | | if (ioType== 1 && deviceBind.getBeSimilar().equals("1") && !Cools.isEmpty(matnr)) { |
| | | if (nearRow != curRow) { |
| | | List<LocItem> locItems = locItemService.list(new LambdaQueryWrapper<LocItem>().eq(LocItem::getMatnrCode, matnr)); |
| | | for (LocItem locItem : locItems) { |
| | | Loc loc1 = locService.getById(locItem.getLocId()); |
| | | if (LocUtils.isShallowLoc(slaveProperties, loc1.getCode())) { |
| | | continue; |
| | | } |
| | | String shallowLocNo = LocUtils.getShallowLoc(slaveProperties, loc1.getCode()); |
| | | // 检测目标库位是否为空库位 |
| | | Loc shallowLoc = locService.getOne(new LambdaQueryWrapper<Loc>().eq(Loc::getCode,shallowLocNo)); |
| | | if (shallowLoc != null && shallowLoc.getUseStatus().equals("O")) { |
| | | if (LocUtils.locMoveCheckLocTypeComplete(shallowLoc, locTypeDto)) { |
| | | loc = shallowLoc; |
| | | deviceNo = shallowLoc.getDeviceNo(); |
| | | break; |
| | | |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | // // 靠近摆放规则 --- 空托 //互通版 |
| | | // if (ioType == 10 && deviceBind.getEmptySimilar().equals("1")) { |
| | | // List<LocMast> locMasts = locMastService.selectList(new EntityWrapper<LocMast>() |
| | | // .eq("loc_sts", "D").ge("row1", sRow).le("row1", eRow).eq("whs_type", rowLastnoType.getType().longValue())); |
| | | // if (!locMasts.isEmpty()) { |
| | | // for (LocMast loc : locMasts) { |
| | | // if (Utils.isShallowLoc(slaveProperties, loc.getLocNo())) { |
| | | // continue; |
| | | // } |
| | | // String shallowLocNo = Utils.getShallowLoc(slaveProperties, loc.getLocNo()); |
| | | // // 检测目标库位是否为空库位 |
| | | // LocMast shallowLoc = locMastService.selectById(shallowLocNo); |
| | | // if (shallowLoc != null && shallowLoc.getLocSts().equals("O")) { |
| | | // if (VersionUtils.locMoveCheckLocTypeComplete(shallowLoc, locTypeDto)) { |
| | | // if (basCrnpService.checkSiteError(shallowLoc.getCrnNo(), true)) { |
| | | // locMast = shallowLoc; |
| | | // crnNo = locMast.getCrnNo(); |
| | | // break; |
| | | // } |
| | | // } |
| | | // } |
| | | // } |
| | | // } |
| | | // } |
| | | //查找路径 |
| | | DeviceSite deviceSite = deviceSiteService.getOne(new LambdaQueryWrapper<DeviceSite>() |
| | | .eq(DeviceSite::getType, ioType) |
| | | .eq(DeviceSite::getSite, sourceStaNo) |
| | | .eq(DeviceSite::getDeviceCode, deviceNo) |
| | | ); |
| | | if (Cools.isEmpty(deviceSite)){ |
| | | deviceNo = 0; |
| | | }else { |
| | | inTaskMsgDto.setStaNo(Integer.parseInt(deviceSite.getDeviceSite())); |
| | | } |
| | | |
| | | //更新当前排 |
| | | deviceBind.setCurrentRow(curRow); |
| | | deviceBindService.updateById(deviceBind); |
| | | |
| | | // 开始查找库位 ==============================>> |
| | | |
| | | // 1.按规则查找库位 |
| | | if (Cools.isEmpty(loc) && deviceNo != 0) { |
| | | List<Loc> locMasts = null; |
| | | locMasts = locService.list(new LambdaQueryWrapper<Loc>() |
| | | .eq(Loc::getRow, nearRow) |
| | | .eq(Loc::getUseStatus, "O") |
| | | .eq(Loc::getType, locTypeDto.getLocType1()) |
| | | .eq(Loc::getAreaId,area) |
| | | .orderByAsc(Loc::getLev) |
| | | .orderByAsc(Loc::getCol) |
| | | ); |
| | | for (Loc locMast1 : locMasts) { |
| | | if (!LocUtils.locMoveCheckLocTypeComplete(locMast1, locTypeDto)) { |
| | | continue; |
| | | } |
| | | String shallowLoc = LocUtils.getDeepLoc(slaveProperties, locMast1.getCode()); |
| | | if ((ioType== 1 && deviceBind.getBeSimilar().equals("1"))) { |
| | | //相似物料打开,判断深库位有没有货,没货就放深库位,有货就不操作 |
| | | Loc locMast2 = locService.getOne(new LambdaQueryWrapper<Loc>() |
| | | .eq(Loc::getRow, shallowLoc) |
| | | .eq(Loc::getUseStatus, "O") |
| | | .eq(Loc::getAreaId,area) |
| | | ); |
| | | if (!Cools.isEmpty(locMast2)) { |
| | | loc = locMast2; |
| | | break; |
| | | } |
| | | } else { |
| | | //相似物料关闭,判断深库位有没有货,有货就放浅库位,无货就不操作 |
| | | Loc locMast2 = locService.getOne(new LambdaQueryWrapper<Loc>() |
| | | .eq(Loc::getCode, shallowLoc) |
| | | .in(Loc::getUseStatus, "D","F") |
| | | .eq(Loc::getAreaId,area) |
| | | ); |
| | | if (!Cools.isEmpty(locMast2)) { |
| | | loc = locMast1; |
| | | break; |
| | | }else{ |
| | | locMast2 = locService.getOne(new LambdaQueryWrapper<Loc>() |
| | | .eq(Loc::getCode, shallowLoc) |
| | | .eq(Loc::getUseStatus, "O") |
| | | .eq(Loc::getAreaId,area) |
| | | ); |
| | | if (!Cools.isEmpty(locMast2)) { |
| | | loc = locMast2; |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | if (Cools.isEmpty(loc) && deviceBind.getBeSimilar().equals("1")) { |
| | | for (Loc locMast1 : locMasts) { |
| | | if (!LocUtils.locMoveCheckLocTypeComplete(locMast1, locTypeDto)) { |
| | | continue; |
| | | } |
| | | if (deviceBind.getBeSimilar().equals("1")) { |
| | | String shallowLoc = LocUtils.getDeepLoc(slaveProperties, locMast1.getCode()); |
| | | Loc locMast2 = locService.getOne(new LambdaQueryWrapper<Loc>() |
| | | .eq(Loc::getCode, shallowLoc) |
| | | .eq(Loc::getUseStatus, "O") |
| | | .eq(Loc::getAreaId,area) |
| | | ); |
| | | if (!Cools.isEmpty(locMast2)) { |
| | | loc = locMast2; |
| | | break; |
| | | } else { |
| | | locMast2 = locService.getOne(new LambdaQueryWrapper<Loc>() |
| | | .eq(Loc::getCode, shallowLoc) |
| | | .in(Loc::getUseStatus, "D","F") |
| | | .eq(Loc::getAreaId,area) |
| | | ); |
| | | if (!Cools.isEmpty(locMast2)) { |
| | | loc = locMast1; |
| | | break; |
| | | } |
| | | } |
| | | } else { |
| | | if (!Cools.isEmpty(locMast1)) { |
| | | loc = locMast1; |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | //查询当前库位类型空库位 小于5个则locmast = null |
| | | List<Loc> locTypeLocMasts = locService.list(new LambdaQueryWrapper<Loc>() |
| | | .eq(Loc::getUseStatus, "O") |
| | | .eq(Loc::getDeviceNo, deviceNo) |
| | | .eq(Loc::getType, locTypeDto.getLocType1()) |
| | | .eq(Loc::getAreaId,area) |
| | | ); |
| | | if (null !=locTypeLocMasts && locTypeLocMasts.size()<=5){ |
| | | loc = null; |
| | | } |
| | | // 递归查询 |
| | | if (Cools.isEmpty(loc) || !loc.getUseStatus().equals("O")) { |
| | | // 当前巷道无空库位时,递归调整至下一巷道,检索全部巷道无果后,跳出递归 |
| | | if (times < rowCount * 2) { |
| | | times = times + 1; |
| | | return getLocNoCrn(area,sourceStaNo,matnr,batch,locTypeDto,times, ioType); |
| | | |
| | | } |
| | | // 2.库位当前所属尺寸无空库位时,调整尺寸参数,向上兼容检索库位 |
| | | if (locTypeDto.getLocType1() < 3) { |
| | | int i = locTypeDto.getLocType1() + 1; |
| | | locTypeDto.setLocType1(i); |
| | | return getLocNoCrn(area,sourceStaNo,matnr,batch,locTypeDto,0, ioType); |
| | | } |
| | | throw new CoolException("没有空库位"); |
| | | } |
| | | String locNo = loc.getCode(); |
| | | |
| | | // 返回dto |
| | | inTaskMsgDto.setDeviceNo(deviceNo); |
| | | inTaskMsgDto.setSourceStaNo(sourceStaNo); |
| | | // inTaskMsgDto.setStaNo(); |
| | | inTaskMsgDto.setLocNo(locNo); |
| | | return inTaskMsgDto; |
| | | } |
| | | } |
New file |
| | |
| | | package com.vincent.rsf.server.api.utils; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.vincent.rsf.framework.common.Arith; |
| | | import com.vincent.rsf.framework.common.Cools; |
| | | import com.vincent.rsf.framework.common.SpringUtils; |
| | | import com.vincent.rsf.framework.exception.CoolException; |
| | | import com.vincent.rsf.server.api.entity.dto.LocTypeDto; |
| | | import com.vincent.rsf.server.manager.entity.DeviceBind; |
| | | import com.vincent.rsf.server.manager.entity.Loc; |
| | | import com.vincent.rsf.server.manager.service.DeviceBindService; |
| | | |
| | | |
| | | import java.util.List; |
| | | |
| | | public class LocUtils { |
| | | |
| | | /** |
| | | * 获取 浅库位对应的深库位号 |
| | | */ |
| | | public static String getDeepLoc(SlaveProperties slaveProperties, String shallowLoc) { |
| | | int row = getRow(shallowLoc); |
| | | int remainder = (int) Arith.remainder(row, slaveProperties.getGroupCount()); |
| | | int targetRow; |
| | | if (remainder == 2) { |
| | | targetRow = row - 1; |
| | | } else if (remainder == 3) { |
| | | targetRow = row + 1; |
| | | } else { |
| | | throw new CoolException(shallowLoc + "不是浅库位,系统繁忙"); |
| | | } |
| | | return zerofill(String.valueOf(targetRow), 2) + shallowLoc.substring(2); |
| | | } |
| | | |
| | | /** |
| | | * 获取 深库位对应的浅库位号 |
| | | */ |
| | | public static String getShallowLoc(SlaveProperties slaveProperties, String deepLoc) { |
| | | int row = getRow(deepLoc); |
| | | int remainder = (int) Arith.remainder(row, slaveProperties.getGroupCount()); |
| | | int shallowRow = remainder == 1 ? (row + 1) : (row - 1); |
| | | return zerofill(String.valueOf(shallowRow), 2) + deepLoc.substring(2); |
| | | } |
| | | |
| | | /** |
| | | * 判断是否为浅库位 |
| | | */ |
| | | public static boolean isShallowLoc(SlaveProperties slaveProperties, String locNo) { |
| | | if (slaveProperties.isDoubleDeep()) { |
| | | int row = getRow(locNo); |
| | | return !slaveProperties.getDoubleLocs().contains(row); |
| | | } else { |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | //获取站点对应的库类型 |
| | | public static Long getAreaType(Integer sourceStaNo) { |
| | | DeviceBindService rowLastnoService = SpringUtils.getBean(DeviceBindService.class); |
| | | List<DeviceBind> deviceBinds = rowLastnoService.list(new LambdaQueryWrapper<DeviceBind>()); |
| | | for (DeviceBind deviceBind : deviceBinds) { |
| | | String[] staNoList = deviceBind.getStaList().split(";"); |
| | | for (String staNo : staNoList) { |
| | | if (staNo.equals(sourceStaNo.toString())) { |
| | | return deviceBind.getId(); |
| | | } |
| | | } |
| | | } |
| | | return 0L; |
| | | } |
| | | |
| | | //库位排号分配 |
| | | public static int[] LocNecessaryParameters(DeviceBind deviceBind, Integer curRow, Integer crnNumber) { |
| | | |
| | | return LocNecessaryParametersDoubleExtension(curRow, crnNumber); //已完善 |
| | | |
| | | |
| | | } |
| | | |
| | | //经典双伸库位 |
| | | public static int[] LocNecessaryParametersDoubleExtension( Integer curRow, Integer crnNumber) { |
| | | int[] necessaryParameters = new int[]{0, 0, 0, 0}; |
| | | |
| | | necessaryParameters[0] = crnNumber; // 轮询次数 |
| | | //满板正常入库 |
| | | if (curRow.equals(crnNumber * 4)) { |
| | | necessaryParameters[1] = 1; //curRow 最深库位排 |
| | | necessaryParameters[2] = 1; //crnNo 堆垛机号 |
| | | necessaryParameters[3] = 2; //nearRow 最浅库位排 |
| | | } else if (curRow.equals(crnNumber * 4 - 3)) { |
| | | necessaryParameters[1] = 4; //curRow 最深库位排 |
| | | necessaryParameters[2] = 1; //crnNo 堆垛机号 |
| | | necessaryParameters[3] = 3; //nearRow 最浅库位排 |
| | | } else { |
| | | curRow = curRow + 4; |
| | | if (curRow < 1 || curRow > (crnNumber * 4)) { |
| | | throw new CoolException("库位排号异常:排号:" + curRow); |
| | | } |
| | | if ((curRow - 1) % 4 == 0) { |
| | | necessaryParameters[1] = curRow; //curRow 最深库位排 |
| | | necessaryParameters[2] = (curRow + 3) / 4; //crnNo 堆垛机号 |
| | | necessaryParameters[3] = curRow + 1; //nearRow 最浅库位排 |
| | | } else if (curRow % 4 == 0) { |
| | | necessaryParameters[1] = curRow; //curRow 最深库位排 |
| | | necessaryParameters[2] = curRow / 4; //crnNo 堆垛机号 |
| | | necessaryParameters[3] = curRow - 1; //nearRow 最浅库位排 |
| | | } else { |
| | | throw new CoolException("库位排号异常:排号:" + curRow); |
| | | } |
| | | } |
| | | |
| | | return necessaryParameters; |
| | | } |
| | | |
| | | /** |
| | | * 通过库位号获取 排 |
| | | */ |
| | | public static int getRow(String locNo) { |
| | | if (!Cools.isEmpty(locNo)) { |
| | | return Integer.parseInt(locNo.substring(0, 2)); |
| | | } |
| | | throw new RuntimeException("库位解析异常"); |
| | | } |
| | | |
| | | /** |
| | | * 通过库位号获取 列 |
| | | */ |
| | | public static int getBay(String locNo) { |
| | | if (!Cools.isEmpty(locNo)) { |
| | | return Integer.parseInt(locNo.substring(2, 5)); |
| | | } |
| | | throw new RuntimeException("库位解析异常"); |
| | | } |
| | | |
| | | /** |
| | | * 通过库位号获取 层 |
| | | */ |
| | | public static int getLev(String locNo) { |
| | | if (!Cools.isEmpty(locNo)) { |
| | | return Integer.parseInt(locNo.substring(5, 7)); |
| | | } |
| | | throw new RuntimeException("库位解析异常"); |
| | | } |
| | | |
| | | /** |
| | | * 类型检测 |
| | | * 完全检测 |
| | | **/ |
| | | public static boolean locMoveCheckLocTypeComplete(Loc loc, LocTypeDto dto) { |
| | | // 如果源库位是高库位,目标库位是低库位 |
| | | return dto.getLocType1().equals(Integer.parseInt(loc.getType())); |
| | | } |
| | | public static String zerofill(String msg, Integer count) { |
| | | if (msg.length() == count) { |
| | | return msg; |
| | | } else if (msg.length() > count) { |
| | | return msg.substring(0, 16); |
| | | } else { |
| | | StringBuilder msgBuilder = new StringBuilder(msg); |
| | | for (int i = 0; i < count - msg.length(); i++) { |
| | | msgBuilder.insert(0, "0"); |
| | | } |
| | | return msgBuilder.toString(); |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | package com.vincent.rsf.server.api.utils; |
| | | |
| | | import lombok.Data; |
| | | import org.springframework.boot.context.properties.ConfigurationProperties; |
| | | import org.springframework.context.annotation.Configuration; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * Created by vincent on 2020/8/4 |
| | | */ |
| | | @Data |
| | | @Configuration |
| | | @ConfigurationProperties(prefix = "wcs-slave") |
| | | public class SlaveProperties { |
| | | |
| | | private boolean doubleDeep; |
| | | // 双深库位排号 |
| | | private List<Integer> doubleLocs = new ArrayList<>(); |
| | | // 左深库位排号 |
| | | private List<Integer> doubleLocsLeft = new ArrayList<>(); |
| | | // 右深库位排号 |
| | | private List<Integer> doubleLocsRight = new ArrayList<>(); |
| | | |
| | | private int groupCount; |
| | | |
| | | } |
| | |
| | | package com.vincent.rsf.server.common.config; |
| | | |
| | | import com.vincent.rsf.server.common.constant.Constants; |
| | | import com.vincent.rsf.server.common.interceptor.DynamicFieldsInterceptor; |
| | | import com.vincent.rsf.server.common.interceptor.severlet.DynamicFieldsInterceptor; |
| | | import com.vincent.rsf.server.common.utils.Http; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Configuration; |
New file |
| | |
| | | package com.vincent.rsf.server.common.interceptor.severlet; |
| | | |
| | | import org.springframework.stereotype.Component; |
| | | import org.springframework.web.filter.OncePerRequestFilter; |
| | | import javax.servlet.FilterChain; |
| | | import javax.servlet.ServletException; |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import javax.servlet.http.HttpServletResponse; |
| | | import java.io.IOException; |
| | | |
| | | @Component |
| | | public class CustomParameterFilter extends OncePerRequestFilter { |
| | | |
| | | @Override |
| | | protected void doFilterInternal(HttpServletRequest request, |
| | | HttpServletResponse response, |
| | | FilterChain filterChain) |
| | | throws ServletException, IOException { |
| | | |
| | | ParameterAddableRequest wrappedRequest = new ParameterAddableRequest(request); |
| | | // 添加系统级参数 |
| | | wrappedRequest.addParameter("systemVersion", "1.0.0"); |
| | | wrappedRequest.addParameter("environment", System.getProperty("spring.profiles.active", "default")); |
| | | // 添加请求追踪信息 |
| | | addTraceInfo(wrappedRequest); |
| | | |
| | | filterChain.doFilter(wrappedRequest, response); |
| | | } |
| | | |
| | | private void addTraceInfo(ParameterAddableRequest request) { |
| | | String traceId = request.getHeader("X-Trace-Id"); |
| | | // if (traceId == null || traceId.isEmpty()) { |
| | | // traceId = UUID.randomUUID().toString(); |
| | | // } |
| | | request.addParameter("traceId", "traceId"); |
| | | } |
| | | } |
New file |
| | |
| | | package com.vincent.rsf.server.common.interceptor.severlet; |
| | | |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.web.servlet.HandlerInterceptor; |
| | | import org.springframework.web.servlet.ModelAndView; |
| | | |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import javax.servlet.http.HttpServletResponse; |
| | | |
| | | /** |
| | | * @author Ryan |
| | | * @version 1.0 |
| | | * @title DynamicFieldsInterceptor |
| | | * @description |
| | | * @create 2025/4/16 16:10 |
| | | */ |
| | | @Slf4j |
| | | public class DynamicFieldsInterceptor implements HandlerInterceptor { |
| | | |
| | | @Override |
| | | public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { |
| | | |
| | | |
| | | // if (request instanceof ParameterAddableRequest) { |
| | | // ParameterAddableRequest wrappedRequest = (ParameterAddableRequest) request; |
| | | // |
| | | // // 添加业务参数 |
| | | // wrappedRequest.addParameter("processedBy", "CustomParameterInterceptor"); |
| | | // |
| | | // // 可以从Session或其他地方获取数据 |
| | | // Object userId = request.getSession().getAttribute("userId"); |
| | | // if (userId != null) { |
| | | // wrappedRequest.addParameter("currentUserId", userId.toString()); |
| | | // } |
| | | // } |
| | | // |
| | | // return true; |
| | | |
| | | |
| | | // List<Fields> fields = FieldsUtils.getFieldsSta(); |
| | | // List<String> fieldsKey = fields.stream().filter(item -> item.getFlagEnable() == 1).map(Fields::getFields).collect(Collectors.toList()); |
| | | // fieldsKey.forEach(key -> { |
| | | // if (request.getParameterMap().keySet().contains(key)) { |
| | | // request.setAttribute(key, request.getParameterMap().get(key)); |
| | | // } |
| | | // }) |
| | | // if (request instanceof ParameterAddableRequest) { |
| | | // ParameterAddableRequest wrappedRequest = (ParameterAddableRequest) request; |
| | | // wrappedRequest.addParameter("DynamicFields", "springValue"); |
| | | // } |
| | | |
| | | // return true; |
| | | return HandlerInterceptor.super.preHandle(request, response, handler); |
| | | } |
| | | |
| | | @Override |
| | | public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { |
| | | HandlerInterceptor.super.postHandle(request, response, handler, modelAndView); |
| | | } |
| | | |
| | | @Override |
| | | public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { |
| | | System.out.println(response.getOutputStream().toString()); |
| | | HandlerInterceptor.super.afterCompletion(request, response, handler, ex); |
| | | } |
| | | } |
New file |
| | |
| | | package com.vincent.rsf.server.common.interceptor.severlet; |
| | | |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import javax.servlet.http.HttpServletRequestWrapper; |
| | | import java.util.*; |
| | | |
| | | public class ParameterAddableRequest extends HttpServletRequestWrapper { |
| | | private final Map<String, String[]> additionalParams = new HashMap<>(); |
| | | |
| | | public ParameterAddableRequest(HttpServletRequest request) { |
| | | super(request); |
| | | } |
| | | |
| | | /** |
| | | * 添加新参数 |
| | | * @param name 参数名 |
| | | * @param value 参数值 |
| | | */ |
| | | public void addParameter(String name, String value) { |
| | | additionalParams.put(name, new String[]{value}); |
| | | } |
| | | |
| | | /** |
| | | * 添加新参数(多值) |
| | | * @param name 参数名 |
| | | * @param values 参数值数组 |
| | | */ |
| | | public void addParameter(String name, String[] values) { |
| | | additionalParams.put(name, values); |
| | | } |
| | | |
| | | @Override |
| | | public String getParameter(String name) { |
| | | if (additionalParams.containsKey(name)) { |
| | | return additionalParams.get(name)[0]; |
| | | } |
| | | return super.getParameter(name); |
| | | } |
| | | |
| | | @Override |
| | | public Map<String, String[]> getParameterMap() { |
| | | Map<String, String[]> combinedMap = new HashMap<>(super.getParameterMap()); |
| | | combinedMap.putAll(additionalParams); |
| | | return Collections.unmodifiableMap(combinedMap); |
| | | } |
| | | |
| | | @Override |
| | | public Enumeration<String> getParameterNames() { |
| | | Set<String> names = new HashSet<>(Collections.list(super.getParameterNames())); |
| | | names.addAll(additionalParams.keySet()); |
| | | return Collections.enumeration(names); |
| | | } |
| | | |
| | | @Override |
| | | public String[] getParameterValues(String name) { |
| | | if (additionalParams.containsKey(name)) { |
| | | return additionalParams.get(name); |
| | | } |
| | | return super.getParameterValues(name); |
| | | } |
| | | } |
New file |
| | |
| | | package com.vincent.rsf.server.common.interceptor.severlet; |
| | | |
| | | import javax.servlet.*; |
| | | import javax.servlet.annotation.WebFilter; |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import java.io.IOException; |
| | | |
| | | @WebFilter("/*") // 拦截所有请求 |
| | | public class ParameterAddingFilter implements Filter { |
| | | |
| | | @Override |
| | | public void init(FilterConfig filterConfig) throws ServletException { |
| | | // 初始化逻辑 |
| | | } |
| | | |
| | | @Override |
| | | public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) |
| | | throws IOException, ServletException { |
| | | |
| | | if (request instanceof HttpServletRequest) { |
| | | // 创建可修改参数的请求包装器 |
| | | ParameterAddableRequest wrappedRequest = |
| | | new ParameterAddableRequest((HttpServletRequest) request); |
| | | |
| | | // 添加自定义参数 |
| | | addCustomParameters(wrappedRequest); |
| | | |
| | | // 继续过滤器链 |
| | | chain.doFilter(wrappedRequest, response); |
| | | } else { |
| | | chain.doFilter(request, response); |
| | | } |
| | | } |
| | | |
| | | private void addCustomParameters(ParameterAddableRequest request) { |
| | | // 添加请求ID和时间戳 |
| | | // request.addParameter("requestId", UUID.randomUUID().toString()); |
| | | request.addParameter("timestamp", String.valueOf(System.currentTimeMillis())); |
| | | // 根据业务需求添加其他参数 |
| | | String userAgent = request.getHeader("User-Agent"); |
| | | if (userAgent != null && userAgent.contains("Mobile")) { |
| | | request.addParameter("deviceType", "mobile"); |
| | | } else { |
| | | request.addParameter("deviceType", "desktop"); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public void destroy() { |
| | | // 清理逻辑 |
| | | } |
| | | } |
| | |
| | | "/v2/api-docs/**", |
| | | "/v3/api-docs/**", |
| | | "/swagger-ui/**", |
| | | "/ws/**" |
| | | "/ws/**", |
| | | "/wcs/**" |
| | | }; |
| | | |
| | | @Resource |
New file |
| | |
| | | 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.BasDevice; |
| | | import com.vincent.rsf.server.manager.service.BasDeviceService; |
| | | 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 BasDeviceController extends BaseController { |
| | | |
| | | @Autowired |
| | | private BasDeviceService basDeviceService; |
| | | |
| | | @PreAuthorize("hasAuthority('manager:basDevice:list')") |
| | | @PostMapping("/basDevice/page") |
| | | public R page(@RequestBody Map<String, Object> map) { |
| | | BaseParam baseParam = buildParam(map, BaseParam.class); |
| | | PageParam<BasDevice, BaseParam> pageParam = new PageParam<>(baseParam, BasDevice.class); |
| | | return R.ok().add(basDeviceService.page(pageParam, pageParam.buildWrapper(true))); |
| | | } |
| | | |
| | | @PreAuthorize("hasAuthority('manager:basDevice:list')") |
| | | @PostMapping("/basDevice/list") |
| | | public R list(@RequestBody Map<String, Object> map) { |
| | | return R.ok().add(basDeviceService.list()); |
| | | } |
| | | |
| | | @PreAuthorize("hasAuthority('manager:basDevice:list')") |
| | | @PostMapping({"/basDevice/many/{ids}", "/basDevices/many/{ids}"}) |
| | | public R many(@PathVariable Long[] ids) { |
| | | return R.ok().add(basDeviceService.listByIds(Arrays.asList(ids))); |
| | | } |
| | | |
| | | @PreAuthorize("hasAuthority('manager:basDevice:list')") |
| | | @GetMapping("/basDevice/{id}") |
| | | public R get(@PathVariable("id") Long id) { |
| | | return R.ok().add(basDeviceService.getById(id)); |
| | | } |
| | | |
| | | @PreAuthorize("hasAuthority('manager:basDevice:save')") |
| | | @OperationLog("Create 基础设备表") |
| | | @PostMapping("/basDevice/save") |
| | | public R save(@RequestBody BasDevice basDevice) { |
| | | basDevice.setCreateBy(getLoginUserId()); |
| | | basDevice.setCreateTime(new Date()); |
| | | basDevice.setUpdateBy(getLoginUserId()); |
| | | basDevice.setUpdateTime(new Date()); |
| | | if (!basDeviceService.save(basDevice)) { |
| | | return R.error("Save Fail"); |
| | | } |
| | | return R.ok("Save Success").add(basDevice); |
| | | } |
| | | |
| | | @PreAuthorize("hasAuthority('manager:basDevice:update')") |
| | | @OperationLog("Update 基础设备表") |
| | | @PostMapping("/basDevice/update") |
| | | public R update(@RequestBody BasDevice basDevice) { |
| | | basDevice.setUpdateBy(getLoginUserId()); |
| | | basDevice.setUpdateTime(new Date()); |
| | | if (!basDeviceService.updateById(basDevice)) { |
| | | return R.error("Update Fail"); |
| | | } |
| | | return R.ok("Update Success").add(basDevice); |
| | | } |
| | | |
| | | @PreAuthorize("hasAuthority('manager:basDevice:remove')") |
| | | @OperationLog("Delete 基础设备表") |
| | | @PostMapping("/basDevice/remove/{ids}") |
| | | public R remove(@PathVariable Long[] ids) { |
| | | if (!basDeviceService.removeByIds(Arrays.asList(ids))) { |
| | | return R.error("Delete Fail"); |
| | | } |
| | | return R.ok("Delete Success").add(ids); |
| | | } |
| | | |
| | | @PreAuthorize("hasAuthority('manager:basDevice:list')") |
| | | @PostMapping("/basDevice/query") |
| | | public R query(@RequestParam(required = false) String condition) { |
| | | List<KeyValVo> vos = new ArrayList<>(); |
| | | LambdaQueryWrapper<BasDevice> wrapper = new LambdaQueryWrapper<>(); |
| | | if (!Cools.isEmpty(condition)) { |
| | | wrapper.like(BasDevice::getId, condition); |
| | | } |
| | | basDeviceService.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:basDevice:list')") |
| | | @PostMapping("/basDevice/export") |
| | | public void export(@RequestBody Map<String, Object> map, HttpServletResponse response) throws Exception { |
| | | ExcelUtil.build(ExcelUtil.create(basDeviceService.list(), BasDevice.class), response); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.vincent.rsf.server.manager.entity; |
| | | |
| | | import java.text.SimpleDateFormat; |
| | | import java.util.Date; |
| | | 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 |
| | | @TableName("man_bas_device") |
| | | public class BasDevice implements Serializable { |
| | | |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * id |
| | | */ |
| | | @ApiModelProperty(value= "id") |
| | | @TableId(value = "id", type = IdType.AUTO) |
| | | private Long id; |
| | | |
| | | /** |
| | | * 设备号 |
| | | */ |
| | | @ApiModelProperty(value= "设备号") |
| | | private Long deviceNo; |
| | | |
| | | /** |
| | | * 可入 |
| | | */ |
| | | @ApiModelProperty(value= "可入") |
| | | private String inEnable; |
| | | |
| | | /** |
| | | * 可出 |
| | | */ |
| | | @ApiModelProperty(value= "可出") |
| | | private String outEnable; |
| | | |
| | | /** |
| | | * 状态 |
| | | */ |
| | | @ApiModelProperty(value= "状态") |
| | | private String status; |
| | | |
| | | /** |
| | | * 源数据 |
| | | */ |
| | | @ApiModelProperty(value= "源数据") |
| | | private String origin; |
| | | |
| | | /** |
| | | * 创建人 |
| | | */ |
| | | @ApiModelProperty(value= "创建人") |
| | | private Long createBy; |
| | | |
| | | /** |
| | | * 创建时间 |
| | | */ |
| | | @ApiModelProperty(value= "创建时间") |
| | | @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") |
| | | private Date createTime; |
| | | |
| | | /** |
| | | * 更新人 |
| | | */ |
| | | @ApiModelProperty(value= "更新人") |
| | | private Long updateBy; |
| | | |
| | | /** |
| | | * 更新时间 |
| | | */ |
| | | @ApiModelProperty(value= "更新时间") |
| | | @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") |
| | | private Date updateTime; |
| | | |
| | | /** |
| | | * 备注 |
| | | */ |
| | | @ApiModelProperty(value= "备注") |
| | | private String memo; |
| | | |
| | | public BasDevice() {} |
| | | |
| | | public BasDevice(Long deviceNo,String inEnable,String outEnable,String status,String origin,Long createBy,Date createTime,Long updateBy,Date updateTime,String memo) { |
| | | this.deviceNo = deviceNo; |
| | | this.inEnable = inEnable; |
| | | this.outEnable = outEnable; |
| | | this.status = status; |
| | | this.origin = origin; |
| | | this.createBy = createBy; |
| | | this.createTime = createTime; |
| | | this.updateBy = updateBy; |
| | | this.updateTime = updateTime; |
| | | this.memo = memo; |
| | | } |
| | | |
| | | // BasDevice basDevice = new BasDevice( |
| | | // null, // 设备号 |
| | | // null, // 可入 |
| | | // null, // 可出 |
| | | // null, // 状态 |
| | | // null, // 源数据 |
| | | // null, // 创建人 |
| | | // null, // 创建时间 |
| | | // null, // 更新人 |
| | | // null, // 更新时间 |
| | | // null // 备注 |
| | | // ); |
| | | |
| | | public String getCreateTime$(){ |
| | | if (Cools.isEmpty(this.createTime)){ |
| | | return ""; |
| | | } |
| | | return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.createTime); |
| | | } |
| | | |
| | | public String getUpdateTime$(){ |
| | | if (Cools.isEmpty(this.updateTime)){ |
| | | return ""; |
| | | } |
| | | return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.updateTime); |
| | | } |
| | | |
| | | |
| | | |
| | | // public Boolean getStatusBool(){ |
| | | // if (null == this.status){ return null; } |
| | | // switch (this.status){ |
| | | // case "1": |
| | | // return true; |
| | | // case "0": |
| | | // return false; |
| | | // default: |
| | | // return null; |
| | | // } |
| | | // } |
| | | |
| | | } |
| | |
| | | */ |
| | | @ApiModelProperty(value= "宽") |
| | | private Double width; |
| | | |
| | | /** |
| | | * 排 |
| | | */ |
| | |
| | | private Integer row; |
| | | |
| | | /** |
| | | * 设备号 |
| | | */ |
| | | @ApiModelProperty(value= "设备号") |
| | | private Integer deviceNo; |
| | | |
| | | /** |
| | | * 列 |
| | | */ |
| | | @ApiModelProperty(value= "列") |
New file |
| | |
| | | package com.vincent.rsf.server.manager.mapper; |
| | | |
| | | import com.vincent.rsf.server.manager.entity.BasDevice; |
| | | import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | import org.springframework.stereotype.Repository; |
| | | |
| | | @Mapper |
| | | @Repository |
| | | public interface BasDeviceMapper extends BaseMapper<BasDevice> { |
| | | |
| | | } |
New file |
| | |
| | | package com.vincent.rsf.server.manager.service; |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | | import com.vincent.rsf.server.manager.entity.BasDevice; |
| | | |
| | | public interface BasDeviceService extends IService<BasDevice> { |
| | | |
| | | } |
New file |
| | |
| | | package com.vincent.rsf.server.manager.service.impl; |
| | | |
| | | import com.vincent.rsf.server.manager.mapper.BasDeviceMapper; |
| | | import com.vincent.rsf.server.manager.entity.BasDevice; |
| | | import com.vincent.rsf.server.manager.service.BasDeviceService; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | @Service("basDeviceService") |
| | | public class BasDeviceServiceImpl extends ServiceImpl<BasDeviceMapper, BasDevice> implements BasDeviceService { |
| | | |
| | | } |
| | |
| | | logging:
|
| | | file:
|
| | | path: logs/@pom.artifactId@
|
| | |
|
| | | # 下位机配置
|
| | | wcs-slave:
|
| | | # 双深
|
| | | doubleDeep: true
|
| | | # 双深库位排号
|
| | | doubleLocs: 1,4,5,8
|
| | | # 一个堆垛机负责的货架排数
|
| | | groupCount: 4
|
| | | # 左深库位排号
|
| | | doubleLocsLeft: 1,5,9,13
|
| | | # 右深库位排号
|
| | | doubleLocsRight: 4,8,12,16
|
New file |
| | |
| | | <?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.BasDeviceMapper"> |
| | | |
| | | </mapper> |