#新增
1. 新增波次列表及详情
2. 新增立库站点绑定
| | |
| | | loadMore: 'Load More Data', |
| | | complete: 'Complete', |
| | | deprecate: 'Deprecate', |
| | | inputPlaceholder: 'Use commas to separate', |
| | | resend: 'RESEND', |
| | | selected: 'selected', |
| | | batch: 'batch' |
| | |
| | | outStockItem: 'Out Stock Item', |
| | | inStockPoces: 'In Stock Pocess', |
| | | outStockPoces: 'Out Stock Pocess', |
| | | deviceBind: 'Device Bind', |
| | | }, |
| | | table: { |
| | | field: { |
| | |
| | | }, |
| | | deliveryItem: { |
| | | deliveryId: "deliveryId", |
| | | deliveryCode: "Delivery Code", |
| | | platItemId: "platItemId", |
| | | matnrCode: "matnrCode", |
| | | matnrName: "matnrName", |
| | |
| | | deviceCode: "deviceCode", |
| | | deviceSite: "deviceSite", |
| | | flagInit: "flagInit", |
| | | sites: "sites", |
| | | }, |
| | | waitPakin: { |
| | | code: "code", |
| | |
| | | model: "model", |
| | | fieldsIndex: "fieldsIndex", |
| | | }, |
| | | deviceBind: { |
| | | currentRow: "currentRow", |
| | | startRow: "startRow", |
| | | endRow: "endRow", |
| | | deviceQty: "deviceQty", |
| | | startDeviceNo: "startDeviceNo", |
| | | endDeviceNo: "endDeviceNo", |
| | | staList: "staList", |
| | | typeId: "typeId", |
| | | beSimilar: "beSimilar", |
| | | emptySimilar: "emptySimilar", |
| | | }, |
| | | } |
| | | }, |
| | | page: { |
| | |
| | | asnCreate: "Create By Order", |
| | | createTask: "createTask", |
| | | recover: "recover", |
| | | createWave: "Create Wave", |
| | | order: 'Orders', |
| | | |
| | | }, |
| | |
| | | collapse: '折叠', |
| | | collapseAll: '全部折叠', |
| | | scope: '权限', |
| | | inputPlaceholder: '站点可填多个,中间以英文逗号区分(,)', |
| | | import: { |
| | | title: '导入', |
| | | stop: '停止导入', |
| | |
| | | outStockItem: '出库单明细', |
| | | inStockPoces: '入库流程', |
| | | outStockPoces: '出库流程', |
| | | deviceBind: '设备绑定', |
| | | }, |
| | | table: { |
| | | field: { |
| | |
| | | loc: { |
| | | warehouseId: "所属仓库", |
| | | areaId: "所属库区", |
| | | code: "库位编码", |
| | | type: "库位类型", |
| | | code: "编码", |
| | | type: "类型", |
| | | name: "名称", |
| | | flagLogic: "虚拟库位", |
| | | fucAtrrs: "功能属性", |
| | |
| | | }, |
| | | deliveryItem: { |
| | | deliveryId: "主单ID", |
| | | deliveryCode: "单号", |
| | | platItemId: "行号", |
| | | matnrCode: "物料编码", |
| | | matnrName: "物料名称", |
| | |
| | | }, |
| | | deviceSite: { |
| | | type: "入出库类型", |
| | | site: "站点编号", |
| | | site: "作业站点", |
| | | name: "名称", |
| | | wcsCode: "wcs站点编号", |
| | | target: "目标站点", |
| | | label: "站点标签", |
| | | device: "立库类型", |
| | | deviceCode: "设备编号", |
| | | deviceSite: "设备站点", |
| | | flagInit: "是否初始化", |
| | | sites: "作业站点", |
| | | }, |
| | | waitPakin: { |
| | | code: "编码", |
| | |
| | | model: "型号", |
| | | fieldsIndex: "动态索引", |
| | | }, |
| | | deviceBind: { |
| | | currentRow: "当前排号", |
| | | startRow: "起始排号", |
| | | endRow: "终止排号", |
| | | deviceQty: "设备数量", |
| | | startDeviceNo: "起始设备号", |
| | | endDeviceNo: "终止设备号", |
| | | staList: "站点集", |
| | | typeId: "库区类型", |
| | | beSimilar: "相似开关", |
| | | emptySimilar: "空板靠近开关", |
| | | }, |
| | | } |
| | | }, |
| | | page: { |
| | |
| | | complete: "完成", |
| | | close: "关闭", |
| | | asnCreate: "通过单据创建", |
| | | createTask: "生成任务", |
| | | createTask: "下发任务", |
| | | createWave: "生成波次", |
| | | recover: "继续收货", |
| | | }, |
| | | }; |
| | |
| | | import stock from './orders/stock'; |
| | | import delivery from './orders/delivery'; |
| | | import outStock from './orders/outStock'; |
| | | import deviceBind from './deviceBind'; |
| | | |
| | | |
| | | const ResourceContent = (node) => { |
| | |
| | | return delivery; |
| | | case 'outStock': |
| | | return outStock; |
| | | case 'deviceBind': |
| | | return deviceBind; |
| | | default: |
| | | return { |
| | | list: ListGuesser, |
| | |
| | | preferenceKey='deviceSite' |
| | | bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />} |
| | | rowClick={(id, resource, record) => false} |
| | | omit={['id', 'createTime', 'createBy', 'memo']} |
| | | omit={['id', 'createTime', 'createBy', 'memo', 'label']} |
| | | > |
| | | <NumberField source="id" /> |
| | | <TextField source="name" label="table.field.deviceSite.name" /> |
| | | <NumberField source="type$" label="table.field.deviceSite.type" /> |
| | | <TextField source="site" label="table.field.deviceSite.site" /> |
| | | <TextField source="wcsCode" label="table.field.deviceSite.wcsCode" /> |
| | | <TextField source="target" label="table.field.deviceSite.target" /> |
| | | <TextField source="label" label="table.field.deviceSite.label" /> |
| | | <TextField source="device$" label="table.field.deviceSite.device" /> |
| | | <TextField source="deviceCode" label="table.field.deviceSite.deviceCode" /> |
| | | <TextField source="deviceSite" label="table.field.deviceSite.deviceSite" /> |
| | | |
| | | <ReferenceField source="updateBy" label="common.field.updateBy" reference="user" link={false} sortable={false}> |
| | | <TextField source="nickname" /> |
| | | </ReferenceField> |
| | |
| | | |
| | | |
| | | return ( |
| | | <Dialog open={open} maxWidth="md" fullWidth> |
| | | <Dialog open={open} maxWidth="lg" fullWidth> |
| | | <Form onSubmit={handleSubmit}> |
| | | <DialogCloseButton onClose={handleClose} /> |
| | | <DialogTitle>{translate('toolbar.siteInit')}</DialogTitle> |
| | |
| | | dictTypeCode="sys_device_type" |
| | | /> |
| | | </Grid> |
| | | |
| | | |
| | | <Grid item xs={4}> |
| | | <TextInput |
| | | label={translate("table.field.deviceSite.deviceCode")} |
| | |
| | | type="number" |
| | | /> |
| | | </Grid> |
| | | |
| | | <Grid item xs={4}> |
| | | <TextInput |
| | | label={translate("table.field.deviceSite.deviceSite")} |
| | | name="deviceSites" |
| | | placeholder={translate('common.action.inputPlaceholder')} |
| | | size="small" |
| | | type="number" |
| | | // type="number" |
| | | /> |
| | | </Grid> |
| | | |
| | | <Grid item xs={4}> |
| | | <TextInput |
| | | label={translate("table.field.deviceSite.sites")} |
| | | name="sites" |
| | | label={translate("table.field.deviceSite.site")} |
| | | name="site" |
| | | placeholder={translate('common.action.inputPlaceholder')} |
| | | size="small" |
| | | type="number" |
| | | // type="number" |
| | | /> |
| | | </Grid> |
| | | |
| | | <Grid item xs={4}> |
| | | <TextInput |
| | | label={translate("table.field.deviceSite.target")} |
| | | name="target" |
| | | placeholder={translate('common.action.inputPlaceholder')} |
| | | size="small" |
| | | // type="number" |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={4}> |
| | | <SelectInput |
| | | label="table.field.deviceSite.flagInit" |
| | |
| | | '& .column-name': { |
| | | }, |
| | | '& .opt': { |
| | | width: 200 |
| | | width: 180 |
| | | }, |
| | | '& .RaDatagrid-headerCell': { |
| | | textAlign: 'left' |
| | | }, |
| | | '& .RaDatagrid-rowCell': { |
| | | textAlign: 'left' |
| | | }, |
| | | // '& .RaDatagrid-headerCell': { |
| | | // textAlign: 'left' |
| | | // }, |
| | | // '& .RaDatagrid-rowCell': { |
| | | // textAlign: 'left' |
| | | // }, |
| | | '& .type .MuiTypography-root': { |
| | | whiteSpace: 'nowrap', |
| | | overflow: 'hidden', |
| | | textOverflow: 'ellipsis', |
| | | display: 'block', |
| | | width: '200px', |
| | | width: 'auto', |
| | | }, |
| | | })); |
| | | |
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 DeviceBindCreate = (props) => { |
| | | const { open, setOpen } = props; |
| | | |
| | | const translate = useTranslate(); |
| | | const notify = useNotify(); |
| | | |
| | | const handleClose = (event, reason) => { |
| | | if (reason !== "backdropClick") { |
| | | setOpen(false); |
| | | } |
| | | }; |
| | | |
| | | const handleSuccess = async (data) => { |
| | | setOpen(false); |
| | | notify('common.response.success'); |
| | | }; |
| | | |
| | | const handleError = async (error) => { |
| | | notify(error.message || 'common.response.fail', { type: 'error', messageArgs: { _: error.message } }); |
| | | }; |
| | | |
| | | return ( |
| | | <> |
| | | <CreateBase |
| | | record={{}} |
| | | transform={(data) => { |
| | | return data; |
| | | }} |
| | | mutationOptions={{ onSuccess: handleSuccess, onError: handleError }} |
| | | > |
| | | <Dialog |
| | | open={open} |
| | | onClose={handleClose} |
| | | aria-labelledby="form-dialog-title" |
| | | fullWidth |
| | | disableRestoreFocus |
| | | maxWidth="md" // 'xs' | 'sm' | 'md' | 'lg' | 'xl' |
| | | > |
| | | <Form> |
| | | <DialogTitle id="form-dialog-title" sx={{ |
| | | position: 'sticky', |
| | | top: 0, |
| | | backgroundColor: 'background.paper', |
| | | zIndex: 1000 |
| | | }} |
| | | > |
| | | {translate('create.title')} |
| | | <Box sx={{ position: 'absolute', top: 8, right: 8, zIndex: 1001 }}> |
| | | <DialogCloseButton onClose={handleClose} /> |
| | | </Box> |
| | | </DialogTitle> |
| | | <DialogContent sx={{ mt: 2 }}> |
| | | <Grid container rowSpacing={2} columnSpacing={2}> |
| | | <Grid item xs={6} display="flex" gap={1}> |
| | | <NumberInput |
| | | label="table.field.deviceBind.currentRow" |
| | | source="currentRow" |
| | | autoFocus |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6} display="flex" gap={1}> |
| | | <NumberInput |
| | | label="table.field.deviceBind.startRow" |
| | | source="startRow" |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6} display="flex" gap={1}> |
| | | <NumberInput |
| | | label="table.field.deviceBind.endRow" |
| | | source="endRow" |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6} display="flex" gap={1}> |
| | | <NumberInput |
| | | label="table.field.deviceBind.deviceQty" |
| | | source="deviceQty" |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6} display="flex" gap={1}> |
| | | <NumberInput |
| | | label="table.field.deviceBind.startDeviceNo" |
| | | source="startDeviceNo" |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6} display="flex" gap={1}> |
| | | <NumberInput |
| | | label="table.field.deviceBind.endDeviceNo" |
| | | source="endDeviceNo" |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6} display="flex" gap={1}> |
| | | <TextInput |
| | | label="table.field.deviceBind.staList" |
| | | source="staList" |
| | | parse={v => v} |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6} display="flex" gap={1}> |
| | | <NumberInput |
| | | label="table.field.deviceBind.typeId" |
| | | source="typeId" |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6} display="flex" gap={1}> |
| | | <TextInput |
| | | label="table.field.deviceBind.beSimilar" |
| | | source="beSimilar" |
| | | parse={v => v} |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6} display="flex" gap={1}> |
| | | <TextInput |
| | | label="table.field.deviceBind.emptySimilar" |
| | | source="emptySimilar" |
| | | parse={v => v} |
| | | /> |
| | | </Grid> |
| | | |
| | | <Grid item xs={6} display="flex" gap={1}> |
| | | <StatusSelectInput /> |
| | | </Grid> |
| | | <Grid item xs={12} display="flex" gap={1}> |
| | | <Stack direction="column" spacing={1} width={'100%'}> |
| | | <MemoInput /> |
| | | </Stack> |
| | | </Grid> |
| | | </Grid> |
| | | </DialogContent> |
| | | <DialogActions sx={{ position: 'sticky', bottom: 0, backgroundColor: 'background.paper', zIndex: 1000 }}> |
| | | <Toolbar sx={{ width: '100%', justifyContent: 'space-between' }} > |
| | | <SaveButton /> |
| | | </Toolbar> |
| | | </DialogActions> |
| | | </Form> |
| | | </Dialog> |
| | | </CreateBase> |
| | | </> |
| | | ) |
| | | } |
| | | |
| | | export default DeviceBindCreate; |
New file |
| | |
| | | import React, { useState, useRef, useEffect, useMemo } from "react"; |
| | | import { |
| | | Edit, |
| | | SimpleForm, |
| | | FormDataConsumer, |
| | | useTranslate, |
| | | TextInput, |
| | | NumberInput, |
| | | BooleanInput, |
| | | DateInput, |
| | | SelectInput, |
| | | ReferenceInput, |
| | | ReferenceArrayInput, |
| | | AutocompleteInput, |
| | | SaveButton, |
| | | Toolbar, |
| | | Labeled, |
| | | NumberField, |
| | | required, |
| | | useRecordContext, |
| | | DeleteButton, |
| | | } from 'react-admin'; |
| | | import { useWatch, useFormContext } from "react-hook-form"; |
| | | import { Stack, Grid, Box, Typography } from '@mui/material'; |
| | | import * as Common from '@/utils/common'; |
| | | import { EDIT_MODE, REFERENCE_INPUT_PAGESIZE } from '@/config/setting'; |
| | | import EditBaseAside from "../components/EditBaseAside"; |
| | | import CustomerTopToolBar from "../components/EditTopToolBar"; |
| | | import MemoInput from "../components/MemoInput"; |
| | | import StatusSelectInput from "../components/StatusSelectInput"; |
| | | |
| | | const FormToolbar = () => { |
| | | const { getValues } = useFormContext(); |
| | | |
| | | return ( |
| | | <Toolbar sx={{ justifyContent: 'space-between' }}> |
| | | <SaveButton /> |
| | | <DeleteButton mutationMode="optimistic" /> |
| | | </Toolbar> |
| | | ) |
| | | } |
| | | |
| | | const DeviceBindEdit = () => { |
| | | const translate = useTranslate(); |
| | | |
| | | return ( |
| | | <Edit |
| | | redirect="list" |
| | | mutationMode={EDIT_MODE} |
| | | actions={<CustomerTopToolBar />} |
| | | aside={<EditBaseAside />} |
| | | > |
| | | <SimpleForm |
| | | shouldUnregister |
| | | warnWhenUnsavedChanges |
| | | toolbar={<FormToolbar />} |
| | | mode="onTouched" |
| | | defaultValues={{}} |
| | | // validate={(values) => { }} |
| | | > |
| | | <Grid container width={{ xs: '100%', xl: '80%' }} rowSpacing={3} columnSpacing={3}> |
| | | <Grid item xs={12} md={8}> |
| | | <Typography variant="h6" gutterBottom> |
| | | {translate('common.edit.title.main')} |
| | | </Typography> |
| | | <Stack direction='row' gap={2}> |
| | | <NumberInput |
| | | label="table.field.deviceBind.currentRow" |
| | | source="currentRow" |
| | | autoFocus |
| | | /> |
| | | </Stack> |
| | | <Stack direction='row' gap={2}> |
| | | <NumberInput |
| | | label="table.field.deviceBind.startRow" |
| | | source="startRow" |
| | | /> |
| | | </Stack> |
| | | <Stack direction='row' gap={2}> |
| | | <NumberInput |
| | | label="table.field.deviceBind.endRow" |
| | | source="endRow" |
| | | /> |
| | | </Stack> |
| | | <Stack direction='row' gap={2}> |
| | | <NumberInput |
| | | label="table.field.deviceBind.deviceQty" |
| | | source="deviceQty" |
| | | /> |
| | | </Stack> |
| | | <Stack direction='row' gap={2}> |
| | | <NumberInput |
| | | label="table.field.deviceBind.startDeviceNo" |
| | | source="startDeviceNo" |
| | | /> |
| | | </Stack> |
| | | <Stack direction='row' gap={2}> |
| | | <NumberInput |
| | | label="table.field.deviceBind.endDeviceNo" |
| | | source="endDeviceNo" |
| | | /> |
| | | </Stack> |
| | | <Stack direction='row' gap={2}> |
| | | <TextInput |
| | | label="table.field.deviceBind.staList" |
| | | source="staList" |
| | | parse={v => v} |
| | | /> |
| | | </Stack> |
| | | <Stack direction='row' gap={2}> |
| | | <NumberInput |
| | | label="table.field.deviceBind.typeId" |
| | | source="typeId" |
| | | /> |
| | | </Stack> |
| | | <Stack direction='row' gap={2}> |
| | | <TextInput |
| | | label="table.field.deviceBind.beSimilar" |
| | | source="beSimilar" |
| | | parse={v => v} |
| | | /> |
| | | </Stack> |
| | | <Stack direction='row' gap={2}> |
| | | <TextInput |
| | | label="table.field.deviceBind.emptySimilar" |
| | | source="emptySimilar" |
| | | parse={v => v} |
| | | /> |
| | | </Stack> |
| | | |
| | | </Grid> |
| | | <Grid item xs={12} md={4}> |
| | | <Typography variant="h6" gutterBottom> |
| | | {translate('common.edit.title.common')} |
| | | </Typography> |
| | | <StatusSelectInput /> |
| | | <Box mt="2em" /> |
| | | <MemoInput /> |
| | | </Grid> |
| | | </Grid> |
| | | </SimpleForm> |
| | | </Edit > |
| | | ) |
| | | } |
| | | |
| | | export default DeviceBindEdit; |
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 DeviceBindCreate from "./DeviceBindCreate"; |
| | | import DeviceBindPanel from "./DeviceBindPanel"; |
| | | import EmptyData from "../components/EmptyData"; |
| | | import MyCreateButton from "../components/MyCreateButton"; |
| | | import MyExportButton from '../components/MyExportButton'; |
| | | import PageDrawer from "../components/PageDrawer"; |
| | | import MyField from "../components/MyField"; |
| | | import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting'; |
| | | import * as Common from '@/utils/common'; |
| | | |
| | | const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({ |
| | | '& .css-1vooibu-MuiSvgIcon-root': { |
| | | height: '.9em' |
| | | }, |
| | | '& .RaDatagrid-row': { |
| | | cursor: 'auto' |
| | | }, |
| | | '& .column-name': { |
| | | }, |
| | | '& .opt': { |
| | | width: 200 |
| | | }, |
| | | })); |
| | | |
| | | const filters = [ |
| | | <SearchInput source="condition" alwaysOn />, |
| | | <DateInput label='common.time.after' source="timeStart" alwaysOn />, |
| | | <DateInput label='common.time.before' source="timeEnd" alwaysOn />, |
| | | |
| | | <NumberInput source="currentRow" label="table.field.deviceBind.currentRow" />, |
| | | <NumberInput source="startRow" label="table.field.deviceBind.startRow" />, |
| | | <NumberInput source="endRow" label="table.field.deviceBind.endRow" />, |
| | | <NumberInput source="deviceQty" label="table.field.deviceBind.deviceQty" />, |
| | | <NumberInput source="startDeviceNo" label="table.field.deviceBind.startDeviceNo" />, |
| | | <NumberInput source="endDeviceNo" label="table.field.deviceBind.endDeviceNo" />, |
| | | <TextInput source="staList" label="table.field.deviceBind.staList" />, |
| | | <NumberInput source="typeId" label="table.field.deviceBind.typeId" />, |
| | | <TextInput source="beSimilar" label="table.field.deviceBind.beSimilar" />, |
| | | <TextInput source="emptySimilar" label="table.field.deviceBind.emptySimilar" />, |
| | | |
| | | <TextInput label="common.field.memo" source="memo" />, |
| | | <SelectInput |
| | | label="common.field.status" |
| | | source="status" |
| | | choices={[ |
| | | { id: '1', name: 'common.enums.statusTrue' }, |
| | | { id: '0', name: 'common.enums.statusFalse' }, |
| | | ]} |
| | | resettable |
| | | />, |
| | | ] |
| | | |
| | | const DeviceBindList = () => { |
| | | const translate = useTranslate(); |
| | | |
| | | const [createDialog, setCreateDialog] = useState(false); |
| | | const [drawerVal, setDrawerVal] = useState(false); |
| | | |
| | | return ( |
| | | <Box display="flex"> |
| | | <List |
| | | sx={{ |
| | | flexGrow: 1, |
| | | transition: (theme) => |
| | | theme.transitions.create(['all'], { |
| | | duration: theme.transitions.duration.enteringScreen, |
| | | }), |
| | | marginRight: !!drawerVal ? `${PAGE_DRAWER_WIDTH}px` : 0, |
| | | }} |
| | | title={"menu.deviceBind"} |
| | | empty={<EmptyData onClick={() => { setCreateDialog(true) }} />} |
| | | filters={filters} |
| | | sort={{ field: "create_time", order: "desc" }} |
| | | actions={( |
| | | <TopToolbar> |
| | | <FilterButton /> |
| | | <MyCreateButton onClick={() => { setCreateDialog(true) }} /> |
| | | <SelectColumnsButton preferenceKey='deviceBind' /> |
| | | <MyExportButton /> |
| | | </TopToolbar> |
| | | )} |
| | | perPage={DEFAULT_PAGE_SIZE} |
| | | > |
| | | <StyledDatagrid |
| | | preferenceKey='deviceBind' |
| | | bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />} |
| | | rowClick={(id, resource, record) => false} |
| | | expand={() => <DeviceBindPanel />} |
| | | expandSingle={true} |
| | | omit={['id', 'createTime', 'createBy', 'memo']} |
| | | > |
| | | <NumberField source="id" /> |
| | | <NumberField source="currentRow" label="table.field.deviceBind.currentRow" /> |
| | | <NumberField source="startRow" label="table.field.deviceBind.startRow" /> |
| | | <NumberField source="endRow" label="table.field.deviceBind.endRow" /> |
| | | <NumberField source="deviceQty" label="table.field.deviceBind.deviceQty" /> |
| | | <NumberField source="startDeviceNo" label="table.field.deviceBind.startDeviceNo" /> |
| | | <NumberField source="endDeviceNo" label="table.field.deviceBind.endDeviceNo" /> |
| | | <TextField source="staList" label="table.field.deviceBind.staList" /> |
| | | <NumberField source="typeId" label="table.field.deviceBind.typeId" /> |
| | | <TextField source="beSimilar" label="table.field.deviceBind.beSimilar" /> |
| | | <TextField source="emptySimilar" label="table.field.deviceBind.emptySimilar" /> |
| | | |
| | | <ReferenceField source="updateBy" label="common.field.updateBy" reference="user" link={false} sortable={false}> |
| | | <TextField source="nickname" /> |
| | | </ReferenceField> |
| | | <DateField source="updateTime" label="common.field.updateTime" showTime /> |
| | | <ReferenceField source="createBy" label="common.field.createBy" reference="user" link={false} sortable={false}> |
| | | <TextField source="nickname" /> |
| | | </ReferenceField> |
| | | <DateField source="createTime" label="common.field.createTime" showTime /> |
| | | <BooleanField source="statusBool" label="common.field.status" sortable={false} /> |
| | | <TextField source="memo" label="common.field.memo" sortable={false} /> |
| | | <WrapperField cellClassName="opt" label="common.field.opt"> |
| | | <EditButton sx={{ padding: '1px', fontSize: '.75rem' }} /> |
| | | <DeleteButton sx={{ padding: '1px', fontSize: '.75rem' }} mutationMode={OPERATE_MODE} /> |
| | | </WrapperField> |
| | | </StyledDatagrid> |
| | | </List> |
| | | <DeviceBindCreate |
| | | open={createDialog} |
| | | setOpen={setCreateDialog} |
| | | /> |
| | | <PageDrawer |
| | | title='DeviceBind Detail' |
| | | drawerVal={drawerVal} |
| | | setDrawerVal={setDrawerVal} |
| | | > |
| | | </PageDrawer> |
| | | </Box> |
| | | ) |
| | | } |
| | | |
| | | export default DeviceBindList; |
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 DeviceBindPanel = () => { |
| | | const record = useRecordContext(); |
| | | if (!record) return null; |
| | | const translate = useTranslate(); |
| | | return ( |
| | | <> |
| | | <Card sx={{ width: { xs: 300, sm: 500, md: 600, lg: 800 }, margin: 'auto' }}> |
| | | <CardContent> |
| | | <Grid container spacing={2}> |
| | | <Grid item xs={12} sx={{ display: 'flex', justifyContent: 'space-between' }}> |
| | | <Typography variant="h6" gutterBottom align="left" sx={{ |
| | | maxWidth: { xs: '100px', sm: '180px', md: '260px', lg: '360px' }, |
| | | whiteSpace: 'nowrap', |
| | | overflow: 'hidden', |
| | | textOverflow: 'ellipsis', |
| | | }}> |
| | | {Common.camelToPascalWithSpaces(translate('table.field.deviceBind.id'))}: {record.id} |
| | | </Typography> |
| | | {/* inherit, primary, secondary, textPrimary, textSecondary, error */} |
| | | <Typography variant="h6" gutterBottom align="right" > |
| | | ID: {record.id} |
| | | </Typography> |
| | | </Grid> |
| | | </Grid> |
| | | <Grid container spacing={2}> |
| | | <Grid item xs={12} container alignContent="flex-end"> |
| | | <Typography variant="caption" color="textSecondary" sx={{ wordWrap: 'break-word', wordBreak: 'break-all' }}> |
| | | {Common.camelToPascalWithSpaces(translate('common.field.memo'))}:{record.memo} |
| | | </Typography> |
| | | </Grid> |
| | | </Grid> |
| | | <Box height={20}> </Box> |
| | | <Grid container spacing={2}> |
| | | <Grid item xs={6}> |
| | | <PanelTypography |
| | | title="table.field.deviceBind.currentRow" |
| | | property={record.currentRow} |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6}> |
| | | <PanelTypography |
| | | title="table.field.deviceBind.startRow" |
| | | property={record.startRow} |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6}> |
| | | <PanelTypography |
| | | title="table.field.deviceBind.endRow" |
| | | property={record.endRow} |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6}> |
| | | <PanelTypography |
| | | title="table.field.deviceBind.deviceQty" |
| | | property={record.deviceQty} |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6}> |
| | | <PanelTypography |
| | | title="table.field.deviceBind.startDeviceNo" |
| | | property={record.startDeviceNo} |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6}> |
| | | <PanelTypography |
| | | title="table.field.deviceBind.endDeviceNo" |
| | | property={record.endDeviceNo} |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6}> |
| | | <PanelTypography |
| | | title="table.field.deviceBind.staList" |
| | | property={record.staList} |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6}> |
| | | <PanelTypography |
| | | title="table.field.deviceBind.typeId" |
| | | property={record.typeId} |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6}> |
| | | <PanelTypography |
| | | title="table.field.deviceBind.beSimilar" |
| | | property={record.beSimilar} |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6}> |
| | | <PanelTypography |
| | | title="table.field.deviceBind.emptySimilar" |
| | | property={record.emptySimilar} |
| | | /> |
| | | </Grid> |
| | | |
| | | </Grid> |
| | | </CardContent> |
| | | </Card > |
| | | </> |
| | | ); |
| | | }; |
| | | |
| | | export default DeviceBindPanel; |
New file |
| | |
| | | import React, { useState, useRef, useEffect, useMemo } from "react"; |
| | | import { |
| | | ListGuesser, |
| | | EditGuesser, |
| | | ShowGuesser, |
| | | } from "react-admin"; |
| | | |
| | | import DeviceBindList from "./DeviceBindList"; |
| | | import DeviceBindEdit from "./DeviceBindEdit"; |
| | | |
| | | export default { |
| | | list: DeviceBindList, |
| | | edit: DeviceBindEdit, |
| | | show: ShowGuesser, |
| | | recordRepresentation: (record) => { |
| | | return `${record.id}` |
| | | } |
| | | }; |
| | |
| | | import OutOrderCreate from "./OutOrderCreate"; |
| | | import AddIcon from '@mui/icons-material/Add'; |
| | | import OutOrderModal from "./OutOrderModal"; |
| | | import PublicIcon from '@mui/icons-material/Public'; |
| | | |
| | | const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({ |
| | | '& .css-1vooibu-MuiSvgIcon-root': { |
| | |
| | | <MyCreateButton onClick={() => { setManualDialog(true) }} /> |
| | | <SelectColumnsButton preferenceKey='outStock' /> |
| | | <ImportButton value={'asnOrderItem'} /> |
| | | <MyExportButton /> |
| | | {/* <MyExportButton /> */} |
| | | </TopToolbar> |
| | | )} |
| | | perPage={DEFAULT_PAGE_SIZE} |
| | |
| | | preferenceKey='outStock' |
| | | bulkActionButtons={ |
| | | <> |
| | | <PublicTaskButton /> |
| | | <MyExportButton /> |
| | | <BulkDeleteButton mutationMode={OPERATE_MODE} |
| | | /> |
| | |
| | | } |
| | | export default OutOrderList; |
| | | |
| | | |
| | | const PublicTaskButton = () => { |
| | | const record = useRecordContext(); |
| | | const { selectedIds, onUnselectItems } = useListContext(); |
| | | |
| | | const pubClick = (event) => { |
| | | event.stopPropagation(); |
| | | onUnselectItems(); |
| | | |
| | | } |
| | | |
| | | return ( |
| | | <Button |
| | | onClick={pubClick} |
| | | label={"toolbar.createWave"} |
| | | startIcon={<PublicIcon />} |
| | | />); |
| | | } |
| | | |
| | | const MyButton = ({ setCreateDialog, setmodalType }) => { |
| | | const record = useRecordContext(); |
| | | const handleEditClick = (btn) => { |
| | |
| | | const refresh = useRefresh(); |
| | | |
| | | const createByOrder = async (event) => { |
| | | const {selectedIds, onUnselectItems} = useListContext(); |
| | | event.stopPropagation(); |
| | | setCreateDialog(true); |
| | | const res = await request.post(`/outStock/generate/wave`, { ids: selectedIds }); |
| | | if (res?.data?.code === 200) { |
| | | notify(res.data.msg); |
| | | } else { |
| | | notify(res.data.msg); |
| | | } |
| | | |
| | | } |
| | | |
| | | return ( |
| | |
| | | const record = useRecordContext(); |
| | | const notify = useNotify(); |
| | | const refresh = useRefresh(); |
| | | console.log(record); |
| | | |
| | | const cancelOrder = async () => { |
| | | const { data: { code, data, msg } } = await request.get(`/outStock/cancel/${record?.id}`); |
| | |
| | | '& .RaDatagrid-row': { |
| | | cursor: 'auto' |
| | | }, |
| | | '& .column-name': { |
| | | }, |
| | | '& .opt': { |
| | | width: 220 |
| | | }, |
| | | '& .wkType': { |
| | | width: 110 |
| | | }, |
| | | '& .status': { |
| | | width: 90 |
| | | }, |
| | |
| | | const { filterValues, setFilters, refetch } = useListContext('deliveryItem'); |
| | | const [formValues, setFormValues] = useState(filterValues); |
| | | const handleChange = (event) => { |
| | | if (event.target == undefined || event.target == null) {return} |
| | | setFormValues(formValues => ({ |
| | | ...formValues, |
| | | [event.target.name]: event.target.value |
| | | [event.target.name]: event.target.value |
| | | })); |
| | | }; |
| | | |
| | |
| | | </Stack> |
| | | <Stack> |
| | | <TextInput |
| | | source="deliveryCode" |
| | | label="table.field.deliveryItem.deliveryCode" |
| | | defaultValue={params?.matnrName} |
| | | onChange={handleChange} |
| | | resettable |
| | | |
| | | /> |
| | | </Stack> |
| | | <Stack> |
| | | <TextInput |
| | | source="matnrName" |
| | | label="table.field.deliveryItem.matnrName" |
| | | defaultValue={params?.matnrName} |
| | | onChange={handleChange} |
| | | resettable |
| | | |
| | | /> |
| | | </Stack> |
| | | <Stack> |
| | |
| | | source="matnrCode" |
| | | label="table.field.deliveryItem.matnrCode" |
| | | defaultValue={params?.matnrCode} |
| | | resettable |
| | | onChange={handleChange} /> |
| | | </Stack> |
| | | <Stack> |
| | |
| | | source="splrName" |
| | | label="table.field.deliveryItem.splrName" |
| | | defaultValue={params?.splrName} |
| | | resettable |
| | | onChange={handleChange} /> |
| | | </Stack> |
| | | </Grid> |
| | |
| | | aria-hidden |
| | | fullWidth |
| | | disableRestoreFocus |
| | | maxWidth="lg" |
| | | maxWidth="xl" |
| | | > |
| | | <DialogTitle id="form-dialog-title" sx={{ |
| | | position: 'sticky', |
| | |
| | | perPage={DEFAULT_PAGE_SIZE} |
| | | > |
| | | <StyledDatagrid |
| | | sx={{ height: '400' }} |
| | | preferenceKey='deliveryItem' |
| | | bulkActionButtons={<AddOutStockButton setOpen={setOpen}/>} |
| | | bulkActionButtons={<AddOutStockButton setOpen={setOpen} />} |
| | | rowClick={(id, resource, record) => false} |
| | | expand={false} |
| | | expandSingle={true} |
| | | omit={['id', 'createTime', 'createBy', 'memo', 'workQty', 'startTime', 'endTime', 'updateBy', 'createTime']} |
| | | > |
| | | <NumberField source="id" /> |
| | | <TextField source="deliveryCode" label="table.field.deliveryItem.deliveryCode" /> |
| | | <TextField source="matnrCode" label="table.field.deliveryItem.matnrCode" /> |
| | | <TextField source="matnrName" label="table.field.deliveryItem.matnrName" /> |
| | | <TextField source="unit" label="table.field.deliveryItem.unit" /> |
| | |
| | | const { selectedIds, onUnselectItems } = useListContext(); |
| | | const notify = useNotify(); |
| | | const confirm = async (event) => { |
| | | console.log(selectedIds); |
| | | const res = await request.post(`/outStock/generate/orders`, {ids: selectedIds}); |
| | | const res = await request.post(`/outStock/generate/orders`, { ids: selectedIds }); |
| | | if (res?.data?.code === 200) { |
| | | notify(res.data.msg); |
| | | } else { |
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 WaveCreate = (props) => { |
| | | const { open, setOpen } = props; |
| | | |
| | | const translate = useTranslate(); |
| | | const notify = useNotify(); |
| | | |
| | | const handleClose = (event, reason) => { |
| | | if (reason !== "backdropClick") { |
| | | setOpen(false); |
| | | } |
| | | }; |
| | | |
| | | const handleSuccess = async (data) => { |
| | | setOpen(false); |
| | | notify('common.response.success'); |
| | | }; |
| | | |
| | | const handleError = async (error) => { |
| | | notify(error.message || 'common.response.fail', { type: 'error', messageArgs: { _: error.message } }); |
| | | }; |
| | | |
| | | return ( |
| | | <> |
| | | <CreateBase |
| | | record={{}} |
| | | transform={(data) => { |
| | | return data; |
| | | }} |
| | | mutationOptions={{ onSuccess: handleSuccess, onError: handleError }} |
| | | > |
| | | <Dialog |
| | | open={open} |
| | | onClose={handleClose} |
| | | aria-labelledby="form-dialog-title" |
| | | fullWidth |
| | | disableRestoreFocus |
| | | maxWidth="md" // 'xs' | 'sm' | 'md' | 'lg' | 'xl' |
| | | > |
| | | <Form> |
| | | <DialogTitle id="form-dialog-title" sx={{ |
| | | position: 'sticky', |
| | | top: 0, |
| | | backgroundColor: 'background.paper', |
| | | zIndex: 1000 |
| | | }} |
| | | > |
| | | {translate('create.title')} |
| | | <Box sx={{ position: 'absolute', top: 8, right: 8, zIndex: 1001 }}> |
| | | <DialogCloseButton onClose={handleClose} /> |
| | | </Box> |
| | | </DialogTitle> |
| | | <DialogContent sx={{ mt: 2 }}> |
| | | <Grid container rowSpacing={2} columnSpacing={2}> |
| | | <Grid item xs={6} display="flex" gap={1}> |
| | | <TextInput |
| | | label="table.field.wave.code" |
| | | source="code" |
| | | parse={v => v} |
| | | autoFocus |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6} display="flex" gap={1}> |
| | | <SelectInput |
| | | label="table.field.wave.type" |
| | | source="type" |
| | | choices={[ |
| | | { id: 0, name: '手动' }, |
| | | { id: 1, name: '自动' }, |
| | | ]} |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6} display="flex" gap={1}> |
| | | <SelectInput |
| | | label="table.field.wave.exceStatus" |
| | | source="exceStatus" |
| | | choices={[ |
| | | { id: 0, name: '初始化' }, |
| | | { id: 1, name: '生成任务' }, |
| | | { id: 2, name: '任务播种' }, |
| | | { id: 3, name: '完成' }, |
| | | ]} |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6} display="flex" gap={1}> |
| | | <NumberInput |
| | | label="table.field.wave.anfme" |
| | | source="anfme" |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6} display="flex" gap={1}> |
| | | <NumberInput |
| | | label="table.field.wave.qty" |
| | | source="qty" |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6} display="flex" gap={1}> |
| | | <NumberInput |
| | | label="table.field.wave.orderNum" |
| | | source="orderNum" |
| | | /> |
| | | </Grid> |
| | | |
| | | <Grid item xs={6} display="flex" gap={1}> |
| | | <StatusSelectInput /> |
| | | </Grid> |
| | | <Grid item xs={12} display="flex" gap={1}> |
| | | <Stack direction="column" spacing={1} width={'100%'}> |
| | | <MemoInput /> |
| | | </Stack> |
| | | </Grid> |
| | | </Grid> |
| | | </DialogContent> |
| | | <DialogActions sx={{ position: 'sticky', bottom: 0, backgroundColor: 'background.paper', zIndex: 1000 }}> |
| | | <Toolbar sx={{ width: '100%', justifyContent: 'space-between' }} > |
| | | <SaveButton /> |
| | | </Toolbar> |
| | | </DialogActions> |
| | | </Form> |
| | | </Dialog> |
| | | </CreateBase> |
| | | </> |
| | | ) |
| | | } |
| | | |
| | | export default WaveCreate; |
New file |
| | |
| | | import React, { useState, useRef, useEffect, useMemo } from "react"; |
| | | import { |
| | | Edit, |
| | | SimpleForm, |
| | | FormDataConsumer, |
| | | useTranslate, |
| | | TextInput, |
| | | NumberInput, |
| | | BooleanInput, |
| | | DateInput, |
| | | SelectInput, |
| | | ReferenceInput, |
| | | ReferenceArrayInput, |
| | | AutocompleteInput, |
| | | SaveButton, |
| | | Toolbar, |
| | | Labeled, |
| | | NumberField, |
| | | required, |
| | | useRecordContext, |
| | | DeleteButton, |
| | | } from 'react-admin'; |
| | | import { useWatch, useFormContext } from "react-hook-form"; |
| | | import { Stack, Grid, Box, Typography } from '@mui/material'; |
| | | import * as Common from '@/utils/common'; |
| | | import { EDIT_MODE, REFERENCE_INPUT_PAGESIZE } from '@/config/setting'; |
| | | import EditBaseAside from "../components/EditBaseAside"; |
| | | import CustomerTopToolBar from "../components/EditTopToolBar"; |
| | | import MemoInput from "../components/MemoInput"; |
| | | import StatusSelectInput from "../components/StatusSelectInput"; |
| | | |
| | | const FormToolbar = () => { |
| | | const { getValues } = useFormContext(); |
| | | |
| | | return ( |
| | | <Toolbar sx={{ justifyContent: 'space-between' }}> |
| | | <SaveButton /> |
| | | <DeleteButton mutationMode="optimistic" /> |
| | | </Toolbar> |
| | | ) |
| | | } |
| | | |
| | | const WaveEdit = () => { |
| | | const translate = useTranslate(); |
| | | |
| | | return ( |
| | | <Edit |
| | | redirect="list" |
| | | mutationMode={EDIT_MODE} |
| | | actions={<CustomerTopToolBar />} |
| | | aside={<EditBaseAside />} |
| | | > |
| | | <SimpleForm |
| | | shouldUnregister |
| | | warnWhenUnsavedChanges |
| | | toolbar={<FormToolbar />} |
| | | mode="onTouched" |
| | | defaultValues={{}} |
| | | // validate={(values) => { }} |
| | | > |
| | | <Grid container width={{ xs: '100%', xl: '80%' }} rowSpacing={3} columnSpacing={3}> |
| | | <Grid item xs={12} md={8}> |
| | | <Typography variant="h6" gutterBottom> |
| | | {translate('common.edit.title.main')} |
| | | </Typography> |
| | | <Stack direction='row' gap={2}> |
| | | <TextInput |
| | | label="table.field.wave.code" |
| | | source="code" |
| | | parse={v => v} |
| | | autoFocus |
| | | /> |
| | | </Stack> |
| | | <Stack direction='row' gap={2}> |
| | | <SelectInput |
| | | label="table.field.wave.type" |
| | | source="type" |
| | | choices={[ |
| | | { id: 0, name: '手动' }, |
| | | { id: 1, name: '自动' }, |
| | | ]} |
| | | /> |
| | | </Stack> |
| | | <Stack direction='row' gap={2}> |
| | | <SelectInput |
| | | label="table.field.wave.exceStatus" |
| | | source="exceStatus" |
| | | choices={[ |
| | | { id: 0, name: '初始化' }, |
| | | { id: 1, name: '生成任务' }, |
| | | { id: 2, name: '任务播种' }, |
| | | { id: 3, name: '完成' }, |
| | | ]} |
| | | /> |
| | | </Stack> |
| | | <Stack direction='row' gap={2}> |
| | | <NumberInput |
| | | label="table.field.wave.anfme" |
| | | source="anfme" |
| | | /> |
| | | </Stack> |
| | | <Stack direction='row' gap={2}> |
| | | <NumberInput |
| | | label="table.field.wave.qty" |
| | | source="qty" |
| | | /> |
| | | </Stack> |
| | | <Stack direction='row' gap={2}> |
| | | <NumberInput |
| | | label="table.field.wave.orderNum" |
| | | source="orderNum" |
| | | /> |
| | | </Stack> |
| | | |
| | | </Grid> |
| | | <Grid item xs={12} md={4}> |
| | | <Typography variant="h6" gutterBottom> |
| | | {translate('common.edit.title.common')} |
| | | </Typography> |
| | | <StatusSelectInput /> |
| | | <Box mt="2em" /> |
| | | <MemoInput /> |
| | | </Grid> |
| | | </Grid> |
| | | </SimpleForm> |
| | | </Edit > |
| | | ) |
| | | } |
| | | |
| | | export default WaveEdit; |
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 WaveCreate from "./WaveCreate"; |
| | | import WavePanel from "./WavePanel"; |
| | | import EmptyData from "../components/EmptyData"; |
| | | import MyCreateButton from "../components/MyCreateButton"; |
| | | import MyExportButton from '../components/MyExportButton'; |
| | | import PageDrawer from "../components/PageDrawer"; |
| | | import MyField from "../components/MyField"; |
| | | import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting'; |
| | | import * as Common from '@/utils/common'; |
| | | |
| | | const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({ |
| | | '& .css-1vooibu-MuiSvgIcon-root': { |
| | | height: '.9em' |
| | | }, |
| | | '& .RaDatagrid-row': { |
| | | cursor: 'auto' |
| | | }, |
| | | '& .column-name': { |
| | | }, |
| | | '& .opt': { |
| | | width: 200 |
| | | }, |
| | | })); |
| | | |
| | | const filters = [ |
| | | <SearchInput source="condition" alwaysOn />, |
| | | <DateInput label='common.time.after' source="timeStart" alwaysOn />, |
| | | <DateInput label='common.time.before' source="timeEnd" alwaysOn />, |
| | | |
| | | <TextInput source="code" label="table.field.wave.code" />, |
| | | <SelectInput source="type" label="table.field.wave.type" |
| | | choices={[ |
| | | { id: 0, name: '手动' }, |
| | | { id: 1, name: '自动' }, |
| | | ]} |
| | | />, |
| | | <SelectInput source="exceStatus" label="table.field.wave.exceStatus" |
| | | choices={[ |
| | | { id: 0, name: '初始化' }, |
| | | { id: 1, name: '生成任务' }, |
| | | { id: 2, name: '任务播种' }, |
| | | { id: 3, name: '完成' }, |
| | | ]} |
| | | />, |
| | | <NumberInput source="anfme" label="table.field.wave.anfme" />, |
| | | <NumberInput source="qty" label="table.field.wave.qty" />, |
| | | <NumberInput source="orderNum" label="table.field.wave.orderNum" />, |
| | | |
| | | <TextInput label="common.field.memo" source="memo" />, |
| | | <SelectInput |
| | | label="common.field.status" |
| | | source="status" |
| | | choices={[ |
| | | { id: '1', name: 'common.enums.statusTrue' }, |
| | | { id: '0', name: 'common.enums.statusFalse' }, |
| | | ]} |
| | | resettable |
| | | />, |
| | | ] |
| | | |
| | | const WaveList = () => { |
| | | const translate = useTranslate(); |
| | | |
| | | const [createDialog, setCreateDialog] = useState(false); |
| | | const [drawerVal, setDrawerVal] = useState(false); |
| | | |
| | | return ( |
| | | <Box display="flex"> |
| | | <List |
| | | sx={{ |
| | | flexGrow: 1, |
| | | transition: (theme) => |
| | | theme.transitions.create(['all'], { |
| | | duration: theme.transitions.duration.enteringScreen, |
| | | }), |
| | | marginRight: !!drawerVal ? `${PAGE_DRAWER_WIDTH}px` : 0, |
| | | }} |
| | | title={"menu.wave"} |
| | | empty={<EmptyData onClick={() => { setCreateDialog(true) }} />} |
| | | filters={filters} |
| | | sort={{ field: "create_time", order: "desc" }} |
| | | actions={( |
| | | <TopToolbar> |
| | | <FilterButton /> |
| | | <MyCreateButton onClick={() => { setCreateDialog(true) }} /> |
| | | <SelectColumnsButton preferenceKey='wave' /> |
| | | <MyExportButton /> |
| | | </TopToolbar> |
| | | )} |
| | | perPage={DEFAULT_PAGE_SIZE} |
| | | > |
| | | <StyledDatagrid |
| | | preferenceKey='wave' |
| | | bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />} |
| | | rowClick={(id, resource, record) => false} |
| | | expand={() => <WavePanel />} |
| | | expandSingle={true} |
| | | omit={['id', 'createTime', 'createBy', 'memo']} |
| | | > |
| | | <NumberField source="id" /> |
| | | <TextField source="code" label="table.field.wave.code" /> |
| | | <TextField source="type$" label="table.field.wave.type" sortable={false} /> |
| | | <TextField source="exceStatus$" label="table.field.wave.exceStatus" sortable={false} /> |
| | | <NumberField source="anfme" label="table.field.wave.anfme" /> |
| | | <NumberField source="qty" label="table.field.wave.qty" /> |
| | | <NumberField source="orderNum" label="table.field.wave.orderNum" /> |
| | | |
| | | <ReferenceField source="updateBy" label="common.field.updateBy" reference="user" link={false} sortable={false}> |
| | | <TextField source="nickname" /> |
| | | </ReferenceField> |
| | | <DateField source="updateTime" label="common.field.updateTime" showTime /> |
| | | <ReferenceField source="createBy" label="common.field.createBy" reference="user" link={false} sortable={false}> |
| | | <TextField source="nickname" /> |
| | | </ReferenceField> |
| | | <DateField source="createTime" label="common.field.createTime" showTime /> |
| | | <BooleanField source="statusBool" label="common.field.status" sortable={false} /> |
| | | <TextField source="memo" label="common.field.memo" sortable={false} /> |
| | | <WrapperField cellClassName="opt" label="common.field.opt"> |
| | | <EditButton sx={{ padding: '1px', fontSize: '.75rem' }} /> |
| | | <DeleteButton sx={{ padding: '1px', fontSize: '.75rem' }} mutationMode={OPERATE_MODE} /> |
| | | </WrapperField> |
| | | </StyledDatagrid> |
| | | </List> |
| | | <WaveCreate |
| | | open={createDialog} |
| | | setOpen={setCreateDialog} |
| | | /> |
| | | <PageDrawer |
| | | title='Wave Detail' |
| | | drawerVal={drawerVal} |
| | | setDrawerVal={setDrawerVal} |
| | | > |
| | | </PageDrawer> |
| | | </Box> |
| | | ) |
| | | } |
| | | |
| | | export default WaveList; |
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 WavePanel = () => { |
| | | const record = useRecordContext(); |
| | | if (!record) return null; |
| | | const translate = useTranslate(); |
| | | return ( |
| | | <> |
| | | <Card sx={{ width: { xs: 300, sm: 500, md: 600, lg: 800 }, margin: 'auto' }}> |
| | | <CardContent> |
| | | <Grid container spacing={2}> |
| | | <Grid item xs={12} sx={{ display: 'flex', justifyContent: 'space-between' }}> |
| | | <Typography variant="h6" gutterBottom align="left" sx={{ |
| | | maxWidth: { xs: '100px', sm: '180px', md: '260px', lg: '360px' }, |
| | | whiteSpace: 'nowrap', |
| | | overflow: 'hidden', |
| | | textOverflow: 'ellipsis', |
| | | }}> |
| | | {Common.camelToPascalWithSpaces(translate('table.field.wave.id'))}: {record.id} |
| | | </Typography> |
| | | {/* inherit, primary, secondary, textPrimary, textSecondary, error */} |
| | | <Typography variant="h6" gutterBottom align="right" > |
| | | ID: {record.id} |
| | | </Typography> |
| | | </Grid> |
| | | </Grid> |
| | | <Grid container spacing={2}> |
| | | <Grid item xs={12} container alignContent="flex-end"> |
| | | <Typography variant="caption" color="textSecondary" sx={{ wordWrap: 'break-word', wordBreak: 'break-all' }}> |
| | | {Common.camelToPascalWithSpaces(translate('common.field.memo'))}:{record.memo} |
| | | </Typography> |
| | | </Grid> |
| | | </Grid> |
| | | <Box height={20}> </Box> |
| | | <Grid container spacing={2}> |
| | | <Grid item xs={6}> |
| | | <PanelTypography |
| | | title="table.field.wave.code" |
| | | property={record.code} |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6}> |
| | | <PanelTypography |
| | | title="table.field.wave.type" |
| | | property={record.type$} |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6}> |
| | | <PanelTypography |
| | | title="table.field.wave.exceStatus" |
| | | property={record.exceStatus$} |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6}> |
| | | <PanelTypography |
| | | title="table.field.wave.anfme" |
| | | property={record.anfme} |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6}> |
| | | <PanelTypography |
| | | title="table.field.wave.qty" |
| | | property={record.qty} |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6}> |
| | | <PanelTypography |
| | | title="table.field.wave.orderNum" |
| | | property={record.orderNum} |
| | | /> |
| | | </Grid> |
| | | |
| | | </Grid> |
| | | </CardContent> |
| | | </Card > |
| | | </> |
| | | ); |
| | | }; |
| | | |
| | | export default WavePanel; |
New file |
| | |
| | | import React, { useState, useRef, useEffect, useMemo } from "react"; |
| | | import { |
| | | ListGuesser, |
| | | EditGuesser, |
| | | ShowGuesser, |
| | | } from "react-admin"; |
| | | |
| | | import WaveList from "./WaveList"; |
| | | import WaveEdit from "./WaveEdit"; |
| | | |
| | | export default { |
| | | list: WaveList, |
| | | edit: WaveEdit, |
| | | show: ShowGuesser, |
| | | recordRepresentation: (record) => { |
| | | return `${record.id}` |
| | | } |
| | | }; |
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 WaveItemCreate = (props) => { |
| | | const { open, setOpen } = props; |
| | | |
| | | const translate = useTranslate(); |
| | | const notify = useNotify(); |
| | | |
| | | const handleClose = (event, reason) => { |
| | | if (reason !== "backdropClick") { |
| | | setOpen(false); |
| | | } |
| | | }; |
| | | |
| | | const handleSuccess = async (data) => { |
| | | setOpen(false); |
| | | notify('common.response.success'); |
| | | }; |
| | | |
| | | const handleError = async (error) => { |
| | | notify(error.message || 'common.response.fail', { type: 'error', messageArgs: { _: error.message } }); |
| | | }; |
| | | |
| | | return ( |
| | | <> |
| | | <CreateBase |
| | | record={{}} |
| | | transform={(data) => { |
| | | return data; |
| | | }} |
| | | mutationOptions={{ onSuccess: handleSuccess, onError: handleError }} |
| | | > |
| | | <Dialog |
| | | open={open} |
| | | onClose={handleClose} |
| | | aria-labelledby="form-dialog-title" |
| | | fullWidth |
| | | disableRestoreFocus |
| | | maxWidth="md" // 'xs' | 'sm' | 'md' | 'lg' | 'xl' |
| | | > |
| | | <Form> |
| | | <DialogTitle id="form-dialog-title" sx={{ |
| | | position: 'sticky', |
| | | top: 0, |
| | | backgroundColor: 'background.paper', |
| | | zIndex: 1000 |
| | | }} |
| | | > |
| | | {translate('create.title')} |
| | | <Box sx={{ position: 'absolute', top: 8, right: 8, zIndex: 1001 }}> |
| | | <DialogCloseButton onClose={handleClose} /> |
| | | </Box> |
| | | </DialogTitle> |
| | | <DialogContent sx={{ mt: 2 }}> |
| | | <Grid container rowSpacing={2} columnSpacing={2}> |
| | | <Grid item xs={6} display="flex" gap={1}> |
| | | <NumberInput |
| | | label="table.field.waveItem.waveId" |
| | | source="waveId" |
| | | autoFocus |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6} display="flex" gap={1}> |
| | | <TextInput |
| | | label="table.field.waveItem.waveCode" |
| | | source="waveCode" |
| | | parse={v => v} |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6} display="flex" gap={1}> |
| | | <NumberInput |
| | | label="table.field.waveItem.matnrId" |
| | | source="matnrId" |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6} display="flex" gap={1}> |
| | | <TextInput |
| | | label="table.field.waveItem.matnrName" |
| | | source="matnrName" |
| | | parse={v => v} |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6} display="flex" gap={1}> |
| | | <TextInput |
| | | label="table.field.waveItem.matnrCode" |
| | | source="matnrCode" |
| | | parse={v => v} |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6} display="flex" gap={1}> |
| | | <TextInput |
| | | label="table.field.waveItem.batch" |
| | | source="batch" |
| | | parse={v => v} |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6} display="flex" gap={1}> |
| | | <TextInput |
| | | label="table.field.waveItem.splrBatch" |
| | | source="splrBatch" |
| | | parse={v => v} |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6} display="flex" gap={1}> |
| | | <TextInput |
| | | label="table.field.waveItem.orderCode" |
| | | source="orderCode" |
| | | parse={v => v} |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6} display="flex" gap={1}> |
| | | <NumberInput |
| | | label="table.field.waveItem.orderItemId" |
| | | source="orderItemId" |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6} display="flex" gap={1}> |
| | | <TextInput |
| | | label="table.field.waveItem.unit" |
| | | source="unit" |
| | | parse={v => v} |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6} display="flex" gap={1}> |
| | | <TextInput |
| | | label="table.field.waveItem.trackCode" |
| | | source="trackCode" |
| | | parse={v => v} |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6} display="flex" gap={1}> |
| | | <TextInput |
| | | label="table.field.waveItem.fieldsIndex" |
| | | source="fieldsIndex" |
| | | parse={v => v} |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6} display="flex" gap={1}> |
| | | <NumberInput |
| | | label="table.field.waveItem.anfme" |
| | | source="anfme" |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6} display="flex" gap={1}> |
| | | <NumberInput |
| | | label="table.field.waveItem.workQty" |
| | | source="workQty" |
| | | /> |
| | | </Grid> |
| | | |
| | | <Grid item xs={6} display="flex" gap={1}> |
| | | <StatusSelectInput /> |
| | | </Grid> |
| | | <Grid item xs={12} display="flex" gap={1}> |
| | | <Stack direction="column" spacing={1} width={'100%'}> |
| | | <MemoInput /> |
| | | </Stack> |
| | | </Grid> |
| | | </Grid> |
| | | </DialogContent> |
| | | <DialogActions sx={{ position: 'sticky', bottom: 0, backgroundColor: 'background.paper', zIndex: 1000 }}> |
| | | <Toolbar sx={{ width: '100%', justifyContent: 'space-between' }} > |
| | | <SaveButton /> |
| | | </Toolbar> |
| | | </DialogActions> |
| | | </Form> |
| | | </Dialog> |
| | | </CreateBase> |
| | | </> |
| | | ) |
| | | } |
| | | |
| | | export default WaveItemCreate; |
New file |
| | |
| | | import React, { useState, useRef, useEffect, useMemo } from "react"; |
| | | import { |
| | | Edit, |
| | | SimpleForm, |
| | | FormDataConsumer, |
| | | useTranslate, |
| | | TextInput, |
| | | NumberInput, |
| | | BooleanInput, |
| | | DateInput, |
| | | SelectInput, |
| | | ReferenceInput, |
| | | ReferenceArrayInput, |
| | | AutocompleteInput, |
| | | SaveButton, |
| | | Toolbar, |
| | | Labeled, |
| | | NumberField, |
| | | required, |
| | | useRecordContext, |
| | | DeleteButton, |
| | | } from 'react-admin'; |
| | | import { useWatch, useFormContext } from "react-hook-form"; |
| | | import { Stack, Grid, Box, Typography } from '@mui/material'; |
| | | import * as Common from '@/utils/common'; |
| | | import { EDIT_MODE, REFERENCE_INPUT_PAGESIZE } from '@/config/setting'; |
| | | import EditBaseAside from "../components/EditBaseAside"; |
| | | import CustomerTopToolBar from "../components/EditTopToolBar"; |
| | | import MemoInput from "../components/MemoInput"; |
| | | import StatusSelectInput from "../components/StatusSelectInput"; |
| | | |
| | | const FormToolbar = () => { |
| | | const { getValues } = useFormContext(); |
| | | |
| | | return ( |
| | | <Toolbar sx={{ justifyContent: 'space-between' }}> |
| | | <SaveButton /> |
| | | <DeleteButton mutationMode="optimistic" /> |
| | | </Toolbar> |
| | | ) |
| | | } |
| | | |
| | | const WaveItemEdit = () => { |
| | | const translate = useTranslate(); |
| | | |
| | | return ( |
| | | <Edit |
| | | redirect="list" |
| | | mutationMode={EDIT_MODE} |
| | | actions={<CustomerTopToolBar />} |
| | | aside={<EditBaseAside />} |
| | | > |
| | | <SimpleForm |
| | | shouldUnregister |
| | | warnWhenUnsavedChanges |
| | | toolbar={<FormToolbar />} |
| | | mode="onTouched" |
| | | defaultValues={{}} |
| | | // validate={(values) => { }} |
| | | > |
| | | <Grid container width={{ xs: '100%', xl: '80%' }} rowSpacing={3} columnSpacing={3}> |
| | | <Grid item xs={12} md={8}> |
| | | <Typography variant="h6" gutterBottom> |
| | | {translate('common.edit.title.main')} |
| | | </Typography> |
| | | <Stack direction='row' gap={2}> |
| | | <NumberInput |
| | | label="table.field.waveItem.waveId" |
| | | source="waveId" |
| | | autoFocus |
| | | /> |
| | | </Stack> |
| | | <Stack direction='row' gap={2}> |
| | | <TextInput |
| | | label="table.field.waveItem.waveCode" |
| | | source="waveCode" |
| | | parse={v => v} |
| | | /> |
| | | </Stack> |
| | | <Stack direction='row' gap={2}> |
| | | <NumberInput |
| | | label="table.field.waveItem.matnrId" |
| | | source="matnrId" |
| | | /> |
| | | </Stack> |
| | | <Stack direction='row' gap={2}> |
| | | <TextInput |
| | | label="table.field.waveItem.matnrName" |
| | | source="matnrName" |
| | | parse={v => v} |
| | | /> |
| | | </Stack> |
| | | <Stack direction='row' gap={2}> |
| | | <TextInput |
| | | label="table.field.waveItem.matnrCode" |
| | | source="matnrCode" |
| | | parse={v => v} |
| | | /> |
| | | </Stack> |
| | | <Stack direction='row' gap={2}> |
| | | <TextInput |
| | | label="table.field.waveItem.batch" |
| | | source="batch" |
| | | parse={v => v} |
| | | /> |
| | | </Stack> |
| | | <Stack direction='row' gap={2}> |
| | | <TextInput |
| | | label="table.field.waveItem.splrBatch" |
| | | source="splrBatch" |
| | | parse={v => v} |
| | | /> |
| | | </Stack> |
| | | <Stack direction='row' gap={2}> |
| | | <TextInput |
| | | label="table.field.waveItem.orderCode" |
| | | source="orderCode" |
| | | parse={v => v} |
| | | /> |
| | | </Stack> |
| | | <Stack direction='row' gap={2}> |
| | | <NumberInput |
| | | label="table.field.waveItem.orderItemId" |
| | | source="orderItemId" |
| | | /> |
| | | </Stack> |
| | | <Stack direction='row' gap={2}> |
| | | <TextInput |
| | | label="table.field.waveItem.unit" |
| | | source="unit" |
| | | parse={v => v} |
| | | /> |
| | | </Stack> |
| | | <Stack direction='row' gap={2}> |
| | | <TextInput |
| | | label="table.field.waveItem.trackCode" |
| | | source="trackCode" |
| | | parse={v => v} |
| | | /> |
| | | </Stack> |
| | | <Stack direction='row' gap={2}> |
| | | <TextInput |
| | | label="table.field.waveItem.fieldsIndex" |
| | | source="fieldsIndex" |
| | | parse={v => v} |
| | | /> |
| | | </Stack> |
| | | <Stack direction='row' gap={2}> |
| | | <NumberInput |
| | | label="table.field.waveItem.anfme" |
| | | source="anfme" |
| | | /> |
| | | </Stack> |
| | | <Stack direction='row' gap={2}> |
| | | <NumberInput |
| | | label="table.field.waveItem.workQty" |
| | | source="workQty" |
| | | /> |
| | | </Stack> |
| | | |
| | | </Grid> |
| | | <Grid item xs={12} md={4}> |
| | | <Typography variant="h6" gutterBottom> |
| | | {translate('common.edit.title.common')} |
| | | </Typography> |
| | | <StatusSelectInput /> |
| | | <Box mt="2em" /> |
| | | <MemoInput /> |
| | | </Grid> |
| | | </Grid> |
| | | </SimpleForm> |
| | | </Edit > |
| | | ) |
| | | } |
| | | |
| | | export default WaveItemEdit; |
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 WaveItemCreate from "./WaveItemCreate"; |
| | | import WaveItemPanel from "./WaveItemPanel"; |
| | | import EmptyData from "../components/EmptyData"; |
| | | import MyCreateButton from "../components/MyCreateButton"; |
| | | import MyExportButton from '../components/MyExportButton'; |
| | | import PageDrawer from "../components/PageDrawer"; |
| | | import MyField from "../components/MyField"; |
| | | import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting'; |
| | | import * as Common from '@/utils/common'; |
| | | |
| | | const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({ |
| | | '& .css-1vooibu-MuiSvgIcon-root': { |
| | | height: '.9em' |
| | | }, |
| | | '& .RaDatagrid-row': { |
| | | cursor: 'auto' |
| | | }, |
| | | '& .column-name': { |
| | | }, |
| | | '& .opt': { |
| | | width: 200 |
| | | }, |
| | | })); |
| | | |
| | | const filters = [ |
| | | <SearchInput source="condition" alwaysOn />, |
| | | <DateInput label='common.time.after' source="timeStart" alwaysOn />, |
| | | <DateInput label='common.time.before' source="timeEnd" alwaysOn />, |
| | | |
| | | <NumberInput source="waveId" label="table.field.waveItem.waveId" />, |
| | | <TextInput source="waveCode" label="table.field.waveItem.waveCode" />, |
| | | <NumberInput source="matnrId" label="table.field.waveItem.matnrId" />, |
| | | <TextInput source="matnrName" label="table.field.waveItem.matnrName" />, |
| | | <TextInput source="matnrCode" label="table.field.waveItem.matnrCode" />, |
| | | <TextInput source="batch" label="table.field.waveItem.batch" />, |
| | | <TextInput source="splrBatch" label="table.field.waveItem.splrBatch" />, |
| | | <TextInput source="orderCode" label="table.field.waveItem.orderCode" />, |
| | | <NumberInput source="orderItemId" label="table.field.waveItem.orderItemId" />, |
| | | <TextInput source="unit" label="table.field.waveItem.unit" />, |
| | | <TextInput source="trackCode" label="table.field.waveItem.trackCode" />, |
| | | <TextInput source="fieldsIndex" label="table.field.waveItem.fieldsIndex" />, |
| | | <NumberInput source="anfme" label="table.field.waveItem.anfme" />, |
| | | <NumberInput source="workQty" label="table.field.waveItem.workQty" />, |
| | | |
| | | <TextInput label="common.field.memo" source="memo" />, |
| | | <SelectInput |
| | | label="common.field.status" |
| | | source="status" |
| | | choices={[ |
| | | { id: '1', name: 'common.enums.statusTrue' }, |
| | | { id: '0', name: 'common.enums.statusFalse' }, |
| | | ]} |
| | | resettable |
| | | />, |
| | | ] |
| | | |
| | | const WaveItemList = () => { |
| | | const translate = useTranslate(); |
| | | |
| | | const [createDialog, setCreateDialog] = useState(false); |
| | | const [drawerVal, setDrawerVal] = useState(false); |
| | | |
| | | return ( |
| | | <Box display="flex"> |
| | | <List |
| | | sx={{ |
| | | flexGrow: 1, |
| | | transition: (theme) => |
| | | theme.transitions.create(['all'], { |
| | | duration: theme.transitions.duration.enteringScreen, |
| | | }), |
| | | marginRight: !!drawerVal ? `${PAGE_DRAWER_WIDTH}px` : 0, |
| | | }} |
| | | title={"menu.waveItem"} |
| | | empty={<EmptyData onClick={() => { setCreateDialog(true) }} />} |
| | | filters={filters} |
| | | sort={{ field: "create_time", order: "desc" }} |
| | | actions={( |
| | | <TopToolbar> |
| | | <FilterButton /> |
| | | <MyCreateButton onClick={() => { setCreateDialog(true) }} /> |
| | | <SelectColumnsButton preferenceKey='waveItem' /> |
| | | <MyExportButton /> |
| | | </TopToolbar> |
| | | )} |
| | | perPage={DEFAULT_PAGE_SIZE} |
| | | > |
| | | <StyledDatagrid |
| | | preferenceKey='waveItem' |
| | | bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />} |
| | | rowClick={(id, resource, record) => false} |
| | | expand={() => <WaveItemPanel />} |
| | | expandSingle={true} |
| | | omit={['id', 'createTime', 'createBy', 'memo']} |
| | | > |
| | | <NumberField source="id" /> |
| | | <NumberField source="waveId" label="table.field.waveItem.waveId" /> |
| | | <TextField source="waveCode" label="table.field.waveItem.waveCode" /> |
| | | <NumberField source="matnrId" label="table.field.waveItem.matnrId" /> |
| | | <TextField source="matnrName" label="table.field.waveItem.matnrName" /> |
| | | <TextField source="matnrCode" label="table.field.waveItem.matnrCode" /> |
| | | <TextField source="batch" label="table.field.waveItem.batch" /> |
| | | <TextField source="splrBatch" label="table.field.waveItem.splrBatch" /> |
| | | <TextField source="orderCode" label="table.field.waveItem.orderCode" /> |
| | | <NumberField source="orderItemId" label="table.field.waveItem.orderItemId" /> |
| | | <TextField source="unit" label="table.field.waveItem.unit" /> |
| | | <TextField source="trackCode" label="table.field.waveItem.trackCode" /> |
| | | <TextField source="fieldsIndex" label="table.field.waveItem.fieldsIndex" /> |
| | | <NumberField source="anfme" label="table.field.waveItem.anfme" /> |
| | | <NumberField source="workQty" label="table.field.waveItem.workQty" /> |
| | | |
| | | <ReferenceField source="updateBy" label="common.field.updateBy" reference="user" link={false} sortable={false}> |
| | | <TextField source="nickname" /> |
| | | </ReferenceField> |
| | | <DateField source="updateTime" label="common.field.updateTime" showTime /> |
| | | <ReferenceField source="createBy" label="common.field.createBy" reference="user" link={false} sortable={false}> |
| | | <TextField source="nickname" /> |
| | | </ReferenceField> |
| | | <DateField source="createTime" label="common.field.createTime" showTime /> |
| | | <BooleanField source="statusBool" label="common.field.status" sortable={false} /> |
| | | <TextField source="memo" label="common.field.memo" sortable={false} /> |
| | | <WrapperField cellClassName="opt" label="common.field.opt"> |
| | | <EditButton sx={{ padding: '1px', fontSize: '.75rem' }} /> |
| | | <DeleteButton sx={{ padding: '1px', fontSize: '.75rem' }} mutationMode={OPERATE_MODE} /> |
| | | </WrapperField> |
| | | </StyledDatagrid> |
| | | </List> |
| | | <WaveItemCreate |
| | | open={createDialog} |
| | | setOpen={setCreateDialog} |
| | | /> |
| | | <PageDrawer |
| | | title='WaveItem Detail' |
| | | drawerVal={drawerVal} |
| | | setDrawerVal={setDrawerVal} |
| | | > |
| | | </PageDrawer> |
| | | </Box> |
| | | ) |
| | | } |
| | | |
| | | export default WaveItemList; |
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 WaveItemPanel = () => { |
| | | const record = useRecordContext(); |
| | | if (!record) return null; |
| | | const translate = useTranslate(); |
| | | return ( |
| | | <> |
| | | <Card sx={{ width: { xs: 300, sm: 500, md: 600, lg: 800 }, margin: 'auto' }}> |
| | | <CardContent> |
| | | <Grid container spacing={2}> |
| | | <Grid item xs={12} sx={{ display: 'flex', justifyContent: 'space-between' }}> |
| | | <Typography variant="h6" gutterBottom align="left" sx={{ |
| | | maxWidth: { xs: '100px', sm: '180px', md: '260px', lg: '360px' }, |
| | | whiteSpace: 'nowrap', |
| | | overflow: 'hidden', |
| | | textOverflow: 'ellipsis', |
| | | }}> |
| | | {Common.camelToPascalWithSpaces(translate('table.field.waveItem.id'))}: {record.id} |
| | | </Typography> |
| | | {/* inherit, primary, secondary, textPrimary, textSecondary, error */} |
| | | <Typography variant="h6" gutterBottom align="right" > |
| | | ID: {record.id} |
| | | </Typography> |
| | | </Grid> |
| | | </Grid> |
| | | <Grid container spacing={2}> |
| | | <Grid item xs={12} container alignContent="flex-end"> |
| | | <Typography variant="caption" color="textSecondary" sx={{ wordWrap: 'break-word', wordBreak: 'break-all' }}> |
| | | {Common.camelToPascalWithSpaces(translate('common.field.memo'))}:{record.memo} |
| | | </Typography> |
| | | </Grid> |
| | | </Grid> |
| | | <Box height={20}> </Box> |
| | | <Grid container spacing={2}> |
| | | <Grid item xs={6}> |
| | | <PanelTypography |
| | | title="table.field.waveItem.waveId" |
| | | property={record.waveId} |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6}> |
| | | <PanelTypography |
| | | title="table.field.waveItem.waveCode" |
| | | property={record.waveCode} |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6}> |
| | | <PanelTypography |
| | | title="table.field.waveItem.matnrId" |
| | | property={record.matnrId} |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6}> |
| | | <PanelTypography |
| | | title="table.field.waveItem.matnrName" |
| | | property={record.matnrName} |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6}> |
| | | <PanelTypography |
| | | title="table.field.waveItem.matnrCode" |
| | | property={record.matnrCode} |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6}> |
| | | <PanelTypography |
| | | title="table.field.waveItem.batch" |
| | | property={record.batch} |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6}> |
| | | <PanelTypography |
| | | title="table.field.waveItem.splrBatch" |
| | | property={record.splrBatch} |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6}> |
| | | <PanelTypography |
| | | title="table.field.waveItem.orderCode" |
| | | property={record.orderCode} |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6}> |
| | | <PanelTypography |
| | | title="table.field.waveItem.orderItemId" |
| | | property={record.orderItemId} |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6}> |
| | | <PanelTypography |
| | | title="table.field.waveItem.unit" |
| | | property={record.unit} |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6}> |
| | | <PanelTypography |
| | | title="table.field.waveItem.trackCode" |
| | | property={record.trackCode} |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6}> |
| | | <PanelTypography |
| | | title="table.field.waveItem.fieldsIndex" |
| | | property={record.fieldsIndex} |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6}> |
| | | <PanelTypography |
| | | title="table.field.waveItem.anfme" |
| | | property={record.anfme} |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6}> |
| | | <PanelTypography |
| | | title="table.field.waveItem.workQty" |
| | | property={record.workQty} |
| | | /> |
| | | </Grid> |
| | | |
| | | </Grid> |
| | | </CardContent> |
| | | </Card > |
| | | </> |
| | | ); |
| | | }; |
| | | |
| | | export default WaveItemPanel; |
New file |
| | |
| | | import React, { useState, useRef, useEffect, useMemo } from "react"; |
| | | import { |
| | | ListGuesser, |
| | | EditGuesser, |
| | | ShowGuesser, |
| | | } from "react-admin"; |
| | | |
| | | import WaveItemList from "./WaveItemList"; |
| | | import WaveItemEdit from "./WaveItemEdit"; |
| | | |
| | | export default { |
| | | list: WaveItemList, |
| | | edit: WaveItemEdit, |
| | | show: ShowGuesser, |
| | | recordRepresentation: (record) => { |
| | | return `${record.id}` |
| | | } |
| | | }; |
| | |
| | | generator.frontendPrefixPath = "rsf-admin/"; |
| | | |
| | | generator.sqlOsType = SqlOsType.MYSQL; |
| | | generator.url="192.168.4.24:3306/rsf"; |
| | | generator.url="127.0.0.1:3306/rsf"; |
| | | generator.username="root"; |
| | | generator.password="34821015"; |
| | | // generator.url="47.97.1.152:51433;databasename=jkasrs"; |
| | | // generator.username="sa"; |
| | | // generator.password="Zoneyung@zy56$"; |
| | | |
| | | generator.table="man_delivery_item"; |
| | | generator.tableDesc="综合单据明细"; |
| | | generator.table="man_device_bind"; |
| | | generator.tableDesc="立体库站点绑定"; |
| | | generator.packagePath="com.vincent.rsf.server.manager"; |
| | | |
| | | generator.build(); |
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.DeviceBind; |
| | | import com.vincent.rsf.server.manager.service.DeviceBindService; |
| | | import com.vincent.rsf.server.system.controller.BaseController; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import javax.servlet.http.HttpServletResponse; |
| | | import java.util.*; |
| | | |
| | | @RestController |
| | | public class DeviceBindController extends BaseController { |
| | | |
| | | @Autowired |
| | | private DeviceBindService deviceBindService; |
| | | |
| | | @PreAuthorize("hasAuthority('manager:deviceBind:list')") |
| | | @PostMapping("/deviceBind/page") |
| | | public R page(@RequestBody Map<String, Object> map) { |
| | | BaseParam baseParam = buildParam(map, BaseParam.class); |
| | | PageParam<DeviceBind, BaseParam> pageParam = new PageParam<>(baseParam, DeviceBind.class); |
| | | return R.ok().add(deviceBindService.page(pageParam, pageParam.buildWrapper(true))); |
| | | } |
| | | |
| | | @PreAuthorize("hasAuthority('manager:deviceBind:list')") |
| | | @PostMapping("/deviceBind/list") |
| | | public R list(@RequestBody Map<String, Object> map) { |
| | | return R.ok().add(deviceBindService.list()); |
| | | } |
| | | |
| | | @PreAuthorize("hasAuthority('manager:deviceBind:list')") |
| | | @PostMapping({"/deviceBind/many/{ids}", "/deviceBinds/many/{ids}"}) |
| | | public R many(@PathVariable Long[] ids) { |
| | | return R.ok().add(deviceBindService.listByIds(Arrays.asList(ids))); |
| | | } |
| | | |
| | | @PreAuthorize("hasAuthority('manager:deviceBind:list')") |
| | | @GetMapping("/deviceBind/{id}") |
| | | public R get(@PathVariable("id") Long id) { |
| | | return R.ok().add(deviceBindService.getById(id)); |
| | | } |
| | | |
| | | @PreAuthorize("hasAuthority('manager:deviceBind:save')") |
| | | @OperationLog("Create 立体库站点绑定") |
| | | @PostMapping("/deviceBind/save") |
| | | public R save(@RequestBody DeviceBind deviceBind) { |
| | | deviceBind.setCreateBy(getLoginUserId()); |
| | | deviceBind.setCreateTime(new Date()); |
| | | deviceBind.setUpdateBy(getLoginUserId()); |
| | | deviceBind.setUpdateTime(new Date()); |
| | | if (!deviceBindService.save(deviceBind)) { |
| | | return R.error("Save Fail"); |
| | | } |
| | | return R.ok("Save Success").add(deviceBind); |
| | | } |
| | | |
| | | @PreAuthorize("hasAuthority('manager:deviceBind:update')") |
| | | @OperationLog("Update 立体库站点绑定") |
| | | @PostMapping("/deviceBind/update") |
| | | public R update(@RequestBody DeviceBind deviceBind) { |
| | | deviceBind.setUpdateBy(getLoginUserId()); |
| | | deviceBind.setUpdateTime(new Date()); |
| | | if (!deviceBindService.updateById(deviceBind)) { |
| | | return R.error("Update Fail"); |
| | | } |
| | | return R.ok("Update Success").add(deviceBind); |
| | | } |
| | | |
| | | @PreAuthorize("hasAuthority('manager:deviceBind:remove')") |
| | | @OperationLog("Delete 立体库站点绑定") |
| | | @PostMapping("/deviceBind/remove/{ids}") |
| | | public R remove(@PathVariable Long[] ids) { |
| | | if (!deviceBindService.removeByIds(Arrays.asList(ids))) { |
| | | return R.error("Delete Fail"); |
| | | } |
| | | return R.ok("Delete Success").add(ids); |
| | | } |
| | | |
| | | @PreAuthorize("hasAuthority('manager:deviceBind:list')") |
| | | @PostMapping("/deviceBind/query") |
| | | public R query(@RequestParam(required = false) String condition) { |
| | | List<KeyValVo> vos = new ArrayList<>(); |
| | | LambdaQueryWrapper<DeviceBind> wrapper = new LambdaQueryWrapper<>(); |
| | | if (!Cools.isEmpty(condition)) { |
| | | wrapper.like(DeviceBind::getId, condition); |
| | | } |
| | | deviceBindService.page(new Page<>(1, 30), wrapper).getRecords().forEach( |
| | | item -> vos.add(new KeyValVo(item.getId(), item.getId())) |
| | | ); |
| | | return R.ok().add(vos); |
| | | } |
| | | |
| | | @PreAuthorize("hasAuthority('manager:deviceBind:list')") |
| | | @PostMapping("/deviceBind/export") |
| | | public void export(@RequestBody Map<String, Object> map, HttpServletResponse response) throws Exception { |
| | | ExcelUtil.build(ExcelUtil.create(deviceBindService.list(), DeviceBind.class), response); |
| | | } |
| | | |
| | | } |
| | |
| | | return outStockService.genOutStock(ids); |
| | | } |
| | | |
| | | @PreAuthorize("hasAuthority('manager:outStock:update')") |
| | | @ApiOperation("出库单生成波次") |
| | | @PostMapping("/outStock/generate/wave") |
| | | public R generateWave(@RequestBody Map<String, Object> params) { |
| | | if (Objects.isNull(params)) { |
| | | return R.error("参数不能为空!!"); |
| | | } |
| | | List<Long> ids = (List<Long>) params.get("ids"); |
| | | return outStockService.generateWaves(ids); |
| | | } |
| | | |
| | | |
| | | } |
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.Wave; |
| | | import com.vincent.rsf.server.manager.service.WaveService; |
| | | import com.vincent.rsf.server.system.controller.BaseController; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import javax.servlet.http.HttpServletResponse; |
| | | import java.util.*; |
| | | |
| | | @RestController |
| | | public class WaveController extends BaseController { |
| | | |
| | | @Autowired |
| | | private WaveService waveService; |
| | | |
| | | @PreAuthorize("hasAuthority('manager:wave:list')") |
| | | @PostMapping("/wave/page") |
| | | public R page(@RequestBody Map<String, Object> map) { |
| | | BaseParam baseParam = buildParam(map, BaseParam.class); |
| | | PageParam<Wave, BaseParam> pageParam = new PageParam<>(baseParam, Wave.class); |
| | | return R.ok().add(waveService.page(pageParam, pageParam.buildWrapper(true))); |
| | | } |
| | | |
| | | @PreAuthorize("hasAuthority('manager:wave:list')") |
| | | @PostMapping("/wave/list") |
| | | public R list(@RequestBody Map<String, Object> map) { |
| | | return R.ok().add(waveService.list()); |
| | | } |
| | | |
| | | @PreAuthorize("hasAuthority('manager:wave:list')") |
| | | @PostMapping({"/wave/many/{ids}", "/waves/many/{ids}"}) |
| | | public R many(@PathVariable Long[] ids) { |
| | | return R.ok().add(waveService.listByIds(Arrays.asList(ids))); |
| | | } |
| | | |
| | | @PreAuthorize("hasAuthority('manager:wave:list')") |
| | | @GetMapping("/wave/{id}") |
| | | public R get(@PathVariable("id") Long id) { |
| | | return R.ok().add(waveService.getById(id)); |
| | | } |
| | | |
| | | @PreAuthorize("hasAuthority('manager:wave:save')") |
| | | @OperationLog("Create 波次单据") |
| | | @PostMapping("/wave/save") |
| | | public R save(@RequestBody Wave wave) { |
| | | wave.setCreateBy(getLoginUserId()); |
| | | wave.setUpdateBy(getLoginUserId()); |
| | | if (!waveService.save(wave)) { |
| | | return R.error("Save Fail"); |
| | | } |
| | | return R.ok("Save Success").add(wave); |
| | | } |
| | | |
| | | @PreAuthorize("hasAuthority('manager:wave:update')") |
| | | @OperationLog("Update 波次单据") |
| | | @PostMapping("/wave/update") |
| | | public R update(@RequestBody Wave wave) { |
| | | wave.setUpdateBy(getLoginUserId()); |
| | | wave.setUpdateTime(new Date()); |
| | | if (!waveService.updateById(wave)) { |
| | | return R.error("Update Fail"); |
| | | } |
| | | return R.ok("Update Success").add(wave); |
| | | } |
| | | |
| | | @PreAuthorize("hasAuthority('manager:wave:remove')") |
| | | @OperationLog("Delete 波次单据") |
| | | @PostMapping("/wave/remove/{ids}") |
| | | public R remove(@PathVariable Long[] ids) { |
| | | if (!waveService.removeByIds(Arrays.asList(ids))) { |
| | | return R.error("Delete Fail"); |
| | | } |
| | | return R.ok("Delete Success").add(ids); |
| | | } |
| | | |
| | | @PreAuthorize("hasAuthority('manager:wave:list')") |
| | | @PostMapping("/wave/query") |
| | | public R query(@RequestParam(required = false) String condition) { |
| | | List<KeyValVo> vos = new ArrayList<>(); |
| | | LambdaQueryWrapper<Wave> wrapper = new LambdaQueryWrapper<>(); |
| | | if (!Cools.isEmpty(condition)) { |
| | | wrapper.like(Wave::getId, condition); |
| | | } |
| | | waveService.page(new Page<>(1, 30), wrapper).getRecords().forEach( |
| | | item -> vos.add(new KeyValVo(item.getId(), item.getId())) |
| | | ); |
| | | return R.ok().add(vos); |
| | | } |
| | | |
| | | @PreAuthorize("hasAuthority('manager:wave:list')") |
| | | @PostMapping("/wave/export") |
| | | public void export(@RequestBody Map<String, Object> map, HttpServletResponse response) throws Exception { |
| | | ExcelUtil.build(ExcelUtil.create(waveService.list(), Wave.class), response); |
| | | } |
| | | |
| | | } |
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.WaveItem; |
| | | import com.vincent.rsf.server.manager.service.WaveItemService; |
| | | import com.vincent.rsf.server.system.controller.BaseController; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import javax.servlet.http.HttpServletResponse; |
| | | import java.util.*; |
| | | |
| | | @RestController |
| | | public class WaveItemController extends BaseController { |
| | | |
| | | @Autowired |
| | | private WaveItemService waveItemService; |
| | | |
| | | @PreAuthorize("hasAuthority('manager:waveItem:list')") |
| | | @PostMapping("/waveItem/page") |
| | | public R page(@RequestBody Map<String, Object> map) { |
| | | BaseParam baseParam = buildParam(map, BaseParam.class); |
| | | PageParam<WaveItem, BaseParam> pageParam = new PageParam<>(baseParam, WaveItem.class); |
| | | return R.ok().add(waveItemService.page(pageParam, pageParam.buildWrapper(true))); |
| | | } |
| | | |
| | | @PreAuthorize("hasAuthority('manager:waveItem:list')") |
| | | @PostMapping("/waveItem/list") |
| | | public R list(@RequestBody Map<String, Object> map) { |
| | | return R.ok().add(waveItemService.list()); |
| | | } |
| | | |
| | | @PreAuthorize("hasAuthority('manager:waveItem:list')") |
| | | @PostMapping({"/waveItem/many/{ids}", "/waveItems/many/{ids}"}) |
| | | public R many(@PathVariable Long[] ids) { |
| | | return R.ok().add(waveItemService.listByIds(Arrays.asList(ids))); |
| | | } |
| | | |
| | | @PreAuthorize("hasAuthority('manager:waveItem:list')") |
| | | @GetMapping("/waveItem/{id}") |
| | | public R get(@PathVariable("id") Long id) { |
| | | return R.ok().add(waveItemService.getById(id)); |
| | | } |
| | | |
| | | @PreAuthorize("hasAuthority('manager:waveItem:save')") |
| | | @OperationLog("Create 波次明细") |
| | | @PostMapping("/waveItem/save") |
| | | public R save(@RequestBody WaveItem waveItem) { |
| | | waveItem.setCreateBy(getLoginUserId()); |
| | | waveItem.setCreateTime(new Date()); |
| | | waveItem.setUpdateBy(getLoginUserId()); |
| | | waveItem.setUpdateTime(new Date()); |
| | | if (!waveItemService.save(waveItem)) { |
| | | return R.error("Save Fail"); |
| | | } |
| | | return R.ok("Save Success").add(waveItem); |
| | | } |
| | | |
| | | @PreAuthorize("hasAuthority('manager:waveItem:update')") |
| | | @OperationLog("Update 波次明细") |
| | | @PostMapping("/waveItem/update") |
| | | public R update(@RequestBody WaveItem waveItem) { |
| | | waveItem.setUpdateBy(getLoginUserId()); |
| | | waveItem.setUpdateTime(new Date()); |
| | | if (!waveItemService.updateById(waveItem)) { |
| | | return R.error("Update Fail"); |
| | | } |
| | | return R.ok("Update Success").add(waveItem); |
| | | } |
| | | |
| | | @PreAuthorize("hasAuthority('manager:waveItem:remove')") |
| | | @OperationLog("Delete 波次明细") |
| | | @PostMapping("/waveItem/remove/{ids}") |
| | | public R remove(@PathVariable Long[] ids) { |
| | | if (!waveItemService.removeByIds(Arrays.asList(ids))) { |
| | | return R.error("Delete Fail"); |
| | | } |
| | | return R.ok("Delete Success").add(ids); |
| | | } |
| | | |
| | | @PreAuthorize("hasAuthority('manager:waveItem:list')") |
| | | @PostMapping("/waveItem/query") |
| | | public R query(@RequestParam(required = false) String condition) { |
| | | List<KeyValVo> vos = new ArrayList<>(); |
| | | LambdaQueryWrapper<WaveItem> wrapper = new LambdaQueryWrapper<>(); |
| | | if (!Cools.isEmpty(condition)) { |
| | | wrapper.like(WaveItem::getId, condition); |
| | | } |
| | | waveItemService.page(new Page<>(1, 30), wrapper).getRecords().forEach( |
| | | item -> vos.add(new KeyValVo(item.getId(), item.getId())) |
| | | ); |
| | | return R.ok().add(vos); |
| | | } |
| | | |
| | | @PreAuthorize("hasAuthority('manager:waveItem:list')") |
| | | @PostMapping("/waveItem/export") |
| | | public void export(@RequestBody Map<String, Object> map, HttpServletResponse response) throws Exception { |
| | | ExcelUtil.build(ExcelUtil.create(waveItemService.list(), WaveItem.class), response); |
| | | } |
| | | |
| | | } |
| | |
| | | private List<Long> typeIds; |
| | | |
| | | @ApiModelProperty("作业站点") |
| | | private String sites; |
| | | private String site; |
| | | |
| | | @ApiModelProperty("设备编号") |
| | | private String deviceCode; |
| | |
| | | @ApiModelProperty("设备作业站点") |
| | | private String deviceSites; |
| | | |
| | | @ApiModelProperty("目标站点") |
| | | private String target; |
| | | |
| | | } |
New file |
| | |
| | | package com.vincent.rsf.server.manager.entity; |
| | | |
| | | |
| | | import com.baomidou.mybatisplus.annotation.IdType; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableLogic; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | | import com.vincent.rsf.framework.common.Cools; |
| | | import com.vincent.rsf.framework.common.SpringUtils; |
| | | import com.vincent.rsf.server.system.service.UserService; |
| | | import com.vincent.rsf.server.system.entity.User; |
| | | import java.io.Serializable; |
| | | import java.util.Date; |
| | | |
| | | @Data |
| | | @TableName("man_device_bind") |
| | | public class DeviceBind implements Serializable { |
| | | |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * id |
| | | */ |
| | | @ApiModelProperty(value= "id") |
| | | @TableId(value = "id", type = IdType.AUTO) |
| | | private Long id; |
| | | |
| | | /** |
| | | * 当前排号 |
| | | */ |
| | | @ApiModelProperty(value= "当前排号") |
| | | private Integer currentRow; |
| | | |
| | | /** |
| | | * 起始排号 |
| | | */ |
| | | @ApiModelProperty(value= "起始排号") |
| | | private Integer startRow; |
| | | |
| | | /** |
| | | * 终止排号 |
| | | */ |
| | | @ApiModelProperty(value= "终止排号") |
| | | private Integer endRow; |
| | | |
| | | /** |
| | | * 设备数量 |
| | | */ |
| | | @ApiModelProperty(value= "设备数量") |
| | | private Integer deviceQty; |
| | | |
| | | /** |
| | | * 起始设备号 |
| | | */ |
| | | @ApiModelProperty(value= "起始设备号") |
| | | private Integer startDeviceNo; |
| | | |
| | | /** |
| | | * 终止设备号 |
| | | */ |
| | | @ApiModelProperty(value= "终止设备号") |
| | | private Integer endDeviceNo; |
| | | |
| | | /** |
| | | * 站点list |
| | | */ |
| | | @ApiModelProperty(value= "站点list") |
| | | private String staList; |
| | | |
| | | /** |
| | | * 库区类型 |
| | | */ |
| | | @ApiModelProperty(value= "库区类型") |
| | | private Integer typeId; |
| | | |
| | | /** |
| | | * 物料相似开关 |
| | | */ |
| | | @ApiModelProperty(value= "物料相似开关") |
| | | private String beSimilar; |
| | | |
| | | /** |
| | | * 空板靠近开关 |
| | | */ |
| | | @ApiModelProperty(value= "空板靠近开关") |
| | | private String emptySimilar; |
| | | |
| | | public DeviceBind() {} |
| | | |
| | | public DeviceBind(Integer currentRow,Integer startRow,Integer endRow,Integer deviceQty,Integer startDeviceNo,Integer endDeviceNo,String staList,Integer typeId,String beSimilar,String emptySimilar) { |
| | | this.currentRow = currentRow; |
| | | this.startRow = startRow; |
| | | this.endRow = endRow; |
| | | this.deviceQty = deviceQty; |
| | | this.startDeviceNo = startDeviceNo; |
| | | this.endDeviceNo = endDeviceNo; |
| | | this.staList = staList; |
| | | this.typeId = typeId; |
| | | this.beSimilar = beSimilar; |
| | | this.emptySimilar = emptySimilar; |
| | | } |
| | | |
| | | // DeviceBind deviceBind = new DeviceBind( |
| | | // null, // 当前排号 |
| | | // null, // 起始排号 |
| | | // null, // 终止排号 |
| | | // null, // 设备数量 |
| | | // null, // 起始设备号 |
| | | // null, // 终止设备号 |
| | | // null, // 站点list |
| | | // null, // 库区类型 |
| | | // null, // 物料相似开关 |
| | | // null // 空板靠近开关 |
| | | // ); |
| | | |
| | | |
| | | |
| | | public Boolean getStatusBool(){ |
| | | if (null == this.status){ return null; } |
| | | switch (this.status){ |
| | | case 1: |
| | | return true; |
| | | case 0: |
| | | return false; |
| | | default: |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | } |
| | |
| | | /** |
| | | * wcs站点编号 |
| | | */ |
| | | @ApiModelProperty(value= "wcs站点编号") |
| | | private String wcsCode; |
| | | @ApiModelProperty(value= "目标位置") |
| | | private String target; |
| | | |
| | | /** |
| | | * 站点标签 |
| | |
| | | this.type = type; |
| | | this.site = site; |
| | | this.name = name; |
| | | this.wcsCode = wcsCode; |
| | | this.target = wcsCode; |
| | | this.label = label; |
| | | this.device = device; |
| | | this.deviceCode = deviceCode; |
New file |
| | |
| | | package com.vincent.rsf.server.manager.entity; |
| | | |
| | | import java.text.SimpleDateFormat; |
| | | import java.util.Date; |
| | | |
| | | import lombok.experimental.Accessors; |
| | | import org.springframework.format.annotation.DateTimeFormat; |
| | | import java.text.SimpleDateFormat; |
| | | import java.util.Date; |
| | | import com.baomidou.mybatisplus.annotation.TableLogic; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.IdType; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableLogic; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | | import com.vincent.rsf.framework.common.Cools; |
| | | import com.vincent.rsf.framework.common.SpringUtils; |
| | | import com.vincent.rsf.server.system.service.UserService; |
| | | import com.vincent.rsf.server.system.entity.User; |
| | | import java.io.Serializable; |
| | | import java.util.Date; |
| | | |
| | | @Data |
| | | @TableName("man_wave") |
| | | @Accessors(chain = true) |
| | | public class Wave implements Serializable { |
| | | |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * ID |
| | | */ |
| | | @ApiModelProperty(value= "ID") |
| | | @TableId(value = "id", type = IdType.AUTO) |
| | | private Long id; |
| | | |
| | | /** |
| | | * 波次号 |
| | | */ |
| | | @ApiModelProperty(value= "波次号") |
| | | private String code; |
| | | |
| | | /** |
| | | * 波次类型 0: 手动 1: 自动 |
| | | */ |
| | | @ApiModelProperty(value= "波次类型 0: 手动 1: 自动 ") |
| | | private Short type; |
| | | |
| | | /** |
| | | * 波次状态 0: 初始化 1: 生成任务 2: 任务播种 3: 完成 |
| | | */ |
| | | @ApiModelProperty(value= "波次状态 0: 初始化 1: 生成任务 2: 任务播种 3: 完成 ") |
| | | private Short exceStatus; |
| | | |
| | | /** |
| | | * 单据数量 |
| | | */ |
| | | @ApiModelProperty(value= "单据数量") |
| | | private Double anfme; |
| | | |
| | | /** |
| | | * 已完成数量 |
| | | */ |
| | | @ApiModelProperty(value= "已完成数量") |
| | | private Double qty; |
| | | |
| | | /** |
| | | * 单据数量 |
| | | */ |
| | | @ApiModelProperty(value= "单据数量") |
| | | private Integer orderNum; |
| | | |
| | | /** |
| | | * 状态 1: 正常 0: 禁用 |
| | | */ |
| | | @ApiModelProperty(value= "状态 1: 正常 0: 禁用 ") |
| | | private Integer status; |
| | | |
| | | /** |
| | | * 所属机构 |
| | | */ |
| | | @ApiModelProperty(value= "所属机构") |
| | | private Long tenantId; |
| | | |
| | | /** |
| | | * 添加时间 |
| | | */ |
| | | @ApiModelProperty(value= "添加时间") |
| | | @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") |
| | | private Date createTime; |
| | | |
| | | /** |
| | | * 添加人员 |
| | | */ |
| | | @ApiModelProperty(value= "添加人员") |
| | | private Long createBy; |
| | | |
| | | /** |
| | | * 修改时间 |
| | | */ |
| | | @ApiModelProperty(value= "修改时间") |
| | | @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") |
| | | private Date updateTime; |
| | | |
| | | /** |
| | | * 修改人员 |
| | | */ |
| | | @ApiModelProperty(value= "修改人员") |
| | | private Long updateBy; |
| | | |
| | | /** |
| | | * 是否删除 1: 是 0: 否 |
| | | */ |
| | | @ApiModelProperty(value= "是否删除 1: 是 0: 否 ") |
| | | @TableLogic |
| | | private Integer deleted; |
| | | |
| | | /** |
| | | * 备注 |
| | | */ |
| | | @ApiModelProperty(value= "备注") |
| | | private String memo; |
| | | |
| | | public Wave() {} |
| | | |
| | | public Wave(String code,Short type,Short exceStatus,Double anfme,Double qty,Integer orderNum,Integer status,Long tenantId,Date createTime,Long createBy,Date updateTime,Long updateBy,Integer deleted,String memo) { |
| | | this.code = code; |
| | | this.type = type; |
| | | this.exceStatus = exceStatus; |
| | | this.anfme = anfme; |
| | | this.qty = qty; |
| | | this.orderNum = orderNum; |
| | | this.status = status; |
| | | this.tenantId = tenantId; |
| | | this.createTime = createTime; |
| | | this.createBy = createBy; |
| | | this.updateTime = updateTime; |
| | | this.updateBy = updateBy; |
| | | this.deleted = deleted; |
| | | this.memo = memo; |
| | | } |
| | | |
| | | // Wave wave = new Wave( |
| | | // null, // 波次号 |
| | | // null, // 波次类型 |
| | | // null, // 波次状态 |
| | | // null, // 单据数量 |
| | | // null, // 已完成数量 |
| | | // null, // 单据数量 |
| | | // null, // 状态 |
| | | // null, // 所属机构 |
| | | // null, // 添加时间 |
| | | // null, // 添加人员 |
| | | // null, // 修改时间 |
| | | // null, // 修改人员 |
| | | // null, // 是否删除 |
| | | // null // 备注 |
| | | // ); |
| | | |
| | | public String getType$(){ |
| | | if (null == this.type){ return null; } |
| | | switch (this.type){ |
| | | case 0: |
| | | return "手动"; |
| | | case 1: |
| | | return "自动"; |
| | | default: |
| | | return String.valueOf(this.type); |
| | | } |
| | | } |
| | | |
| | | public String getExceStatus$(){ |
| | | if (null == this.exceStatus){ return null; } |
| | | switch (this.exceStatus){ |
| | | case 0: |
| | | return "初始化"; |
| | | case 1: |
| | | return "生成任务"; |
| | | case 2: |
| | | return "任务播种"; |
| | | case 3: |
| | | return "完成"; |
| | | default: |
| | | return String.valueOf(this.exceStatus); |
| | | } |
| | | } |
| | | |
| | | public String getStatus$(){ |
| | | if (null == this.status){ return null; } |
| | | switch (this.status){ |
| | | case 1: |
| | | return "正常"; |
| | | case 0: |
| | | return "禁用"; |
| | | default: |
| | | return String.valueOf(this.status); |
| | | } |
| | | } |
| | | |
| | | public String getCreateTime$(){ |
| | | if (Cools.isEmpty(this.createTime)){ |
| | | return ""; |
| | | } |
| | | return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.createTime); |
| | | } |
| | | |
| | | public String getCreateBy$(){ |
| | | UserService service = SpringUtils.getBean(UserService.class); |
| | | User user = service.getById(this.createBy); |
| | | if (!Cools.isEmpty(user)){ |
| | | return String.valueOf(user.getNickname()); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | public String getUpdateTime$(){ |
| | | if (Cools.isEmpty(this.updateTime)){ |
| | | return ""; |
| | | } |
| | | return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.updateTime); |
| | | } |
| | | |
| | | public String getUpdateBy$(){ |
| | | UserService service = SpringUtils.getBean(UserService.class); |
| | | User user = service.getById(this.updateBy); |
| | | if (!Cools.isEmpty(user)){ |
| | | return String.valueOf(user.getNickname()); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | |
| | | |
| | | public Boolean getStatusBool(){ |
| | | if (null == this.status){ return null; } |
| | | switch (this.status){ |
| | | case 1: |
| | | return true; |
| | | case 0: |
| | | return false; |
| | | default: |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.vincent.rsf.server.manager.entity; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.TableLogic; |
| | | import java.text.SimpleDateFormat; |
| | | import java.util.Date; |
| | | |
| | | import lombok.experimental.Accessors; |
| | | import org.springframework.format.annotation.DateTimeFormat; |
| | | import java.text.SimpleDateFormat; |
| | | import java.util.Date; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.IdType; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableLogic; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | | import com.vincent.rsf.framework.common.Cools; |
| | | import com.vincent.rsf.framework.common.SpringUtils; |
| | | import com.vincent.rsf.server.system.service.UserService; |
| | | import com.vincent.rsf.server.system.entity.User; |
| | | import java.io.Serializable; |
| | | import java.util.Date; |
| | | |
| | | @Data |
| | | @Accessors(chain = true) |
| | | @TableName("man_wave_item") |
| | | public class WaveItem implements Serializable { |
| | | |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * ID |
| | | */ |
| | | @ApiModelProperty(value= "ID") |
| | | @TableId(value = "id", type = IdType.AUTO) |
| | | private Long id; |
| | | |
| | | /** |
| | | * 波次ID |
| | | */ |
| | | @ApiModelProperty(value= "波次ID") |
| | | private Long waveId; |
| | | |
| | | /** |
| | | * 波次号 |
| | | */ |
| | | @ApiModelProperty(value= "波次号") |
| | | private String waveCode; |
| | | |
| | | /** |
| | | * 商品ID |
| | | */ |
| | | @ApiModelProperty(value= "商品ID") |
| | | private Long matnrId; |
| | | |
| | | /** |
| | | * 物料名称 |
| | | */ |
| | | @ApiModelProperty(value= "物料名称") |
| | | private String matnrName; |
| | | |
| | | /** |
| | | * 商品编号 |
| | | */ |
| | | @ApiModelProperty(value= "商品编号") |
| | | private String matnrCode; |
| | | |
| | | /** |
| | | * 批号 |
| | | */ |
| | | @ApiModelProperty(value= "批号") |
| | | private String batch; |
| | | |
| | | /** |
| | | * 供应商批次 |
| | | */ |
| | | @ApiModelProperty(value= "供应商批次") |
| | | private String splrBatch; |
| | | |
| | | /** |
| | | * 单据编码 |
| | | */ |
| | | @ApiModelProperty(value= "单据编码") |
| | | private String orderCode; |
| | | |
| | | /** |
| | | * 单据ID |
| | | */ |
| | | @ApiModelProperty(value= "单据ID") |
| | | private Long orderItemId; |
| | | |
| | | @ApiModelProperty("订单ID") |
| | | private Long orderId; |
| | | |
| | | /** |
| | | * 单位 |
| | | */ |
| | | @ApiModelProperty(value= "单位") |
| | | private String unit; |
| | | |
| | | /** |
| | | * 跟踪码 |
| | | */ |
| | | @ApiModelProperty(value= "跟踪码") |
| | | private String trackCode; |
| | | |
| | | /** |
| | | * 商品库存索引 |
| | | */ |
| | | @ApiModelProperty(value= "商品库存索引") |
| | | private String fieldsIndex; |
| | | |
| | | /** |
| | | * 数量 |
| | | */ |
| | | @ApiModelProperty(value= "数量") |
| | | private Double anfme; |
| | | |
| | | @ApiModelProperty("已完成数量") |
| | | private Double qty; |
| | | |
| | | /** |
| | | * 工作数量 |
| | | */ |
| | | @ApiModelProperty(value= "工作数量") |
| | | private Double workQty; |
| | | |
| | | /** |
| | | * 所属机构 |
| | | */ |
| | | @ApiModelProperty(value= "所属机构") |
| | | private Long tenantId; |
| | | |
| | | /** |
| | | * 状态 1: 正常 0: 禁用 |
| | | */ |
| | | @ApiModelProperty(value= "状态 1: 正常 0: 禁用 ") |
| | | private Integer status; |
| | | |
| | | /** |
| | | * 是否删除 1: 是 0: 否 |
| | | */ |
| | | @ApiModelProperty(value= "是否删除 1: 是 0: 否 ") |
| | | @TableLogic |
| | | private Integer deleted; |
| | | |
| | | /** |
| | | * 添加时间 |
| | | */ |
| | | @ApiModelProperty(value= "添加时间") |
| | | @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") |
| | | private Date createTime; |
| | | |
| | | /** |
| | | * 添加人员 |
| | | */ |
| | | @ApiModelProperty(value= "添加人员") |
| | | private Long createBy; |
| | | |
| | | /** |
| | | * 修改时间 |
| | | */ |
| | | @ApiModelProperty(value= "修改时间") |
| | | @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") |
| | | private Date updateTime; |
| | | |
| | | /** |
| | | * 修改人员 |
| | | */ |
| | | @ApiModelProperty(value= "修改人员") |
| | | private Long updateBy; |
| | | |
| | | /** |
| | | * 备注 |
| | | */ |
| | | @ApiModelProperty(value= "备注") |
| | | private String memo; |
| | | |
| | | public WaveItem() {} |
| | | |
| | | public WaveItem(Long waveId,String waveCode,Long matnrId,String matnrName,String matnrCode,String batch,String splrBatch,String orderCode,Long orderItemId,String unit,String trackCode,String fieldsIndex,Double anfme,Double workQty,Long tenantId,Integer status,Integer deleted,Date createTime,Long createBy,Date updateTime,Long updateBy,String memo) { |
| | | this.waveId = waveId; |
| | | this.waveCode = waveCode; |
| | | this.matnrId = matnrId; |
| | | this.matnrName = matnrName; |
| | | this.matnrCode = matnrCode; |
| | | this.batch = batch; |
| | | this.splrBatch = splrBatch; |
| | | this.orderCode = orderCode; |
| | | this.orderItemId = orderItemId; |
| | | this.unit = unit; |
| | | this.trackCode = trackCode; |
| | | this.fieldsIndex = fieldsIndex; |
| | | this.anfme = anfme; |
| | | this.workQty = workQty; |
| | | this.tenantId = tenantId; |
| | | this.status = status; |
| | | this.deleted = deleted; |
| | | this.createTime = createTime; |
| | | this.createBy = createBy; |
| | | this.updateTime = updateTime; |
| | | this.updateBy = updateBy; |
| | | this.memo = memo; |
| | | } |
| | | |
| | | // WaveItem waveItem = new WaveItem( |
| | | // null, // 波次ID |
| | | // null, // 波次号 |
| | | // null, // 商品ID |
| | | // null, // 物料名称 |
| | | // null, // 商品编号 |
| | | // null, // 批号 |
| | | // null, // 供应商批次 |
| | | // null, // 单据编码 |
| | | // null, // 单据ID |
| | | // null, // 单位 |
| | | // null, // 跟踪码 |
| | | // null, // 商品库存索引 |
| | | // null, // 数量 |
| | | // null, // 工作数量 |
| | | // null, // 所属机构 |
| | | // null, // 状态 |
| | | // null, // 是否删除 |
| | | // null, // 添加时间 |
| | | // null, // 添加人员 |
| | | // null, // 修改时间 |
| | | // null, // 修改人员 |
| | | // null // 备注 |
| | | // ); |
| | | |
| | | public String getStatus$(){ |
| | | if (null == this.status){ return null; } |
| | | switch (this.status){ |
| | | case 1: |
| | | return "正常"; |
| | | case 0: |
| | | return "禁用"; |
| | | default: |
| | | return String.valueOf(this.status); |
| | | } |
| | | } |
| | | |
| | | public String getCreateTime$(){ |
| | | if (Cools.isEmpty(this.createTime)){ |
| | | return ""; |
| | | } |
| | | return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.createTime); |
| | | } |
| | | |
| | | public String getCreateBy$(){ |
| | | UserService service = SpringUtils.getBean(UserService.class); |
| | | User user = service.getById(this.createBy); |
| | | if (!Cools.isEmpty(user)){ |
| | | return String.valueOf(user.getNickname()); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | public String getUpdateTime$(){ |
| | | if (Cools.isEmpty(this.updateTime)){ |
| | | return ""; |
| | | } |
| | | return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.updateTime); |
| | | } |
| | | |
| | | public String getUpdateBy$(){ |
| | | UserService service = SpringUtils.getBean(UserService.class); |
| | | User user = service.getById(this.updateBy); |
| | | if (!Cools.isEmpty(user)){ |
| | | return String.valueOf(user.getNickname()); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | |
| | | |
| | | public Boolean getStatusBool(){ |
| | | if (null == this.status){ return null; } |
| | | switch (this.status){ |
| | | case 1: |
| | | return true; |
| | | case 0: |
| | | return false; |
| | | default: |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.vincent.rsf.server.manager.enums; |
| | | |
| | | /** |
| | | * @author Ryan |
| | | * @version 1.0 |
| | | * @title WaveExceStatus |
| | | * @description |
| | | * @create 2025/4/24 17:56 |
| | | */ |
| | | public enum WaveExceStatus { |
| | | |
| | | //波次执行状态 |
| | | WAVE_EXCE_STATUS_INIT("0", "初始化"), |
| | | WAVE_EXCE_STATUS_TASK("1", "生成任务"), |
| | | WAVE_EXCE_STATUS_SPEED("2", "播种任务"), |
| | | WAVE_EXCE_STATUS_DONE("3", "完成"), |
| | | ; |
| | | |
| | | WaveExceStatus(String val, String desc) { |
| | | this.val = Short.parseShort(val); |
| | | this.desc = desc; |
| | | } |
| | | |
| | | public Short val; |
| | | |
| | | public String desc; |
| | | } |
New file |
| | |
| | | package com.vincent.rsf.server.manager.mapper; |
| | | |
| | | import com.vincent.rsf.server.manager.entity.DeviceBind; |
| | | import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | import org.springframework.stereotype.Repository; |
| | | |
| | | @Mapper |
| | | @Repository |
| | | public interface DeviceBindMapper extends BaseMapper<DeviceBind> { |
| | | |
| | | } |
New file |
| | |
| | | package com.vincent.rsf.server.manager.mapper; |
| | | |
| | | import com.vincent.rsf.server.manager.entity.WaveItem; |
| | | import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | import org.springframework.stereotype.Repository; |
| | | |
| | | @Mapper |
| | | @Repository |
| | | public interface WaveItemMapper extends BaseMapper<WaveItem> { |
| | | |
| | | } |
New file |
| | |
| | | package com.vincent.rsf.server.manager.mapper; |
| | | |
| | | import com.vincent.rsf.server.manager.entity.Wave; |
| | | import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | import org.springframework.stereotype.Repository; |
| | | |
| | | @Mapper |
| | | @Repository |
| | | public interface WaveMapper extends BaseMapper<Wave> { |
| | | |
| | | } |
New file |
| | |
| | | package com.vincent.rsf.server.manager.service; |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | | import com.vincent.rsf.server.manager.entity.DeviceBind; |
| | | |
| | | public interface DeviceBindService extends IService<DeviceBind> { |
| | | |
| | | } |
| | |
| | | R cancelOutOrder(String id); |
| | | |
| | | R genOutStock(List<Long> ids); |
| | | |
| | | R generateWaves(List<Long> ids); |
| | | } |
New file |
| | |
| | | package com.vincent.rsf.server.manager.service; |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | | import com.vincent.rsf.server.manager.entity.WaveItem; |
| | | |
| | | public interface WaveItemService extends IService<WaveItem> { |
| | | |
| | | } |
New file |
| | |
| | | package com.vincent.rsf.server.manager.service; |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | | import com.vincent.rsf.server.manager.entity.Wave; |
| | | |
| | | public interface WaveService extends IService<Wave> { |
| | | |
| | | } |
New file |
| | |
| | | package com.vincent.rsf.server.manager.service.impl; |
| | | |
| | | import com.vincent.rsf.server.manager.mapper.DeviceBindMapper; |
| | | import com.vincent.rsf.server.manager.entity.DeviceBind; |
| | | import com.vincent.rsf.server.manager.service.DeviceBindService; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | @Service("deviceBindService") |
| | | public class DeviceBindServiceImpl extends ServiceImpl<DeviceBindMapper, DeviceBind> implements DeviceBindService { |
| | | |
| | | } |
| | |
| | | if (Objects.isNull(param.getDeviceSites()) || StringUtils.isBlank(param.getDeviceSites())) { |
| | | throw new CoolException("初始化失败: 设备作业站点不能为空!!"); |
| | | } |
| | | if (Objects.isNull(param.getSites()) || StringUtils.isBlank(param.getSites())) { |
| | | if (Objects.isNull(param.getSite()) || StringUtils.isBlank(param.getSite())) { |
| | | throw new CoolException("初始化失败: 作业站点不能为空!!"); |
| | | } |
| | | if (Objects.isNull(param.getTypeIds()) || param.getTypeIds().isEmpty()) { |
| | | throw new CoolException("初始化失败: 作业类型不能为空!!"); |
| | | } |
| | | List<String> sites = Arrays.asList(StringUtils.split(param.getSites(), ",")); |
| | | if (Objects.isNull(param.getTarget()) || param.getTarget().isEmpty()) { |
| | | throw new CoolException("初始化失败: 目标站点不能为空!!"); |
| | | } |
| | | List<String> sites = Arrays.asList(StringUtils.split(param.getSite(), ",")); |
| | | List<String> dvSites = Arrays.asList(StringUtils.split(param.getDeviceSites(), ",")); |
| | | List<String> targets = Arrays.asList(StringUtils.split(param.getTarget(), ",")); |
| | | List<DeviceSite> deviceSites = new ArrayList<>(); |
| | | for (String site : sites) { |
| | | for (String deviceSite : dvSites) { |
| | | for (Long id : param.getTypeIds()) { |
| | | DeviceSite site1 = new DeviceSite(); |
| | | site1.setType(id + "") |
| | | .setSite(site) |
| | | .setDevice(param.getDeviceType()) |
| | | .setDeviceSite(deviceSite) |
| | | .setDeviceCode(param.getDeviceCode()); |
| | | deviceSites.add(site1); |
| | | for (String target : targets) { |
| | | DeviceSite site1 = new DeviceSite(); |
| | | site1.setType(id + "") |
| | | .setSite(site) |
| | | .setDevice(param.getDeviceType()) |
| | | .setDeviceSite(deviceSite) |
| | | .setTarget(target) |
| | | .setDeviceCode(param.getDeviceCode()); |
| | | deviceSites.add(site1); |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | import com.vincent.rsf.server.manager.controller.params.BatchUpdateParam; |
| | | import com.vincent.rsf.server.manager.entity.*; |
| | | import com.vincent.rsf.server.manager.enums.AsnExceStatus; |
| | | import com.vincent.rsf.server.manager.enums.WaveExceStatus; |
| | | import com.vincent.rsf.server.manager.mapper.AsnOrderMapper; |
| | | import com.vincent.rsf.server.manager.mapper.PurchaseMapper; |
| | | import com.vincent.rsf.server.manager.service.*; |
| | |
| | | private AsnOrderLogService asnOrderLogService; |
| | | @Autowired |
| | | private AsnOrderItemLogService asnOrderItemLogService; |
| | | |
| | | @Autowired |
| | | private DeliveryItemService deliveryItemService; |
| | | |
| | | @Autowired |
| | | private DeliveryService deliveryService; |
| | | @Autowired |
| | | private MatnrService matnrService; |
| | | |
| | | @Autowired |
| | | private WaveService waveService; |
| | | @Autowired |
| | | private WaveItemService waveItemService; |
| | | |
| | | |
| | | /** |
| | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public R cancelOutOrder(String id) { |
| | | //TODO 出库单取消流程,QMS(单据取消)->DO单->出库单->波次->判断是否全单据->全单据下发取消任务至WCS,非全单数据取消删除流程所有关联数据 |
| | | if (Cools.isEmpty(id)) { |
| | | throw new CoolException("参数不能为空!!"); |
| | | } |
| | |
| | | }); |
| | | return R.ok(); |
| | | } |
| | | |
| | | /** |
| | | * @param |
| | | * @return |
| | | * @author Ryan |
| | | * @description 生成波次 |
| | | * @time 2025/4/24 15:04 |
| | | */ |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public R generateWaves(List<Long> ids) { |
| | | if (Objects.isNull(ids) || ids.isEmpty()) { |
| | | throw new CoolException("参数不能为空!!"); |
| | | } |
| | | List<AsnOrder> orders = this.listByIds(ids); |
| | | if (orders.isEmpty()) { |
| | | throw new CoolException("单据不存在!!"); |
| | | } |
| | | double sum = orders.stream().mapToDouble(AsnOrder::getAnfme).sum(); |
| | | Wave wave = new Wave(); |
| | | String ruleCode = SerialRuleUtils.generateRuleCode(SerialRuleCode.SYS_WAVE_TYPE, null); |
| | | if (Objects.isNull(ruleCode) || StringUtils.isBlank(ruleCode)) { |
| | | throw new CoolException("编码规则错误:请要查看「SYS_WAVE_TYPE」是否设置成功!!"); |
| | | } |
| | | wave.setOrderNum(ids.size()) |
| | | .setType(Short.parseShort("1")) |
| | | .setCode(ruleCode) |
| | | .setExceStatus(WaveExceStatus.WAVE_EXCE_STATUS_INIT.val) |
| | | .setAnfme(sum); |
| | | if (!waveService.save(wave)) { |
| | | throw new CoolException("波次保存失败!!"); |
| | | } |
| | | List<Long> list = orders.stream().map(AsnOrder::getId).collect(Collectors.toList()); |
| | | List<WaveItem> items = new ArrayList<>(); |
| | | List<AsnOrderItem> orderItems = asnOrderItemService |
| | | .list(new LambdaQueryWrapper<AsnOrderItem>() |
| | | .in(AsnOrderItem::getAsnId, list)); |
| | | |
| | | |
| | | for (AsnOrderItem item : orderItems) { |
| | | WaveItem waveItem = new WaveItem(); |
| | | BeanUtils.copyProperties(item, waveItem); |
| | | waveItem.setWaveId(wave.getId()) |
| | | .setWaveCode(wave.getCode()) |
| | | .setOrderId(item.getAsnId()) |
| | | .setOrderCode(item.getAsnCode()) |
| | | .setOrderItemId(item.getId()); |
| | | items.add(waveItem); |
| | | } |
| | | if (!waveItemService.saveBatch(items)) { |
| | | throw new CoolException("波次明细保存失败!!"); |
| | | } |
| | | return R.ok("操作完成!!"); |
| | | } |
| | | } |
New file |
| | |
| | | package com.vincent.rsf.server.manager.service.impl; |
| | | |
| | | import com.vincent.rsf.server.manager.mapper.WaveItemMapper; |
| | | import com.vincent.rsf.server.manager.entity.WaveItem; |
| | | import com.vincent.rsf.server.manager.service.WaveItemService; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | @Service("waveItemService") |
| | | public class WaveItemServiceImpl extends ServiceImpl<WaveItemMapper, WaveItem> implements WaveItemService { |
| | | |
| | | } |
New file |
| | |
| | | package com.vincent.rsf.server.manager.service.impl; |
| | | |
| | | import com.vincent.rsf.server.manager.mapper.WaveMapper; |
| | | import com.vincent.rsf.server.manager.entity.Wave; |
| | | import com.vincent.rsf.server.manager.service.WaveService; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | @Service("waveService") |
| | | public class WaveServiceImpl extends ServiceImpl<WaveMapper, Wave> implements WaveService { |
| | | |
| | | } |
| | |
| | | */ |
| | | public final static String SYS_OUT_STOCK_CODE = "sys_out_stock_code"; |
| | | |
| | | /** |
| | | * 波次类型 |
| | | */ |
| | | public final static String SYS_WAVE_TYPE = "sys_wave_type"; |
| | | |
| | | } |
New file |
| | |
| | | -- save deviceBind record |
| | | -- mysql |
| | | insert into `sys_menu` ( `name`, `parent_id`, `route`, `component`, `type`, `sort`, `tenant_id`, `status`) values ( 'menu.deviceBind', '0', '/manager/deviceBind', 'deviceBind', '0' , '0', '1' , '1'); |
| | | |
| | | insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Query 立体库站点绑定', '', '1', 'manager:deviceBind:list', '0', '1', '1'); |
| | | insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Create 立体库站点绑定', '', '1', 'manager:deviceBind:save', '1', '1', '1'); |
| | | insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Update 立体库站点绑定', '', '1', 'manager:deviceBind:update', '2', '1', '1'); |
| | | insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Delete 立体库站点绑定', '', '1', 'manager:deviceBind:remove', '3', '1', '1'); |
| | | |
| | | -- locale menu name |
| | | deviceBind: 'DeviceBind', |
| | | |
| | | -- locale field |
| | | deviceBind: { |
| | | currentRow: "currentRow", |
| | | startRow: "startRow", |
| | | endRow: "endRow", |
| | | deviceQty: "deviceQty", |
| | | startDeviceNo: "startDeviceNo", |
| | | endDeviceNo: "endDeviceNo", |
| | | staList: "staList", |
| | | typeId: "typeId", |
| | | beSimilar: "beSimilar", |
| | | emptySimilar: "emptySimilar", |
| | | }, |
| | | |
| | | -- ResourceContent |
| | | import deviceBind from './deviceBind'; |
| | | |
| | | case 'deviceBind': |
| | | return deviceBind; |
New file |
| | |
| | | -- save wave record |
| | | -- mysql |
| | | insert into `sys_menu` ( `name`, `parent_id`, `route`, `component`, `type`, `sort`, `tenant_id`, `status`) values ( 'menu.wave', '0', '/manager/wave', 'wave', '0' , '0', '1' , '1'); |
| | | |
| | | insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Query 波次单据', '', '1', 'manager:wave:list', '0', '1', '1'); |
| | | insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Create 波次单据', '', '1', 'manager:wave:save', '1', '1', '1'); |
| | | insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Update 波次单据', '', '1', 'manager:wave:update', '2', '1', '1'); |
| | | insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Delete 波次单据', '', '1', 'manager:wave:remove', '3', '1', '1'); |
| | | |
| | | -- locale menu name |
| | | wave: 'Wave', |
| | | |
| | | -- locale field |
| | | wave: { |
| | | code: "code", |
| | | type: "type", |
| | | exceStatus: "exceStatus", |
| | | anfme: "anfme", |
| | | qty: "qty", |
| | | orderNum: "orderNum", |
| | | }, |
| | | |
| | | -- ResourceContent |
| | | import wave from './wave'; |
| | | |
| | | case 'wave': |
| | | return wave; |
New file |
| | |
| | | -- save waveItem record |
| | | -- mysql |
| | | insert into `sys_menu` ( `name`, `parent_id`, `route`, `component`, `type`, `sort`, `tenant_id`, `status`) values ( 'menu.waveItem', '0', '/manager/waveItem', 'waveItem', '0' , '0', '1' , '1'); |
| | | |
| | | insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Query 波次明细', '', '1', 'manager:waveItem:list', '0', '1', '1'); |
| | | insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Create 波次明细', '', '1', 'manager:waveItem:save', '1', '1', '1'); |
| | | insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Update 波次明细', '', '1', 'manager:waveItem:update', '2', '1', '1'); |
| | | insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Delete 波次明细', '', '1', 'manager:waveItem:remove', '3', '1', '1'); |
| | | |
| | | -- locale menu name |
| | | waveItem: 'WaveItem', |
| | | |
| | | -- locale field |
| | | waveItem: { |
| | | waveId: "waveId", |
| | | waveCode: "waveCode", |
| | | matnrId: "matnrId", |
| | | matnrName: "matnrName", |
| | | matnrCode: "matnrCode", |
| | | batch: "batch", |
| | | splrBatch: "splrBatch", |
| | | orderCode: "orderCode", |
| | | orderItemId: "orderItemId", |
| | | unit: "unit", |
| | | trackCode: "trackCode", |
| | | fieldsIndex: "fieldsIndex", |
| | | anfme: "anfme", |
| | | workQty: "workQty", |
| | | }, |
| | | |
| | | -- ResourceContent |
| | | import waveItem from './waveItem'; |
| | | |
| | | case 'waveItem': |
| | | return waveItem; |
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.DeviceBindMapper"> |
| | | |
| | | </mapper> |
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.WaveItemMapper"> |
| | | |
| | | </mapper> |
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.WaveMapper"> |
| | | |
| | | </mapper> |