skyouc
15 小时以前 5c372e346df385e4ca4600e0bd3c3f2e143ead7e
调拔单功能优化
15个文件已修改
2个文件已添加
585 ■■■■■ 已修改文件
rsf-admin/src/i18n/zh.js 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/components/DictSelect.jsx 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/components/WarehouseSelect.jsx 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/transfer/ManualCreate.jsx 91 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/transfer/TransferEdit.jsx 39 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/transfer/TransferItemList.jsx 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/transfer/TransferList.jsx 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/transfer/TransferPanel.jsx 183 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/TransferController.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/Transfer.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/TransferOrder.java 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/mapper/TransferMapper.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/TransferService.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/TransferItemServiceImpl.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/TransferServiceImpl.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/system/constant/DictTypeCode.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/resources/mapper/manager/TransferMapper.xml 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/i18n/zh.js
@@ -217,6 +217,7 @@
        checkOrder: '盘点单',
        checkDiff: '盘点差异单',
        transfer: '调拔单',
        transferItem: '调拔单明细'
    },
    table: {
        field: {
rsf-admin/src/page/components/DictSelect.jsx
@@ -47,7 +47,6 @@
                variant="filled"
                onChange={handleChange}
                size='small'
            >
                {list.map((item) => (
                    <MenuItem key={item.value} value={item.value}>
rsf-admin/src/page/components/WarehouseSelect.jsx
New file
@@ -0,0 +1,64 @@
import { useState, useEffect } from 'react';
import {
    useTranslate, useNotify, required
} from 'react-admin';
import request from '@/utils/request';
import { Select, MenuItem, FormControl, InputLabel } from '@mui/material';
const WarehouseSelect = (props) => {
    const { dictTypeCode, label, value, onChange, ...params } = props;
    const translate = useTranslate();
    const notify = useNotify();
    const [list, setList] = useState([]);
    useEffect(() => {
        http();
    }, [dictTypeCode]);
    const http = async () => {
        const res = await request.post('/warehouseAreas/page', {});
        if (res?.data?.code === 200) {
            setList(res.data.data.records.map((item) => {
                return {
                    id: item.id,
                    name: item.name
                };
            }));
        } else {
            notify(res.data.msg);
        }
    };
    const handleChange = (event) => {
        const selectedValue = event.target.value;
        console.log(event);
        if (onChange) {
            onChange(event);
        }
    };
    const validValue = list.some(item => item.id === value) ? value : '';
    return (
        <FormControl fullWidth>
            <InputLabel id="demo-select-small-label">{label}</InputLabel>
            <Select
                labelId="demo-select-small-label"
                value={validValue}
                variant="filled"
                onChange={handleChange}
                size='small'
            >
                {list.map((item) => (
                    <MenuItem
                        key={item.id}
                        value={item.id}>
                        {item.name}
                    </MenuItem>
                ))}
            </Select>
        </FormControl>
    );
};
export default WarehouseSelect;
rsf-admin/src/page/orders/transfer/ManualCreate.jsx
@@ -17,6 +17,7 @@
    useNotify,
    Form,
    useCreateController,
    SimpleForm,
} from 'react-admin';
import {
    Dialog,
@@ -35,11 +36,13 @@
} from '@mui/material';
import ConfirmationNumberIcon from '@mui/icons-material/ConfirmationNumber';
import DialogCloseButton from "../../components/DialogCloseButton.jsx";
import WarehouseSelect from "../../components/WarehouseSelect.jsx";
import { DataGrid, useGridApiRef } from '@mui/x-data-grid';
import ConfirmButton from "../../components/ConfirmButton";
import CreateBySelectMats from "./CreateBySelectMats.jsx";
import { Add, Edit, Delete } from '@mui/icons-material';
import DictSelect from "../../components/DictSelect";
import { useFormContext, useWatch } from "react-hook-form";
import { minHeight, padding } from "@mui/system";
import SaveIcon from '@mui/icons-material/Save';
import request from '@/utils/request';
@@ -54,6 +57,8 @@
    const [selectedRows, setSelectedRows] = useState([]);
    const [createDialog, setCreateDialog] = useState(false);
    const [formData, setFormData] = useState({});
    const [list, setList] = useState([]);
    const handleClose = (event, reason) => {
        if (reason !== "backdropClick") {
            setOpen(false);
@@ -69,15 +74,17 @@
        setTableData([...tabelData]);
    }
    const handleSubmit = async () => {
        setFinally()
        setDisabled(true)
        if (orderId === 0) {
        if (orderId == null || orderId == undefined) {
            const parmas = {
                "orders": formData,
                "transfer": formData,
                "items": tabelData,
            }
            const res = await request.post(`/transfer/items/save`, parmas);
            if (res?.data?.code === 200) {
                setOpen(false);
@@ -88,7 +95,7 @@
            }
        } else {
            const parmas = {
                "orders": formData,
                "transfer": formData,
                "items": tabelData,
            }
            const res = await request.post(`/transfer/items/update`, parmas);
@@ -117,43 +124,69 @@
        notify(error.message || 'common.response.fail', { type: 'error', messageArgs: { _: error.message } });
    };
    const getWarehouse = async () => {
        const res = await request.post('/warehouseAreas/page');
        if (res?.data?.code === 200) {
            setList(res.data.data.records.map((item) => {
                return {
                    id: item.id,
                    name: item.name
                };
            }));
        } else {
            notify(res.data.msg);
        }
    }
    const handleChange = (value, name) => {
        console.log(name);
        console.log(value);
        setFormData((prevData) => ({
            ...prevData,
            [name]: value
        }));
        console.log(formData);
    };
    return (
        <>
            <Box sx={{ padding: 1 }}>
                <Box sx={{ display: 'flex', flexDirection: 'column', gap: 3 }}>
                    <Form defaultValues={formData}>
                        <Grid container spacing={2}>
                            <Grid item md={2}>
                                <DictSelect
                                    label={translate("table.field.transfer.type")}
                                    value={formData.type}
                                    variant="filled"
                                    onChange={(e) => handleChange(e.target.value, 'type')}
                                    dictTypeCode="sys_transfer_type"
                                    required
                                />
                            </Grid>
                            <Grid item md={2}>
                                <ReferenceInput reference="warehouseAreas" source="orgAreaName">
                                    <AutocompleteInput optionText="name" label="table.field.transfer.orgAreaName" />
                                </ReferenceInput>
                            </Grid>
                            <Grid item md={2}>
                                <ReferenceInput reference="warehouseAreas" source="tarAreaName">
                                    <AutocompleteInput optionText="name" label="table.field.transfer.tarAreaName" />
                                </ReferenceInput>
                            </Grid>
                <SimpleForm toolbar={false}>
                    <Grid container spacing={2}>
                        <Grid item md={2}>
                            <DictSelect
                                label={translate("table.field.transfer.type")}
                                value={formData.type}
                                variant="filled"
                                onChange={(e) => handleChange(e.target.value, 'type')}
                                dictTypeCode="sys_transfer_type"
                                required
                            />
                        </Grid>
                    </Form>
                </Box>
                        <Grid item md={2}>
                            <WarehouseSelect
                                value={formData.orgAreaId}
                                variant="filled"
                                dictTypeCode="warehouse"
                                required
                                onChange={(e) => handleChange(e.target.value, 'orgAreaId')}
                                label={translate("table.field.transfer.orgAreaName")} />
                        </Grid>
                        <Grid item md={2}>
                            <WarehouseSelect
                                label={translate("table.field.transfer.tarAreaName")}
                                value={formData.tarAreaId}
                                dictTypeCode="warehouse"
                                variant="filled"
                                required
                                onChange={(e) => handleChange(e.target.value, 'tarAreaId')}
                            />
                        </Grid>
                    </Grid>
                </SimpleForm>
                <Box sx={{ mt: 2 }}>
                    <Stack direction="row" spacing={2} sx={{ justifyContent: "flex-end" }}>
                        <Button variant="contained" onClick={() => setCreateDialog(true)} >
@@ -461,7 +494,7 @@
                onRowSelectionModelChange={handleSelectionChange}
                selectionModel={selectedRows}
                sx={{
                    height: 610,
                    height: 580,
                    '& .MuiDataGrid-cell input': {
                        border: '1px solid #ccc'
                    },
rsf-admin/src/page/orders/transfer/TransferEdit.jsx
@@ -34,7 +34,7 @@
  const { getValues } = useFormContext();
  return (
    <Toolbar sx={{ justifyContent: "space-between" }}>
    <Toolbar sx={{ justifyContent: "flex-end" }}>
      <SaveButton />
      <DeleteButton mutationMode="optimistic" />
    </Toolbar>
@@ -53,20 +53,34 @@
        aside={<EditBaseAside />}
      >
        <SimpleForm
          sx={{
            "& .MuiFormLabel-root.MuiInputLabel-root.Mui-disabled": {
              bgcolor: 'white',
              WebkitTextFillColor: "rgba(0, 0, 0)"
            },
            "& .MuiInputBase-input.MuiFilledInput-input.Mui-disabled": {
              bgcolor: 'white',
              WebkitTextFillColor: "rgba(0, 0, 0)"
            },
            "& .MuiFilledInput-root.MuiInputBase-sizeSmall": {
              bgcolor: 'white',
            }
          }}
          shouldUnregister
          warnWhenUnsavedChanges
          toolbar={<FormToolbar />}
          toolbar={false}
          mode="onTouched"
          defaultValues={{}}
          // validate={(values) => { }}
        >
          <Grid
            container
            width={{ xs: "100%", xl: "80%" }}
            width={{ xs: "100%", xl: "90%", }}
            rowSpacing={3}
            columnSpacing={3}
          >
            <Grid item xs={12} md={8}>
            <Grid item xs={24} md={16}>
              <Typography variant="h6" gutterBottom>
                {translate("common.edit.title.main")}
              </Typography>
@@ -76,13 +90,13 @@
                  source="code"
                  parse={(v) => v}
                  autoFocus
                  readOnly
                />
              </Stack>
              <Stack direction="row" gap={2}>
                <NumberInput label="table.field.transfer.type" source="type" />
                <NumberInput label="table.field.transfer.type" source="type" readOnly/>
                <SelectInput
                  label="table.field.transfer.source"
                  source="source"
                  readOnly
                  choices={[
                    { id: 1, name: "ERP系统" },
                    { id: 2, name: "WMS系统生成" },
@@ -93,6 +107,7 @@
                <SelectInput
                  label="table.field.transfer.exceStatus"
                  source="exceStatus"
                  readOnly
                  choices={[
                    { id: 0, name: "未执行" },
                    { id: 1, name: "执行中" },
@@ -104,19 +119,23 @@
                <NumberInput
                  label="table.field.transfer.orgWareId"
                  source="orgWareId"
                  readOnly
                />
                <TextInput
                  label="table.field.transfer.orgWareName"
                  source="orgWareName"
                  readOnly
                  parse={(v) => v}
                />
                <NumberInput
                  label="table.field.transfer.tarWareId"
                  source="tarWareId"
                  readOnly
                />
                <TextInput
                  label="table.field.transfer.tarWareName"
                  source="tarWareName"
                  readOnly
                  parse={(v) => v}
                />
              </Stack>
@@ -124,19 +143,23 @@
                <NumberInput
                  label="table.field.transfer.orgAreaId"
                  source="orgAreaId"
                  readOnly
                />
                <TextInput
                  label="table.field.transfer.orgAreaName"
                  source="orgAreaName"
                  readOnly
                  parse={(v) => v}
                />
                <NumberInput
                  label="table.field.transfer.tarAreaId"
                  source="tarAreaId"
                  readOnly
                />
                <TextInput
                  label="table.field.transfer.tarAreaName"
                  source="tarAreaName"
                  readOnly
                  parse={(v) => v}
                />
              </Stack>
rsf-admin/src/page/orders/transfer/TransferItemList.jsx
@@ -91,77 +91,65 @@
const TransferItemList = () => {
    const translate = useTranslate();
    const [createDialog, setCreateDialog] = useState(false);
    const [drawerVal, setDrawerVal] = useState(false);
    const [createDialog, setCreateDialog] = useState(false);
    return (
        <Box display="flex">
            <List
                resource="transferItem"
                sx={{
                    flexGrow: 1,
                    transition: (theme) =>
                        theme.transitions.create(['all'], {
                            duration: theme.transitions.duration.enteringScreen,
                        }),
                    marginRight: !!drawerVal ? `${PAGE_DRAWER_WIDTH}px` : 0,
                }}
                title={"menu.transferItem"}
                empty={<EmptyData onClick={() => { setCreateDialog(true) }} />}
                title={false}
                empty={false}
                filters={filters}
                sort={{ field: "create_time", order: "desc" }}
                actions={(
                    <TopToolbar>
                        <FilterButton />
                        <MyCreateButton onClick={() => { setCreateDialog(true) }} />
                        <SelectColumnsButton preferenceKey='transferItem' />
                        <MyExportButton />
                    </TopToolbar>
                )}
                perPage={DEFAULT_PAGE_SIZE}
            >
                <StyledDatagrid
                    preferenceKey='transferItem'
                    bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />}
                    bulkActionButtons={false}
                    rowClick={(id, resource, record) => false}
                    expand={false}
                    expandSingle={false}
                    omit={['id', 'createTime', 'createBy', 'memo']}
                    omit={['id', 'transferId', 'matnrId', 'createTime', 'createBy', 'memo', 'platItemId', 'splrId', 'fieldsIndex', 'platOrderCode', 'platWorkCode', 'projectCode']}
                >
                    <NumberField source="id" />
                    <NumberField source="transferId" label="table.field.transferItem.transferId" />
                    <TextField source="transferCode" label="table.field.transferItem.transferCode" />
                    <NumberField source="matnrId" label="table.field.transferItem.matnrId" />
                    <TextField source="maktx" label="table.field.transferItem.maktx" />
                    <TextField source="matnrCode" label="table.field.transferItem.matnrCode" />
                    <TextField source="unit" label="table.field.transferItem.unit" />
                    <NumberField source="anfme" label="table.field.transferItem.anfme" />
                    <NumberField source="qty" label="table.field.transferItem.qty" />
                    <NumberField source="workQty" label="table.field.transferItem.workQty" />
                    <TextField source="batch" label="table.field.transferItem.batch" />
                    <NumberField source="splrId" label="table.field.transferItem.splrId" />
                    <TextField source="maktx" label="table.field.transferItem.maktx" />
                    <TextField source="spec" label="table.field.transferItem.spec" />
                    <TextField source="model" label="table.field.transferItem.model" />
                    <TextField source="batch" label="table.field.transferItem.batch" />
                    <TextField source="unit" label="table.field.transferItem.unit" />
                    <NumberField source="anfme" label="table.field.transferItem.anfme" />
                    <NumberField source="workQty" label="table.field.transferItem.workQty" />
                    <NumberField source="qty" label="table.field.transferItem.qty" />
                    <NumberField source="splrId" label="table.field.transferItem.splrId" />
                    <TextField source="fieldsIndex" label="table.field.transferItem.fieldsIndex" />
                    <TextField source="platItemId" label="table.field.transferItem.platItemId" />
                    <TextField source="platOrderCode" label="table.field.transferItem.platOrderCode" />
                    <TextField source="platWorkCode" label="table.field.transferItem.platWorkCode" />
                    <TextField source="projectCode" label="table.field.transferItem.projectCode" />
                    <ReferenceField source="updateBy" label="common.field.updateBy" reference="user" link={false} sortable={false}>
                        <TextField source="nickname" />
                    </ReferenceField>
                    <TextField source="updateBy$" label="common.field.updateBy" />
                    <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>
                    <TextField source="createBy$" label="common.field.createBy" />
                    <DateField source="createTime" label="common.field.createTime" showTime />
                    <BooleanField source="statusBool" label="common.field.status" sortable={false} />
                    {/* <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>
            <PageDrawer
rsf-admin/src/page/orders/transfer/TransferList.jsx
@@ -32,12 +32,11 @@
    AutocompleteInput,
    DeleteButton,
} from 'react-admin';
import { Box, Typography, Card, Stack } from '@mui/material';
import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting.js';
import MyCreateButton from "../../components/MyCreateButton.jsx";
import MyExportButton from '../../components/MyExportButton.jsx';
import PageEditDrawer from "../../components/PageEditDrawer";
import { Box, Typography, Card, Stack } from '@mui/material';
import PageDrawer from "../../components/PageDrawer.jsx";
import EmptyData from "../../components/EmptyData.jsx";
import MyField from "../../components/MyField.jsx";
@@ -138,13 +137,12 @@
                    rowClick={(id, resource, record) => false}
                    expand={() => <TransferPanel />}
                    expandSingle={true}
                    omit={['id', 'createTime', 'createBy$', 'memo']}
                    omit={['id', 'createTime', 'createBy$', 'memo', 'orgWareId', 'tarWareId', 'orgAreaId', 'tarAreaId']}
                >
                    <NumberField source="id" />
                    <TextField source="code" label="table.field.transfer.code" />
                    <NumberField source="type" label="table.field.transfer.type" />
                    <NumberField source="type$" label="table.field.transfer.type" />
                    <TextField source="source$" label="table.field.transfer.source" sortable={false} />
                    <TextField source="exceStatus$" label="table.field.transfer.exceStatus" sortable={false} />
                    <NumberField source="orgWareId" label="table.field.transfer.orgWareId" />
                    <TextField source="orgWareName" label="table.field.transfer.orgWareName" />
                    <NumberField source="tarWareId" label="table.field.transfer.tarWareId" />
@@ -153,11 +151,11 @@
                    <TextField source="orgAreaName" label="table.field.transfer.orgAreaName" />
                    <NumberField source="tarAreaId" label="table.field.transfer.tarAreaId" />
                    <TextField source="tarAreaName" label="table.field.transfer.tarAreaName" />
                    <TextField source="exceStatus$" label="table.field.transfer.exceStatus" sortable={false} />
                    <TextField source="updateBy$" label="common.field.updateBy" />
                    <DateField source="updateTime" label="common.field.updateTime" showTime />
                    <TextField source="createBy$" label="common.field.createBy" />
                    <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' }} />
@@ -170,7 +168,7 @@
                drawerVal={createDialog}
                setDrawerVal={setCreateDialog}
            >
                <ManualCreate />
                <ManualCreate setOpen={setCreateDialog} />
            </PageEditDrawer>
        </Box>
    )
rsf-admin/src/page/orders/transfer/TransferPanel.jsx
@@ -1,11 +1,43 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import { Box, Card, CardContent, Grid, Typography, Tooltip } from '@mui/material';
import {
    List,
    DateField,
    TextField,
    TopToolbar,
    FilterButton,
    NumberField,
    useTranslate,
    WrapperField,
    useRecordContext,
    DatagridConfigurable,
} from 'react-admin';
import PanelTypography from "../../components/PanelTypography.jsx";
import * as Common from '@/utils/common.js'
import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting.js';
import BillStatusField from '../../components/BillStatusField';
import { styled } from '@mui/material/styles';
import * as Common from '@/utils/common.js';
const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({
    '& .css-1vooibu-MuiSvgIcon-root': {
        height: '.9em'
    },
    '& .RaDatagrid-row': {
        cursor: 'auto'
    },
    '& .column-name': {
    },
    '& .opt': {
        width: 220
    },
    '& .wkType': {
        width: 110
    },
    '& .status': {
        width: 90
    },
}));
const TransferPanel = () => {
    const record = useRecordContext();
@@ -13,108 +45,51 @@
    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.transfer.id'))}: {record.id}
                            </Typography>
                            {/*  inherit, primary, secondary, textPrimary, textSecondary, error */}
                            <Typography variant="h6" gutterBottom align="right" >
                                ID: {record.id}
                            </Typography>
                        </Grid>
                    </Grid>
                    <Grid container spacing={2}>
                        <Grid item xs={12} container alignContent="flex-end">
                            <Typography variant="caption" color="textSecondary" sx={{ wordWrap: 'break-word', wordBreak: 'break-all' }}>
                                {Common.camelToPascalWithSpaces(translate('common.field.memo'))}:{record.memo}
                            </Typography>
                        </Grid>
                    </Grid>
                    <Box height={20}>&nbsp;</Box>
                    <Grid container spacing={2}>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.transfer.code"
                                property={record.code}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.transfer.type"
                                property={record.type}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.transfer.source"
                                property={record.source$}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.transfer.exceStatus"
                                property={record.exceStatus$}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.transfer.orgWareId"
                                property={record.orgWareId}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.transfer.orgWareName"
                                property={record.orgWareName}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.transfer.tarWareId"
                                property={record.tarWareId}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.transfer.tarWareName"
                                property={record.tarWareName}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.transfer.orgAreaId"
                                property={record.orgAreaId}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.transfer.orgAreaName"
                                property={record.orgAreaName}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.transfer.tarAreaId"
                                property={record.tarAreaId}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.transfer.tarAreaName"
                                property={record.tarAreaName}
                            />
                        </Grid>
                    </Grid>
                </CardContent>
            <Card sx={{ margin: 'auto' }}>
                <List
                    resource="transfer/orders"
                    sx={{
                        flexGrow: 1,
                        transition: (theme) =>
                            theme.transitions.create(['all'], {
                                duration: theme.transitions.duration.enteringScreen,
                            }),
                    }}
                    title={false}
                    empty={false}
                    pagination={false}
                    filters={false}
                    filter={{ id: record?.id }}
                    sort={{ field: "create_time", order: "desc" }}
                    actions={false}
                    perPage={DEFAULT_PAGE_SIZE}
                >
                    <StyledDatagrid
                        sx={{ width: '100%' }}
                        preferenceKey='outStock'
                        bulkActionButtons={false}
                        rowClick={false}
                        expandSingle={true}
                        omit={['id', 'createTime', 'createBy$', 'memo', 'rleStatus$']}
                    >
                        <NumberField source="id" />
                        <TextField source="code" label="table.field.outStock.code" />
                        <TextField source="poCode" label="table.field.outStock.poCode" />
                        <TextField source="type$" label="table.field.outStock.type" />
                        <TextField cellClassName="wkType" source="wkType$" label="table.field.outStock.wkType" />
                        <NumberField source="anfme" label="table.field.outStock.anfme" />
                        <NumberField source="workQty" label="table.field.outStock.workQty" />
                        <NumberField source="qty" label="table.field.outStock.qty" />
                        <TextField source="logisNo" label="table.field.outStock.logisNo" />
                        <TextField source="rleStatus$" label="table.field.outStock.rleStatus" sortable={false} />
                        <TextField source="updateBy$" label="common.field.updateBy" />
                        <DateField source="updateTime" label="common.field.updateTime" showTime />
                        <TextField source="createBy$" label="common.field.createBy" />
                        <DateField source="createTime" label="common.field.createTime" showTime />
                        <BillStatusField cellClassName="status" source="exceStatus" label="table.field.outStock.exceStatus" />
                        <TextField source="memo" label="common.field.memo" sortable={false} />
                    </StyledDatagrid>
                </List>
            </Card >
        </>
    );
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/TransferController.java
@@ -42,6 +42,14 @@
    }
    @PreAuthorize("hasAuthority('manager:transfer:list')")
    @PostMapping("/transfer/orders/page")
    public R getTransferInfo(@RequestBody Map<String, Object> map) {
        BaseParam baseParam = buildParam(map, BaseParam.class);
        PageParam<Transfer, BaseParam> pageParam = new PageParam<>(baseParam, Transfer.class);
        return R.ok().add(transferService.transfersPage(pageParam, pageParam.buildWrapper(true)));
    }
    @PreAuthorize("hasAuthority('manager:transfer:list')")
    @PostMapping("/transfer/list")
    public R list(@RequestBody Map<String, Object> map) {
        return R.ok().add(transferService.list());
rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/Transfer.java
@@ -230,13 +230,25 @@
        }
    }
    public String getType$() {
        if (null == this.type){ return null; }
        DictDataService dictDataService = SpringUtils.getBean(DictDataService.class);
        DictData dictData = dictDataService.getOne(new LambdaQueryWrapper<DictData>()
                .eq(DictData::getDictTypeCode, DictTypeCode.SYS_TRANSFER_TYPE)
                .eq(DictData::getValue, this.type));
        if (Objects.isNull(dictData)) {
            return null;
        }
        return dictData.getLabel();
    }
    public String getExceStatus$() {
        if (Cools.isEmpty(this.exceStatus)){
            return "";
        }
        DictDataService dictDataService = SpringUtils.getBean(DictDataService.class);
        DictData dictData = dictDataService.getOne(new LambdaQueryWrapper<DictData>()
                .eq(DictData::getDictTypeCode, DictTypeCode.SYS_ORDER_SOURCE)
                .eq(DictData::getDictTypeCode, DictTypeCode.SYS_WAVE_EXCE_STATUS)
                .eq(DictData::getValue, this.exceStatus));
        if (Objects.isNull(dictData)) {
            return null;
rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/TransferOrder.java
New file
@@ -0,0 +1,32 @@
package com.vincent.rsf.server.manager.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
@Data
@Accessors
@TableName("man_transfer_order")
public class TransferOrder implements Serializable {
    private static final long serialVersionUID = 1L;
    @ApiModelProperty(value= "ID")
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    @ApiModelProperty("调拔单ID")
    private Long transferId;
    @ApiModelProperty("订单ID")
    private Long orderId;
    @ApiModelProperty("执行状态")
    private Integer exceStatus;
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/mapper/TransferMapper.java
@@ -1,12 +1,20 @@
package com.vincent.rsf.server.manager.mapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.vincent.rsf.server.common.domain.BaseParam;
import com.vincent.rsf.server.common.domain.PageParam;
import com.vincent.rsf.server.manager.entity.Transfer;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.vincent.rsf.server.manager.entity.WkOrder;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
@Mapper
@Repository
public interface TransferMapper extends BaseMapper<Transfer> {
    IPage<WkOrder> transfersPage(PageParam<Transfer, BaseParam> pageParam, @Param("transferId") Long transferId);
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/TransferService.java
@@ -1,14 +1,23 @@
package com.vincent.rsf.server.manager.service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import com.vincent.rsf.framework.common.R;
import com.vincent.rsf.server.common.domain.BaseParam;
import com.vincent.rsf.server.common.domain.PageParam;
import com.vincent.rsf.server.manager.controller.params.TransferItemParams;
import com.vincent.rsf.server.manager.entity.Transfer;
import com.vincent.rsf.server.manager.entity.WkOrder;
import java.util.List;
public interface TransferService extends IService<Transfer> {
    R saveTransfer(TransferItemParams params, Long loginUserId);
    R updateTransfer(TransferItemParams params, Long loginUserId);
    IPage<WkOrder> transfersPage(PageParam<Transfer, BaseParam> pageParam, QueryWrapper<Transfer> transferQueryWrapper);
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/TransferItemServiceImpl.java
@@ -6,7 +6,6 @@
import com.vincent.rsf.framework.exception.CoolException;
import com.vincent.rsf.server.common.utils.FieldsUtils;
import com.vincent.rsf.server.manager.entity.Companys;
import com.vincent.rsf.server.manager.entity.WkOrderItem;
import com.vincent.rsf.server.manager.enums.CompanysType;
import com.vincent.rsf.server.manager.mapper.TransferItemMapper;
import com.vincent.rsf.server.manager.entity.TransferItem;
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/TransferServiceImpl.java
@@ -1,22 +1,25 @@
package com.vincent.rsf.server.manager.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.vincent.rsf.framework.common.R;
import com.vincent.rsf.framework.exception.CoolException;
import com.vincent.rsf.server.common.domain.BaseParam;
import com.vincent.rsf.server.common.domain.PageParam;
import com.vincent.rsf.server.common.domain.PageResult;
import com.vincent.rsf.server.manager.controller.params.TransferItemParams;
import com.vincent.rsf.server.manager.entity.TransferItem;
import com.vincent.rsf.server.manager.entity.WkOrder;
import com.vincent.rsf.server.manager.entity.WkOrderItem;
import com.vincent.rsf.server.manager.entity.*;
import com.vincent.rsf.server.manager.enums.AsnExceStatus;
import com.vincent.rsf.server.manager.enums.CheckExceStatus;
import com.vincent.rsf.server.manager.enums.OrderSourceType;
import com.vincent.rsf.server.manager.enums.OrderType;
import com.vincent.rsf.server.manager.mapper.TransferMapper;
import com.vincent.rsf.server.manager.entity.Transfer;
import com.vincent.rsf.server.manager.service.AsnOrderItemService;
import com.vincent.rsf.server.manager.service.TransferItemService;
import com.vincent.rsf.server.manager.service.TransferService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.vincent.rsf.server.manager.service.WarehouseAreasService;
import com.vincent.rsf.server.system.constant.SerialRuleCode;
import com.vincent.rsf.server.system.utils.SerialRuleUtils;
import org.apache.commons.lang3.StringUtils;
@@ -24,6 +27,7 @@
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.List;
import java.util.Objects;
@@ -32,6 +36,9 @@
    @Autowired
    private TransferItemService transferItemService;
    @Autowired
    private WarehouseAreasService warehouseAreasService;
    /**
     * @author Ryan
@@ -54,9 +61,30 @@
        if (StringUtils.isBlank(ruleCode)) {
            throw new CoolException("编码规则错误:请检查「SYS_TRANSFER_ORDER_CODE」是否设置正确!!");
        }
        WarehouseAreas orgWarehosue = warehouseAreasService.getById(transfer.getOrgAreaId());
        if (Objects.isNull(orgWarehosue)) {
            throw new CoolException("所选原库区不存在!!");
        }
        WarehouseAreas tarWarehouse = warehouseAreasService.getById(transfer.getTarAreaId());
        if (Objects.isNull(tarWarehouse)) {
            throw new CoolException("所选目标库区不存在!!");
        }
        transfer.setCode(ruleCode)
                .setExceStatus(CheckExceStatus.CHECK_ORDER_STATUS_UN_EXCE.val)
                .setSource(OrderSourceType.ORDER_SOURCE_TYPE_SYSTEM.val)
                .setOrgAreaId(orgWarehosue.getId())
                .setOrgAreaName(orgWarehosue.getName())
                .setOrgWareId(orgWarehosue.getWarehouseId())
                .setOrgWareName(orgWarehosue.getWarehouseId$())
                .setTarAreaId(tarWarehouse.getId())
                .setTarWareId(tarWarehouse.getWarehouseId())
                .setTarAreaName(tarWarehouse.getName())
                .setTarWareName(tarWarehouse.getWarehouseId$())
                .setUpdateTime(new Date())
                .setCreateTime(new Date())
                .setUpdateBy(loginUserId)
                .setCreateBy(loginUserId);
        if (!this.save(transfer)) {
@@ -128,4 +156,19 @@
        return R.ok("修改完成!!");
    }
    /**
     * @author Ryan
     * @date 2025/7/28
     * @description: 获取调拔单关联订单
     * @version 1.0
     */
    @Override
    public IPage<WkOrder> transfersPage(PageParam<Transfer, BaseParam> pageParam, QueryWrapper<Transfer> transferQueryWrapper) {
        Transfer one = this.getOne(transferQueryWrapper);
        if (Objects.isNull(one)) {
            throw new CoolException("单据不存在!!");
        }
        return this.baseMapper.transfersPage(pageParam, one.getId());
    }
}
rsf-server/src/main/java/com/vincent/rsf/server/system/constant/DictTypeCode.java
@@ -94,4 +94,6 @@
    /**单据来源*/
    public final static String SYS_ORDER_SOURCE = "sys_order_source";
    public final static String SYS_TRANSFER_TYPE = "sys_transfer_type";
}
rsf-server/src/main/resources/mapper/manager/TransferMapper.xml
@@ -2,4 +2,29 @@
<!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.TransferMapper">
    <select id="transfersPage" resultType="com.vincent.rsf.server.manager.entity.WkOrder">
        SELECT
            id,
            `code`,
            `type`,
            `wk_type`,
            `anfme`,
            `qty`,
            `work_qty`,
            `warehouse_id`,
            `ware_area_id`,
            `wave_id`,
            `exce_status`
        FROM
            man_asn_order
        WHERE
            id IN (
                SELECT
                    order_id
                FROM
                    man_transfer_order
                WHERE
                    transfer_id = #{transferId}
            )
    </select>
</mapper>