Merge branch 'devlop' of http://47.97.1.152:5880/r/wms-master into devlop
 
	
	
	
	
	
	
	
	
	
	
	
	
	
 |  |  | 
 |  |  |         deviceBind: '设备绑定', | 
 |  |  |         tasks: '任务管理', | 
 |  |  |         wave: '波次管理', | 
 |  |  |         basStation: '站点信息' | 
 |  |  |     }, | 
 |  |  |     table: { | 
 |  |  |     table: {         | 
 |  |  |         field: { | 
 |  |  |             basStation: { | 
 |  |  |                 stationName: '站点名称', | 
 |  |  |                 inAble: '能入', | 
 |  |  |                 outAble: '能出', | 
 |  |  |                 useStatus: '状态', | 
 |  |  |                 status: '状态', | 
 |  |  |                 area: '所属库区类型', | 
 |  |  |                 isCrossZone: '是否跨区', | 
 |  |  |                 crossZoneArea: '可跨区类型', | 
 |  |  |                 isWcs: '是否WCS站站点', | 
 |  |  |                 wcsData: 'wcs数据', | 
 |  |  |                 containerType: '容器类型', | 
 |  |  |                 barcode: '条码',   | 
 |  |  |                 autoTransfer: '自动调拨',           | 
 |  |  |             }, | 
 |  |  |             host: { | 
 |  |  |  | 
 |  |  |             }, | 
 
 |  |  | 
 |  |  | import deviceBind from './deviceBind'; | 
 |  |  | import wave from './orders/wave'; | 
 |  |  | import locItem from './locItem' | 
 |  |  | import basStation from './basicInfo/basStation'; | 
 |  |  |  | 
 |  |  | const ResourceContent = (node) => { | 
 |  |  |     switch (node.component) { | 
 |  |  | 
 |  |  |             return wave; | 
 |  |  |         case 'locItem': | 
 |  |  |             return locItem; | 
 |  |  |         case 'basStation': | 
 |  |  |             return basStation; | 
 |  |  |         default: | 
 |  |  |             return { | 
 |  |  |                 list: ListGuesser, | 
 
| 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 BasStationCreate = (props) => { | 
 |  |  |     const { open, setOpen } = props; | 
 |  |  |  | 
 |  |  |     const translate = useTranslate(); | 
 |  |  |     const notify = useNotify(); | 
 |  |  |  | 
 |  |  |     const handleClose = (event, reason) => { | 
 |  |  |         if (reason !== "backdropClick") { | 
 |  |  |             setOpen(false); | 
 |  |  |         } | 
 |  |  |     }; | 
 |  |  |  | 
 |  |  |     const handleSuccess = async (data) => { | 
 |  |  |         setOpen(false); | 
 |  |  |         notify('common.response.success'); | 
 |  |  |     }; | 
 |  |  |  | 
 |  |  |     const handleError = async (error) => { | 
 |  |  |         notify(error.message || 'common.response.fail', { type: 'error', messageArgs: { _: error.message } }); | 
 |  |  |     }; | 
 |  |  |  | 
 |  |  |     return ( | 
 |  |  |         <> | 
 |  |  |             <CreateBase | 
 |  |  |                 record={{}} | 
 |  |  |                 transform={(data) => { | 
 |  |  |                     return data; | 
 |  |  |                 }} | 
 |  |  |                 mutationOptions={{ onSuccess: handleSuccess, onError: handleError }} | 
 |  |  |             > | 
 |  |  |                 <Dialog | 
 |  |  |                     open={open} | 
 |  |  |                     onClose={handleClose} | 
 |  |  |                     aria-labelledby="form-dialog-title" | 
 |  |  |                     fullWidth | 
 |  |  |                     disableRestoreFocus | 
 |  |  |                     maxWidth="md"   // 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 
 |  |  |                 > | 
 |  |  |                     <Form> | 
 |  |  |                         <DialogTitle id="form-dialog-title" sx={{ | 
 |  |  |                             position: 'sticky', | 
 |  |  |                             top: 0, | 
 |  |  |                             backgroundColor: 'background.paper', | 
 |  |  |                             zIndex: 1000 | 
 |  |  |                         }} | 
 |  |  |                         > | 
 |  |  |                             {translate('create.title')} | 
 |  |  |                             <Box sx={{ position: 'absolute', top: 8, right: 8, zIndex: 1001 }}> | 
 |  |  |                                 <DialogCloseButton onClose={handleClose} /> | 
 |  |  |                             </Box> | 
 |  |  |                         </DialogTitle> | 
 |  |  |                         <DialogContent sx={{ mt: 2 }}> | 
 |  |  |                             <Grid container rowSpacing={2} columnSpacing={2}> | 
 |  |  |                                 <Grid item xs={6} display="flex" gap={1}> | 
 |  |  |                                     <TextInput | 
 |  |  |                                         label="table.field.basStation.stationName" | 
 |  |  |                                         source="stationName" | 
 |  |  |                                         parse={v => v} | 
 |  |  |                                         autoFocus | 
 |  |  |                                     /> | 
 |  |  |                                 </Grid> | 
 |  |  |                                 <Grid item xs={6} display="flex" gap={1}> | 
 |  |  |                                     <NumberInput | 
 |  |  |                                         label="table.field.basStation.inAble" | 
 |  |  |                                         source="inAble" | 
 |  |  |                                     /> | 
 |  |  |                                 </Grid> | 
 |  |  |                                 <Grid item xs={6} display="flex" gap={1}> | 
 |  |  |                                     <NumberInput | 
 |  |  |                                         label="table.field.basStation.outAble" | 
 |  |  |                                         source="outAble" | 
 |  |  |                                     /> | 
 |  |  |                                 </Grid> | 
 |  |  |                                 <Grid item xs={6} display="flex" gap={1}> | 
 |  |  |                                     <TextInput | 
 |  |  |                                         label="table.field.basStation.useStatus" | 
 |  |  |                                         source="useStatus" | 
 |  |  |                                         parse={v => v} | 
 |  |  |                                     /> | 
 |  |  |                                 </Grid> | 
 |  |  |                                 <Grid item xs={6} display="flex" gap={1}> | 
 |  |  |                                     <NumberInput | 
 |  |  |                                         label="table.field.basStation.area" | 
 |  |  |                                         source="area" | 
 |  |  |                                     /> | 
 |  |  |                                 </Grid> | 
 |  |  |                                 <Grid item xs={6} display="flex" gap={1}> | 
 |  |  |                                     <NumberInput | 
 |  |  |                                         label="table.field.basStation.isCrossZone" | 
 |  |  |                                         source="isCrossZone" | 
 |  |  |                                     /> | 
 |  |  |                                 </Grid> | 
 |  |  |                                 <Grid item xs={6} display="flex" gap={1}> | 
 |  |  |                                     <TextInput | 
 |  |  |                                         label="table.field.basStation.crossZoneArea" | 
 |  |  |                                         source="crossZoneArea" | 
 |  |  |                                         parse={v => v} | 
 |  |  |                                     /> | 
 |  |  |                                 </Grid> | 
 |  |  |                                 <Grid item xs={6} display="flex" gap={1}> | 
 |  |  |                                     <NumberInput | 
 |  |  |                                         label="table.field.basStation.isWcs" | 
 |  |  |                                         source="isWcs" | 
 |  |  |                                     /> | 
 |  |  |                                 </Grid> | 
 |  |  |                                 <Grid item xs={6} display="flex" gap={1}> | 
 |  |  |                                     <TextInput | 
 |  |  |                                         label="table.field.basStation.wcsData" | 
 |  |  |                                         source="wcsData" | 
 |  |  |                                         parse={v => v} | 
 |  |  |                                     /> | 
 |  |  |                                 </Grid> | 
 |  |  |                                 <Grid item xs={6} display="flex" gap={1}> | 
 |  |  |                                     <NumberInput | 
 |  |  |                                         label="table.field.basStation.containerType" | 
 |  |  |                                         source="containerType" | 
 |  |  |                                     /> | 
 |  |  |                                 </Grid> | 
 |  |  |                                 <Grid item xs={6} display="flex" gap={1}> | 
 |  |  |                                     <TextInput | 
 |  |  |                                         label="table.field.basStation.barcode" | 
 |  |  |                                         source="barcode" | 
 |  |  |                                         parse={v => v} | 
 |  |  |                                     /> | 
 |  |  |                                 </Grid> | 
 |  |  |                                 <Grid item xs={6} display="flex" gap={1}> | 
 |  |  |                                     <NumberInput | 
 |  |  |                                         label="table.field.basStation.autoTransfer" | 
 |  |  |                                         source="autoTransfer" | 
 |  |  |                                     /> | 
 |  |  |                                 </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 BasStationCreate; | 
 
| 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, | 
 |  |  |     SelectArrayInput, | 
 |  |  | } from 'react-admin'; | 
 |  |  | import { useWatch, useFormContext } from "react-hook-form"; | 
 |  |  | import { Stack, Grid, Box, Typography } from '@mui/material'; | 
 |  |  | import * as Common from '@/utils/common'; | 
 |  |  | import { EDIT_MODE, REFERENCE_INPUT_PAGESIZE } from '@/config/setting'; | 
 |  |  | import EditBaseAside from "../../components/EditBaseAside"; | 
 |  |  | import CustomerTopToolBar from "../../components/EditTopToolBar"; | 
 |  |  | import MemoInput from "../../components/MemoInput"; | 
 |  |  | import StatusSelectInput from "../../components/StatusSelectInput"; | 
 |  |  | import DictionarySelect from "../../components/DictionarySelect"; | 
 |  |  |  | 
 |  |  | const FormToolbar = () => { | 
 |  |  |     const { getValues } = useFormContext(); | 
 |  |  |  | 
 |  |  |     return ( | 
 |  |  |         <Toolbar sx={{ justifyContent: 'space-between' }}> | 
 |  |  |             <SaveButton /> | 
 |  |  |             <DeleteButton mutationMode="optimistic" /> | 
 |  |  |         </Toolbar> | 
 |  |  |     ) | 
 |  |  | } | 
 |  |  |  | 
 |  |  | const BasStationEdit = () => { | 
 |  |  |     const translate = useTranslate(); | 
 |  |  |  | 
 |  |  |     return ( | 
 |  |  |         <Edit | 
 |  |  |             redirect="list" | 
 |  |  |             mutationMode={EDIT_MODE} | 
 |  |  |             actions={<CustomerTopToolBar />} | 
 |  |  |             aside={<EditBaseAside />} | 
 |  |  |         > | 
 |  |  |             <SimpleForm | 
 |  |  |                 shouldUnregister | 
 |  |  |                 warnWhenUnsavedChanges | 
 |  |  |                 toolbar={<FormToolbar />} | 
 |  |  |                 mode="onTouched" | 
 |  |  |                 defaultValues={{}} | 
 |  |  |             // validate={(values) => { }} | 
 |  |  |             > | 
 |  |  |                 <Grid container width={{ xs: '100%', xl: '80%' }} rowSpacing={3} columnSpacing={3}> | 
 |  |  |                     <Grid item xs={12} md={8}> | 
 |  |  |                         <Typography variant="h6" gutterBottom> | 
 |  |  |                             {translate('common.edit.title.main')} | 
 |  |  |                         </Typography> | 
 |  |  |                         <Stack direction='row' gap={2}> | 
 |  |  |                             <TextInput | 
 |  |  |                                 label="table.field.basStation.stationName" | 
 |  |  |                                 source="stationName" | 
 |  |  |                                 parse={v => v} | 
 |  |  |                                 autoFocus | 
 |  |  |                             /> | 
 |  |  |                         </Stack> | 
 |  |  |                         <Stack direction='row' gap={2}>                             | 
 |  |  |                             <SelectInput | 
 |  |  |                                     label="table.field.basStation.inAble" | 
 |  |  |                                     source="inAble" | 
 |  |  |                                     choices={[ | 
 |  |  |                                         { id: 0, name: '否' }, | 
 |  |  |                                         { id: 1, name: '是' }, | 
 |  |  |                                     ]} | 
 |  |  |                             /> | 
 |  |  |                         </Stack> | 
 |  |  |                         <Stack direction='row' gap={2}>                             | 
 |  |  |                             <SelectInput | 
 |  |  |                                     label="table.field.basStation.outAble" | 
 |  |  |                                     source="outAble" | 
 |  |  |                                     choices={[ | 
 |  |  |                                         { id: 0, name: '否' }, | 
 |  |  |                                         { id: 1, name: '是' }, | 
 |  |  |                                     ]} | 
 |  |  |                             /> | 
 |  |  |                         </Stack> | 
 |  |  |                         <Stack direction='row' gap={2}>                             | 
 |  |  |                             <DictionarySelect | 
 |  |  |                                 label={translate("table.field.basStation.useStatus")} | 
 |  |  |                                 name="useStatus" | 
 |  |  |                                 size="small" | 
 |  |  |                                 validate={[required()]} | 
 |  |  |                                 dictTypeCode="sys_sta_use_stas" | 
 |  |  |                             /> | 
 |  |  |                         </Stack> | 
 |  |  |                         <Stack direction='row' gap={2}>                             | 
 |  |  |                             <ReferenceInput source="area" reference="warehouseAreas"> | 
 |  |  |                                 <SelectInput  | 
 |  |  |                                     label="table.field.basStation.area" | 
 |  |  |                                     optionText="name" | 
 |  |  |                                     optionValue="id" | 
 |  |  |                                     fullWidth   | 
 |  |  |                                     validate={[required()]}      | 
 |  |  |                                 /> | 
 |  |  |                             </ReferenceInput> | 
 |  |  |                         </Stack> | 
 |  |  |                         <Stack direction='row' gap={2}>                             | 
 |  |  |                             <SelectInput | 
 |  |  |                                     label="table.field.basStation.isCrossZone" | 
 |  |  |                                     source="isCrossZone" | 
 |  |  |                                     choices={[ | 
 |  |  |                                         { id: 0, name: '否' }, | 
 |  |  |                                         { id: 1, name: '是' }, | 
 |  |  |                                     ]} | 
 |  |  |                                     validate={[required()]} | 
 |  |  |                             /> | 
 |  |  |                         </Stack> | 
 |  |  |                         <Stack direction='row' gap={2}>  | 
 |  |  |                             <ReferenceArrayInput source="areaIds" reference="warehouseAreas"> | 
 |  |  |                                 <SelectArrayInput  | 
 |  |  |                                     label="table.field.basStation.crossZoneArea" | 
 |  |  |                                     optionText="name" | 
 |  |  |                                     optionValue="id" | 
 |  |  |                                     fullWidth        | 
 |  |  |                                 /> | 
 |  |  |                             </ReferenceArrayInput>                              | 
 |  |  |                         </Stack> | 
 |  |  |                         <Stack direction='row' gap={2}>                             | 
 |  |  |                             <SelectInput | 
 |  |  |                                     label="table.field.basStation.isWcs" | 
 |  |  |                                     source="isWcs" | 
 |  |  |                                     choices={[ | 
 |  |  |                                         { id: 0, name: '否' }, | 
 |  |  |                                         { id: 1, name: '是' }, | 
 |  |  |                                     ]} | 
 |  |  |                                     validate={[required()]} | 
 |  |  |                             /> | 
 |  |  |                         </Stack>                         | 
 |  |  |                         <Stack direction='row' gap={2}>                             | 
 |  |  |                             <DictionarySelect | 
 |  |  |                                 label={translate("table.field.basStation.containerType")} | 
 |  |  |                                 name="containerType" | 
 |  |  |                                 size="small" | 
 |  |  |                                 validate={[required()]} | 
 |  |  |                                 dictTypeCode="sys_container_type" | 
 |  |  |                             /> | 
 |  |  |                         </Stack>                         | 
 |  |  |                         <Stack direction='row' gap={2}>                             | 
 |  |  |                             <SelectInput | 
 |  |  |                                     label="table.field.basStation.autoTransfer" | 
 |  |  |                                     source="autoTransfer" | 
 |  |  |                                     choices={[ | 
 |  |  |                                         { id: 0, name: '否' }, | 
 |  |  |                                         { id: 1, name: '是' }, | 
 |  |  |                                     ]} | 
 |  |  |                             /> | 
 |  |  |                         </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 BasStationEdit; | 
 
| 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 BasStationCreate from "./BasStationCreate"; | 
 |  |  | import BasStationPanel from "./BasStationPanel"; | 
 |  |  | 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'; | 
 |  |  | import WarehouseAreaField from "./WarehouseAreaField"; | 
 |  |  |  | 
 |  |  | const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({ | 
 |  |  |     '& .css-1vooibu-MuiSvgIcon-root': { | 
 |  |  |         height: '.9em' | 
 |  |  |     }, | 
 |  |  |     '& .RaDatagrid-row': { | 
 |  |  |         cursor: 'auto' | 
 |  |  |     }, | 
 |  |  |     '& .column-name': { | 
 |  |  |     }, | 
 |  |  |     '& .opt': { | 
 |  |  |         width: 200 | 
 |  |  |     }, | 
 |  |  | })); | 
 |  |  |  | 
 |  |  | const filters = [ | 
 |  |  |     <SearchInput source="condition" alwaysOn />, | 
 |  |  |     <DateInput label='common.time.after' source="timeStart" alwaysOn />, | 
 |  |  |     <DateInput label='common.time.before' source="timeEnd" alwaysOn />, | 
 |  |  |  | 
 |  |  |     <TextInput source="stationName" label="table.field.basStation.stationName" />, | 
 |  |  |     <NumberInput source="inAble" label="table.field.basStation.inAble" />, | 
 |  |  |     <NumberInput source="outAble" label="table.field.basStation.outAble" />, | 
 |  |  |     <TextInput source="useStatus" label="table.field.basStation.useStatus" />, | 
 |  |  |     <NumberInput source="area" label="table.field.basStation.area" />, | 
 |  |  |     <NumberInput source="isCrossZone" label="table.field.basStation.isCrossZone" />, | 
 |  |  |     <TextInput source="crossZoneArea" label="table.field.basStation.crossZoneArea" />, | 
 |  |  |     <NumberInput source="isWcs" label="table.field.basStation.isWcs" />, | 
 |  |  |     <TextInput source="wcsData" label="table.field.basStation.wcsData" />, | 
 |  |  |     <NumberInput source="containerType" label="table.field.basStation.containerType" />, | 
 |  |  |     <TextInput source="barcode" label="table.field.basStation.barcode" />, | 
 |  |  |     <NumberInput source="autoTransfer" label="table.field.basStation.autoTransfer" />, | 
 |  |  |  | 
 |  |  |     <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 BasStationList = () => { | 
 |  |  |     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.basStation"} | 
 |  |  |                 empty={false} | 
 |  |  |                 filters={filters} | 
 |  |  |                 sort={{ field: "create_time", order: "desc" }} | 
 |  |  |                 actions={( | 
 |  |  |                     <TopToolbar> | 
 |  |  |                         <FilterButton /> | 
 |  |  |                         <MyCreateButton onClick={() => { setCreateDialog(true) }} /> | 
 |  |  |                         <SelectColumnsButton preferenceKey='basStation' /> | 
 |  |  |                         <MyExportButton /> | 
 |  |  |                     </TopToolbar> | 
 |  |  |                 )} | 
 |  |  |                 perPage={DEFAULT_PAGE_SIZE} | 
 |  |  |             > | 
 |  |  |                 <StyledDatagrid | 
 |  |  |                     preferenceKey='basStation' | 
 |  |  |                     bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />} | 
 |  |  |                     rowClick={(id, resource, record) => false}                     | 
 |  |  |                     expandSingle={true} | 
 |  |  |                     omit={['id', 'createTime', 'createBy', 'memo']} | 
 |  |  |                 > | 
 |  |  |                     <NumberField source="id" /> | 
 |  |  |                     <TextField source="stationName" label="table.field.basStation.stationName" /> | 
 |  |  |                     <FunctionField | 
 |  |  |                         source="inAble" | 
 |  |  |                         label="table.field.basStation.inAble" | 
 |  |  |                         render={record => record.inAble === 1 ? '是' : '否'} | 
 |  |  |                     />                     | 
 |  |  |                     <FunctionField | 
 |  |  |                         source="outAble" | 
 |  |  |                         label="table.field.basStation.outAble" | 
 |  |  |                         render={record => record.inAble === 1 ? '是' : '否'} | 
 |  |  |                     /> | 
 |  |  |                     <TextField source="useStatus" label="table.field.basStation.useStatus" /> | 
 |  |  |                     <NumberField source="area$" label="table.field.basStation.area" />                     | 
 |  |  |                     <FunctionField | 
 |  |  |                         source="isCrossZone" | 
 |  |  |                         label="table.field.basStation.isCrossZone" | 
 |  |  |                         render={record => record.inAble === 1 ? '是' : '否'} | 
 |  |  |                     /> | 
 |  |  |                     <TextField source="crossZoneArea" label="table.field.basStation.crossZoneArea" />                     | 
 |  |  |                      | 
 |  |  |                     <FunctionField | 
 |  |  |                         source="isWcs" | 
 |  |  |                         label="table.field.basStation.isWcs" | 
 |  |  |                         render={record => record.inAble === 1 ? '是' : '否'} | 
 |  |  |                     />                     | 
 |  |  |                     <NumberField source="containerType$" label="table.field.basStation.containerType" /> | 
 |  |  |                     <TextField source="barcode" label="table.field.basStation.barcode" />                     | 
 |  |  |                     <FunctionField | 
 |  |  |                         source="autoTransfer" | 
 |  |  |                         label="table.field.basStation.autoTransfer" | 
 |  |  |                         render={record => record.inAble === 1 ? '是' : '否'} | 
 |  |  |                     /> | 
 |  |  |                     <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 />                     | 
 |  |  |                     <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> | 
 |  |  |             <BasStationCreate | 
 |  |  |                 open={createDialog} | 
 |  |  |                 setOpen={setCreateDialog} | 
 |  |  |             /> | 
 |  |  |             <PageDrawer | 
 |  |  |                 title='BasStation Detail' | 
 |  |  |                 drawerVal={drawerVal} | 
 |  |  |                 setDrawerVal={setDrawerVal} | 
 |  |  |             > | 
 |  |  |             </PageDrawer> | 
 |  |  |         </Box> | 
 |  |  |     ) | 
 |  |  | } | 
 |  |  |  | 
 |  |  | export default BasStationList; | 
 
| 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 BasStationPanel = () => { | 
 |  |  |     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.basStation.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.basStation.stationName"  | 
 |  |  |                                 property={record.stationName} | 
 |  |  |                             /> | 
 |  |  |                         </Grid> | 
 |  |  |                         <Grid item xs={6}> | 
 |  |  |                             <PanelTypography | 
 |  |  |                                 title="table.field.basStation.inAble"  | 
 |  |  |                                 property={record.inAble} | 
 |  |  |                             /> | 
 |  |  |                         </Grid> | 
 |  |  |                         <Grid item xs={6}> | 
 |  |  |                             <PanelTypography | 
 |  |  |                                 title="table.field.basStation.outAble"  | 
 |  |  |                                 property={record.outAble} | 
 |  |  |                             /> | 
 |  |  |                         </Grid> | 
 |  |  |                         <Grid item xs={6}> | 
 |  |  |                             <PanelTypography | 
 |  |  |                                 title="table.field.basStation.useStatus"  | 
 |  |  |                                 property={record.useStatus} | 
 |  |  |                             /> | 
 |  |  |                         </Grid> | 
 |  |  |                         <Grid item xs={6}> | 
 |  |  |                             <PanelTypography | 
 |  |  |                                 title="table.field.basStation.area"  | 
 |  |  |                                 property={record.area} | 
 |  |  |                             /> | 
 |  |  |                         </Grid> | 
 |  |  |                         <Grid item xs={6}> | 
 |  |  |                             <PanelTypography | 
 |  |  |                                 title="table.field.basStation.isCrossZone"  | 
 |  |  |                                 property={record.isCrossZone} | 
 |  |  |                             /> | 
 |  |  |                         </Grid> | 
 |  |  |                         <Grid item xs={6}> | 
 |  |  |                             <PanelTypography | 
 |  |  |                                 title="table.field.basStation.crossZoneArea"  | 
 |  |  |                                 property={record.crossZoneArea} | 
 |  |  |                             /> | 
 |  |  |                         </Grid> | 
 |  |  |                         <Grid item xs={6}> | 
 |  |  |                             <PanelTypography | 
 |  |  |                                 title="table.field.basStation.isWcs"  | 
 |  |  |                                 property={record.isWcs} | 
 |  |  |                             /> | 
 |  |  |                         </Grid> | 
 |  |  |                         <Grid item xs={6}> | 
 |  |  |                             <PanelTypography | 
 |  |  |                                 title="table.field.basStation.wcsData"  | 
 |  |  |                                 property={record.wcsData} | 
 |  |  |                             /> | 
 |  |  |                         </Grid> | 
 |  |  |                         <Grid item xs={6}> | 
 |  |  |                             <PanelTypography | 
 |  |  |                                 title="table.field.basStation.containerType"  | 
 |  |  |                                 property={record.containerType} | 
 |  |  |                             /> | 
 |  |  |                         </Grid> | 
 |  |  |                         <Grid item xs={6}> | 
 |  |  |                             <PanelTypography | 
 |  |  |                                 title="table.field.basStation.barcode"  | 
 |  |  |                                 property={record.barcode} | 
 |  |  |                             /> | 
 |  |  |                         </Grid> | 
 |  |  |                         <Grid item xs={6}> | 
 |  |  |                             <PanelTypography | 
 |  |  |                                 title="table.field.basStation.autoTransfer"  | 
 |  |  |                                 property={record.autoTransfer} | 
 |  |  |                             /> | 
 |  |  |                         </Grid> | 
 |  |  |  | 
 |  |  |                     </Grid> | 
 |  |  |                 </CardContent> | 
 |  |  |             </Card > | 
 |  |  |         </> | 
 |  |  |     ); | 
 |  |  | }; | 
 |  |  |  | 
 |  |  | export default BasStationPanel; | 
 
| New file | 
 |  |  | 
 |  |  | import * as React from 'react'; | 
 |  |  | import { Stack, Chip } from '@mui/material'; | 
 |  |  | import { useTranslate, useRecordContext } from 'react-admin'; | 
 |  |  |  | 
 |  |  | const WarehouseAreaField = () => { | 
 |  |  |     const translate = useTranslate(); | 
 |  |  |     const record = useRecordContext(); | 
 |  |  |  | 
 |  |  |     React.useEffect(() => { | 
 |  |  |  | 
 |  |  |     }, [record]); | 
 |  |  |  | 
 |  |  |     return ( | 
 |  |  |         <Stack direction="row" gap={1} flexWrap="wrap"> | 
 |  |  |             {record.areaIds?.map((item, idx) => { | 
 |  |  |                 if (item) { | 
 |  |  |                     return <Chip | 
 |  |  |                         size="small" | 
 |  |  |                         key={item.id} | 
 |  |  |                         label={item.id} | 
 |  |  |                     />; | 
 |  |  |                 } | 
 |  |  |             })} | 
 |  |  |         </Stack> | 
 |  |  |     ) | 
 |  |  | } | 
 |  |  |  | 
 |  |  | export default WarehouseAreaField; | 
 
| New file | 
 |  |  | 
 |  |  | import * as React from 'react'; | 
 |  |  | import { SelectArrayInput, useRecordContext } from 'react-admin'; | 
 |  |  | import request from '@/utils/request' | 
 |  |  |  | 
 |  |  | const WarehouseAreaSelect = (props) => { | 
 |  |  |     const [arr, setArr] = React.useState([]); | 
 |  |  |     const [loading, setLoading] = React.useState(true);     | 
 |  |  |  | 
 |  |  |     React.useEffect(() => { | 
 |  |  |         setLoading(true); | 
 |  |  |         request.post('/warehouseAreas/list', {}).then(res => { | 
 |  |  |             if (res?.data?.code === 200) { | 
 |  |  |                 setArr(res.data.data.map(item => { | 
 |  |  |                     return { | 
 |  |  |                         id: item.id, | 
 |  |  |                         name: item.name | 
 |  |  |                     } | 
 |  |  |                 })); | 
 |  |  |             } | 
 |  |  |             setLoading(false); | 
 |  |  |         }).catch(() => { | 
 |  |  |             setLoading(false); | 
 |  |  |         }); | 
 |  |  |     }, []); | 
 |  |  |  | 
 |  |  |     return ( | 
 |  |  |         <SelectArrayInput | 
 |  |  |             {...props} | 
 |  |  |             choices={arr} | 
 |  |  |             disabled={loading} | 
 |  |  |         /> | 
 |  |  |     ); | 
 |  |  | }; | 
 |  |  |  | 
 |  |  | export default WarehouseAreaSelect; | 
 
| New file | 
 |  |  | 
 |  |  | import React, { useState, useRef, useEffect, useMemo } from "react"; | 
 |  |  | import { | 
 |  |  |     ListGuesser, | 
 |  |  |     EditGuesser, | 
 |  |  |     ShowGuesser, | 
 |  |  | } from "react-admin"; | 
 |  |  |  | 
 |  |  | import BasStationList from "./BasStationList"; | 
 |  |  | import BasStationEdit from "./BasStationEdit"; | 
 |  |  |  | 
 |  |  | export default { | 
 |  |  |     list: BasStationList, | 
 |  |  |     edit: BasStationEdit, | 
 |  |  |     show: ShowGuesser, | 
 |  |  |     recordRepresentation: (record) => { | 
 |  |  |         return `${record.id}` | 
 |  |  |     } | 
 |  |  | }; | 
 
| New file | 
 |  |  | 
 |  |  | -- save basStation record | 
 |  |  | -- mysql | 
 |  |  | insert into `sys_menu` ( `name`, `parent_id`, `route`, `component`, `type`, `sort`, `tenant_id`, `status`) values ( 'menu.basStation', '0', '/manager/basStation', 'basStation', '0' , '0', '1' , '1'); | 
 |  |  |  | 
 |  |  | insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Query 站点信息', '', '1', 'manager:basStation:list', '0', '1', '1'); | 
 |  |  | insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Create 站点信息', '', '1', 'manager:basStation:save', '1', '1', '1'); | 
 |  |  | insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Update 站点信息', '', '1', 'manager:basStation:update', '2', '1', '1'); | 
 |  |  | insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Delete 站点信息', '', '1', 'manager:basStation:remove', '3', '1', '1'); | 
 |  |  |  | 
 |  |  | -- locale menu name | 
 |  |  | basStation: 'BasStation', | 
 |  |  |  | 
 |  |  | -- locale field | 
 |  |  | basStation: { | 
 |  |  |     stationName: "stationName", | 
 |  |  |     inAble: "inAble", | 
 |  |  |     outAble: "outAble", | 
 |  |  |     useStatus: "useStatus", | 
 |  |  |     area: "area", | 
 |  |  |     isCrossZone: "isCrossZone", | 
 |  |  |     crossZoneArea: "crossZoneArea", | 
 |  |  |     isWcs: "isWcs", | 
 |  |  |     wcsData: "wcsData", | 
 |  |  |     containerType: "containerType", | 
 |  |  |     barcode: "barcode", | 
 |  |  |     autoTransfer: "autoTransfer", | 
 |  |  | }, | 
 |  |  |  | 
 |  |  | -- ResourceContent | 
 |  |  | import basStation from './basStation'; | 
 |  |  |  | 
 |  |  | case 'basStation': | 
 |  |  |     return basStation; | 
 
| 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.BasStation; | 
 |  |  | import com.vincent.rsf.server.manager.service.BasStationService; | 
 |  |  | 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 BasStationController extends BaseController { | 
 |  |  |  | 
 |  |  |     @Autowired | 
 |  |  |     private BasStationService basStationService; | 
 |  |  |  | 
 |  |  |     @PreAuthorize("hasAuthority('manager:basStation:list')") | 
 |  |  |     @PostMapping("/basStation/page") | 
 |  |  |     public R page(@RequestBody Map<String, Object> map) { | 
 |  |  |         BaseParam baseParam = buildParam(map, BaseParam.class); | 
 |  |  |         PageParam<BasStation, BaseParam> pageParam = new PageParam<>(baseParam, BasStation.class); | 
 |  |  |         PageParam<BasStation, BaseParam> page = basStationService.page(pageParam, pageParam.buildWrapper(true)); | 
 |  |  |         for (BasStation station : page.getRecords()) { | 
 |  |  |             String content = station.getCrossZoneArea().substring(1, station.getCrossZoneArea().length() - 1); | 
 |  |  |             String[] parts = content.split(","); | 
 |  |  |             Long[] longArray = new Long[parts.length]; | 
 |  |  |             for (int i = 0; i < parts.length; i++) { | 
 |  |  |                 longArray[i] = Long.parseLong(parts[i].trim()); | 
 |  |  |             } | 
 |  |  |             station.setAreaIds(longArray); | 
 |  |  |         } | 
 |  |  |         return R.ok().add(page); | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     @PreAuthorize("hasAuthority('manager:basStation:list')") | 
 |  |  |     @PostMapping("/basStation/list") | 
 |  |  |     public R list(@RequestBody Map<String, Object> map) { | 
 |  |  |         return R.ok().add(basStationService.list()); | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     @PreAuthorize("hasAuthority('manager:basStation:list')") | 
 |  |  |     @PostMapping({"/basStation/many/{ids}", "/basStations/many/{ids}"}) | 
 |  |  |     public R many(@PathVariable Long[] ids) { | 
 |  |  |         return R.ok().add(basStationService.listByIds(Arrays.asList(ids))); | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     @PreAuthorize("hasAuthority('manager:basStation:list')") | 
 |  |  |     @GetMapping("/basStation/{id}") | 
 |  |  |     public R get(@PathVariable("id") Long id) { | 
 |  |  |         BasStation basStation = basStationService.getById(id); | 
 |  |  |  | 
 |  |  |  | 
 |  |  |         String content = basStation.getCrossZoneArea().substring(1, basStation.getCrossZoneArea().length() - 1); | 
 |  |  |         String[] parts = content.split(","); | 
 |  |  |         Long[] longArray = new Long[parts.length]; | 
 |  |  |         for (int i = 0; i < parts.length; i++) { | 
 |  |  |             longArray[i] = Long.parseLong(parts[i].trim()); | 
 |  |  |         } | 
 |  |  |         basStation.setAreaIds(longArray); | 
 |  |  |  | 
 |  |  |         return R.ok().add(basStation); | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     @PreAuthorize("hasAuthority('manager:basStation:save')") | 
 |  |  |     @OperationLog("Create 站点信息") | 
 |  |  |     @PostMapping("/basStation/save") | 
 |  |  |     public R save(@RequestBody BasStation basStation) { | 
 |  |  |         basStation.setCreateBy(getLoginUserId()); | 
 |  |  |         basStation.setCreateTime(new Date()); | 
 |  |  |         basStation.setUpdateBy(getLoginUserId()); | 
 |  |  |         basStation.setUpdateTime(new Date()); | 
 |  |  |         if (!basStationService.save(basStation)) { | 
 |  |  |             return R.error("保存失败"); | 
 |  |  |         } | 
 |  |  |         return R.ok("保存成功").add(basStation); | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     @PreAuthorize("hasAuthority('manager:basStation:update')") | 
 |  |  |     @OperationLog("Update 站点信息") | 
 |  |  |     @PostMapping("/basStation/update") | 
 |  |  |     public R update(@RequestBody BasStation basStation) { | 
 |  |  |         basStation.setUpdateBy(getLoginUserId()); | 
 |  |  |         basStation.setUpdateTime(new Date()); | 
 |  |  |         if (null !=basStation.getAreaIds()){ | 
 |  |  |             basStation.setCrossZoneArea(Arrays.toString(basStation.getAreaIds())); | 
 |  |  |         } | 
 |  |  |         if (!basStationService.updateById(basStation)) { | 
 |  |  |             return R.error("更新失败"); | 
 |  |  |         } | 
 |  |  |         return R.ok("更新成功").add(basStation); | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     @PreAuthorize("hasAuthority('manager:basStation:remove')") | 
 |  |  |     @OperationLog("Delete 站点信息") | 
 |  |  |     @PostMapping("/basStation/remove/{ids}") | 
 |  |  |     public R remove(@PathVariable Long[] ids) { | 
 |  |  |         if (!basStationService.removeByIds(Arrays.asList(ids))) { | 
 |  |  |             return R.error("删除失败"); | 
 |  |  |         } | 
 |  |  |         return R.ok("删除成功").add(ids); | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     @PreAuthorize("hasAuthority('manager:basStation:list')") | 
 |  |  |     @PostMapping("/basStation/query") | 
 |  |  |     public R query(@RequestParam(required = false) String condition) { | 
 |  |  |         List<KeyValVo> vos = new ArrayList<>(); | 
 |  |  |         LambdaQueryWrapper<BasStation> wrapper = new LambdaQueryWrapper<>(); | 
 |  |  |         if (!Cools.isEmpty(condition)) { | 
 |  |  |             wrapper.like(BasStation::getId, condition); | 
 |  |  |         } | 
 |  |  |         basStationService.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:basStation:list')") | 
 |  |  |     @PostMapping("/basStation/export") | 
 |  |  |     public void export(@RequestBody Map<String, Object> map, HttpServletResponse response) throws Exception { | 
 |  |  |         ExcelUtil.build(ExcelUtil.create(basStationService.list(), BasStation.class), response); | 
 |  |  |     } | 
 |  |  |  | 
 |  |  | } | 
 
| New file | 
 |  |  | 
 |  |  | package com.vincent.rsf.server.manager.entity; | 
 |  |  |  | 
 |  |  | import java.text.SimpleDateFormat; | 
 |  |  | import java.util.Arrays; | 
 |  |  | import java.util.Date; | 
 |  |  |  | 
 |  |  | import com.alibaba.fastjson.JSONArray; | 
 |  |  | import com.baomidou.mybatisplus.annotation.*; | 
 |  |  | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | 
 |  |  | import com.vincent.rsf.server.manager.service.WarehouseAreasService; | 
 |  |  | import com.vincent.rsf.server.system.entity.DictData; | 
 |  |  | import com.vincent.rsf.server.system.service.DictDataService; | 
 |  |  | import com.vincent.rsf.server.system.service.DictTypeService; | 
 |  |  | import org.springframework.format.annotation.DateTimeFormat; | 
 |  |  | import java.text.SimpleDateFormat; | 
 |  |  | import java.util.Date; | 
 |  |  |  | 
 |  |  | 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_station") | 
 |  |  | public class BasStation 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 stationName; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 可入 | 
 |  |  |      */ | 
 |  |  |     @ApiModelProperty(value= "可入") | 
 |  |  |     private Integer inAble = 0; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 可出 | 
 |  |  |      */ | 
 |  |  |     @ApiModelProperty(value= "可出") | 
 |  |  |     private Integer outAble = 0; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 状态 | 
 |  |  |      */ | 
 |  |  |     @ApiModelProperty(value= "状态") | 
 |  |  |     private String useStatus; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 所属库区id | 
 |  |  |      */ | 
 |  |  |     @ApiModelProperty(value= "所属库区id") | 
 |  |  |     private Integer area; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 是否可跨区 | 
 |  |  |      */ | 
 |  |  |     @ApiModelProperty(value= "是否可跨区") | 
 |  |  |     private Integer isCrossZone = 0; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 可跨区区域id | 
 |  |  |      */ | 
 |  |  |     @ApiModelProperty(value= "可跨区区域id") | 
 |  |  |     private String crossZoneArea; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 是否wcs站点 | 
 |  |  |      */ | 
 |  |  |     @ApiModelProperty(value= "是否wcs站点") | 
 |  |  |     private Integer isWcs = 0; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * wcs站点信息 | 
 |  |  |      */ | 
 |  |  |     @ApiModelProperty(value= "wcs站点信息") | 
 |  |  |     private String wcsData; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 容器类型 | 
 |  |  |      */ | 
 |  |  |     @ApiModelProperty(value= "容器类型") | 
 |  |  |     private Integer containerType; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 条码 | 
 |  |  |      */ | 
 |  |  |     @ApiModelProperty(value= "条码") | 
 |  |  |     private String barcode; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 是否自动调拨 | 
 |  |  |      */ | 
 |  |  |     @ApiModelProperty(value= "是否自动调拨") | 
 |  |  |     private Integer autoTransfer; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 备注 | 
 |  |  |      */ | 
 |  |  |     @ApiModelProperty(value= "备注") | 
 |  |  |     private String memo; | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 创建人 | 
 |  |  |      */ | 
 |  |  |     @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 Long tenantId; | 
 |  |  |  | 
 |  |  |     @TableField(exist = false) | 
 |  |  |     private Long[] areaIds; | 
 |  |  |  | 
 |  |  |     public BasStation() {} | 
 |  |  |  | 
 |  |  |  | 
 |  |  |  | 
 |  |  | //    BasStation basStation = new BasStation( | 
 |  |  | //            null,    // 站点名称 | 
 |  |  | //            null,    // 可入 | 
 |  |  | //            null,    // 可出 | 
 |  |  | //            null,    // 状态 | 
 |  |  | //            null,    // 所属库区id | 
 |  |  | //            null,    // 是否可跨区 | 
 |  |  | //            null,    // 可跨区区域id | 
 |  |  | //            null,    // 是否wcs站点 | 
 |  |  | //            null,    // wcs站点信息 | 
 |  |  | //            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 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 getContainerType$(){ | 
 |  |  |         if (Cools.isEmpty(this.useStatus)){ | 
 |  |  |             return ""; | 
 |  |  |         } | 
 |  |  |         DictDataService service = SpringUtils.getBean(DictDataService.class); | 
 |  |  |         DictData dictData = service.getOne(new LambdaQueryWrapper<DictData>() | 
 |  |  |                 .eq(DictData::getDictTypeCode, "sys_container_type") | 
 |  |  |                 .eq(DictData::getValue, this.containerType) | 
 |  |  |         ); | 
 |  |  |         if (!Cools.isEmpty(dictData)){ | 
 |  |  |             return String.valueOf(dictData.getLabel()); | 
 |  |  |         } | 
 |  |  |         return ""; | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     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; | 
 |  |  |     } | 
 |  |  | } | 
 
| New file | 
 |  |  | 
 |  |  | package com.vincent.rsf.server.manager.mapper; | 
 |  |  |  | 
 |  |  | import com.vincent.rsf.server.manager.entity.BasStation; | 
 |  |  | import com.baomidou.mybatisplus.core.mapper.BaseMapper; | 
 |  |  | import org.apache.ibatis.annotations.Mapper; | 
 |  |  | import org.springframework.stereotype.Repository; | 
 |  |  |  | 
 |  |  | @Mapper | 
 |  |  | @Repository | 
 |  |  | public interface BasStationMapper extends BaseMapper<BasStation> { | 
 |  |  |  | 
 |  |  | } | 
 
| New file | 
 |  |  | 
 |  |  | package com.vincent.rsf.server.manager.service; | 
 |  |  |  | 
 |  |  | import com.baomidou.mybatisplus.extension.service.IService; | 
 |  |  | import com.vincent.rsf.server.manager.entity.BasStation; | 
 |  |  |  | 
 |  |  | public interface BasStationService extends IService<BasStation> { | 
 |  |  |  | 
 |  |  | } | 
 
| New file | 
 |  |  | 
 |  |  | package com.vincent.rsf.server.manager.service.impl; | 
 |  |  |  | 
 |  |  | import com.vincent.rsf.server.manager.mapper.BasStationMapper; | 
 |  |  | import com.vincent.rsf.server.manager.entity.BasStation; | 
 |  |  | import com.vincent.rsf.server.manager.service.BasStationService; | 
 |  |  | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; | 
 |  |  | import org.springframework.stereotype.Service; | 
 |  |  |  | 
 |  |  | @Service("basStationService") | 
 |  |  | public class BasStationServiceImpl extends ServiceImpl<BasStationMapper, BasStation> implements BasStationService { | 
 |  |  |  | 
 |  |  | } | 
 
| 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.BasStationMapper"> | 
 |  |  |  | 
 |  |  | </mapper> |