1
7 小时以前 6c3cc6842009f3897c3fb18bef8a6634fe653818
lsh#
12个文件已添加
17个文件已修改
1540 ■■■■■ 已修改文件
rsf-admin/src/page/basStationArea/BasStationAreaCreate.jsx 209 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/basStationArea/BasStationAreaEdit.jsx 181 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/basStationArea/BasStationAreaList.jsx 180 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/basStationArea/BasStationAreaPanel.jsx 141 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/basStationArea/index.jsx 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/basStationArea.sql 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/api/entity/params/PdaGeneralParam.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/InBoundServiceImpl.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/ReceiveMsgServiceImpl.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/common/CodeBuilder.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/BasStationAreaController.java 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/LocController.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/dto/OrderOutItemDto.java 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/params/LocToTaskParams.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/params/OutStockToTaskParams.java 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/BasStation.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/BasStationArea.java 277 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/Task.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/mapper/BasStationAreaMapper.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/schedules/TaskSchedules.java 24 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/BasStationAreaService.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/TaskService.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/BasStationAreaServiceImpl.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/LocItemServiceImpl.java 40 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/OutStockServiceImpl.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/TaskServiceImpl.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/WaveServiceImpl.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/utils/LocManageUtil.java 157 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/resources/mapper/manager/BasStationAreaMapper.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/basStationArea/BasStationAreaCreate.jsx
New file
@@ -0,0 +1,209 @@
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 BasStationAreaCreate = (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.basStationArea.type"
                                        source="type"
                                        autoFocus
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.basStationArea.stationAreaName"
                                        source="stationAreaName"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.basStationArea.inAble"
                                        source="inAble"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.basStationArea.outAble"
                                        source="outAble"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.basStationArea.useStatus"
                                        source="useStatus"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.basStationArea.area"
                                        source="area"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.basStationArea.isCrossZone"
                                        source="isCrossZone"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.basStationArea.crossZoneArea"
                                        source="crossZoneArea"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.basStationArea.isWcs"
                                        source="isWcs"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.basStationArea.wcsData"
                                        source="wcsData"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.basStationArea.containerType"
                                        source="containerType"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.basStationArea.barcode"
                                        source="barcode"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.basStationArea.autoTransfer"
                                        source="autoTransfer"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.basStationArea.stationAreaId"
                                        source="stationAreaId"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.basStationArea.stationAlias"
                                        source="stationAlias"
                                        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 BasStationAreaCreate;
rsf-admin/src/page/basStationArea/BasStationAreaEdit.jsx
New file
@@ -0,0 +1,181 @@
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 BasStationAreaEdit = () => {
    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.basStationArea.type"
                                source="type"
                                autoFocus
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.basStationArea.stationAreaName"
                                source="stationAreaName"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.basStationArea.inAble"
                                source="inAble"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.basStationArea.outAble"
                                source="outAble"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.basStationArea.useStatus"
                                source="useStatus"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.basStationArea.area"
                                source="area"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.basStationArea.isCrossZone"
                                source="isCrossZone"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.basStationArea.crossZoneArea"
                                source="crossZoneArea"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.basStationArea.isWcs"
                                source="isWcs"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.basStationArea.wcsData"
                                source="wcsData"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.basStationArea.containerType"
                                source="containerType"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.basStationArea.barcode"
                                source="barcode"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.basStationArea.autoTransfer"
                                source="autoTransfer"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.basStationArea.stationAreaId"
                                source="stationAreaId"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.basStationArea.stationAlias"
                                source="stationAlias"
                                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 BasStationAreaEdit;
rsf-admin/src/page/basStationArea/BasStationAreaList.jsx
New file
@@ -0,0 +1,180 @@
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 BasStationAreaCreate from "./BasStationAreaCreate";
import BasStationAreaPanel from "./BasStationAreaPanel";
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="type" label="table.field.basStationArea.type" />,
    <TextInput source="stationAreaName" label="table.field.basStationArea.stationAreaName" />,
    <NumberInput source="inAble" label="table.field.basStationArea.inAble" />,
    <NumberInput source="outAble" label="table.field.basStationArea.outAble" />,
    <TextInput source="useStatus" label="table.field.basStationArea.useStatus" />,
    <NumberInput source="area" label="table.field.basStationArea.area" />,
    <NumberInput source="isCrossZone" label="table.field.basStationArea.isCrossZone" />,
    <TextInput source="crossZoneArea" label="table.field.basStationArea.crossZoneArea" />,
    <NumberInput source="isWcs" label="table.field.basStationArea.isWcs" />,
    <TextInput source="wcsData" label="table.field.basStationArea.wcsData" />,
    <TextInput source="containerType" label="table.field.basStationArea.containerType" />,
    <TextInput source="barcode" label="table.field.basStationArea.barcode" />,
    <NumberInput source="autoTransfer" label="table.field.basStationArea.autoTransfer" />,
    <TextInput source="stationAreaId" label="table.field.basStationArea.stationAreaId" />,
    <TextInput source="stationAlias" label="table.field.basStationArea.stationAlias" />,
    <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 BasStationAreaList = () => {
    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.basStationArea"}
                empty={<EmptyData onClick={() => { setCreateDialog(true) }} />}
                filters={filters}
                sort={{ field: "create_time", order: "desc" }}
                actions={(
                    <TopToolbar>
                        <FilterButton />
                        <MyCreateButton onClick={() => { setCreateDialog(true) }} />
                        <SelectColumnsButton preferenceKey='basStationArea' />
                        <MyExportButton />
                    </TopToolbar>
                )}
                perPage={DEFAULT_PAGE_SIZE}
            >
                <StyledDatagrid
                    preferenceKey='basStationArea'
                    bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />}
                    rowClick={(id, resource, record) => false}
                    expand={() => <BasStationAreaPanel />}
                    expandSingle={true}
                    omit={['id', 'createTime', 'createBy', 'memo']}
                >
                    <NumberField source="id" />
                    <NumberField source="type" label="table.field.basStationArea.type" />
                    <TextField source="stationAreaName" label="table.field.basStationArea.stationAreaName" />
                    <NumberField source="inAble" label="table.field.basStationArea.inAble" />
                    <NumberField source="outAble" label="table.field.basStationArea.outAble" />
                    <TextField source="useStatus" label="table.field.basStationArea.useStatus" />
                    <NumberField source="area" label="table.field.basStationArea.area" />
                    <NumberField source="isCrossZone" label="table.field.basStationArea.isCrossZone" />
                    <TextField source="crossZoneArea" label="table.field.basStationArea.crossZoneArea" />
                    <NumberField source="isWcs" label="table.field.basStationArea.isWcs" />
                    <TextField source="wcsData" label="table.field.basStationArea.wcsData" />
                    <TextField source="containerType" label="table.field.basStationArea.containerType" />
                    <TextField source="barcode" label="table.field.basStationArea.barcode" />
                    <NumberField source="autoTransfer" label="table.field.basStationArea.autoTransfer" />
                    <TextField source="stationAreaId" label="table.field.basStationArea.stationAreaId" />
                    <TextField source="stationAlias" label="table.field.basStationArea.stationAlias" />
                    <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>
            <BasStationAreaCreate
                open={createDialog}
                setOpen={setCreateDialog}
            />
            <PageDrawer
                title='BasStationArea Detail'
                drawerVal={drawerVal}
                setDrawerVal={setDrawerVal}
            >
            </PageDrawer>
        </Box>
    )
}
export default BasStationAreaList;
rsf-admin/src/page/basStationArea/BasStationAreaPanel.jsx
New file
@@ -0,0 +1,141 @@
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 BasStationAreaPanel = () => {
    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.basStationArea.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}>&nbsp;</Box>
                    <Grid container spacing={2}>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.basStationArea.type"
                                property={record.type}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.basStationArea.stationAreaName"
                                property={record.stationAreaName}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.basStationArea.inAble"
                                property={record.inAble}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.basStationArea.outAble"
                                property={record.outAble}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.basStationArea.useStatus"
                                property={record.useStatus}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.basStationArea.area"
                                property={record.area}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.basStationArea.isCrossZone"
                                property={record.isCrossZone}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.basStationArea.crossZoneArea"
                                property={record.crossZoneArea}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.basStationArea.isWcs"
                                property={record.isWcs}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.basStationArea.wcsData"
                                property={record.wcsData}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.basStationArea.containerType"
                                property={record.containerType}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.basStationArea.barcode"
                                property={record.barcode}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.basStationArea.autoTransfer"
                                property={record.autoTransfer}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.basStationArea.stationAreaId"
                                property={record.stationAreaId}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.basStationArea.stationAlias"
                                property={record.stationAlias}
                            />
                        </Grid>
                    </Grid>
                </CardContent>
            </Card >
        </>
    );
};
export default BasStationAreaPanel;
rsf-admin/src/page/basStationArea/index.jsx
New file
@@ -0,0 +1,18 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import {
    ListGuesser,
    EditGuesser,
    ShowGuesser,
} from "react-admin";
import BasStationAreaList from "./BasStationAreaList";
import BasStationAreaEdit from "./BasStationAreaEdit";
export default {
    list: BasStationAreaList,
    edit: BasStationAreaEdit,
    show: ShowGuesser,
    recordRepresentation: (record) => {
        return `${record.id}`
    }
};
rsf-server/src/main/java/basStationArea.sql
New file
@@ -0,0 +1,36 @@
-- save basStationArea record
-- mysql
insert into `sys_menu` ( `name`, `parent_id`, `route`, `component`, `type`, `sort`, `tenant_id`, `status`) values ( 'menu.basStationArea', '0', '/manager/basStationArea', 'basStationArea', '0' , '0', '1' , '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Query 物料权限', '', '1', 'manager:basStationArea:list', '0', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Create 物料权限', '', '1', 'manager:basStationArea:save', '1', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Update 物料权限', '', '1', 'manager:basStationArea:update', '2', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Delete 物料权限', '', '1', 'manager:basStationArea:remove', '3', '1', '1');
-- locale menu name
basStationArea: 'BasStationArea',
-- locale field
basStationArea: {
    type: "type",
    stationAreaName: "stationAreaName",
    inAble: "inAble",
    outAble: "outAble",
    useStatus: "useStatus",
    area: "area",
    isCrossZone: "isCrossZone",
    crossZoneArea: "crossZoneArea",
    isWcs: "isWcs",
    wcsData: "wcsData",
    containerType: "containerType",
    barcode: "barcode",
    autoTransfer: "autoTransfer",
    stationAreaId: "stationAreaId",
    stationAlias: "stationAlias",
},
-- ResourceContent
import basStationArea from './basStationArea';
case 'basStationArea':
    return basStationArea;
rsf-server/src/main/java/com/vincent/rsf/server/api/entity/params/PdaGeneralParam.java
@@ -24,7 +24,7 @@
     */
    private Integer staOperateType;
    private String locNo;
    private String locNo;//库位号
    // 任务来源:mes erp
    private String taskOrigin;
rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/InBoundServiceImpl.java
@@ -80,7 +80,7 @@
            throw new CoolException("站点状态不为空闲");
        }
        if (!Cools.isEmpty(basStation.getContainerType())) {
            List<Long> longs1 = JSONObject.parseArray(basStation.getContainerType(), Long.class);
            List<Integer> longs1 = basStation.getContainerType();
            List<BasContainer> containers = basContainerService.list(
                    new LambdaQueryWrapper<BasContainer>()
                            .in(BasContainer::getContainerType, longs1)
@@ -131,12 +131,12 @@
            throw new CoolException("站点状态不为空闲");
        }
        List<String> areaList = JSONObject.parseArray(basStation.getCrossZoneArea(), String.class);
        if (!areaList.contains(area)) {
        List<Integer> areaList = basStation.getCrossZoneArea();
        if (!areaList.contains(Integer.parseInt(area))) {
            throw new CoolException("当前站点不支持目标库区");
        }
        if (!Cools.isEmpty(basStation.getContainerType())) {
            List<Long> longs1 = JSONObject.parseArray(basStation.getContainerType(), Long.class);
            List<Integer> longs1 = basStation.getContainerType();
            List<BasContainer> containers = basContainerService.list(
                    new LambdaQueryWrapper<BasContainer>()
                            .in(BasContainer::getContainerType, longs1)
rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/ReceiveMsgServiceImpl.java
@@ -622,13 +622,15 @@
            List<OutStockToTaskParams> tasks = new ArrayList<>();
            for (OrderOutItemDto orderOutItemDto : orderOutTaskItemAuto){
                OutStockToTaskParams outStockToTaskParams = new OutStockToTaskParams(orderOutItemDto);
                outStockToTaskParams.setId(orderOutItemDto.getLocItem().getId());
                outStockToTaskParams.setOutQty(orderOutItemDto.getOutQty());
                outStockToTaskParams.setLocCode(orderOutItemDto.getLocItem().getLocCode());
                outStockToTaskParams.setBarcode(orderOutItemDto.getLocItem().getBarcode());
                outStockToTaskParams.setSiteNo(stationId);
                tasks.add(outStockToTaskParams);
                for (LocItem locItem : orderOutItemDto.getLocItemList()) {
                    OutStockToTaskParams outStockToTaskParams = new OutStockToTaskParams(orderOutItemDto,locItem);
                    outStockToTaskParams.setId(locItem.getId());
                    outStockToTaskParams.setOutQty(locItem.getOutQty());
                    outStockToTaskParams.setLocCode(locItem.getLocCode());
                    outStockToTaskParams.setBarcode(locItem.getBarcode());
                    outStockToTaskParams.setSiteNo(stationId);
                    tasks.add(outStockToTaskParams);
                }
            }
            if (tasks.isEmpty()){
                log.warn("订单ID {} 没有找到可出库明细,跳过自动出库", orderId);
rsf-server/src/main/java/com/vincent/rsf/server/common/CodeBuilder.java
@@ -15,16 +15,16 @@
        generator.frontendPrefixPath = "rsf-admin/";
        generator.sqlOsType = SqlOsType.MYSQL;
        generator.url = "192.168.4.36:3306/rsf";
        generator.url = "127.0.0.1:3306/rsf";
        generator.username = "root";
        generator.password = "root";
//        generator.url="47.97.1.152:51433;databasename=jkasrs";
//        generator.username="sa";
//        generator.password="Zoneyung@zy56$";
        generator.table = "sys_warehouse_role_menu";
        generator.table = "man_bas_station_area";
        generator.tableDesc = "物料权限";
        generator.packagePath = "com.vincent.rsf.server.system";
        generator.packagePath = "com.vincent.rsf.server.manager";
        generator.build();
    }
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/BasStationAreaController.java
New file
@@ -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.BasStationArea;
import com.vincent.rsf.server.manager.service.BasStationAreaService;
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 BasStationAreaController extends BaseController {
    @Autowired
    private BasStationAreaService basStationAreaService;
    @PreAuthorize("hasAuthority('manager:basStationArea:list')")
    @PostMapping("/basStationArea/page")
    public R page(@RequestBody Map<String, Object> map) {
        BaseParam baseParam = buildParam(map, BaseParam.class);
        PageParam<BasStationArea, BaseParam> pageParam = new PageParam<>(baseParam, BasStationArea.class);
        return R.ok().add(basStationAreaService.page(pageParam, pageParam.buildWrapper(true)));
    }
    @PreAuthorize("hasAuthority('manager:basStationArea:list')")
    @PostMapping("/basStationArea/list")
    public R list(@RequestBody Map<String, Object> map) {
        return R.ok().add(basStationAreaService.list());
    }
    @PreAuthorize("hasAuthority('manager:basStationArea:list')")
    @PostMapping({"/basStationArea/many/{ids}", "/basStationAreas/many/{ids}"})
    public R many(@PathVariable Long[] ids) {
        return R.ok().add(basStationAreaService.listByIds(Arrays.asList(ids)));
    }
    @PreAuthorize("hasAuthority('manager:basStationArea:list')")
    @GetMapping("/basStationArea/{id}")
    public R get(@PathVariable("id") Long id) {
        return R.ok().add(basStationAreaService.getById(id));
    }
    @PreAuthorize("hasAuthority('manager:basStationArea:save')")
    @OperationLog("Create 物料权限")
    @PostMapping("/basStationArea/save")
    public R save(@RequestBody BasStationArea basStationArea) {
        basStationArea.setCreateBy(getLoginUserId());
        basStationArea.setCreateTime(new Date());
        basStationArea.setUpdateBy(getLoginUserId());
        basStationArea.setUpdateTime(new Date());
        if (!basStationAreaService.save(basStationArea)) {
            return R.error("Save Fail");
        }
        return R.ok("Save Success").add(basStationArea);
    }
    @PreAuthorize("hasAuthority('manager:basStationArea:update')")
    @OperationLog("Update 物料权限")
    @PostMapping("/basStationArea/update")
    public R update(@RequestBody BasStationArea basStationArea) {
        basStationArea.setUpdateBy(getLoginUserId());
        basStationArea.setUpdateTime(new Date());
        if (!basStationAreaService.updateById(basStationArea)) {
            return R.error("Update Fail");
        }
        return R.ok("Update Success").add(basStationArea);
    }
    @PreAuthorize("hasAuthority('manager:basStationArea:remove')")
    @OperationLog("Delete 物料权限")
    @PostMapping("/basStationArea/remove/{ids}")
    public R remove(@PathVariable Long[] ids) {
        if (!basStationAreaService.removeByIds(Arrays.asList(ids))) {
            return R.error("Delete Fail");
        }
        return R.ok("Delete Success").add(ids);
    }
    @PreAuthorize("hasAuthority('manager:basStationArea:list')")
    @PostMapping("/basStationArea/query")
    public R query(@RequestParam(required = false) String condition) {
        List<KeyValVo> vos = new ArrayList<>();
        LambdaQueryWrapper<BasStationArea> wrapper = new LambdaQueryWrapper<>();
        if (!Cools.isEmpty(condition)) {
            wrapper.like(BasStationArea::getId, condition);
        }
        basStationAreaService.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:basStationArea:list')")
    @PostMapping("/basStationArea/export")
    public void export(@RequestBody Map<String, Object> map, HttpServletResponse response) throws Exception {
        ExcelUtil.build(ExcelUtil.create(basStationAreaService.list(), BasStationArea.class), response);
    }
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/LocController.java
@@ -71,7 +71,7 @@
                .last("LIMIT 1"));
        List<Loc> list = locService.list(new LambdaQueryWrapper<Loc>()
                .eq(Loc::getAreaId, loc.getAreaId())
                .eq(!Objects.isNull(loc.getChannel()), Loc::getChannel,loc.getChannel())
//                .eq(!Objects.isNull(loc.getChannel()), Loc::getChannel,loc.getChannel())//
                .eq(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_O.type)
        );
        List<String> list1 = list.stream().map(obj -> obj.getCode()).collect(Collectors.toList());
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/dto/OrderOutItemDto.java
@@ -1,11 +1,13 @@
package com.vincent.rsf.server.manager.controller.dto;
import com.vincent.rsf.server.manager.entity.Loc;
import com.vincent.rsf.server.manager.entity.LocItem;
import com.vincent.rsf.server.manager.utils.Synchro;
import lombok.Data;
import lombok.experimental.Accessors;
import lombok.experimental.Delegate;
import java.util.ArrayList;
import java.util.List;
@@ -13,12 +15,18 @@
@Accessors(chain = true)
public class OrderOutItemDto {
    @Delegate(types = LocItem.class)
    private LocItem locItem;
//    @Delegate(types = LocItem.class)
//    private LocItem locItem;
//    @Delegate(types = Loc.class)
    private Loc loc;
    private List<LocItem> locItemList = new ArrayList<>();
    private List<staListDto> staNos;
    private List<String> targSiteAreaList;
    private String sitesNo;
    private String siteNo;
    private String sourceId;
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/params/LocToTaskParams.java
@@ -34,4 +34,7 @@
    @ApiModelProperty("备注")
    private String memo;
    @ApiModelProperty("目标区域集合")
    private List<String> targSiteAreaList;
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/params/OutStockToTaskParams.java
@@ -3,6 +3,7 @@
import com.baomidou.mybatisplus.annotation.TableField;
import com.vincent.rsf.server.manager.controller.dto.OrderOutItemDto;
import com.vincent.rsf.server.manager.entity.LocItem;
import com.vincent.rsf.server.manager.entity.WkOrderItem;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
@@ -49,16 +50,16 @@
    public OutStockToTaskParams(){};
    public OutStockToTaskParams(OrderOutItemDto orderOutItemDto){
    public OutStockToTaskParams(OrderOutItemDto orderOutItemDto, LocItem locItem){
//        this.locCode = w;//库位
//        this.id = wkOrderItem.getId();
        this.barcode = orderOutItemDto.getBarcode();
        this.batch = orderOutItemDto.getBatch();
        this.unit = orderOutItemDto.getUnit();
        this.platOrderCode = orderOutItemDto.getPlatOrderCode();
        this.fieldsIndex = orderOutItemDto.getFieldsIndex();
        this.extendFields = orderOutItemDto.getExtendFields();
        this.outQty = orderOutItemDto.getAnfme();
        this.barcode = locItem.getBarcode();
        this.batch = locItem.getBatch();
        this.unit = locItem.getUnit();
        this.platOrderCode = locItem.getPlatOrderCode();
        this.fieldsIndex = locItem.getFieldsIndex();
        this.extendFields = locItem.getExtendFields();
//        this.outQty = locItem.getAnfme();
//        this.siteNo = siteNo;
    };
rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/BasStation.java
@@ -88,7 +88,8 @@
     * 可跨区区域id
     */
    @ApiModelProperty(value = "可跨区区域id")
    private String crossZoneArea;
    @TableField(typeHandler = JacksonTypeHandler.class)
    private List<Integer> crossZoneArea;
    /**
     * 是否wcs站点
@@ -106,7 +107,8 @@
     * 容器类型
     */
    @ApiModelProperty(value = "容器类型")
    private String containerType;
    @TableField(typeHandler = JacksonTypeHandler.class)
    private List<Integer> containerType;
    /**
     * 条码
@@ -194,11 +196,11 @@
        }
        DictDataService service = SpringUtils.getBean(DictDataService.class);
        Object parse = JSONArray.parse(this.getContainerType());
        List<Long> longs1 = JSONObject.parseArray(parse.toString(), Long.class);
//        Object parse = JSONArray.parse(this.getContainerType());
//        List<Long> longs1 = JSONObject.parseArray(parse.toString(), Long.class);
        List<DictData> dictData = service.list(new LambdaQueryWrapper<DictData>()
                .eq(DictData::getDictTypeCode, "sys_container_type")
                .in(DictData::getValue, longs1));
                .in(DictData::getValue, this.getContainerType()));
        List<Long> longs = dictData.stream().map(DictData::getId).collect(Collectors.toList());
        return longs;
    }
rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/BasStationArea.java
New file
@@ -0,0 +1,277 @@
package com.vincent.rsf.server.manager.entity;
import com.baomidou.mybatisplus.annotation.*;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import com.vincent.rsf.framework.common.Cools;
import com.vincent.rsf.framework.common.SpringUtils;
import com.vincent.rsf.server.manager.enums.StationTypeEnum;
import com.vincent.rsf.server.manager.service.WarehouseAreasService;
import com.vincent.rsf.server.system.entity.DictData;
import com.vincent.rsf.server.system.entity.User;
import com.vincent.rsf.server.system.service.DictDataService;
import com.vincent.rsf.server.system.service.UserService;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
@Data
@TableName(value = "man_bas_station_area", autoResultMap = true)
public class BasStationArea 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 stationAreaName;
    /**
     * 站点名称
     */
    @ApiModelProperty(value = "区域编号")
    private String stationAreaId;
    @ApiModelProperty("类型: {0:光电, 1:无光电}")
    private Integer type;
    /**
     * 可入
     */
    @ApiModelProperty(value = "可入")
    private Integer inAble = 0;
    /**
     * 可出
     */
    @ApiModelProperty(value = "可出")
    private Integer outAble = 0;
    /**
     * 状态
     */
    @ApiModelProperty(value = "状态")
    private String useStatus;
    /**
     * 所属库区id
     */
    @ApiModelProperty(value = "所属库区id")
    private Long area;
    /**
     * 是否可跨区
     */
    @ApiModelProperty(value = "是否可跨区")
    private Integer isCrossZone = 0;
    /**
     * 可跨区区域id
     */
    @ApiModelProperty(value = "可执行库区区区域id")
    @TableField(typeHandler = JacksonTypeHandler.class)
    private List<Integer> crossZoneArea;
    /**
     * 是否wcs站点
     */
    @ApiModelProperty(value = "是否wcs站点")
    private Integer isWcs = 0;
    /**
     * wcs站点信息
     */
    @ApiModelProperty(value = "wcs站点信息")
    private String wcsData;
    /**
     * 容器类型
     */
    @ApiModelProperty(value = "容器类型")
    @TableField(typeHandler = JacksonTypeHandler.class)
    private List<Integer> containerType;
    /**
     * 条码
     */
    @ApiModelProperty(value = "条码")
    @TableField(updateStrategy = FieldStrategy.IGNORED)
    private String barcode;
    /**
     * 是否自动调拨
     */
    @ApiModelProperty(value = "是否自动调拨")
    private Integer autoTransfer;
    /**
     * 备注
     */
    @ApiModelProperty(value = "备注")
    private String memo;
    @ApiModelProperty(value = "是否删除 1: 是  0: 否  ")
    @TableLogic
    private Integer deleted;
    /**
     * 创建人
     */
    @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 Integer status;
    /**
     * 所属机构
     */
    @ApiModelProperty(value = "租户")
    private Long tenantId;
    @TableField(exist = false)
    private List<Long> areaIds;
    @TableField(exist = false)
    private List<Long> containerTypes;
    /**
     * 区域包含站点集
     */
    @ApiModelProperty(value = "区域包含站点集")
    @TableField(typeHandler = JacksonTypeHandler.class)
    private List<String> stationAlias;
    public BasStationArea() {
    }
    public String getType$() {
        if (this.type == null)
            return null;
        return StationTypeEnum.getStationDesc(this.type);
    }
    public List<Long> getContainerTypes$() {
        if (Cools.isEmpty(this.containerType)) {
            return new ArrayList<>();
        }
        DictDataService service = SpringUtils.getBean(DictDataService.class);
//        Object parse = JSONArray.parse(this.getContainerType());
//        List<Long> longs1 = JSONObject.parseArray(parse.toString(), Long.class);
        List<DictData> dictData = service.list(new LambdaQueryWrapper<DictData>()
                .eq(DictData::getDictTypeCode, "sys_container_type")
                .in(DictData::getValue, this.getContainerType()));
        List<Long> longs = dictData.stream().map(DictData::getId).collect(Collectors.toList());
        return longs;
    }
    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 String getUseStatus$() {
        if (Cools.isEmpty(this.useStatus)) {
            return "";
        }
        DictDataService service = SpringUtils.getBean(DictDataService.class);
        DictData dictData = service.getOne(new LambdaQueryWrapper<DictData>()
                .eq(DictData::getDictTypeCode, "sys_sta_use_stas")
                .eq(DictData::getValue, this.useStatus));
        if (!Cools.isEmpty(dictData)) {
            return String.valueOf(dictData.getLabel());
        }
        return "";
    }
    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 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 String getArea$() {
        if (null == this.area) {
            return null;
        }
        WarehouseAreasService service = SpringUtils.getBean(WarehouseAreasService.class);
        WarehouseAreas warehouseAreas = service.getById(this.area);
        if (!Cools.isEmpty(warehouseAreas)) {
            return String.valueOf(warehouseAreas.getName());
        }
        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;
        }
    }
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/Task.java
@@ -3,27 +3,18 @@
import java.text.SimpleDateFormat;
import java.util.*;
import com.baomidou.mybatisplus.annotation.*;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.vincent.rsf.server.manager.service.TaskService;
import com.vincent.rsf.server.system.constant.DictTypeCode;
import com.vincent.rsf.server.system.entity.DictData;
import com.vincent.rsf.server.system.service.DictDataService;
import lombok.experimental.Accessors;
import org.apache.commons.lang3.StringUtils;
import org.springframework.format.annotation.DateTimeFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.TableLogic;
import java.text.SimpleDateFormat;
import java.util.Date;
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;
@@ -32,12 +23,10 @@
import com.vincent.rsf.server.system.service.UserService;
import com.vincent.rsf.server.system.entity.User;
import java.io.Serializable;
import java.util.Date;
import java.util.stream.Collectors;
import com.vincent.rsf.server.manager.service.BasStationService;
@Data
@Accessors(chain = true)
@TableName("man_task")
@TableName(value = "man_task", autoResultMap = true)
@ApiModel(value = "Task", description = "任务档")
public class Task implements Serializable {
    /**
@@ -222,6 +211,11 @@
    @ApiModelProperty(value= "步序终点")
    private String endStep;
    @TableField(typeHandler = JacksonTypeHandler.class)
    private List<Integer> targSiteArea;
    private String targLocArea;
    public Task() {}
    public Task(String taskCode,Integer taskStatus,Integer taskType,String orgLoc,String targLoc,String barcode,String robotCode,Short exceStatus,String expDesc,Integer sort,String expCode,Date startTime,Date endTime,Integer status,Integer deleted,Integer tenantId,Long createBy,Date createTime,Long updateBy,Date updateTime,String memo) {
rsf-server/src/main/java/com/vincent/rsf/server/manager/mapper/BasStationAreaMapper.java
New file
@@ -0,0 +1,12 @@
package com.vincent.rsf.server.manager.mapper;
import com.vincent.rsf.server.manager.entity.BasStationArea;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
@Mapper
@Repository
public interface BasStationAreaMapper extends BaseMapper<BasStationArea> {
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/schedules/TaskSchedules.java
@@ -134,7 +134,7 @@
                taskInstanceNode.setStatus(flowInstance.getStatus());
                TaskInstance taskInstance = taskInstanceService.getById(flowInstance.getTaskId());
                if (Cools.isEmpty(taskInstance)) { continue;}
                Task task = taskService.getOne(new LambdaQueryWrapper<Task>().eq(Task::getTaskCode, taskInstance.getTaskNo()));
                Task task = taskService.getOne(new LambdaQueryWrapper<Task>().eq(Task::getTaskCode, taskInstance.getTaskNo()).last("limit 1"),false);
                if (Cools.isEmpty(task)) { continue;}
                if (!task.getTaskStatus().equals(flowStepInstance.getWmsNowTaskStatus())) {
                    log.error("任务号:"+task.getTaskCode()+"的任务状态与执行档案任务状态:"+flowStepInstance.getWmsNowTaskStatus()+"不一致!!!");
@@ -156,7 +156,7 @@
                                    .eq(FlowStepInstance::getStatus, (short)0)
                                    .eq(FlowStepInstance::getTaskNo, flowStepInstance.getTaskNo())
                                    .eq(FlowStepInstance::getStepOrder, flowStepInstance.getStepOrder() + 1)
                                    .eq(FlowStepInstance::getWmsNowTaskStatus, flowStepInstance.getWmsNextTaskStatus()));
                                    .eq(FlowStepInstance::getWmsNowTaskStatus, flowStepInstance.getWmsNextTaskStatus()).last("limit 1"));
                            if (Cools.isEmpty(nextFlowStepInstance)) {
                                throw new CoolException("任务号"+task.getTaskCode()+"任务步骤丢失!!!");
                            }
@@ -183,7 +183,7 @@
                    if (souSign){
                        WarehouseAreas warehouseAreas = warehouseAreasService.getById(Long.parseLong(taskInstance.getSourceCode()));
                        if (Cools.isEmpty(warehouseAreas)){
                            BasStation basStation = basStationService.getOne(new LambdaQueryWrapper<BasStation>().eq(BasStation::getStationName, taskInstance.getSourceCode()));
                            BasStation basStation = basStationService.getOne(new LambdaQueryWrapper<BasStation>().eq(BasStation::getStationName, taskInstance.getSourceCode()).last("limit 1"));
                            if (Cools.isEmpty(basStation)){
                                basStation = basStationService.getOne(new LambdaQueryWrapper<BasStation>()
                                        .apply("station_alias != '[]'")  // 不是空数组
@@ -209,7 +209,7 @@
                            missionTaskIssueParam.setSourceCode(taskInstance.getSourceCode());
                        }
                    } else {
                        BasStation basStation = basStationService.getOne(new LambdaQueryWrapper<BasStation>().eq(BasStation::getStationName, taskInstance.getSourceCode()));
                        BasStation basStation = basStationService.getOne(new LambdaQueryWrapper<BasStation>().eq(BasStation::getStationName, taskInstance.getSourceCode()).last("limit 1"));
                        if (Cools.isEmpty(basStation)){
                            basStation = basStationService.getOne(new LambdaQueryWrapper<BasStation>()
                                    .apply("station_alias != '[]'")  // 不是空数组
@@ -235,7 +235,7 @@
                    if (endSign){
                        WarehouseAreas warehouseAreas = warehouseAreasService.getById(Long.parseLong(taskInstance.getTargetCode()));
                        if (Cools.isEmpty(warehouseAreas)){
                            BasStation basStation = basStationService.getOne(new LambdaQueryWrapper<BasStation>().eq(BasStation::getStationName, taskInstance.getTargetCode()));
                            BasStation basStation = basStationService.getOne(new LambdaQueryWrapper<BasStation>().eq(BasStation::getStationName, taskInstance.getTargetCode()).last("limit 1"));
                            if (Cools.isEmpty(basStation)){
                                basStation = basStationService.getOne(new LambdaQueryWrapper<BasStation>()
                                        .apply("station_alias != '[]'")  // 不是空数组
@@ -261,7 +261,7 @@
                            missionTaskIssueParam.setTargetCode(taskInstance.getTargetCode());
                        }
                    } else {
                        BasStation basStation = basStationService.getOne(new LambdaQueryWrapper<BasStation>().eq(BasStation::getStationName, taskInstance.getTargetCode()));
                        BasStation basStation = basStationService.getOne(new LambdaQueryWrapper<BasStation>().eq(BasStation::getStationName, taskInstance.getTargetCode()).last("limit 1"));
                        if (Cools.isEmpty(basStation)){
                            basStation = basStationService.getOne(new LambdaQueryWrapper<BasStation>()
                                    .apply("station_alias != '[]'")  // 不是空数组
@@ -345,7 +345,7 @@
                                            .eq(FlowStepInstance::getStatus, (short)0)
                                            .eq(FlowStepInstance::getTaskNo, flowStepInstance.getTaskNo())
                                            .eq(FlowStepInstance::getStepOrder, flowStepInstance.getStepOrder() + 1)
                                            .eq(FlowStepInstance::getWmsNowTaskStatus, flowStepInstance.getWmsNextTaskStatus()));
                                            .eq(FlowStepInstance::getWmsNowTaskStatus, flowStepInstance.getWmsNextTaskStatus()).last("limit 1"));
                                    if (Cools.isEmpty(nextFlowStepInstance)) {
                                        throw new CoolException("任务号"+task.getTaskCode()+"任务步骤丢失!!!");
                                    }
@@ -760,7 +760,7 @@
        BasStation station = null;
        if (!task.getTaskType().equals(TaskType.TASK_TYPE_LOC_MOVE.type)) {
            station = basStationService.getOne(new LambdaQueryWrapper<BasStation>().eq(BasStation::getStationName, task.getTargSite()));
            station = basStationService.getOne(new LambdaQueryWrapper<BasStation>().eq(BasStation::getStationName, task.getTargSite()).last("limit 1"));
            if (Objects.isNull(station)) {
                throw new CoolException("站点不存在!!");
            }
@@ -771,7 +771,7 @@
        Loc locStart = null;
        if (task.getTaskType().equals(TaskType.TASK_TYPE_OUT.type) || task.getTaskType().equals(TaskType.TASK_TYPE_MERGE_OUT.type) ||
                task.getTaskType().equals(TaskType.TASK_TYPE_CHECK_OUT.type) || task.getTaskType().equals(TaskType.TASK_TYPE_EMPTY_OUT.type)) {
            locStart = locService.getOne(new LambdaQueryWrapper<Loc>().eq(Loc::getCode, task.getOrgLoc()));
            locStart = locService.getOne(new LambdaQueryWrapper<Loc>().eq(Loc::getCode, task.getOrgLoc()).last("limit 1"));
            if (Objects.isNull(locStart)) {
                throw new CoolException("源库位不存在!!");
            }
@@ -790,7 +790,7 @@
                    task.getTaskType().equals(TaskType.TASK_TYPE_PICK_IN.type) ||
                    task.getTaskType().equals(TaskType.TASK_TYPE_MERGE_IN.type) || task.getTaskType().equals(TaskType.TASK_TYPE_CHECK_IN.type)
            ) {
                BasStation stationS = basStationService.getOne(new LambdaQueryWrapper<BasStation>().eq(BasStation::getStationName, task.getOrgSite()));
                BasStation stationS = basStationService.getOne(new LambdaQueryWrapper<BasStation>().eq(BasStation::getStationName, task.getOrgSite()).last("limit 1"));
                if (Objects.isNull(stationS)) {
                    throw new CoolException("源库位不存在!!");
                }
@@ -798,7 +798,7 @@
                if (stationS.getType().equals(StationTypeEnum.STATION_TYPE_MUTI.type)) {
                    taskParams.setSign(LocStsWcsOrOtherType.LOC_STS_TYPE_WCS.type);
                } else {
                    Loc locEnd = locService.getOne(new LambdaQueryWrapper<Loc>().eq(Loc::getCode, task.getTargLoc()));
                    Loc locEnd = locService.getOne(new LambdaQueryWrapper<Loc>().eq(Loc::getCode, task.getTargLoc()).last("limit 1"));
                    if (Objects.isNull(locEnd)) {
                        throw new CoolException("源库位不存在!!");
                    }
@@ -858,7 +858,7 @@
            /**站点间移库参数*/
            itemParam.setOriSta(task.getOrgSite()).setDestSta(task.getTargSite());
            BasStation curSta = basStationService.getOne(new LambdaQueryWrapper<BasStation>().eq(BasStation::getStationName, task.getOrgSite()));
            BasStation curSta = basStationService.getOne(new LambdaQueryWrapper<BasStation>().eq(BasStation::getStationName, task.getOrgSite()).last("limit 1"));
            if (Objects.isNull(curSta)) {
                throw new CoolException("站点不存在!!");
            }
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/BasStationAreaService.java
New file
@@ -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.BasStationArea;
public interface BasStationAreaService extends IService<BasStationArea> {
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/TaskService.java
@@ -21,6 +21,7 @@
    R removeTask(Long[] ids, Long loginUserId);
    Task pickOrCheckTask(Long id, String oType) throws Exception;
//    Task pickOrCheckTask(Long id, String oType, Long loginUserId) throws Exception;
    void complateInTask(List<Task> tasks) throws Exception;
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/BasStationAreaServiceImpl.java
New file
@@ -0,0 +1,12 @@
package com.vincent.rsf.server.manager.service.impl;
import com.vincent.rsf.server.manager.mapper.BasStationAreaMapper;
import com.vincent.rsf.server.manager.entity.BasStationArea;
import com.vincent.rsf.server.manager.service.BasStationAreaService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
@Service("basStationAreaService")
public class BasStationAreaServiceImpl extends ServiceImpl<BasStationAreaMapper, BasStationArea> implements BasStationAreaService {
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/LocItemServiceImpl.java
@@ -136,9 +136,9 @@
    @Synchronized
    @Transactional(rollbackFor = Exception.class)
    public synchronized void generateTask(Short resouce, LocToTaskParams map, Long loginUserId) throws Exception {
        if (Objects.isNull(map.getSiteNo())) {
            throw new CoolException("站点不能为空!");
        }
//        if (Objects.isNull(map.getSiteNo())) {
//            throw new CoolException("站点不能为空!");
//        }
        if (Objects.isNull(map.getItems()) || map.getItems().isEmpty()) {
            throw new CoolException("明细不能为空!");
        }
@@ -288,8 +288,6 @@
                    throw new CoolException("主任务关联失败!!");
                }
            }
            locItemWorkingService.remove(new LambdaQueryWrapper<LocItemWorking>().eq(LocItemWorking::getTaskId, task.getId()));
            List<TaskItem> taskItems = new ArrayList<>();
            listMap.get(key).forEach(item -> {
                TaskItem taskItem = new TaskItem();
@@ -344,22 +342,26 @@
                    throw new CoolException("库存信息修改失败!!");
                }
                if (taskItem.getAnfme() > 0) {
                    LocItemWorking itemWorking = new LocItemWorking();
                    BeanUtils.copyProperties(taskItem, itemWorking);
                    itemWorking.setTaskId(task.getId())
                            .setQty(0.0)
                            .setLocId(loc.getId())
                            .setLocItemId(locItem.getId())
                            .setType("out")
                            .setLocCode(loc.getCode());
                    if (!locItemWorkingService.save(itemWorking)) {
                        throw new CoolException("临时库存更新失败!!");
                    }
                }
            });
            locItemWorkingService.remove(new LambdaQueryWrapper<LocItemWorking>().eq(LocItemWorking::getTaskId, task.getId()));
            List<LocItemWorking> workings = new ArrayList<>();
            for (LocItem item : locItems) {
                LocItemWorking working = new LocItemWorking();
                BeanUtils.copyProperties(item, working);
                working.setId(null)
                        .setTaskId(task.getId())
                        .setLocItemId(item.getId())
                        .setUpdateBy(loginUserId)
                        .setUpdateTime(new Date());
                workings.add(working);
            }
            if (!locItemWorkingService.saveBatch(workings)) {
                throw new CoolException("临时库存更新失败!!");
            }
            if (!taskItemService.saveBatch(taskItems)) {
                throw new CoolException("任务明细生成失败!!");
            }
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/OutStockServiceImpl.java
@@ -710,7 +710,8 @@
                        locItem.setOutQty(issued.doubleValue() >= locItem.getAnfme() ? locItem.getAnfme() : issued.doubleValue());
                        locItem.setBarcode(loc.getBarcode());
                        OrderOutItemDto orderOutItemDto = new OrderOutItemDto();
                        orderOutItemDto.setLocItem(locItem);
//                        orderOutItemDto.setLocItem(locItem);
                        orderOutItemDto.getLocItemList().add(locItem);
                        List<DeviceSite> deviceSites = deviceSiteService.list(new LambdaQueryWrapper<DeviceSite>()
                                .eq(DeviceSite::getChannel, loc.getChannel())
@@ -748,7 +749,8 @@
                        .setUnit(wkOrderItem.getStockUnit())
                        .setBatch(wkOrderItem.getSplrBatch());
                OrderOutItemDto orderOutItemDto = new OrderOutItemDto();
                orderOutItemDto.setLocItem(locItem);
//                orderOutItemDto.setLocItem(locItem);
                orderOutItemDto.getLocItemList().add(locItem);
                list.add(orderOutItemDto);
            }
        }
@@ -786,7 +788,8 @@
                        locItem.setOutQty(issued.doubleValue() >= locItem.getAnfme() ? locItem.getAnfme() : issued.doubleValue());
                        locItem.setBarcode(loc.getBarcode());
                        OrderOutItemDto orderOutItemDto = new OrderOutItemDto();
                        orderOutItemDto.setLocItem(locItem);
//                        orderOutItemDto.setLocItem(locItem);
                        orderOutItemDto.getLocItemList().add(locItem);
                        List<DeviceSite> deviceSites = deviceSiteService.list(new LambdaQueryWrapper<DeviceSite>()
                                .eq(DeviceSite::getChannel, loc.getChannel())
@@ -824,7 +827,8 @@
                        .setUnit(wkOrderItem.getStockUnit())
                        .setBatch(wkOrderItem.getSplrBatch());
                OrderOutItemDto orderOutItemDto = new OrderOutItemDto();
                orderOutItemDto.setLocItem(locItem);
//                orderOutItemDto.setLocItem(locItem);
                orderOutItemDto.getLocItemList().add(locItem);
                list.add(orderOutItemDto);
            }
        }
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/TaskServiceImpl.java
@@ -494,12 +494,12 @@
            throw new CoolException("站点状态不为空闲");
        }
        List<String> areaList = JSONObject.parseArray(basStation.getCrossZoneArea(), String.class);
        if (!areaList.contains(area)) {
        List<Integer> areaList = basStation.getCrossZoneArea();
        if (!areaList.contains(Integer.parseInt(area))) {
            throw new CoolException("当前站点不支持目标库区");
        }
        if (!Cools.isEmpty(basStation.getContainerType())) {
            List<Long> longs1 = JSONObject.parseArray(basStation.getContainerType(), Long.class);
            List<Integer> longs1 = basStation.getContainerType();
            List<BasContainer> containers = basContainerService.list(
                    new LambdaQueryWrapper<BasContainer>()
                            .in(BasContainer::getContainerType, longs1)
@@ -988,7 +988,7 @@
                    //110.空板出库
                    complateOutStockEmpty(task, loginUserId);
                } else if (task.getTaskType().equals(TaskType.TASK_TYPE_CROSS_DOCKING_OUT.type)) {
                    //109.越库
                    //109.备货
                    complateOutStockDocking(task, loginUserId);
                } else if (task.getTaskType().equals(TaskType.TASK_TYPE_CHECK_OUT.type)) {
                    //107.盘
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/WaveServiceImpl.java
@@ -297,12 +297,13 @@
    public void generateOutTask(List<OrderOutItemDto> itemParams, Long loginUserId, Wave wave) throws Exception {
        for (OrderOutItemDto itemDto : itemParams) {
            LocToTaskParams taskParams = new LocToTaskParams();
            Loc loc = locService.getById(itemDto.getLocId());
            Loc loc = locService.getById(itemDto.getLoc().getId());
            if (Objects.isNull(loc)) {
                continue;
            }
            taskParams.setItems(Arrays.asList(itemDto.getLocItem()))
                    .setSiteNo(itemDto.getSitesNo())
            taskParams.setItems(itemDto.getLocItemList())
                    .setSiteNo(itemDto.getSiteNo())
                    .setTargSiteAreaList(itemDto.getTargSiteAreaList())
                    .setType(Constants.TASK_TYPE_WAVE_OUT_STOCK)
                    .setSourceId(wave.getId())
                    .setTarLoc(loc.getCode());
rsf-server/src/main/java/com/vincent/rsf/server/manager/utils/LocManageUtil.java
@@ -1,6 +1,7 @@
package com.vincent.rsf.server.manager.utils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
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.utils.LocUtils;
@@ -175,7 +176,9 @@
        LocService locService = SpringUtils.getBean(LocService.class);
        LocItemService locItemService = SpringUtils.getBean(LocItemService.class);
        DeviceSiteService deviceSiteService = SpringUtils.getBean(DeviceSiteService.class);
        BasStationAreaService basStationAreaService = SpringUtils.getBean(BasStationAreaService.class);
//        List<BasStationArea> basStationAreas = basStationAreaService.list(new LambdaQueryWrapper<>());//
        List<Loc> locList = new  ArrayList<>();
        List<OrderOutItemDto> list = new ArrayList<>();
        //不让站点重复使用问题
        List<BasStation> stations = new ArrayList<>();
@@ -198,10 +201,27 @@
                    locItems = LocManageUtil.getFirstInFirstOutItemList(item.getMatnrCode(), item.getBatch(), item.getAnfme());
                }
            }
            for (LocItem locItem : locItems) {
                Loc loc = locService.getById(locItem.getLocId());
                List<LocItem> itemList = locItemService.list(new LambdaQueryWrapper<LocItem>().eq(LocItem::getLocCode, locItem.getLocCode()));
                if (issued.doubleValue() > 0) {
                List<LocItem> itemList = locItemService.list(new LambdaQueryWrapper<LocItem>().eq(LocItem::getLocId, loc.getId()));
                if (issued.doubleValue() > 0 && locList.contains(loc)) {
                    for (OrderOutItemDto itemDto : list) {
                        if (itemDto.getLoc().equals(loc)) {
                            ExistDto existDto = new ExistDto().setBatch(locItem.getBatch()).setMatnr(locItem.getMatnrCode()).setLocNo(locItem.getLocCode());
                            if (existDtos.add(existDto)) {
                                locItem.setOutQty(issued.doubleValue() >= locItem.getAnfme() ? locItem.getAnfme() : issued.doubleValue());
                                locItem.setBarcode(loc.getBarcode())
                                        .setSourceId(item.getWaveId())//波次ID
                                        .setSource(item.getItemId());//波次明细ID
                                itemDto.getLocItemList().add(locItem);
                                issued = issued.subtract(new BigDecimal(locItem.getAnfme().toString()));
                            }
                            break;
                        }
                    }
                } else if (issued.doubleValue() > 0) {
                    ExistDto existDto = new ExistDto().setBatch(locItem.getBatch()).setMatnr(locItem.getMatnrCode()).setLocNo(locItem.getLocCode());
                    if (existDtos.add(existDto)) {
                        locItem.setOutQty(issued.doubleValue() >= locItem.getAnfme() ? locItem.getAnfme() : issued.doubleValue());
@@ -209,65 +229,96 @@
                                .setSourceId(item.getWaveId())//波次ID
                                .setSource(item.getItemId());//波次明细ID
                        OrderOutItemDto orderOutItemDto = new OrderOutItemDto();
                        orderOutItemDto.setLocItem(locItem);
                        List<DeviceSite> deviceSites = deviceSiteService.list(new LambdaQueryWrapper<DeviceSite>()
                                .eq(!Objects.isNull(loc.getChannel()), DeviceSite::getChannel, loc.getChannel())
                                .eq(DeviceSite::getType, issued.doubleValue() >= locItem.getAnfme() && itemList.size() == 1 ? TaskType.TASK_TYPE_OUT.type : TaskType.TASK_TYPE_PICK_AGAIN_OUT.type)
                        );
                        if (!deviceSites.isEmpty()) {
                            List<OrderOutItemDto.staListDto> maps = new ArrayList<>();
                            for (DeviceSite sta : deviceSites) {
                                OrderOutItemDto.staListDto staListDto = new OrderOutItemDto.staListDto();
                                staListDto.setStaNo(sta.getSite());
                                staListDto.setStaName(sta.getSite());
                                maps.add(staListDto);
                            }
                            orderOutItemDto.setStaNos(maps);
                            //获取满足条件站点
                            Set<String> stationSet = deviceSites.stream().map(DeviceSite::getSite).collect(Collectors.toSet());
                            //已使用站点
                            Set<String> stas = stations.stream().map(BasStation::getStationName).collect(Collectors.toSet());
                            BasStationService basStationService = SpringUtils.getBean(BasStationService.class);
                            BasStation basStation = basStationService.getOne(new LambdaQueryWrapper<BasStation>()
                                    .eq(BasStation::getUseStatus, LocStsType.LOC_STS_TYPE_O.type)
                                    .in(BasStation::getStationName, stationSet)
                                    .notIn(!stas.isEmpty(), BasStation::getStationName, stas)
                                    .last("LIMIT 1"));
                            stations.add(basStation);
                            if (Objects.isNull(basStation)) {
                                throw new CoolException("站點不存在!!");
                            }
                            orderOutItemDto.setSitesNo(basStation.getStationName());
//                        orderOutItemDto.setLocItem(locItem);
                        orderOutItemDto.setLoc(loc);
                        orderOutItemDto.getLocItemList().add(locItem);
                        BasContainer containerType = getContainerType(loc.getBarcode());
                        List<BasStationArea> basStationAreas = basStationAreaService.list(new LambdaQueryWrapper<BasStationArea>()
                                .apply("JSON_CONTAINS(cross_zone_area, '{0}') = 1", loc.getAreaId())//可执行库区区区域id
                                .apply("JSON_CONTAINS(container_type, '{0}') = 1", containerType)//容器类型
//                                .apply("JSON_CONTAINS(station_alias, '\"{0}\"') = 1", null)//区域包含站点集
                                .eq(BasStationArea::getDeleted, 0));// 通常需要加上未删除条件
                        List<String> targSiteAreaList = new ArrayList<>();
                        for (BasStationArea basStationArea : basStationAreas) {
                            targSiteAreaList.add(basStationArea.getStationAreaId());
                        }
                        int count = 0;
                        for (BasStationArea basStationArea : basStationAreas) {
                            count++;
                            if (!basStationArea.getStationAlias().isEmpty()) {
                                List<OrderOutItemDto.staListDto> maps = new ArrayList<>();
                                for (String site : basStationArea.getStationAlias()) {
                                    OrderOutItemDto.staListDto staListDto = new OrderOutItemDto.staListDto();
                                    staListDto.setStaNo(site);
                                    staListDto.setStaName(site);
                                    maps.add(staListDto);
                                }
                                orderOutItemDto.setStaNos(maps);
                                //获取满足条件站点
                                Set<String> stationSet = new HashSet<>(basStationArea.getStationAlias());
//                                Set<String> stationSet = basStationArea.getStationAlias().stream().collect(Collectors.toSet());
//                                Set<String> stationSet = deviceSites.stream().map(DeviceSite::getSite).collect(Collectors.toSet());
                                //已使用站点
                                Set<String> stas = stations.stream().map(BasStation::getStationName).collect(Collectors.toSet());
                                BasStationService basStationService = SpringUtils.getBean(BasStationService.class);
                                BasStation basStation = basStationService.getOne(new LambdaQueryWrapper<BasStation>()
                                        .eq(BasStation::getUseStatus, LocStsType.LOC_STS_TYPE_O.type)
                                        .in(BasStation::getStationName, stationSet)
                                        .notIn(!stas.isEmpty(), BasStation::getStationName, stas)
                                        .last("LIMIT 1"));
                                if (!Objects.isNull(basStation)) {
                                    stations.add(basStation);
                                }
                        orderOutItemDto.setSource(item.getItemId())
                                .setSourceId(item.getWaveId());
                        list.add(orderOutItemDto);
                                if (count == basStationAreas.size()) {
                                    if (!Objects.isNull(basStation)) {
                                        orderOutItemDto.setSiteNo(basStation.getStationName());
//                                        throw new CoolException("站點不存在!!");
                                    }
                                } else {
                                    if (Objects.isNull(basStation)) {
                                        continue;
//                                        throw new CoolException("站點不存在!!");
                                    }
                                    orderOutItemDto.setSiteNo(basStation.getStationName());
                                }
                        issued = issued.subtract(new BigDecimal(locItem.getAnfme().toString()));
                            }
                            orderOutItemDto.setSource(item.getItemId().toString())
                                    .setTargSiteAreaList(targSiteAreaList)
                                    .setSourceId(item.getWaveId().toString());
                            list.add(orderOutItemDto);
                            locList.add(loc);
                            issued = issued.subtract(new BigDecimal(locItem.getAnfme().toString()));
                            break;
                        }
                    }
                }
            }
//            if (issued.doubleValue() > 0) {
//                LocItem locItem = new LocItem()
//                        .setId(new Random().nextLong())
//                        .setMatnrCode(item.getMatnrCode())
//                        .setMaktx(item.getMaktx())
//                        .setAnfme(0.00)
//                        .setWorkQty(issued.doubleValue())
//                        .setOutQty(issued.doubleValue())
//                        .setUnit(item.getUnit())
//                        .setBatch(item.getBatch());
//                OrderOutItemDto orderOutItemDto = new OrderOutItemDto();
//                orderOutItemDto.setLocItem(locItem);
//                list.add(orderOutItemDto);
//            }
        }
        return list;
    }
    //根据条码获取规则
    private static BasContainer getContainerType(String barcode) {
        BasContainerService basContainerService = SpringUtils.getBean(BasContainerService.class);
        if (Cools.isEmpty(barcode)) {
            throw new CoolException("容器码不能为空");
        }
        List<BasContainer> containers = basContainerService.list(new LambdaQueryWrapper<>());
        for (BasContainer container : containers) {
            String codeType = container.getCodeType();  // 获取正则表达式
            if (barcode.matches(codeType)) {  // 判断条码是否符合这个正则
                return container;
            }
        }
        return null;
    }
}
rsf-server/src/main/resources/mapper/manager/BasStationAreaMapper.xml
New file
@@ -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.BasStationAreaMapper">
</mapper>