2个文件已添加
26个文件已修改
966 ■■■■■ 已修改文件
rsf-admin/.eslintrc.cjs 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/asnOrder/AsnOrderList.jsx 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/asnOrder/AsnOrderModal.jsx 55 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/asnOrder/AsnOrderPanel.jsx 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/asnOrderLog/AsnOrderLogPanel.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/basicInfo/matnr/MatnrEdit.jsx 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/task/TaskList.jsx 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/task/TaskPanel.jsx 264 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/taskItem/TaskItemList.jsx 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/api/controller/MobileController.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/api/entity/dto/ReceiptDetlsDto.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/api/service/MobileService.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/MobileServiceImpl.java 117 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/common/utils/FieldsUtils.java 93 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/common/utils/JSONUtil.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/AsnOrderController.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/WarehouseAreasItem.java 38 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/enums/AsnExceStatus.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/enums/PakinIOStatus.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/schedules/ScheduleJobs.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/AsnOrderService.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/AsnOrderItemServiceImpl.java 27 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/AsnOrderServiceImpl.java 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/MatnrServiceImpl.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/TaskServiceImpl.java 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/WaitPakinServiceImpl.java 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/system/utils/ExtendFieldsUtils.java 108 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/resources/application.yml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/.eslintrc.cjs
@@ -9,6 +9,7 @@
  ],
  ignorePatterns: ["dist", ".eslintrc.cjs"],
  parser: "@typescript-eslint/parser",
  "react/jsx-key": [false, { "checkFragmentShorthand": false }],
  env: {
    browser: true,
    es2021: true,
rsf-admin/src/page/asnOrder/AsnOrderList.jsx
@@ -62,7 +62,7 @@
  '& .column-name': {
  },
  '& .opt': {
    width: 200
    width: 300
  },
}));
@@ -102,7 +102,7 @@
  const [createDialog, setCreateDialog] = useState(false);
  const [drawerVal, setDrawerVal] = useState(false);
  const [modalType, setmodalType] = useState(0);
  const [billReload, setBillReload] = useState(null);
  const billReload = useRef();
  const navigate = useNavigate();
  const assign = (record) => {
@@ -140,7 +140,7 @@
          preferenceKey='asnOrder'
          bulkActionButtons={<> <InspectionsButton /><BulkDeleteButton mutationMode={OPERATE_MODE} /></>}
          rowClick={() => false}
          expand={<AsnOrderPanel setBillReload={setBillReload} />}
          expand={<AsnOrderPanel billReload={billReload} />}
          expandSingle={true}
          omit={['id', 'createTime', 'createBy', 'memo', 'poId']}
        >
@@ -167,7 +167,7 @@
          <TextField source="exceStatus$" label="common.field.status" />
          {/* <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" >
          <WrapperField cellClassName="opt" label="common.field.opt" width={300} >
            {/* <Button label="toolbar.print" onClick={print}>
              <FileDownloadIcon />
            </Button> */}
rsf-admin/src/page/asnOrder/AsnOrderModal.jsx
@@ -51,8 +51,8 @@
import SaveIcon from '@mui/icons-material/Save';
import request from '@/utils/request';
import { Add, Edit, Delete } from '@mui/icons-material';
import _ from 'lodash';
import { DataGrid } from '@mui/x-data-grid';
import _, { set } from 'lodash';
import { DataGrid, useGridApiRef } from '@mui/x-data-grid';
import DictionarySelect from "../components/DictionarySelect";
import DictSelect from "../components/DictSelect";
@@ -65,6 +65,8 @@
    const [disabled, setDisabled] = useState(false)
    const [createDialog, setCreateDialog] = useState(false);
    const tableRef = useRef();
    useEffect(() => {
        if (open && asnId !== 0) {
@@ -97,8 +99,22 @@
        }));
    };
    const setFinally = () => {
        const rows = tableRef.current.state.editRows;
        for (const key in rows) {
            const find = tabelData.find(item => item.matnrId === +key);
            find.anfme = rows[key].anfme.value;
        }
        setTableData([...tabelData]);
    }
    const handleSubmit = async () => {
        setFinally()
        setDisabled(true)
        if (asnId === 0) {
            const parmas = {
                "orders": formData,
@@ -108,8 +124,8 @@
            const res = await request.post(`/asnOrder/items/save`, parmas);
            if (res?.data?.code === 200) {
                setOpen(false);
                billReload()
                refresh();
                billReload?.current()
            } else {
                notify(res.data.msg);
            }
@@ -122,6 +138,7 @@
            if (res?.data?.code === 200) {
                setOpen(false);
                refresh();
                billReload?.current()
            } else {
                notify(res.data.msg);
@@ -162,6 +179,8 @@
    const [selectedRows, setSelectedRows] = useState([]);
    const handleDeleteItem = () => {
        const newTableData = _.filter(tabelData, (item) => !selectedRows.includes(item.matnrId));
        setTableData(newTableData);
@@ -176,7 +195,7 @@
                aria-hidden
                fullWidth
                disableRestoreFocus
                maxWidth="md"   // 'xs' | 'sm' | 'md' | 'lg' | 'xl'
                maxWidth="lg"   // 'xs' | 'sm' | 'md' | 'lg' | 'xl'
            >
                <DialogTitle id="form-dialog-title" sx={{
                    position: 'sticky',
@@ -228,7 +247,7 @@
                    </Box>
                    <Box sx={{ mt: 2 }}>
                        <AsnOrderModalTable tabelData={tabelData} setTableData={setTableData} asnId={asnId} selectedRows={selectedRows} setSelectedRows={setSelectedRows} ></AsnOrderModalTable>
                        <AsnOrderModalTable tabelData={tabelData} setTableData={setTableData} asnId={asnId} selectedRows={selectedRows} setSelectedRows={setSelectedRows} tableRef={tableRef}></AsnOrderModalTable>
                    </Box>
                </DialogContent>
                <DialogActions sx={{ position: 'sticky', bottom: 0, backgroundColor: 'background.paper', zIndex: 1000 }}>
@@ -253,7 +272,7 @@
export default AsnOrderModal;
const AsnOrderModalTable = ({ tabelData, setTableData, asnId, selectedRows, setSelectedRows }) => {
const AsnOrderModalTable = ({ tabelData, setTableData, asnId, selectedRows, setSelectedRows, tableRef }) => {
    const translate = useTranslate();
    const notify = useNotify();
@@ -274,9 +293,14 @@
        {
            field: 'anfme',
            headerName: translate('table.field.asnOrderItem.purQty'),
            type: 'number',
            minWidth: 100,
            flex: 1,
            editable: true,
            // preProcessEditCellProps: (params) => {
            //     const hasError = params.props.value.length !== '';
            //     return { ...params.props, error: hasError };
            // },
        },
        {
            field: 'splrCode',
@@ -392,11 +416,16 @@
    const processRowUpdate = (newRow, oldRow) => {
        setTableData((prevData) =>
            prevData.map((r) =>
                r.matnrId === newRow.matnrId ? { ...newRow } : r
            )
        );
        const rows = tabelData.map((r) =>
            r.matnrId === newRow.matnrId ? { ...newRow } : r
        )
        setTableData(rows)
        // setTableData((prevData) =>
        //     prevData.map((r) =>
        //         r.matnrId === newRow.matnrId ? { ...newRow } : r
        //     )
        // );
        return newRow;
    };
@@ -408,9 +437,13 @@
    };
    tableRef.current = useGridApiRef();
    return (
        <div style={{ height: 400, width: '100%' }}>
            <DataGrid
                apiRef={tableRef}
                rows={tabelData}
                columns={columns}
                disableRowSelectionOnClick
rsf-admin/src/page/asnOrder/AsnOrderPanel.jsx
@@ -15,7 +15,7 @@
import { DataGrid } from '@mui/x-data-grid';
import PrintModal from './PrintModal';
import { width } from "@mui/system";
const AsnOrderPanel = ({ setBillReload }) => {
const AsnOrderPanel = ({ billReload }) => {
    const record = useRecordContext();
    if (!record) return null;
    const translate = useTranslate();
@@ -26,14 +26,7 @@
    useEffect(() => {
        debouncedHttp({ maktx });
        setBillReload(http)
    }, [asnId, maktx]);
    useEffect(() => {
        setBillReload(http)
    }, []);
    const http = async (parmas) => {
        const res = await request.post('/asnOrderItem/page', { ...parmas, asnId });
@@ -45,9 +38,12 @@
    }
    useEffect(() => {
        billReload.current = http
    }, []);
    const debouncedHttp = useMemo(() => debounce(http, 300), []);
    const columns = [
        {
rsf-admin/src/page/asnOrderLog/AsnOrderLogPanel.jsx
@@ -21,7 +21,7 @@
    const notify = useNotify();
    const [rows, setRows] = useState([]);
    const [maktx, setMaktx] = useState('');
    const asnId = record.id;
    const asnId = record.asnId;
    useEffect(() => {
        debouncedHttp({ maktx });
rsf-admin/src/page/basicInfo/matnr/MatnrEdit.jsx
@@ -22,7 +22,7 @@
    useNotify,
} from 'react-admin';
import PropTypes from 'prop-types';
import { useWatch, useFormContext } from "react-hook-form";
import { useWatch, useFormContext, useForm, useFormState } from "react-hook-form";
import { Stack, Grid, Box, Typography, Tabs, Tab, } from '@mui/material';
import * as Common from '@/utils/common';
import { EDIT_MODE, REFERENCE_INPUT_PAGESIZE } from '@/config/setting';
@@ -33,7 +33,7 @@
import TreeSelectInput from "@/page/components/TreeSelectInput";
import request from '@/utils/request';
const FormToolbar = () => {
    const { getValues } = useFormContext();
    const { getValues } = useFormState();
    return (
        <Toolbar sx={{ justifyContent: 'space-between' }}>
            <SaveButton />
@@ -74,6 +74,7 @@
const MatnrEdit = () => {
    const translate = useTranslate();
    const [value, setValue] = React.useState(0);
    const form = useForm();
    const notify = useNotify();
    const [dynamicFields, setDynamicFields] = useState([]);
@@ -88,6 +89,7 @@
        if (code === 200) {
            setDynamicFields(data || [])
        } else {
            notify(msg);
        }
rsf-admin/src/page/task/TaskList.jsx
@@ -114,7 +114,7 @@
                    marginRight: !!drawerVal ? `${PAGE_DRAWER_WIDTH}px` : 0,
                }}
                title={"menu.task"}
                empty={<EmptyData onClick={() => { }} />}
                empty={false}
                filters={filters}
                sort={{ field: "sort", order: "desc" }}
                actions={(
@@ -138,8 +138,8 @@
                        </>
                    }
                    rowClick={(id, resource, record) => false}
                    // expand={() => <TaskPanel />}
                    // expandSingle={true}
                    expand={() => <TaskPanel />}
                    expandSingle={true}
                    omit={['id', 'createTime', 'createBy', 'memo', 'robotCode', 'exceStatus', 'expDesc', 'expCode', 'sort']}
                >
                    <NumberField source="id" />
@@ -174,10 +174,6 @@
                    </WrapperField>
                </StyledDatagrid>
            </List>
            {/* <TaskCreate
                open={createDialog}
                setOpen={setCreateDialog}
            /> */}
            <PageDrawer
                title='Task Detail'
                drawerVal={drawerVal}
rsf-admin/src/page/task/TaskPanel.jsx
@@ -1,139 +1,151 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import { Box, Card, CardContent, Grid, Typography, Tooltip } from '@mui/material';
import {
    useTranslate,
    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 PanelTypography from "../components/PanelTypography";
import * as Common from '@/utils/common'
import { styled } from '@mui/material/styles';
import PageDrawer from "../components/PageDrawer";
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"  />,
    <DateInput label='common.time.before' source="timeEnd" />,
    <NumberInput source="taskId" label="table.field.taskItem.taskId" />,
    <NumberInput source="orderId" label="table.field.taskItem.orderId" />,
    <NumberInput source="orderType" label="table.field.taskItem.orderType" />,
    <NumberInput source="orderItemId" label="table.field.taskItem.orderItemId" />,
    <NumberInput source="matnrId" label="table.field.taskItem.matnrId" />,
    <TextInput source="maktx" label="table.field.taskItem.maktx" />,
    <TextInput source="matnrCode" label="table.field.taskItem.matnrCode" />,
    <TextInput source="unit" label="table.field.taskItem.unit" />,
    <NumberInput source="anfme" label="table.field.taskItem.anfme" />,
    <TextInput source="batch" label="table.field.taskItem.batch" />,
    <TextInput source="spec" label="table.field.taskItem.spec" />,
    <TextInput source="model" label="table.field.taskItem.model" />,
    <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 TaskPanel = () => {
    const record = useRecordContext();
    if (!record) return null;
    const translate = useTranslate();
    const [createDialog, setCreateDialog] = useState(false);
    const [drawerVal, setDrawerVal] = useState(false);
    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.task.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.task.taskCode"
                                property={record.taskCode}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.task.taskStatus"
                                property={record.taskStatus}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.task.taskType"
                                property={record.taskType}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.task.orgLoc"
                                property={record.orgLoc}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.task.orgSite"
                                property={record.orgSite}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.task.targLoc"
                                property={record.targLoc}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.task.targSite"
                                property={record.targSite}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.task.barcode"
                                property={record.barcode}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.task.robotCode"
                                property={record.robotCode}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.task.exceStatus"
                                property={record.exceStatus}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.task.expDesc"
                                property={record.expDesc}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.task.sort"
                                property={record.sort}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.task.expCode"
                                property={record.expCode}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.task.startTime"
                                property={record.startTime$}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.task.endTime"
                                property={record.endTime$}
                            />
                        </Grid>
                    </Grid>
                </CardContent>
            </Card >
            <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.taskItem"}
                    empty={false}
                    filters={filters}
                    sort={{ field: "create_time", order: "desc" }}
                    actions={(
                        <TopToolbar>
                            <FilterButton />
                        </TopToolbar>
                    )}
                    perPage={DEFAULT_PAGE_SIZE}
                >
                    <StyledDatagrid
                        preferenceKey='taskItem'
                        bulkActionButtons={false}
                        rowClick={(id, resource, record) => false}
                        expandSingle={true}
                        omit={['id', 'createTime', 'createBy', 'memo', 'taskId', 'orderId', 'orderItemId', 'matnrId']}
                    >
                        <NumberField source="id" />
                        <NumberField source="taskId" label="table.field.taskItem.taskId" />
                        <NumberField source="orderId" label="table.field.taskItem.orderId" />
                        <NumberField source="orderType$" label="table.field.taskItem.orderType" />
                        <NumberField source="orderItemId" label="table.field.taskItem.orderItemId" />
                        <NumberField source="matnrId" label="table.field.taskItem.matnrId" />
                        <TextField source="maktx" label="table.field.taskItem.maktx" />
                        <TextField source="matnrCode" label="table.field.taskItem.matnrCode" />
                        <TextField source="unit" label="table.field.taskItem.unit" />
                        <NumberField source="anfme" label="table.field.taskItem.anfme" />
                        <TextField source="batch" label="table.field.taskItem.batch" />
                        <TextField source="spec" label="table.field.taskItem.spec" />
                        <TextField source="model" label="table.field.taskItem.model" />
                        <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} />
                    </StyledDatagrid>
                </List>
                <PageDrawer
                    title='TaskItem Detail'
                    drawerVal={drawerVal}
                    setDrawerVal={setDrawerVal}
                >
                </PageDrawer>
            </Box>
        </>
    );
};
rsf-admin/src/page/taskItem/TaskItemList.jsx
@@ -34,11 +34,6 @@
} from 'react-admin';
import { Box, Typography, Card, Stack } from '@mui/material';
import { styled } from '@mui/material/styles';
import TaskItemCreate from "./TaskItemCreate";
import TaskItemPanel from "./TaskItemPanel";
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';
@@ -88,7 +83,6 @@
const TaskItemList = () => {
    const translate = useTranslate();
    const [createDialog, setCreateDialog] = useState(false);
    const [drawerVal, setDrawerVal] = useState(false);
@@ -104,6 +98,7 @@
                    marginRight: !!drawerVal ? `${PAGE_DRAWER_WIDTH}px` : 0,
                }}
                title={"menu.taskItem"}
                empty={false}
                filters={filters}
                sort={{ field: "create_time", order: "desc" }}
                actions={(
rsf-server/src/main/java/com/vincent/rsf/server/api/controller/MobileController.java
@@ -16,6 +16,7 @@
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
import java.util.Objects;
/**
@@ -78,7 +79,7 @@
    @PreAuthorize("hasAuthority('manager:warehouseAreas:save')")
    @PostMapping("/orders/confirm")
    @ApiOperation("确认收货")
    public R confirmReceipt(@RequestBody ReceiptParams params) {
    public R confirmReceipt(@RequestBody Map<String, Object> params) {
       if (Objects.isNull(params)) {
           throw new CoolException("请求参数不能为空!!");
       }
rsf-server/src/main/java/com/vincent/rsf/server/api/entity/dto/ReceiptDetlsDto.java
@@ -85,6 +85,9 @@
    @ApiModelProperty("供应商编码")
    private String splrCode;
    @ApiModelProperty("扩展字段索引")
    private String fieldsIndex;
    @ApiModelProperty("扩展字段")
    private Map<String, Object> extendFields;
rsf-server/src/main/java/com/vincent/rsf/server/api/service/MobileService.java
@@ -11,6 +11,7 @@
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;
/**
 * @author Ryan
@@ -25,7 +26,7 @@
    R getOrderByCode(String barcode);
    R receiptToWarehouse(ReceiptParams orders);
    R receiptToWarehouse(Map<String, Object> orders);
    R otherReceipt(OtherReceiptParams params);
rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/MobileServiceImpl.java
@@ -1,6 +1,8 @@
package com.vincent.rsf.server.api.service.impl;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.vincent.rsf.framework.common.Cools;
import com.vincent.rsf.framework.common.R;
import com.vincent.rsf.framework.exception.CoolException;
@@ -13,10 +15,13 @@
import com.vincent.rsf.server.common.enums.WarehouseAreaType;
import com.vincent.rsf.server.common.security.JwtSubject;
import com.vincent.rsf.server.common.utils.CommonUtil;
import com.vincent.rsf.server.common.utils.FieldsUtils;
import com.vincent.rsf.server.common.utils.JSONUtil;
import com.vincent.rsf.server.common.utils.JwtUtil;
import com.vincent.rsf.server.manager.controller.params.IsptItemsParams;
import com.vincent.rsf.server.manager.controller.params.WaitPakinParam;
import com.vincent.rsf.server.manager.entity.*;
import com.vincent.rsf.server.manager.enums.AsnExceStatus;
import com.vincent.rsf.server.manager.mapper.*;
import com.vincent.rsf.server.manager.service.*;
import com.vincent.rsf.server.system.constant.CodeRes;
@@ -29,6 +34,7 @@
import com.vincent.rsf.server.system.mapper.UserMapper;
import com.vincent.rsf.server.system.service.FieldsItemService;
import com.vincent.rsf.server.system.service.UserLoginService;
import com.vincent.rsf.server.system.utils.ExtendFieldsUtils;
import com.vincent.rsf.server.system.utils.SerialRuleUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
@@ -181,25 +187,25 @@
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public R receiptToWarehouse(ReceiptParams params) {
        if (params.getReceipts().isEmpty()) {
    public R receiptToWarehouse(Map<String, Object> params) {
        if (Objects.isNull(params)) {
            throw new CoolException("参数不能为空!!");
        }
        ReceiptParams receiptParam = JSONObject.parseObject(JSONObject.toJSONString(params), ReceiptParams.class);
        if (receiptParam.getReceipts().isEmpty()) {
            throw new CoolException("收货明细不能为空!!");
        }
        if (Objects.isNull(params.getWhAreaId())) {
        if (Objects.isNull(receiptParam.getWhAreaId())) {
            throw new CoolException("库区标识不能为空!!");
        }
        WarehouseAreas areasItem = warehouseAreasService.getOne(new LambdaQueryWrapper<WarehouseAreas>()
                .eq(WarehouseAreas::getId, params.getWhAreaId()));
                .eq(WarehouseAreas::getId, receiptParam.getWhAreaId()));
        if (Objects.isNull(areasItem)) {
            throw new CoolException("数据错误:当前库区不存在!!");
        }
        //获取已启用的动态扩展字
        List<Fields> fields = fieldsMapper.selectList(new LambdaQueryWrapper<Fields>()
                .eq(Fields::getFlagEnable, 1)
                .eq(Fields::getStatus, 1));
        List<ReceiptDetlsDto> receipts = params.getReceipts();
        List<ReceiptDetlsDto> receipts = receiptParam.getReceipts();
        List<WarehouseAreasItem> allOrders = new ArrayList<>();
        Double receiptQty = receipts.stream().mapToDouble(ReceiptDetlsDto::getReceiptQty).sum();
@@ -211,15 +217,17 @@
        if (Objects.isNull(asnOrder)) {
            throw new CoolException("数据错误:主单不存在!!");
        }
        /**收货数量累加,1. 会出超收情况 2. 会有收货不足情况*/
        //TODO /**收货数量累加,1. 会出超收情况 2. 会有收货不足情况*/
        Double rcptedQty = asnOrder.getQty() + receiptQty;
        asnOrder.setQty(rcptedQty);
        asnOrder.setQty(rcptedQty).setExceStatus(Short.parseShort(AsnExceStatus.ASN_EXCE_STATUS_EXCE_ING.val));
        if (!asnOrderMapper.updateById(asnOrder)) {
            throw new CoolException("已收货数量修改失败!!");
        }
        receipts.forEach(dto -> {
        List<Map<String, Object>> receipts1 = (List<Map<String, Object>>) params.get("receipts");
        for (Map<String, Object> rcpt : receipts1) {
            if (Objects.isNull(rcpt)) {continue;}
            ReceiptDetlsDto dto = JSONObject.parseObject(JSONObject.toJSONString(rcpt), ReceiptDetlsDto.class);
            Matnr matnr = matnrMapper.selectById(dto.getMatnrId());
            if (Objects.isNull(matnr)) {
                throw new CoolException("数据错误:当前物料不存在!!");
@@ -227,49 +235,36 @@
            if (Objects.isNull(dto.getReceiptQty())) {
                throw new CoolException("收货数据不能为空!!");
            }
            if (dto.getReceiptQty().compareTo(dto.getAnfme()) > 0) {
                throw new CoolException("收货数量不能大于采购数量!!");
            }
//            if (dto.getReceiptQty().compareTo(dto.getAnfme()) > 0) {
//                throw new CoolException("收货数量不能大于采购数量!!");
//            }
            AsnOrderItem orderItem = asnOrderItemMapper.selectOne(new LambdaQueryWrapper<AsnOrderItem>()
                    .eq(AsnOrderItem::getAsnCode, asnCode)
                    .eq(AsnOrderItem::getMatnrId, dto.getMatnrId()));
            if (Objects.isNull(orderItem)) {
                throw new CoolException("通知单明细不存在!!");
            }
//            if (Objects.isNull(dto.getReceiptQty()) || Double.compare(dto.getReceiptQty(), 0.0) == 0) {
//                throw new CoolException("收货数量不能为零!!");
//            }
            if (Objects.isNull(dto.getReceiptQty()) || Double.compare(dto.getReceiptQty(), 0.0) == 0) {
                throw new CoolException("收货数量不能为零!!");
            }
            Double itemRcptQty = dto.getReceiptQty() + orderItem.getQty();
            orderItem.setQty(itemRcptQty)
                    .setSplrBatch(dto.getSplrBatch())
                    .setStockUnit(dto.getStockUnit())
                    .setProdTime(dto.getProdTime());
            if (!Objects.isNull(fields)) {
                if (!Objects.isNull(dto.getExtendFields())) {
                    //获取16位uuid
                    String uuid16 = CommonUtil.randomUUID16();
                    Map<String, Object> extendFields = dto.getExtendFields();
                    //字段集合申明
                    List<FieldsItem> fieldsItems = new ArrayList<>();
                    extendFields.keySet().forEach(key -> {
                        fields.forEach(obj -> {
                            //判断key值与fields表字段是否相同
                            if (obj.getFields().equals(key)) {
                                FieldsItem fieldsItem = new FieldsItem();
                                fieldsItem.setMatnrId(matnr.getId()).setFieldsId(obj.getId())
                                        .setShiperId(matnr.getShipperId())
                                        .setValue(extendFields.get(key).toString())
                                        .setUuid(uuid16);
                                fieldsItems.add(fieldsItem);
                            }
                        });
                    });
                    if (!fieldsItemService.saveBatch(fieldsItems)) {
                        throw new CoolException("扩展字段保存失败!!");
            if (!Objects.isNull(rcpt)) {
                try {
                    if (Objects.isNull(rcpt.get("fieldsindex")) || StringUtils.isBlank(rcpt.get("fieldsindex").toString())) {
                        //获取16位uuid
                        String uuid16 = CommonUtil.randomUUID16();
                        rcpt.put("index", uuid16);
                        orderItem.setFieldsIndex(uuid16);
                    }
                    orderItem.setFieldsIndex(uuid16);
                    //保存或更新扩展字段
                    FieldsUtils.updateFieldsValue(rcpt);
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
@@ -283,29 +278,31 @@
//            if (Objects.isNull(dto.getProdTime())) {
//                 format = dateFormat.format(dto.getProdTime());
//            }
            item.setBarcode(dto.getBarcode())
            item.setTrackCode(dto.getBarcode())
                    .setAreaName(areasItem.getName())
                    .setAreaId(areasItem.getId())
                    .setAsnItemId(orderItem.getId())
                    .setAsnCode(asnOrder.getCode())
                    .setAsnId(asnOrder.getId())
                    .setProdTime(dto.getProdTime())
                    .setWeight(dto.getWeigth())
                    .setStockUnit(dto.getStockUnit())
                    .setBatch(SerialRuleUtils.generateRuleCode(SerialRuleCode.SYS_RECEIPT_BATCH, dto))
                    .setAnfme(itemRcptQty)
                    .setSplrBtch(dto.getSplrBatch())
                    .setSplrBatch(dto.getSplrBatch())
                    .setMatnrCode(matnr.getCode())
                    .setMatnrId(matnr.getId())
                    .setMatnrName(matnr.getName())
                    .setMaktx(matnr.getName())
                    //库存单位为最小单位
                    .setUnit(dto.getStockUnit())
                    .setStockUnit(dto.getStockUnit())
                    .setWeight(matnr.getWeight())
                    .setFieldsIndex(orderItem.getFieldsIndex())
                    .setShipperId(matnr.getShipperId());
                    //TODO 供应商标识未设置,标识由PO单供应商编码转换
            //TODO 供应商标识未设置,标识由PO单供应商编码转换
            allOrders.add(item);
        });
        }
        if (!warehouseAreasItemService.saveBatch(allOrders)) {
            throw new CoolException("收货失败!!");
@@ -381,9 +378,21 @@
        return fieldsMapper.selectList(new LambdaQueryWrapper<Fields>().eq(Fields::getFlagEnable, 1).eq(Fields::getStatus, 1));
    }
    /**
     * @author Ryan
     * @description 获取组盘明细
     * @param
     * @return
     * @time 2025/4/7 16:58
     */
    @Override
    public R getDeltByCode(String code) {
        return R.ok(asnOrderItemMapper.selectOne(new LambdaQueryWrapper<AsnOrderItem>().eq(AsnOrderItem::getTrackCode, code)));
        //TODO 后续需根据策略配置,获取组拖数据。如:混装,按批次混装等
        LambdaQueryWrapper<WarehouseAreasItem> queryWrapper = new QueryWrapper<WarehouseAreasItem>()
                .select("SUM(anfme) as anfme, track_code, asn_code, id, splr_batch, ispt_result, plat_item_id, batch, qty, work_qty, matnr_code, matnr_id, maktx").lambda()
                .eq(WarehouseAreasItem::getTrackCode, code)
                .groupBy(WarehouseAreasItem::getSplrBatch, WarehouseAreasItem::getAsnId, WarehouseAreasItem::getAreaId, WarehouseAreasItem::getMatnrId);
        return R.ok(warehouseAreasItemService.getOne(queryWrapper));
    }
    /**
@@ -398,6 +407,12 @@
        return waitPakinService.mergeItems(waitPakin);
    }
    /**
     * @author Ryan
     * @description 解绑
     * @param param
     * @return
     */
    @Override
    public WaitPakin unBind(WaitPakinParam param) {
        return waitPakinService.unBind(param);
@@ -718,6 +733,7 @@
            detlsDto.setAsnCode(asnOrderItem.getAsnCode())
                    .setMaktx(asnOrderItem.getMaktx())
                    .setFieldsIndex(asnOrderItem.getFieldsIndex())
                    .setBarcode(asnOrderItem.getTrackCode())
                    .setQty(asnOrderItem.getQty())
                    .setPoCode(asnOrderItem.getPoCode())
@@ -758,7 +774,6 @@
                    detlsDto.setPlatformId(purchaseItem.getPlatItemId());
                }
            }
            detlsDtos.add(detlsDto);
        });
rsf-server/src/main/java/com/vincent/rsf/server/common/utils/FieldsUtils.java
@@ -7,6 +7,8 @@
import com.vincent.rsf.server.system.entity.FieldsItem;
import com.vincent.rsf.server.system.service.FieldsItemService;
import com.vincent.rsf.server.system.service.FieldsService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
@@ -24,7 +26,7 @@
     * @author Ryan
     * @description 通过字段唯一标识获取动态字段对象key-value
     * @param
     * @return
     * @return 扩展字段对象
     * @time 2025/3/12 12:50
     */
    public static Map<String, String> getFields(String uuid) {
@@ -51,28 +53,42 @@
        return  fieldsMap;
    }
    public static void mergeFields(Map<String, Object> fileds ,String uuid) {
    /**
     * @author Ryan
     * @description 获取集合扩展字段key-value值
     * @param
     * @return  包含扩展字段的集合对象
     * @time 2025/3/15 15:05
     */
    public static List<Map<String, Object>> getExtendFields(List<Map<String, Object>> params) {
        FieldsService fieldsService = SpringUtils.getBean(FieldsService.class);
        List<Fields> fields = fieldsService.list(new LambdaQueryWrapper<Fields>().eq(Fields::getFlagEnable, 1).eq(Fields::getStatus, 1));
        if (fields.isEmpty()) {
            return;
        }
        List<Fields> fields = fieldsService.list(new LambdaQueryWrapper<Fields>()
                .eq(Fields::getStatus, 1)
                .eq(Fields::getFlagEnable, 1));
        FieldsItemService fieldsItemService = SpringUtils.getBean(FieldsItemService.class);
        List<FieldsItem> fieldsItems = fieldsItemService.list(new LambdaQueryWrapper<FieldsItem>().eq(FieldsItem::getUuid, uuid));
        for (Fields field : fields ) {
            if (fieldsItems.isEmpty()) {
                fileds.put(field.getFields(), null);
        List<Map<String, Object>> result = new ArrayList<>();
        for (Map<String, Object> param : params) {
            result.add(param);
            if (Objects.isNull(param.get("fieldsIndex"))) {
                continue;
            }
            fieldsItems.forEach(fieldsItem -> {
                if (fieldsItem.getFieldsId().equals(field.getId())) {
                    fileds.put(field.getFields(), fieldsItem.getValue());
            List<FieldsItem> itemList = fieldsItemService
                    .list(new LambdaQueryWrapper<FieldsItem>()
                            .eq(FieldsItem::getUuid, param.get("fieldsIndex")));
            if (itemList.isEmpty()) {
                continue;
            }
            fields.forEach(fds -> {
                for (FieldsItem fieldsItem : itemList) {
                    if (!Objects.isNull(fieldsItem.getFieldsId()) && fieldsItem.getFieldsId().equals(fds.getId())) {
                        param.put(fds.getFields(), fieldsItem.getValue());
                    }
                }
            });
        }
        return result;
    }
    /**
     * @param template
     * @return
@@ -80,25 +96,31 @@
     * @description 动态字段value保存
     * @time 2025/3/18 15:00
     */
    public static void saveFields(Map<String, ?> template, String uuid) throws Exception{
    @Transactional(rollbackFor = Exception.class)
    public static boolean saveFields(Map<String, ?> template, String uuid) throws Exception{
        List<Fields> fields = getFieldsSta();
        FieldsItemService fieldsItemService = SpringUtils.getBean(FieldsItemService.class);
        if (fields.isEmpty()) {
            throw new CoolException("扩展字段不存在!!");
        }
        List<FieldsItem> fieldsItems = new ArrayList<>();
        for (Fields field : fields) {
            if (!Objects.isNull(template.get(field.getFields()))) {
                FieldsItem item = new FieldsItem();
                item.setFieldsId(field.getId())
                        .setUuid(uuid)
                        .setValue(template.get(field.getFields()).toString());
                fieldsItems.add(item);
        if (!fields.isEmpty()) {
            for (Fields obj : fields) {
                if (!Objects.isNull(template.get(obj.getFields())) && StringUtils.isNotBlank(template.get(obj.getFields()).toString())) {
                    FieldsItem item = new FieldsItem();
                    item.setUuid(uuid)
                            .setValue(template.get(obj.getFields()).toString())
                            .setMatnrId(Long.parseLong(template.get("matnrId").toString()))
                            .setFieldsId(obj.getId());
                    fieldsItems.add(item);
                }
            }
            if (fieldsItems.isEmpty()) {
                return false;
            }
            if (!fieldsItemService.saveBatch(fieldsItems)) {
                throw new CoolException("扩展字段保存失败!!");
            }
            return true;
        }
       if (!fieldsItemService.saveBatch(fieldsItems)) {
           throw new CoolException("动态字段值保存失败!!");
       }
        return false;
    }
    /**
@@ -110,11 +132,19 @@
        return fieldsService.list(new LambdaQueryWrapper<Fields>().eq(Fields::getStatus, 1).eq(Fields::getFlagEnable, 1));
    }
    public static void updateFieldsValue(Map<String, Object> params) throws Exception{
    /**
     * @author Ryan
     * @description 动态字段修改
     * @param
     * @return
     * @time 2025/4/7 15:28
     */
    @Transactional(rollbackFor = Exception.class)
    public static void updateFieldsValue(Map<String, Object> params) throws Exception {
        List<Fields> fields = getFieldsSta();
        if (fields.isEmpty()) { return; }
        Object fieldsIndex = params.get("fieldsIndex");
        if (!Objects.isNull(fieldsIndex)) {
        if (!Objects.isNull(fieldsIndex) && StringUtils.isNotBlank(fieldsIndex.toString())) {
            String index = fieldsIndex.toString();
            FieldsItemService fieldsItemService = SpringUtils.getBean(FieldsItemService.class);
            for (Fields field : fields) {
@@ -127,6 +157,7 @@
                            FieldsItem item = new FieldsItem();
                            item.setUuid(index)
                                    .setFieldsId(field.getId())
                                    .setMatnrId(Long.parseLong(params.get("matnrId").toString()))
                                    .setValue(params.get(field.getFields()).toString());
                            if (!fieldsItemService.save(item)) {
                                throw new CoolException("扩展字段修改失败!!");
rsf-server/src/main/java/com/vincent/rsf/server/common/utils/JSONUtil.java
@@ -1,8 +1,12 @@
package com.vincent.rsf.server.common.utils;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;
import com.vincent.rsf.framework.common.Cools;
import org.apache.poi.ss.formula.functions.T;
import java.util.Map;
/**
 * JSON解析工具类
@@ -66,4 +70,7 @@
        return null;
    }
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/AsnOrderController.java
@@ -157,18 +157,17 @@
    @PostMapping("/asnOrder/items/save")
    @ApiOperation("保存主单及明细")
    @PreAuthorize("hasAuthority('manager:asnOrder:save')")
    public R orderAndItem(@RequestBody AsnOrderAndItemsParams params) {
    public R orderAndItem(@RequestBody AsnOrderAndItemsParams params) throws Exception {
        if (Objects.isNull(params)) {
           return R.error("参数不能为空!!");
        }
        return asnOrderService.saveOrderAndItems(params, getLoginUserId());
    }
    @ApiOperation("单据信息修改")
    @PostMapping("/asnOrder/items/update")
    @PreAuthorize("hasAuthority('manager:asnOrder:update')")
    public R orderAndrItemUpdate(@RequestBody AsnOrderAndItemsParams params) {
    public R orderAndrItemUpdate(@RequestBody AsnOrderAndItemsParams params) throws Exception {
        if (Objects.isNull(params)) {
            return R.error("参数不能为空!!");
        }
rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/WarehouseAreasItem.java
@@ -44,6 +44,28 @@
    @ApiModelProperty(value= "仓库区域")
    private Long areaId;
    @ApiModelProperty("单据ID")
    private Long asnId;
    @ApiModelProperty("单据编码")
    private String asnCode;
    @ApiModelProperty("单据明细ID")
    private Long asnItemId;
    @ApiModelProperty("行号")
    private String platItemId;
    @ApiModelProperty("质检结果")
    private Short isptResult;
    @ApiModelProperty("已收货数量")
    private Double qty;
    @ApiModelProperty("执行数量")
    private Double workQty;
    /**
     * 区域名称
     */
@@ -63,7 +85,7 @@
     * 物料名称
     */
    @ApiModelProperty(value= "物料名称")
    private String matnrName;
    private String maktx;
    /**
     * 物料编码
@@ -74,8 +96,8 @@
    /**
     * 条形码
     */
    @ApiModelProperty(value= "条形码")
    private String barcode;
    @ApiModelProperty(value= "物料跟踪码")
    private String trackCode;
    /**
     * 数量
@@ -135,7 +157,7 @@
     * 供应商批次
     */
    @ApiModelProperty(value= "供应商批次")
    private String splrBtch;
    private String splrBatch;
    /**
     * 状态 1: 正常  0: 冻结  
@@ -194,13 +216,13 @@
    public WarehouseAreasItem() {}
    public WarehouseAreasItem(Long areaId,String areaName,Long matnrId,String matnrName,String matnrCode,String barcode,Double anfme,String batch,String unit,String stockUnit,String brand,Long shipperId,String splrId,Double weight,String prodTime,String splrBtch,Integer status,Integer deleted,Integer tenantId,Long createBy,Date createTime,Long updateBy,Date updateTime,String memo) {
    public WarehouseAreasItem(Long areaId,String areaName,Long matnrId,String matnrName,String matnrCode,String trackCode,Double anfme,String batch,String unit,String stockUnit,String brand,Long shipperId,String splrId,Double weight,String prodTime,String splrBtch,Integer status,Integer deleted,Integer tenantId,Long createBy,Date createTime,Long updateBy,Date updateTime,String memo) {
        this.areaId = areaId;
        this.areaName = areaName;
        this.matnrId = matnrId;
        this.matnrName = matnrName;
        this.maktx = matnrName;
        this.matnrCode = matnrCode;
        this.barcode = barcode;
        this.trackCode = trackCode;
        this.anfme = anfme;
        this.batch = batch;
        this.unit = unit;
@@ -210,7 +232,7 @@
        this.splrId = splrId;
        this.weight = weight;
        this.prodTime = prodTime;
        this.splrBtch = splrBtch;
        this.splrBatch = splrBtch;
        this.status = status;
        this.deleted = deleted;
        this.tenantId = tenantId;
rsf-server/src/main/java/com/vincent/rsf/server/manager/enums/AsnExceStatus.java
New file
@@ -0,0 +1,27 @@
package com.vincent.rsf.server.manager.enums;
/**
 * @author Ryan
 * @version 1.0
 * @title PakinIOStatus
 * @description
 * @create 2025/4/7 08:48
 */
public enum AsnExceStatus {
    //质检状态
    ASN_EXCE_STATUS_UN_EXCE("0", "未执行"),
    ASN_EXCE_STATUS_EXCE_ING("1", "执行中"),
    ASN_EXCE_STATUS_TASK_DONE("2", "已完成"),
    ASN_EXCE_STATUS_TASK_CANCEL("3", "取消"),
    ASN_EXCE_STATUS_TASK_CLOSE("4", "已关闭")
            ;
    AsnExceStatus(String val, String desc) {
        this.val = val;
        this.desc = desc;
    }
    public String val;
    public String desc;
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/enums/PakinIOStatus.java
New file
@@ -0,0 +1,27 @@
package com.vincent.rsf.server.manager.enums;
/**
 * @author Ryan
 * @version 1.0
 * @title PakinIOStatus
 * @description
 * @create 2025/4/7 08:48
 */
public enum PakinIOStatus {
    //质检状态
    PAKIN_IO_STATUS_HOLD("0", "待入库"),
    PAKIN_IO_STATUS_DONE("1", "组拖完成"),
    PAKIN_IO_STATUS_TASK_EXCE("2", "任务执行中"),
    PAKIN_IO_STATUS_TASK_DONE("3", "任务完成")
            ;
    PakinIOStatus(String val, String desc) {
        this.val = val;
        this.desc = desc;
    }
    public String val;
    public String desc;
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/schedules/ScheduleJobs.java
@@ -6,6 +6,7 @@
import com.vincent.rsf.server.common.utils.CommonUtil;
import com.vincent.rsf.server.common.utils.DateUtils;
import com.vincent.rsf.server.manager.entity.*;
import com.vincent.rsf.server.manager.enums.PakinIOStatus;
import com.vincent.rsf.server.manager.service.*;
import com.vincent.rsf.server.system.constant.SerialRuleCode;
import com.vincent.rsf.server.system.utils.SerialRuleUtils;
@@ -183,10 +184,13 @@
     * @return
     * @time 2025/3/29 12:36
     */
    @Scheduled(cron = "0/5 * * * * ?")
//    @Scheduled(cron = "0 0/05 * * * ?  ")
    @Scheduled(cron = "0/25 * * * * ?")
    @Transactional(rollbackFor = Exception.class)
    public void pakinLog() {
        List<WaitPakin>  pakinIds = waitPakinService.list(new LambdaQueryWrapper<WaitPakin>().eq(WaitPakin::getIoStatus, 2).select(WaitPakin::getId));
        List<WaitPakin>  pakinIds = waitPakinService.list(new LambdaQueryWrapper<WaitPakin>()
                .eq(WaitPakin::getIoStatus, Short.valueOf(PakinIOStatus.PAKIN_IO_STATUS_TASK_DONE.val))
                .select(WaitPakin::getId));
        if (pakinIds.isEmpty()) {
            return;
        }
@@ -221,10 +225,10 @@
        if (!waitPakinItemLogService.saveBatch(itemLogs)) {
            throw new CoolException("历史明细档保存失败!!");
        }
        if (!waitPakinService.removeByIds(pakins)) {
        if (!waitPakinService.removeByIds(list)) {
            throw new CoolException("原单据删除失败!!");
        }
        if (!waitPakinItemService.removeByIds(pakinItems)) {
        if (!waitPakinItemService.remove(new LambdaQueryWrapper<WaitPakinItem>().in(WaitPakinItem::getPakinId, list))) {
            throw new CoolException("原单据明细删除失败!!");
        }
    }
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/AsnOrderService.java
@@ -15,9 +15,9 @@
    List<AsnOrder> getListByMatnr(Map<String, String> params);
    R saveOrderAndItems(AsnOrderAndItemsParams params, Long loginUserId);
    R saveOrderAndItems(AsnOrderAndItemsParams params, Long loginUserId) throws Exception;
    R updateOrderItem(AsnOrderAndItemsParams params, Long loginUserId);
    R updateOrderItem(AsnOrderAndItemsParams params, Long loginUserId) throws Exception;
    boolean batchUpdate(BatchUpdateParam params, Long loginUserId);
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/AsnOrderItemServiceImpl.java
@@ -13,7 +13,9 @@
import com.vincent.rsf.server.api.service.ReportMsgService;
import com.vincent.rsf.server.common.domain.BaseParam;
import com.vincent.rsf.server.common.domain.PageParam;
import com.vincent.rsf.server.common.utils.CommonUtil;
import com.vincent.rsf.server.common.utils.ExcelUtil;
import com.vincent.rsf.server.common.utils.FieldsUtils;
import com.vincent.rsf.server.manager.controller.params.BatchUpdateParam;
import com.vincent.rsf.server.manager.entity.AsnOrder;
import com.vincent.rsf.server.manager.entity.excel.AsnOrderTemplate;
@@ -103,21 +105,36 @@
        return R.ok("操作成功!!");
    }
    /**
     * @author Ryan
     * @description ASN明细单据保存,及扩展字段保存
     * @param
     * @return
     * @time 2025/4/7 09:59
     */
    @Override
    public boolean fieldsSave(Map<String, Object> params) {
    @Transactional(rollbackFor = Exception.class)
    public boolean fieldsSave(Map<String, Object> params){
        AsnOrderItem asnOrderItem = JSONObject.parseObject(JSONObject.toJSONString(params), AsnOrderItem.class);
        if (StringUtils.isBlank(asnOrderItem.getTrackCode())) {
            String ruleCode = SerialRuleUtils.generateRuleCode(SerialRuleCode.SYS_LABEL_CODE, asnOrderItem);
            asnOrderItem.setTrackCode(ruleCode);
        }
        if (!this.saveOrUpdate(asnOrderItem)) {
            throw new CoolException("收货通知单明细保存失败!!");
        if (Objects.isNull(asnOrderItem.getAnfme()) || Double.compare(asnOrderItem.getAnfme(), 0.0) <= 0) {
            throw new CoolException("计划收货数不能为空!!");
        }
        //保存扩展字段
        try {
            ExtendFieldsUtils.saveFields(params);
            String uuid16 = CommonUtil.randomUUID16();
            Boolean fields = FieldsUtils.saveFields(params, uuid16);
            if (fields) {
                asnOrderItem.setFieldsIndex(uuid16);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        if (!this.saveOrUpdate(asnOrderItem)) {
            throw new CoolException("收货通知单明细保存失败!!");
        }
        return true;
    }
@@ -128,7 +145,7 @@
        if (hsahMap.getRecords().isEmpty()) {
            return hsahMap.setRecords(new ArrayList<>());
        }
        hsahMap.setRecords(ExtendFieldsUtils.getExtendFields(hsahMap.getRecords()));
        hsahMap.setRecords(FieldsUtils.getExtendFields(hsahMap.getRecords()));
        return hsahMap;
    }
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/AsnOrderServiceImpl.java
@@ -13,6 +13,7 @@
import com.vincent.rsf.server.manager.entity.AsnOrderItem;
import com.vincent.rsf.server.manager.entity.AsnOrderItemLog;
import com.vincent.rsf.server.manager.entity.AsnOrderLog;
import com.vincent.rsf.server.manager.enums.AsnExceStatus;
import com.vincent.rsf.server.manager.mapper.AsnOrderMapper;
import com.vincent.rsf.server.manager.entity.AsnOrder;
import com.vincent.rsf.server.manager.mapper.PurchaseMapper;
@@ -24,6 +25,7 @@
import com.vincent.rsf.server.system.constant.SerialRuleCode;
import com.vincent.rsf.server.system.mapper.SerialRuleMapper;
import com.vincent.rsf.server.system.utils.SerialRuleUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -95,7 +97,8 @@
    }
    @Override
    public R saveOrderAndItems(AsnOrderAndItemsParams params, Long loginUserId) {
    @Transactional(rollbackFor = Exception.class)
    public R saveOrderAndItems(AsnOrderAndItemsParams params, Long loginUserId) throws Exception {
        if (Objects.isNull(params.getOrders())) {
            throw new CoolException("主单信息不能为空");
        }
@@ -116,16 +119,9 @@
        if (params.getItems().isEmpty()) {
            throw new CoolException("收货通知单明细不能为寒食节!!");
        }
        params.getItems().forEach(item -> {
            item.put("asnId", orders.getId());
            item.put("asnCode", orders.getCode());
            item.put("poCode", orders.getPoCode());
            item.put("createBy", loginUserId);
            item.put("updateBy", loginUserId);
            if (!asnOrderItemService.fieldsSave(item)) {
                throw new CoolException("明细保存失败!!");
            }
        });
        svaeOrUpdateOrderItem(params,loginUserId);
        return R.ok("保存成功!!");
    }
@@ -137,26 +133,55 @@
     * @return
     */
    @Override
    @Transactional
    public R updateOrderItem(AsnOrderAndItemsParams params, Long loginUserId) {
        if (Objects.isNull(params.getOrders())) {
    @Transactional(rollbackFor = Exception.class)
    public R updateOrderItem(AsnOrderAndItemsParams params, Long loginUserId) throws Exception {
        AsnOrder orders = params.getOrders();
        if (Objects.isNull(orders)) {
            throw new CoolException("主单信息不能为空!!");
        }
        if (Objects.isNull(params.getOrders().getId())) {
        if (Objects.isNull(orders.getId())) {
            throw new CoolException("数据错误:单据ID不能为空!!");
        }
        if (!this.updateById(params.getOrders())) {
        if (!this.updateById(orders)) {
            throw new CoolException("主单修改失败!!");
        }
        if (Objects.isNull(params.getItems()) || params.getItems().isEmpty()) {
            return R.ok("修改完成!!");
            return R.ok("明细参数不能为空!!");
        }
        List<Map<String, Object>> items = params.getItems();
        List<AsnOrderItem> asnOrderItems = JSONArray.parseArray(JSONArray.toJSONString(items), AsnOrderItem.class);
        if (!asnOrderItemService.saveOrUpdateBatch(asnOrderItems)) {
            throw new CoolException("明细修改失败!!");
        }
        svaeOrUpdateOrderItem(params,loginUserId);
        return R.ok("修改完成!!");
    }
    /**
     * @author Ryan
     * @description 更新或保存明细
     * @param
     * @return
     * @time 2025/4/7 13:28
     */
    @Transactional(rollbackFor = Exception.class)
    private void svaeOrUpdateOrderItem(AsnOrderAndItemsParams params, Long loginUserId) throws Exception{
        AsnOrder orders = params.getOrders();
        params.getItems().forEach(item -> {
            item.put("asnId", orders.getId());
            item.put("asnCode", orders.getCode());
            item.put("poCode", orders.getPoCode());
            item.put("createBy", loginUserId);
            item.put("updateBy", loginUserId);
            if (!asnOrderItemService.fieldsSave(item)) {
                throw new CoolException("明细保存失败!!");
            }
        });
        List<AsnOrderItem> orderItems = asnOrderItemService.list(new LambdaQueryWrapper<AsnOrderItem>()
                .eq(AsnOrderItem::getAsnId, params.getOrders().getId()));
        double sum = orderItems.stream().mapToDouble(AsnOrderItem::getAnfme).sum();
        orders.setAnfme(sum);
        if (!this.updateById(orders)) {
            throw new CoolException("计划收货数量修改失败!!");
        }
    }
    /**
@@ -218,9 +243,12 @@
        if (Objects.isNull(asrder) || Objects.isNull(asrder.getId())) {
            throw new CoolException("参数不能为空!!");
        }
        if (Objects.isNull(asrder.getAnfme()) || asrder.getAnfme().compareTo(0.00) == 0) {
            throw new CoolException("收货数量不能为零!!");
        }
        AsnOrder order = this.getById(asrder.getId());
        AsnOrderLog orderLog = new AsnOrderLog();
        order.setExceStatus(Short.valueOf("2"));
        order.setExceStatus(Short.parseShort(AsnExceStatus.ASN_EXCE_STATUS_TASK_DONE.val));
        BeanUtils.copyProperties(order, orderLog);
        orderLog.setId(null);
        orderLog.setAsnId(order.getId());
@@ -228,6 +256,7 @@
        if (!this.saveOrUpdate(order)) {
            throw new CoolException("状态修改失败!!");
        }
        orderLog.setExceStatus(Short.parseShort(AsnExceStatus.ASN_EXCE_STATUS_TASK_CLOSE.val));
        if (!asnOrderLogService.save(orderLog)) {
            throw new CoolException("主单历史档添加失败!!");
        }
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/MatnrServiceImpl.java
@@ -86,11 +86,13 @@
            }
            //获取动态字段,并保存明细内容
            if (!FieldsUtils.getFieldsSta().isEmpty()) {
                String uuid = CommonUtil.randomUUID16();
                matnr.setFieldsIndex(uuid);
                //保存物料扩展属性值
                try {
                    FieldsUtils.saveFields(template, uuid);
                    String uuid = CommonUtil.randomUUID16();
                    boolean b = FieldsUtils.saveFields(template, uuid);
                    if (b) {
                        matnr.setFieldsIndex(uuid);
                    }
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/TaskServiceImpl.java
@@ -8,6 +8,7 @@
import com.vincent.rsf.framework.exception.CoolException;
import com.vincent.rsf.server.api.entity.enums.TaskType;
import com.vincent.rsf.server.manager.entity.*;
import com.vincent.rsf.server.manager.enums.PakinIOStatus;
import com.vincent.rsf.server.manager.mapper.TaskMapper;
import com.vincent.rsf.server.manager.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@@ -67,9 +68,11 @@
        }
        /**获取组拖*/
        List<Long> ids = waitPakin.stream().map(WaitPakin::getId).collect(Collectors.toList());
        List<WaitPakin> waitPakins = waitPakinService.list(new LambdaQueryWrapper<WaitPakin>().in(WaitPakin::getId, ids));
        List<WaitPakin> waitPakins = waitPakinService.list(new LambdaQueryWrapper<WaitPakin>()
                .in(WaitPakin::getId, ids)
                .eq(WaitPakin::getIoStatus, Short.parseShort(PakinIOStatus.PAKIN_IO_STATUS_DONE.val)));
        if (waitPakins.isEmpty()) {
            throw new CoolException("组拖信息不存在!!");
            throw new CoolException("请检查组拖状态是否完成!!");
        }
        waitPakins.forEach(pakin -> {
            List<TaskItem> taskItems = new ArrayList<>();
@@ -90,11 +93,10 @@
            if (!this.save(task)) {
                throw new CoolException("任务保存失败!!");
            }
            if (!locService.update(new LambdaUpdateWrapper<Loc>().eq(Loc::getCode, pakin.getCode())
            if (!locService.update(new LambdaUpdateWrapper<Loc>().eq(Loc::getCode, task.getTargLoc())
                    .set(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_S.type).set(Loc::getBarcode, pakin.getBarcode()))) {
                throw new CoolException("库位预约失败!!");
            }
            /**获取组拖明细**/
            List<WaitPakinItem> waitPakinItems = waitPakinItemService.list(new LambdaQueryWrapper<WaitPakinItem>().eq(WaitPakinItem::getPakinId, pakin.getId()));
            if (waitPakinItems.isEmpty()) {
@@ -118,9 +120,15 @@
            }
        });
        if (!waitPakinService.update(new LambdaUpdateWrapper<WaitPakin>()
                .in(WaitPakin::getId, ids)
                .set(WaitPakin::getUpdateBy, loginUserId)
                .set(WaitPakin::getCreateBy, loginUserId)
                .set(WaitPakin::getIoStatus, PakinIOStatus.PAKIN_IO_STATUS_TASK_EXCE.val))) {
            throw new CoolException("组拖状态修改失败!!");
        }
        return R.ok("任务生成完毕!");
    }
    /**
     * 完成任务
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/WaitPakinServiceImpl.java
@@ -6,6 +6,7 @@
import com.vincent.rsf.server.manager.controller.params.PakinItem;
import com.vincent.rsf.server.manager.controller.params.WaitPakinParam;
import com.vincent.rsf.server.manager.entity.*;
import com.vincent.rsf.server.manager.enums.PakinIOStatus;
import com.vincent.rsf.server.manager.mapper.WaitPakinMapper;
import com.vincent.rsf.server.manager.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@@ -79,7 +80,7 @@
        }
        pakin.setCode(ruleCode)
                //状态修改为入库中
                .setIoStatus(Short.parseShort("1"))
                .setIoStatus(Short.parseShort(PakinIOStatus.PAKIN_IO_STATUS_DONE.val))
                .setAnfme(sum)
                .setBarcode(waitPakin.getBarcode());
        if (!this.save(pakin)) {
@@ -103,26 +104,25 @@
                    .setAsnId(item.getAsnId())
                    .setAsnCode(item.getAsnCode())
                    .setAsnItemId(item.getId())
                    .setMatnrCode(item.getMatnrCode())
                    .setBatch(item.getSplrBatch())
                    .setUnit(item.getStockUnit())
                    .setFieldsIndex(item.getFieldsIndex())
                    .setUnit(item.getStockUnit())
                    .setMatnrId(item.getMatnrId())
                    .setMaktx(item.getMaktx())
                    .setMatnrCode(item.getMatnrCode());
            for (PakinItem waitPakinItem : waitPakin.getItems()) {
                if (waitPakinItem.getTrackCode().equals(item.getTrackCode())) {
                    Double v = item.getWorkQty() + waitPakinItem.getReceiptQty();
                    pakinItem.setWorkQty(v)
//                    Double v = item.getWorkQty() + waitPakinItem.getReceiptQty();
                    pakinItem
                            .setWorkQty(waitPakinItem.getReceiptQty())
                            .setAnfme(waitPakinItem.getReceiptQty())
                            .setTrackCode(waitPakinItem.getTrackCode());
                    /**更新单据执行中库存*/
                    if (v.compareTo(item.getAnfme()) > 0) {throw new CoolException("执行中数量大于收货数量!!");}
                    if (!asnOrderItemService.update(new LambdaUpdateWrapper<AsnOrderItem>()
                            .eq(AsnOrderItem::getTrackCode, waitPakinItem.getTrackCode()).set(AsnOrderItem::getWorkQty, v))) {
                        throw new CoolException("执行中库存更新失败!!");
                    }
//                    if (v.compareTo(item.getAnfme()) > 0) {throw new CoolException("执行中数量大于收货数量!!");}
//                    if (!asnOrderItemService.update(new LambdaUpdateWrapper<AsnOrderItem>()
//                            .eq(AsnOrderItem::getTrackCode, waitPakinItem.getTrackCode()).set(AsnOrderItem::getWorkQty, v))) {
//                        throw new CoolException("执行中库存更新失败!!");
//                    }
                }
            }
            items.add(pakinItem);
rsf-server/src/main/java/com/vincent/rsf/server/system/utils/ExtendFieldsUtils.java
@@ -8,7 +8,9 @@
import com.vincent.rsf.server.system.entity.FieldsItem;
import com.vincent.rsf.server.system.service.FieldsItemService;
import com.vincent.rsf.server.system.service.FieldsService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
@@ -21,75 +23,41 @@
 */
public class ExtendFieldsUtils {
    /**
     * @author Ryan
     * @description 明细单据保存扩展字段
     * @param
     * @return
     * @time 2025/3/15 13:36
     */
    public static Boolean saveFields(Map<String, Object> params) throws Exception{
        FieldsService fieldsService = SpringUtils.getBean(FieldsService.class);
        List<Fields> fields = fieldsService.list(new LambdaQueryWrapper<Fields>()
                .eq(Fields::getStatus, 1)
                .eq(Fields::getFlagEnable, 1));
        List<FieldsItem> fieldsItems = new ArrayList<>();
        if (!fields.isEmpty()) {
            String uuid16 = CommonUtil.randomUUID16();
            for (Fields obj : fields) {
                if (!Objects.isNull(params.get(obj.getFields()))) {
                    FieldsItem item = new FieldsItem();
                    item.setUuid(uuid16)
                            .setValue(params.get(obj.getFields()).toString())
                            .setMatnrId(Long.parseLong(params.get("matnrId").toString()))
                            .setFieldsId(obj.getId());
                    fieldsItems.add(item);
                }
                params.put("fieldsIndex", uuid16);
            }
            FieldsItemService fieldsItemService = SpringUtils.getBean(FieldsItemService.class);
            if (!fieldsItemService.saveBatch(fieldsItems)) {
                throw new CoolException("单据明细扩展字段保存失败!!");
            }
        }
        return true;
    }
//    /**
//     * @author Ryan
//     * @description 明细单据保存扩展字段
//     * @param
//     * @return
//     * @time 2025/3/15 13:36
//     */
//    @Transactional(rollbackFor = Exception.class)
//    public static Boolean saveFields(Map<String, Object> params, String uuid) throws Exception{
//        FieldsService fieldsService = SpringUtils.getBean(FieldsService.class);
//        List<Fields> fields = fieldsService.list(new LambdaQueryWrapper<Fields>()
//                .eq(Fields::getStatus, 1)
//                .eq(Fields::getFlagEnable, 1));
//        List<FieldsItem> fieldsItems = new ArrayList<>();
//        if (!fields.isEmpty()) {
//            for (Fields obj : fields) {
//                if (!Objects.isNull(params.get(obj.getFields())) && StringUtils.isNotBlank(params.get(obj.getFields()).toString())) {
//                    FieldsItem item = new FieldsItem();
//                    item.setUuid(uuid)
//                            .setValue(params.get(obj.getFields()).toString())
//                            .setMatnrId(Long.parseLong(params.get("matnrId").toString()))
//                            .setFieldsId(obj.getId());
//                    fieldsItems.add(item);
//                }
//            }
//            if (fieldsItems.isEmpty()) {
//                return false;
//            }
//            FieldsItemService fieldsItemService = SpringUtils.getBean(FieldsItemService.class);
//            if (!fieldsItemService.saveBatch(fieldsItems)) {
//                throw new CoolException("扩展字段保存失败!!");
//            }
//            return true;
//        }
//        return false;
//    }
    /**
     * @author Ryan
     * @description 获取扩展字段key-value值
     * @param
     * @return
     * @time 2025/3/15 15:05
     */
    public static List<Map<String, Object>> getExtendFields(List<Map<String, Object>> params) {
        FieldsService fieldsService = SpringUtils.getBean(FieldsService.class);
        List<Fields> fields = fieldsService.list(new LambdaQueryWrapper<Fields>()
                .eq(Fields::getStatus, 1)
                .eq(Fields::getFlagEnable, 1));
        FieldsItemService fieldsItemService = SpringUtils.getBean(FieldsItemService.class);
        List<Map<String, Object>> result = new ArrayList<>();
        for (Map<String, Object> param : params) {
            result.add(param);
            if (Objects.isNull(param.get("fieldsIndex"))) {
                continue;
            }
            List<FieldsItem> itemList = fieldsItemService
                    .list(new LambdaQueryWrapper<FieldsItem>()
                            .eq(FieldsItem::getUuid, param.get("fieldsIndex")));
            if (itemList.isEmpty()) {
                continue;
            }
            fields.forEach(fds -> {
                for (FieldsItem fieldsItem : itemList) {
                    if (!Objects.isNull(fieldsItem.getFieldsId()) && fieldsItem.getFieldsId().equals(fds.getId())) {
                        param.put(fds.getFields(), fieldsItem.getValue());
                    }
                }
            });
        }
        return result;
    }
}
rsf-server/src/main/resources/application.yml
@@ -23,7 +23,7 @@
  #  global-config:
  #    field-strategy: 0
  configuration:
#    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    map-underscore-to-camel-case: true
    cache-enabled: true
    call-setters-on-nulls: true