skyouc
2025-04-15 9c0236bacbd10fb629a4142719c4199bca1038bc
修改
1. 新增库位明细流界面
2. 修改库存信息表
10个文件已添加
7 文件已重命名
3 文件已复制
1个文件已删除
15个文件已修改
2056 ■■■■■ 已修改文件
rsf-admin/src/i18n/en.js 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/i18n/zh.js 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/ResourceContent.js 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/locItem/LocItemCreate.jsx 160 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/locItem/LocItemEdit.jsx 160 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/locItem/LocItemList.jsx 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/locItem/LocItemPanel.jsx 147 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/locItem/index.jsx 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/order/OrderEdit.jsx 126 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/order/OrderCreate.jsx 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/order/OrderEdit.jsx 124 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/order/OrderItemCreate.jsx 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/order/OrderItemEdit.jsx 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/order/OrderItemList.jsx 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/order/OrderList.jsx 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/order/OrderPanel.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/order/index.jsx 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/MobileServiceImpl.java 54 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/common/CodeBuilder.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/LocItemController.java 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/OrderController.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/LocItem.java 304 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/Order.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/OrderItem.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/Stock.java 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/StockItem.java 318 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/TaskItem.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/mapper/LocItemMapper.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/schedules/ScheduleJobs.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/schedules/TaskSchedules.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/LocItemService.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/LocItemServiceImpl.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/TaskServiceImpl.java 168 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/system/constant/SerialRuleCode.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/locItem.sql 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/resources/mapper/manager/LocItemMapper.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/i18n/en.js
@@ -160,6 +160,9 @@
        taskItem: 'TaskItem',
        taskItemLog: 'TaskItemLog',
        taskLog: 'TaskLog',
        orderItem: 'OrderItem',
        order: 'Order',
    },
    table: {
        field: {
@@ -742,6 +745,36 @@
                spec: "spec",
                model: "model",
            },
            order: {
                code: "code",
                sourceCode: "sourceCode",
                sourceId: "sourceId",
                type: "type",
                wkType: "wkType",
                anfme: "anfme",
            },
            orderItem: {
                orderId: "orderId",
                orderCode: "orderCode",
                sourceItemId: "sourceItemId",
                matnrId: "matnrId",
                matnrCode: "matnrCode",
                maktx: "maktx",
                anfme: "anfme",
                stockUnit: "stockUnit",
                workQty: "workQty",
                purQty: "purQty",
                purUnit: "purUnit",
                qty: "qty",
                splrCode: "splrCode",
                batch: "batch",
                splrBatch: "splrBatch",
                splrName: "splrName",
                trackCode: "trackCode",
                barcode: "barcode",
                prodTime: "prodTime",
                packName: "packName",
            },
        }
    },
    page: {
@@ -849,6 +882,8 @@
        asnCreate: "asnCreate",
        createTask: "createTask",
        recover: "recover",
        order: 'Orders',
    },
};
rsf-admin/src/i18n/zh.js
@@ -162,6 +162,8 @@
        taskItem: '任务档明细',
        taskLog: '任务历史档',
        taskItemLog: '任务明细历史档',
        order: '综合单据管理',
    },
    table: {
        field: {
@@ -752,6 +754,36 @@
                spec: "规格",
                model: "型号",
            },
            order: {
                code: "编码",
                sourceCode: "源单据",
                sourceId: "源单据ID",
                type: "单据类型",
                wkType: "业务类型",
                anfme: "数量",
            },
            orderItem: {
                orderId: "主单ID",
                orderCode: "单据编码",
                sourceItemId: "源明细ID",
                matnrId: "物料ID",
                matnrCode: "物料编码",
                maktx: "物料名称",
                anfme: "数量",
                stockUnit: "stockUnit",
                workQty: "执行数",
                purQty: "采购数",
                purUnit: "采购单位",
                qty: "总数",
                splrCode: "供应商编码",
                batch: "批次",
                splrBatch: "供应商批次",
                splrName: "供应商名称",
                trackCode: "跟踪码",
                barcode: "条形码",
                prodTime: "生产日期",
                packName: "包装名称",
            },
        }
    },
    page: {
rsf-admin/src/page/ResourceContent.js
@@ -40,6 +40,7 @@
import asnOrderLog from './histories/asnOrderLog';
import task from './task';
import taskLog from './histories/taskLog';
import order from './orders/order';
const ResourceContent = (node) => {
    switch (node.component) {
@@ -115,7 +116,8 @@
            return task;
        case 'taskLog':
            return taskLog;
        case 'order':
            return order;
        default:
            return {
                list: ListGuesser,
rsf-admin/src/page/locItem/LocItemCreate.jsx
copy from rsf-admin/src/page/order/OrderItemCreate.jsx copy to rsf-admin/src/page/locItem/LocItemCreate.jsx
File was copied from rsf-admin/src/page/order/OrderItemCreate.jsx
@@ -31,7 +31,7 @@
import StatusSelectInput from "../components/StatusSelectInput";
import MemoInput from "../components/MemoInput";
const OrderItemCreate = (props) => {
const LocItemCreate = (props) => {
    const { open, setOpen } = props;
    const translate = useTranslate();
@@ -86,140 +86,108 @@
                            <Grid container rowSpacing={2} columnSpacing={2}>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.orderItem.orderId"
                                        source="orderId"
                                        label="table.field.locItem.locId"
                                        source="locId"
                                        autoFocus
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.orderItem.orderCode"
                                        source="orderCode"
                                        parse={v => v}
                                    <NumberInput
                                        label="table.field.locItem.orderId"
                                        source="orderId"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.orderItem.sourceItemId"
                                        source="sourceItemId"
                                        label="table.field.locItem.type"
                                        source="type"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.orderItem.matnrId"
                                    <NumberInput
                                        label="table.field.locItem.orderItemId"
                                        source="orderItemId"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.locItem.wkType"
                                        source="wkType"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.locItem.matnrId"
                                        source="matnrId"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.locItem.maktx"
                                        source="maktx"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.orderItem.matnrCode"
                                        label="table.field.locItem.matnrCode"
                                        source="matnrCode"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.orderItem.maktx"
                                        source="maktx"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.orderItem.anfme"
                                        source="anfme"
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.orderItem.stockUnit"
                                        source="stockUnit"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.orderItem.workQty"
                                        source="workQty"
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.orderItem.purQty"
                                        source="purQty"
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.orderItem.purUnit"
                                        source="purUnit"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.orderItem.qty"
                                        source="qty"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.orderItem.splrCode"
                                        source="splrCode"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.orderItem.batch"
                                        source="batch"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.orderItem.splrBatch"
                                        source="splrBatch"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.orderItem.splrName"
                                        source="splrName"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.orderItem.trackCode"
                                        label="table.field.locItem.trackCode"
                                        source="trackCode"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.orderItem.barcode"
                                        source="barcode"
                                        label="table.field.locItem.unit"
                                        source="unit"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.locItem.anfme"
                                        source="anfme"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.locItem.batch"
                                        source="batch"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.orderItem.prodTime"
                                        source="prodTime"
                                        label="table.field.locItem.splrBatch"
                                        source="splrBatch"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.orderItem.packName"
                                        source="packName"
                                        label="table.field.locItem.spec"
                                        source="spec"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.locItem.model"
                                        source="model"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.locItem.fieldsIndex"
                                        source="fieldsIndex"
                                        parse={v => v}
                                    />
                                </Grid>
@@ -246,4 +214,4 @@
    )
}
export default OrderItemCreate;
export default LocItemCreate;
rsf-admin/src/page/locItem/LocItemEdit.jsx
copy from rsf-admin/src/page/order/OrderItemEdit.jsx copy to rsf-admin/src/page/locItem/LocItemEdit.jsx
File was copied from rsf-admin/src/page/order/OrderItemEdit.jsx
@@ -40,7 +40,7 @@
    )
}
const OrderItemEdit = () => {
const LocItemEdit = () => {
    const translate = useTranslate();
    return (
@@ -65,140 +65,108 @@
                        </Typography>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.orderItem.orderId"
                                source="orderId"
                                label="table.field.locItem.locId"
                                source="locId"
                                autoFocus
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.orderItem.orderCode"
                                source="orderCode"
                                parse={v => v}
                            <NumberInput
                                label="table.field.locItem.orderId"
                                source="orderId"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.orderItem.sourceItemId"
                                source="sourceItemId"
                                label="table.field.locItem.type"
                                source="type"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.orderItem.matnrId"
                            <NumberInput
                                label="table.field.locItem.orderItemId"
                                source="orderItemId"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.locItem.wkType"
                                source="wkType"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.locItem.matnrId"
                                source="matnrId"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.locItem.maktx"
                                source="maktx"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.orderItem.matnrCode"
                                label="table.field.locItem.matnrCode"
                                source="matnrCode"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.orderItem.maktx"
                                source="maktx"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.orderItem.anfme"
                                source="anfme"
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.orderItem.stockUnit"
                                source="stockUnit"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.orderItem.workQty"
                                source="workQty"
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.orderItem.purQty"
                                source="purQty"
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.orderItem.purUnit"
                                source="purUnit"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.orderItem.qty"
                                source="qty"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.orderItem.splrCode"
                                source="splrCode"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.orderItem.batch"
                                source="batch"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.orderItem.splrBatch"
                                source="splrBatch"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.orderItem.splrName"
                                source="splrName"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.orderItem.trackCode"
                                label="table.field.locItem.trackCode"
                                source="trackCode"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.orderItem.barcode"
                                source="barcode"
                                label="table.field.locItem.unit"
                                source="unit"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.locItem.anfme"
                                source="anfme"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.locItem.batch"
                                source="batch"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.orderItem.prodTime"
                                source="prodTime"
                                label="table.field.locItem.splrBatch"
                                source="splrBatch"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.orderItem.packName"
                                source="packName"
                                label="table.field.locItem.spec"
                                source="spec"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.locItem.model"
                                source="model"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.locItem.fieldsIndex"
                                source="fieldsIndex"
                                parse={v => v}
                            />
                        </Stack>
@@ -218,4 +186,4 @@
    )
}
export default OrderItemEdit;
export default LocItemEdit;
rsf-admin/src/page/locItem/LocItemList.jsx
copy from rsf-admin/src/page/order/OrderList.jsx copy to rsf-admin/src/page/locItem/LocItemList.jsx
File was copied from rsf-admin/src/page/order/OrderList.jsx
@@ -34,8 +34,8 @@
} from 'react-admin';
import { Box, Typography, Card, Stack } from '@mui/material';
import { styled } from '@mui/material/styles';
import OrderCreate from "./OrderCreate";
import OrderPanel from "./OrderPanel";
import LocItemCreate from "./LocItemCreate";
import LocItemPanel from "./LocItemPanel";
import EmptyData from "../components/EmptyData";
import MyCreateButton from "../components/MyCreateButton";
import MyExportButton from '../components/MyExportButton';
@@ -63,12 +63,22 @@
    <DateInput label='common.time.after' source="timeStart" alwaysOn />,
    <DateInput label='common.time.before' source="timeEnd" alwaysOn />,
    <TextInput source="code" label="table.field.order.code" />,
    <TextInput source="sourceCode" label="table.field.order.sourceCode" />,
    <NumberInput source="sourceId" label="table.field.order.sourceId" />,
    <TextInput source="type" label="table.field.order.type" />,
    <TextInput source="wkType" label="table.field.order.wkType" />,
    <NumberInput source="anfme" label="table.field.order.anfme" />,
    <NumberInput source="locId" label="table.field.locItem.locId" />,
    <NumberInput source="orderId" label="table.field.locItem.orderId" />,
    <TextInput source="type" label="table.field.locItem.type" />,
    <NumberInput source="orderItemId" label="table.field.locItem.orderItemId" />,
    <NumberInput source="wkType" label="table.field.locItem.wkType" />,
    <NumberInput source="matnrId" label="table.field.locItem.matnrId" />,
    <TextInput source="maktx" label="table.field.locItem.maktx" />,
    <TextInput source="matnrCode" label="table.field.locItem.matnrCode" />,
    <TextInput source="trackCode" label="table.field.locItem.trackCode" />,
    <TextInput source="unit" label="table.field.locItem.unit" />,
    <NumberInput source="anfme" label="table.field.locItem.anfme" />,
    <TextInput source="batch" label="table.field.locItem.batch" />,
    <TextInput source="splrBatch" label="table.field.locItem.splrBatch" />,
    <TextInput source="spec" label="table.field.locItem.spec" />,
    <TextInput source="model" label="table.field.locItem.model" />,
    <TextInput source="fieldsIndex" label="table.field.locItem.fieldsIndex" />,
    <TextInput label="common.field.memo" source="memo" />,
    <SelectInput
@@ -82,7 +92,7 @@
    />,
]
const OrderList = () => {
const LocItemList = () => {
    const translate = useTranslate();
    const [createDialog, setCreateDialog] = useState(false);
@@ -99,7 +109,7 @@
                        }),
                    marginRight: !!drawerVal ? `${PAGE_DRAWER_WIDTH}px` : 0,
                }}
                title={"menu.order"}
                title={"menu.locItem"}
                empty={<EmptyData onClick={() => { setCreateDialog(true) }} />}
                filters={filters}
                sort={{ field: "create_time", order: "desc" }}
@@ -107,27 +117,37 @@
                    <TopToolbar>
                        <FilterButton />
                        <MyCreateButton onClick={() => { setCreateDialog(true) }} />
                        <SelectColumnsButton preferenceKey='order' />
                        <SelectColumnsButton preferenceKey='locItem' />
                        <MyExportButton />
                    </TopToolbar>
                )}
                perPage={DEFAULT_PAGE_SIZE}
            >
                <StyledDatagrid
                    preferenceKey='order'
                    preferenceKey='locItem'
                    bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />}
                    rowClick={(id, resource, record) => false}
                    expand={() => <OrderPanel />}
                    expand={() => <LocItemPanel />}
                    expandSingle={true}
                    omit={['id', 'createTime', 'createBy', 'memo']}
                >
                    <NumberField source="id" />
                    <TextField source="code" label="table.field.order.code" />
                    <TextField source="sourceCode" label="table.field.order.sourceCode" />
                    <NumberField source="sourceId" label="table.field.order.sourceId" />
                    <TextField source="type" label="table.field.order.type" />
                    <TextField source="wkType" label="table.field.order.wkType" />
                    <NumberField source="anfme" label="table.field.order.anfme" />
                    <NumberField source="locId" label="table.field.locItem.locId" />
                    <NumberField source="orderId" label="table.field.locItem.orderId" />
                    <TextField source="type" label="table.field.locItem.type" />
                    <NumberField source="orderItemId" label="table.field.locItem.orderItemId" />
                    <NumberField source="wkType" label="table.field.locItem.wkType" />
                    <NumberField source="matnrId" label="table.field.locItem.matnrId" />
                    <TextField source="maktx" label="table.field.locItem.maktx" />
                    <TextField source="matnrCode" label="table.field.locItem.matnrCode" />
                    <TextField source="trackCode" label="table.field.locItem.trackCode" />
                    <TextField source="unit" label="table.field.locItem.unit" />
                    <NumberField source="anfme" label="table.field.locItem.anfme" />
                    <TextField source="batch" label="table.field.locItem.batch" />
                    <TextField source="splrBatch" label="table.field.locItem.splrBatch" />
                    <TextField source="spec" label="table.field.locItem.spec" />
                    <TextField source="model" label="table.field.locItem.model" />
                    <TextField source="fieldsIndex" label="table.field.locItem.fieldsIndex" />
                    <ReferenceField source="updateBy" label="common.field.updateBy" reference="user" link={false} sortable={false}>
                        <TextField source="nickname" />
@@ -145,12 +165,12 @@
                    </WrapperField>
                </StyledDatagrid>
            </List>
            <OrderCreate
            <LocItemCreate
                open={createDialog}
                setOpen={setCreateDialog}
            />
            <PageDrawer
                title='Order Detail'
                title='LocItem Detail'
                drawerVal={drawerVal}
                setDrawerVal={setDrawerVal}
            >
@@ -159,4 +179,4 @@
    )
}
export default OrderList;
export default LocItemList;
rsf-admin/src/page/locItem/LocItemPanel.jsx
New file
@@ -0,0 +1,147 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import { Box, Card, CardContent, Grid, Typography, Tooltip } from '@mui/material';
import {
    useTranslate,
    useRecordContext,
} from 'react-admin';
import PanelTypography from "../components/PanelTypography";
import * as Common from '@/utils/common'
const LocItemPanel = () => {
    const record = useRecordContext();
    if (!record) return null;
    const translate = useTranslate();
    return (
        <>
            <Card sx={{ width: { xs: 300, sm: 500, md: 600, lg: 800 }, margin: 'auto' }}>
                <CardContent>
                    <Grid container spacing={2}>
                        <Grid item xs={12} sx={{ display: 'flex', justifyContent: 'space-between' }}>
                            <Typography variant="h6" gutterBottom align="left" sx={{
                                maxWidth: { xs: '100px', sm: '180px', md: '260px', lg: '360px' },
                                whiteSpace: 'nowrap',
                                overflow: 'hidden',
                                textOverflow: 'ellipsis',
                            }}>
                                {Common.camelToPascalWithSpaces(translate('table.field.locItem.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.locItem.locId"
                                property={record.locId}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.locItem.orderId"
                                property={record.orderId}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.locItem.type"
                                property={record.type}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.locItem.orderItemId"
                                property={record.orderItemId}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.locItem.wkType"
                                property={record.wkType}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.locItem.matnrId"
                                property={record.matnrId}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.locItem.maktx"
                                property={record.maktx}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.locItem.matnrCode"
                                property={record.matnrCode}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.locItem.trackCode"
                                property={record.trackCode}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.locItem.unit"
                                property={record.unit}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.locItem.anfme"
                                property={record.anfme}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.locItem.batch"
                                property={record.batch}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.locItem.splrBatch"
                                property={record.splrBatch}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.locItem.spec"
                                property={record.spec}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.locItem.model"
                                property={record.model}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.locItem.fieldsIndex"
                                property={record.fieldsIndex}
                            />
                        </Grid>
                    </Grid>
                </CardContent>
            </Card >
        </>
    );
};
export default LocItemPanel;
rsf-admin/src/page/locItem/index.jsx
New file
@@ -0,0 +1,18 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import {
    ListGuesser,
    EditGuesser,
    ShowGuesser,
} from "react-admin";
import LocItemList from "./LocItemList";
import LocItemEdit from "./LocItemEdit";
export default {
    list: LocItemList,
    edit: LocItemEdit,
    show: ShowGuesser,
    recordRepresentation: (record) => {
        return `${record.id}`
    }
};
rsf-admin/src/page/order/OrderEdit.jsx
File was deleted
rsf-admin/src/page/orders/order/OrderCreate.jsx
File was renamed from rsf-admin/src/page/order/OrderCreate.jsx
@@ -27,9 +27,9 @@
    Grid,
    Box,
} from '@mui/material';
import DialogCloseButton from "../components/DialogCloseButton";
import StatusSelectInput from "../components/StatusSelectInput";
import MemoInput from "../components/MemoInput";
import DialogCloseButton from "../../components/DialogCloseButton";
import StatusSelectInput from "../../components/StatusSelectInput";
import MemoInput from "../../components/MemoInput";
const OrderCreate = (props) => {
    const { open, setOpen } = props;
rsf-admin/src/page/orders/order/OrderEdit.jsx
New file
@@ -0,0 +1,124 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import {
    Edit,
    SimpleForm,
    FormDataConsumer,
    useTranslate,
    TextInput,
    NumberInput,
    BooleanInput,
    DateInput,
    SelectInput,
    ReferenceInput,
    ReferenceArrayInput,
    AutocompleteInput,
    SaveButton,
    Toolbar,
    required,
    DeleteButton,
} from 'react-admin';
import { useWatch, useFormContext } from "react-hook-form";
import { Stack, Grid, Box, Typography } from '@mui/material';
import * as Common from '@/utils/common';
import { EDIT_MODE, REFERENCE_INPUT_PAGESIZE } from '@/config/setting';
import EditBaseAside from "../../components/EditBaseAside";
import CustomerTopToolBar from "../../components/EditTopToolBar";
import MemoInput from "../../components/MemoInput";
import StatusSelectInput from "../../components/StatusSelectInput";
import OrderItemList from "./OrderItemList";
const FormToolbar = () => {
    const { getValues } = useFormContext();
    return (
        <Toolbar sx={{ justifyContent: 'space-between' }}>
            <SaveButton />
            <DeleteButton mutationMode="optimistic" />
        </Toolbar>
    )
}
const OrderEdit = () => {
    const translate = useTranslate();
    return (
        <Box>
            <Edit
                redirect="list"
                mutationMode={EDIT_MODE}
                actions={<CustomerTopToolBar />}
                aside={<EditBaseAside />}
            >
                <SimpleForm
                    shouldUnregister
                    warnWhenUnsavedChanges
                    toolbar={<FormToolbar />}
                    mode="onTouched"
                    defaultValues={{}}
                >
                    <Grid container width={{ xs: '100%', xl: '80%' }} rowSpacing={3} columnSpacing={3}>
                        <Grid item xs={12} md={8}>
                            <Typography variant="h6" gutterBottom>
                                {translate('common.edit.title.main')}
                            </Typography>
                            <Stack direction='row' gap={2}>
                                <TextInput
                                    label="table.field.order.code"
                                    source="code"
                                    parse={v => v}
                                    autoFocus
                                />
                            </Stack>
                            <Stack direction='row' gap={2}>
                                <TextInput
                                    label="table.field.order.sourceCode"
                                    source="sourceCode"
                                    parse={v => v}
                                />
                            </Stack>
                            <Stack direction='row' gap={2}>
                                <NumberInput
                                    label="table.field.order.sourceId"
                                    source="sourceId"
                                />
                            </Stack>
                            <Stack direction='row' gap={2}>
                                <TextInput
                                    label="table.field.order.type"
                                    source="type"
                                    parse={v => v}
                                    validate={required()}
                                />
                            </Stack>
                            <Stack direction='row' gap={2}>
                                <TextInput
                                    label="table.field.order.wkType"
                                    source="wkType"
                                    parse={v => v}
                                    validate={required()}
                                />
                            </Stack>
                            <Stack direction='row' gap={2}>
                                <NumberInput
                                    label="table.field.order.anfme"
                                    source="anfme"
                                    validate={required()}
                                />
                            </Stack>
                        </Grid>
                        <Grid item xs={12} md={4}>
                            <Typography variant="h6" gutterBottom>
                                {translate('common.edit.title.common')}
                            </Typography>
                            <StatusSelectInput />
                            <Box mt="2em" />
                            <MemoInput />
                        </Grid>
                    </Grid>
                </SimpleForm>
            </Edit >
            <OrderItemList />
        </Box>
    )
}
export default OrderEdit;
rsf-admin/src/page/orders/order/OrderItemCreate.jsx
File was renamed from rsf-admin/src/page/order/OrderItemCreate.jsx
@@ -27,9 +27,9 @@
    Grid,
    Box,
} from '@mui/material';
import DialogCloseButton from "../components/DialogCloseButton";
import StatusSelectInput from "../components/StatusSelectInput";
import MemoInput from "../components/MemoInput";
import DialogCloseButton from "../../components/DialogCloseButton";
import StatusSelectInput from "../../components/StatusSelectInput";
import MemoInput from "../../components/MemoInput";
const OrderItemCreate = (props) => {
    const { open, setOpen } = props;
rsf-admin/src/page/orders/order/OrderItemEdit.jsx
File was renamed from rsf-admin/src/page/order/OrderItemEdit.jsx
@@ -24,10 +24,10 @@
import { Stack, Grid, Box, Typography } from '@mui/material';
import * as Common from '@/utils/common';
import { EDIT_MODE, REFERENCE_INPUT_PAGESIZE } from '@/config/setting';
import EditBaseAside from "../components/EditBaseAside";
import CustomerTopToolBar from "../components/EditTopToolBar";
import MemoInput from "../components/MemoInput";
import StatusSelectInput from "../components/StatusSelectInput";
import EditBaseAside from "../../components/EditBaseAside";
import CustomerTopToolBar from "../../components/EditTopToolBar";
import MemoInput from "../../components/MemoInput";
import StatusSelectInput from "../../components/StatusSelectInput";
const FormToolbar = () => {
    const { getValues } = useFormContext();
rsf-admin/src/page/orders/order/OrderItemList.jsx
File was renamed from rsf-admin/src/page/order/OrderItemList.jsx
@@ -35,11 +35,11 @@
import { Box, Typography, Card, Stack } from '@mui/material';
import { styled } from '@mui/material/styles';
import OrderItemCreate from "./OrderItemCreate";
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 EmptyData from "../../components/EmptyData";
import MyCreateButton from "../../components/MyCreateButton";
import MyExportButton from '../../components/MyExportButton';
import PageDrawer from "../../components/PageDrawer";
import MyField from "../../components/MyField";
import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting';
import * as Common from '@/utils/common';
rsf-admin/src/page/orders/order/OrderList.jsx
File was renamed from rsf-admin/src/page/order/OrderList.jsx
@@ -36,11 +36,11 @@
import { styled } from '@mui/material/styles';
import OrderCreate from "./OrderCreate";
import OrderPanel from "./OrderPanel";
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 EmptyData from "../../components/EmptyData";
import MyCreateButton from "../../components/MyCreateButton";
import MyExportButton from '../../components/MyExportButton';
import PageDrawer from "../../components/PageDrawer";
import MyField from "../../components/MyField";
import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting';
import * as Common from '@/utils/common';
rsf-admin/src/page/orders/order/OrderPanel.jsx
File was renamed from rsf-admin/src/page/order/OrderPanel.jsx
@@ -4,7 +4,7 @@
    useTranslate,
    useRecordContext,
} from 'react-admin';
import PanelTypography from "../components/PanelTypography";
import PanelTypography from "../../components/PanelTypography";
import * as Common from '@/utils/common'
const OrderPanel = () => {
rsf-admin/src/page/orders/order/index.jsx
rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/MobileServiceImpl.java
@@ -84,6 +84,8 @@
    private QlyIsptItemService qlyIsptItemService;
    @Resource
    private StockItemMapper stockItemMapper;
    @Autowired
    private LocItemService locItemService;
    @Resource
    private PurchaseItemMapper purchaseItemMapper;
    @Resource
@@ -619,32 +621,55 @@
            throw new CoolException("单据不存在!!");
        }
        Stock stock = new Stock();
        stock.setAsnId(OrderId).setAsnCode(order.getCode());
        if (!Objects.isNull(order.getPoCode()) && StringUtils.isNotBlank(order.getPoCode())) {
            Purchase purchase = purchaseService.getOne(new LambdaQueryWrapper<Purchase>().eq(Purchase::getCode, order.getPoCode()));
            if (!Objects.isNull(purchase)) {
                stock.setPlatOrderNo(purchase.getPlatCode()).setPlatToken(purchase.getPlatId());
            }
        }
//        if (!Objects.isNull(order.getPoCode()) && StringUtils.isNotBlank(order.getPoCode())) {
//            Purchase purchase = purchaseService.getOne(new LambdaQueryWrapper<Purchase>().eq(Purchase::getCode, order.getPoCode()));
//            if (!Objects.isNull(purchase)) {
//                stock.setPlatOrderNo(purchase.getPlatCode()).setPlatToken(purchase.getPlatId());
//            }
//        }
        String ruleCode = SerialRuleUtils.generateRuleCode(SerialRuleCode.SYS_STOCK_CODE, null);
        if (StringUtils.isBlank(ruleCode)) {
            throw new CoolException("当前业务:" + SerialRuleCode.SYS_STOCK_CODE + ",编码规则不存在!!");
        }
        List<AsnOrderItem> itemList = params.getItemList();
        double sum = itemList.stream().mapToDouble(AsnOrderItem::getAnfme).sum();
        stock.setAnfme(sum)
                .setSourceId(order.getId())
                .setType(order.getType())
                .setWkType(Short.parseShort(order.getWkType()));
        if (!stockService.save(stock)) {
            throw new CoolException("库存保存失败!!");
        }
        //TODO  平库上架策略问题: 1 平库库位是单独设计,还是与产库一起用类型区分
        Loc loc = locService.getOne(new LambdaQueryWrapper<Loc>().eq(Loc::getCode, params.getLocCode()));
        if (Objects.isNull(loc)) {
            throw new CoolException("库位不存在!!");
        }
        //locItemSerivce
        List<LocItem> locItems = new ArrayList<>();
        itemList.forEach(asnOrderItem -> {
            LocItem item = new LocItem();
            BeanUtils.copyProperties(asnOrderItem, item);
            item.setId(loc.getId())
                    .setOrderId(order.getId())
                    .setOrderItemId(asnOrderItem.getId())
                    .setWkType(Short.parseShort(order.getWkType()))
                    .setType(order.getType());
            locItems.add(item);
        });
        if (!locItemService.saveBatch(locItems)) {
            throw new CoolException("库位明细更新失败!!");
        }
        List<StockItem> stockItems = new ArrayList<>();
        params.getItemList().forEach(orderItem -> {
        itemList.forEach(orderItem -> {
            StockItem stockItem = new StockItem();
            BeanUtils.copyProperties(orderItem, stockItem);
            stockItem.setAsnItemId(orderItem.getId())
            stockItem.setSourceItemId(orderItem.getId())
                    .setBarcode(orderItem.getBarcode())
                    .setLocId(loc.getId())
                    .setStockCode(stock.getCode())
                    .setUpdateBy(loginUserId)
                    .setCreateBy(loginUserId)
                    .setId(null)
                    .setStockId(stock.getId());
            stockItems.add(stockItem);
@@ -829,14 +854,15 @@
                detlsDto.setInspect(inspect.getStatus$());
            }
            //获取当前库存信息
            StockItem stockItem = stockItemMapper.selectOne(new LambdaQueryWrapper<StockItem>()
                    .eq(StockItem::getAsnItemId, asnOrderItem.getId())
                    .eq(StockItem::getMatnrId, asnOrderItem.getMatnrId()));
            LocItem stockItem = locItemService.getOne(new LambdaQueryWrapper<LocItem>()
                    .eq(LocItem::getOrderItemId, asnOrderItem.getId())
                    .eq(LocItem::getBatch, asnOrderItem.getBatch())
                    .eq(LocItem::getMatnrId, asnOrderItem.getMatnrId()));
            //SET 当前库存数量
            if (Objects.isNull(stockItem)) {
                detlsDto.setStockQty(0.0);
            } else {
                detlsDto.setStockQty(stockItem.getQty() + stockItem.getWorkQty());
                detlsDto.setStockQty(stockItem.getAnfme() + stockItem.getWorkQty());
            }
            if (!Objects.isNull(asnOrderItem.getPoDetlId())) {
rsf-server/src/main/java/com/vincent/rsf/server/common/CodeBuilder.java
@@ -22,8 +22,8 @@
//        generator.username="sa";
//        generator.password="Zoneyung@zy56$";
        generator.table="man_order_item";
        generator.tableDesc="综合订单明细管理";
        generator.table="man_loc_item";
        generator.tableDesc="库位明细";
        generator.packagePath="com.vincent.rsf.server.manager";
        generator.build();
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/LocItemController.java
New file
@@ -0,0 +1,110 @@
package com.vincent.rsf.server.manager.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.vincent.rsf.framework.common.Cools;
import com.vincent.rsf.framework.common.R;
import com.vincent.rsf.server.common.utils.ExcelUtil;
import com.vincent.rsf.server.common.annotation.OperationLog;
import com.vincent.rsf.server.common.domain.BaseParam;
import com.vincent.rsf.server.common.domain.KeyValVo;
import com.vincent.rsf.server.common.domain.PageParam;
import com.vincent.rsf.server.manager.entity.LocItem;
import com.vincent.rsf.server.manager.service.LocItemService;
import com.vincent.rsf.server.system.controller.BaseController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
@RestController
public class LocItemController extends BaseController {
    @Autowired
    private LocItemService locItemService;
    @PreAuthorize("hasAuthority('manager:locItem:list')")
    @PostMapping("/locItem/page")
    public R page(@RequestBody Map<String, Object> map) {
        BaseParam baseParam = buildParam(map, BaseParam.class);
        PageParam<LocItem, BaseParam> pageParam = new PageParam<>(baseParam, LocItem.class);
        return R.ok().add(locItemService.page(pageParam, pageParam.buildWrapper(true)));
    }
    @PreAuthorize("hasAuthority('manager:locItem:list')")
    @PostMapping("/locItem/list")
    public R list(@RequestBody Map<String, Object> map) {
        return R.ok().add(locItemService.list());
    }
    @PreAuthorize("hasAuthority('manager:locItem:list')")
    @PostMapping({"/locItem/many/{ids}", "/locItems/many/{ids}"})
    public R many(@PathVariable Long[] ids) {
        return R.ok().add(locItemService.listByIds(Arrays.asList(ids)));
    }
    @PreAuthorize("hasAuthority('manager:locItem:list')")
    @GetMapping("/locItem/{id}")
    public R get(@PathVariable("id") Long id) {
        return R.ok().add(locItemService.getById(id));
    }
    @PreAuthorize("hasAuthority('manager:locItem:save')")
    @OperationLog("Create 库位明细")
    @PostMapping("/locItem/save")
    public R save(@RequestBody LocItem locItem) {
        locItem.setCreateBy(getLoginUserId());
        locItem.setCreateTime(new Date());
        locItem.setUpdateBy(getLoginUserId());
        locItem.setUpdateTime(new Date());
        if (!locItemService.save(locItem)) {
            return R.error("Save Fail");
        }
        return R.ok("Save Success").add(locItem);
    }
    @PreAuthorize("hasAuthority('manager:locItem:update')")
    @OperationLog("Update 库位明细")
    @PostMapping("/locItem/update")
    public R update(@RequestBody LocItem locItem) {
        locItem.setUpdateBy(getLoginUserId());
        locItem.setUpdateTime(new Date());
        if (!locItemService.updateById(locItem)) {
            return R.error("Update Fail");
        }
        return R.ok("Update Success").add(locItem);
    }
    @PreAuthorize("hasAuthority('manager:locItem:remove')")
    @OperationLog("Delete 库位明细")
    @PostMapping("/locItem/remove/{ids}")
    public R remove(@PathVariable Long[] ids) {
        if (!locItemService.removeByIds(Arrays.asList(ids))) {
            return R.error("Delete Fail");
        }
        return R.ok("Delete Success").add(ids);
    }
    @PreAuthorize("hasAuthority('manager:locItem:list')")
    @PostMapping("/locItem/query")
    public R query(@RequestParam(required = false) String condition) {
        List<KeyValVo> vos = new ArrayList<>();
        LambdaQueryWrapper<LocItem> wrapper = new LambdaQueryWrapper<>();
        if (!Cools.isEmpty(condition)) {
            wrapper.like(LocItem::getId, condition);
        }
        locItemService.page(new Page<>(1, 30), wrapper).getRecords().forEach(
                item -> vos.add(new KeyValVo(item.getId(), item.getId()))
        );
        return R.ok().add(vos);
    }
    @PreAuthorize("hasAuthority('manager:locItem:list')")
    @PostMapping("/locItem/export")
    public void export(@RequestBody Map<String, Object> map, HttpServletResponse response) throws Exception {
        ExcelUtil.build(ExcelUtil.create(locItemService.list(), LocItem.class), response);
    }
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/OrderController.java
@@ -12,6 +12,7 @@
import com.vincent.rsf.server.manager.entity.Order;
import com.vincent.rsf.server.manager.service.OrderService;
import com.vincent.rsf.server.system.controller.BaseController;
import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
@@ -19,6 +20,7 @@
import javax.servlet.http.HttpServletResponse;
import java.util.*;
@Api(tags = "综合订单管理")
@RestController
public class OrderController extends BaseController {
rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/LocItem.java
New file
@@ -0,0 +1,304 @@
package com.vincent.rsf.server.manager.entity;
import com.baomidou.mybatisplus.annotation.TableLogic;
import java.text.SimpleDateFormat;
import java.util.Date;
import lombok.experimental.Accessors;
import org.springframework.format.annotation.DateTimeFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import com.vincent.rsf.framework.common.Cools;
import com.vincent.rsf.framework.common.SpringUtils;
import com.vincent.rsf.server.system.service.UserService;
import com.vincent.rsf.server.system.entity.User;
import java.io.Serializable;
import java.util.Date;
@Data
@Accessors(chain = true)
@TableName("man_loc_item")
public class LocItem implements Serializable {
    private static final long serialVersionUID = 1L;
    /**
     * ID
     */
    @ApiModelProperty(value= "ID")
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    /**
     * 主单ID
     */
    @ApiModelProperty(value= "主单ID")
    private Long locId;
    /**
     * 单据ID
     */
    @ApiModelProperty(value= "单据ID")
    private Long orderId;
    /**
     * 单据类型
     */
    @ApiModelProperty(value= "单据类型")
    private String type;
    /**
     * 订单明细id
     */
    @ApiModelProperty(value= "订单明细id")
    private Long orderItemId;
    /**
     * 业务类型
     */
    @ApiModelProperty(value= "业务类型")
    private Short wkType;
    /**
     * 物料ID
     */
    @ApiModelProperty(value= "物料ID")
    private Long matnrId;
    /**
     * 物料名称
     */
    @ApiModelProperty(value= "物料名称")
    private String maktx;
    /**
     * 物料编码
     */
    @ApiModelProperty(value= "物料编码")
    private String matnrCode;
    /**
     * 物料跟踪码
     */
    @ApiModelProperty(value= "物料跟踪码")
    private String trackCode;
    /**
     * 库存单位
     */
    @ApiModelProperty(value= "库存单位")
    private String unit;
    /**
     * 数量
     */
    @ApiModelProperty(value= "数量")
    private Double anfme;
    @ApiModelProperty("执行数量")
    private Double workQty;
    /**
     * 库存批次
     */
    @ApiModelProperty(value= "库存批次")
    private String batch;
    /**
     * 供应商批次
     */
    @ApiModelProperty(value= "供应商批次")
    private String splrBatch;
    /**
     * 规格
     */
    @ApiModelProperty(value= "规格")
    private String spec;
    /**
     * 型号
     */
    @ApiModelProperty(value= "型号")
    private String model;
    /**
     * 字段索引
     */
    @ApiModelProperty(value= "字段索引")
    private String fieldsIndex;
    /**
     * 状态 1: 正常  0: 冻结
     */
    @ApiModelProperty(value= "状态 1: 正常  0: 冻结  ")
    private Integer status;
    /**
     * 是否删除 1: 是  0: 否
     */
    @ApiModelProperty(value= "是否删除 1: 是  0: 否  ")
    @TableLogic
    private Integer deleted;
    /**
     * 租户
     */
    @ApiModelProperty(value= "租户")
    private Integer tenantId;
    /**
     * 添加人员
     */
    @ApiModelProperty(value= "添加人员")
    private Long createBy;
    /**
     * 添加时间
     */
    @ApiModelProperty(value= "添加时间")
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
    private Date createTime;
    /**
     * 修改人员
     */
    @ApiModelProperty(value= "修改人员")
    private Long updateBy;
    /**
     * 修改时间
     */
    @ApiModelProperty(value= "修改时间")
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
    private Date updateTime;
    /**
     * 备注
     */
    @ApiModelProperty(value= "备注")
    private String memo;
    public LocItem() {}
    public LocItem(Long locId,Long orderId,String type,Long orderItemId,Short wkType,Long matnrId,String maktx,String matnrCode,String trackCode,String unit,Double anfme,String batch,String splrBatch,String spec,String model,String fieldsIndex,Integer status,Integer deleted,Integer tenantId,Long createBy,Date createTime,Long updateBy,Date updateTime,String memo) {
        this.locId = locId;
        this.orderId = orderId;
        this.type = type;
        this.orderItemId = orderItemId;
        this.wkType = wkType;
        this.matnrId = matnrId;
        this.maktx = maktx;
        this.matnrCode = matnrCode;
        this.trackCode = trackCode;
        this.unit = unit;
        this.anfme = anfme;
        this.batch = batch;
        this.splrBatch = splrBatch;
        this.spec = spec;
        this.model = model;
        this.fieldsIndex = fieldsIndex;
        this.status = status;
        this.deleted = deleted;
        this.tenantId = tenantId;
        this.createBy = createBy;
        this.createTime = createTime;
        this.updateBy = updateBy;
        this.updateTime = updateTime;
        this.memo = memo;
    }
//    LocItem locItem = new LocItem(
//            null,    // 主单ID
//            null,    // 单据ID
//            null,    // 单据类型
//            null,    // 订单明细id
//            null,    // 业务类型
//            null,    // 物料ID
//            null,    // 物料名称
//            null,    // 物料编码
//            null,    // 物料跟踪码
//            null,    // 库存单位
//            null,    // 数量
//            null,    // 库存批次
//            null,    // 供应商批次
//            null,    // 规格
//            null,    // 型号
//            null,    // 字段索引
//            null,    // 状态[非空]
//            null,    // 是否删除[非空]
//            null,    // 租户
//            null,    // 添加人员
//            null,    // 添加时间[非空]
//            null,    // 修改人员
//            null,    // 修改时间[非空]
//            null    // 备注
//    );
    public String getStatus$(){
        if (null == this.status){ return null; }
        switch (this.status){
            case 1:
                return "正常";
            case 0:
                return "冻结";
            default:
                return String.valueOf(this.status);
        }
    }
    public String getCreateBy$(){
        UserService service = SpringUtils.getBean(UserService.class);
        User user = service.getById(this.createBy);
        if (!Cools.isEmpty(user)){
            return String.valueOf(user.getNickname());
        }
        return null;
    }
    public String getCreateTime$(){
        if (Cools.isEmpty(this.createTime)){
            return "";
        }
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.createTime);
    }
    public String getUpdateBy$(){
        UserService service = SpringUtils.getBean(UserService.class);
        User user = service.getById(this.updateBy);
        if (!Cools.isEmpty(user)){
            return String.valueOf(user.getNickname());
        }
        return null;
    }
    public String getUpdateTime$(){
        if (Cools.isEmpty(this.updateTime)){
            return "";
        }
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.updateTime);
    }
    public Boolean getStatusBool(){
        if (null == this.status){ return null; }
        switch (this.status){
            case 1:
                return true;
            case 0:
                return false;
            default:
                return null;
        }
    }
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/Order.java
@@ -3,6 +3,8 @@
import com.baomidou.mybatisplus.annotation.TableLogic;
import java.text.SimpleDateFormat;
import java.util.Date;
import lombok.experimental.Accessors;
import org.springframework.format.annotation.DateTimeFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
@@ -22,6 +24,7 @@
import java.util.Date;
@Data
@Accessors(chain = true)
@TableName("man_order")
public class Order implements Serializable {
rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/OrderItem.java
@@ -3,6 +3,8 @@
import com.baomidou.mybatisplus.annotation.TableLogic;
import java.text.SimpleDateFormat;
import java.util.Date;
import lombok.experimental.Accessors;
import org.springframework.format.annotation.DateTimeFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
@@ -22,6 +24,7 @@
import java.util.Date;
@Data
@Accessors(chain = true)
@TableName("man_order_item")
public class OrderItem implements Serializable {
rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/Stock.java
@@ -29,7 +29,6 @@
@Accessors(chain = true)
@TableName("man_stock")
public class Stock implements Serializable {
    private static final long serialVersionUID = 1L;
    /**
@@ -40,61 +39,40 @@
    private Long id;
    /**
     * ASN单据, 带出PO单
     * 编号
     */
    @ApiModelProperty(value= "ASN单据, 带出PO单")
    private Long asnId;
    @ApiModelProperty("订单编码")
    private String asnCode;
    @ApiModelProperty(value= "编号")
    private String code;
    /**
     * ERP凭证
     * 源单据编码
     */
    @ApiModelProperty(value= "plat凭证")
    private String platToken;
    @ApiModelProperty(value= "源单据编码")
    private String sourceCode;
    /**
     * plat单号
     * 源单据ID
     */
    @ApiModelProperty(value= "plat单号")
    private String platOrderNo;
    @ApiModelProperty(value= "源单据ID")
    private Long sourceId;
    /**
     * plat库存地址
     * 单据类型
     */
    @ApiModelProperty(value= "plat库存地址")
    private String platStkAdr;
    @ApiModelProperty(value= "单据类型")
    private String type;
    /**
     * 合同标识
     * 业务类型
     */
    @ApiModelProperty(value= "合同标识")
    private String contractId;
    @ApiModelProperty(value= "业务类型")
    private Short wkType;
    /**
     * 锁定原因
     * 库存数量
     */
    @ApiModelProperty(value= "锁定原因")
    private String lockReason;
    /**
     * 锁定状态
     */
    @ApiModelProperty(value= "锁定状态")
    private Short lockStatus;
    /**
     * 锁定人
     */
    @ApiModelProperty(value= "锁定人")
    private String locker;
    /**
     * 锁定时间
     */
    @ApiModelProperty(value= "锁定时间")
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
    private Date lockedTime;
    @ApiModelProperty(value= "库存数量")
    private Double anfme;
    /**
     * 状态 1: 正常  0: 冻结  
@@ -149,16 +127,13 @@
    public Stock() {}
    public Stock(String asnOrder,String platToken,String platOrder,String platStkAdr,String contractId,String lockReason,Short lockStatus,String locker,Date lockedTime,Integer status,Integer deleted,Integer tenantId,Long createBy,Date createTime,Long updateBy,Date updateTime,String memo) {
        this.platOrderNo = asnOrder;
        this.platToken = platToken;
        this.platOrderNo = platOrder;
        this.platStkAdr = platStkAdr;
        this.contractId = contractId;
        this.lockReason = lockReason;
        this.lockStatus = lockStatus;
        this.locker = locker;
        this.lockedTime = lockedTime;
    public Stock(String code,String sourceCode,Long sourceId,String type,Short wkType,Double anfme,Integer status,Integer deleted,Integer tenantId,Long createBy,Date createTime,Long updateBy,Date updateTime,String memo) {
        this.code = code;
        this.sourceCode = sourceCode;
        this.sourceId = sourceId;
        this.type = type;
        this.wkType = wkType;
        this.anfme = anfme;
        this.status = status;
        this.deleted = deleted;
        this.tenantId = tenantId;
@@ -189,12 +164,12 @@
//            null    // 备注
//    );
    public String getLockedTime$(){
        if (Cools.isEmpty(this.lockedTime)){
            return "";
        }
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.lockedTime);
    }
//    public String getLockedTime$(){
//        if (Cools.isEmpty(this.lockedTime)){
//            return "";
//        }
//        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.lockedTime);
//    }
    public String getStatus$(){
        if (null == this.status){ return null; }
rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/StockItem.java
@@ -37,21 +37,27 @@
    private Long id;
    /**
     * 任务明细ID
     * 主单ID
     */
    @ApiModelProperty("任务明细ID")
    private Long taskItemId;
    /**
     * 库存外键标识
     */
    @ApiModelProperty(value= "库存外键标识")
    @ApiModelProperty(value= "主单ID")
    private Long stockId;
    /**
     * 物料标识
     * 主单编号
     */
    @ApiModelProperty(value= "物料标识")
    @ApiModelProperty(value= "主单编号")
    private String stockCode;
    /**
     * 编号
     */
    @ApiModelProperty(value= "明细ID")
    private Long sourceItemId;
    /**
     * 物料ID
     */
    @ApiModelProperty(value= "物料ID")
    private Long matnrId;
    /**
@@ -60,21 +66,23 @@
    @ApiModelProperty(value= "物料编码")
    private String matnrCode;
    @ApiModelProperty(value = "通知单明细标识")
    private Long asnItemId;
    /**
     * 名称
     * 物料名称
     */
    @ApiModelProperty(value= "名称")
    @ApiModelProperty(value= "物料名称")
    private String maktx;
    /**
     * 数量
     * 送货数量
     */
    @ApiModelProperty(value= "数量")
    @ApiModelProperty(value= "送货数量")
    private Double anfme;
    /**
     * 库存单位
     */
    @ApiModelProperty(value= "库存单位")
    private String stockUnit;
    /**
     * 执行中数量
@@ -83,46 +91,58 @@
    private Double workQty;
    /**
     * 完成数量
     * 采购数量
     */
    @ApiModelProperty(value= "完成数量")
    @ApiModelProperty(value= "采购数量")
    private Double purQty;
    /**
     * 采购单位
     */
    @ApiModelProperty(value= "采购单位")
    private String purUnit;
    /**
     * 已收数量
     */
    @ApiModelProperty(value= "已收数量")
    private Double qty;
    /**
     * 收货重量
     * 供应商编码
     */
    @ApiModelProperty(value= "收货重量")
    private Double weight;
    @ApiModelProperty(value= "供应商编码")
    private String splrCode;
    /**
     * 单位
     * 库存批次
     */
    @ApiModelProperty(value= "单位")
    private String unit;
    /**
     * 货主标识
     */
    @ApiModelProperty(value= "货主标识")
    private Long shipperId;
    /**
     * 供应商标识
     */
    @ApiModelProperty(value= "供应商标识")
    private String splrId;
    /**
     * 品牌
     */
    @ApiModelProperty(value= "品牌")
    private String brand;
    /**
     * 批次
     */
    @ApiModelProperty(value= "批次")
    @ApiModelProperty(value= "库存批次")
    private String batch;
    /**
     * 供应商批次
     */
    @ApiModelProperty(value= "供应商批次")
    private String splrBatch;
    /**
     * 供应商名称
     */
    @ApiModelProperty(value= "供应商名称")
    private String splrName;
    /**
     * 跟踪码
     */
    @ApiModelProperty(value= "跟踪码")
    private String trackCode;
    /**
     * 条形码
     */
    @ApiModelProperty(value= "条形码")
    private String barcode;
    /**
     * 生产日期
@@ -131,86 +151,10 @@
    private String prodTime;
    /**
     * 质检标识
     * 包装名称
     */
    @ApiModelProperty(value= "质检标识")
    private Long inspectId;
    /**
     * 供应商批次
     */
    @ApiModelProperty(value= "供应商批次")
    private String splrBtch;
    /**
     * ASN单据,带出PO单
     */
    @ApiModelProperty(value= "ASN单据,带出PO单")
    @TableField(exist = false)
    private String asnOrder;
    /**
     * ERP凭证
     */
    @ApiModelProperty(value= "ERP凭证")
    @TableField(exist = false)
    private String erpToken;
    /**
     * ERP单号
     */
    @ApiModelProperty(value= "ERP单号")
    @TableField(exist = false)
    private String erpOrder;
    /**
     * ERP库存地址
     */
    @ApiModelProperty(value= "ERP库存地址")
    @TableField(exist = false)
    private String erpStkAdr;
    /**
     * 库位标识
     */
    @ApiModelProperty(value= "库位标识")
    private Long locId;
    /**
     * 容器编码
     */
    @ApiModelProperty(value= "容器编码")
    private String barcode;
    /**
     * 采购单位
     */
    @ApiModelProperty(value= "采购单位")
    private Double purPrice;
    /**
     * 锁定原因
     */
    @ApiModelProperty(value= "锁定原因")
    private String lockReason;
    /**
     * 锁定状态
     */
    @ApiModelProperty(value= "锁定状态")
    private Short lockStatus;
    /**
     * 锁定人
     */
    @ApiModelProperty(value= "锁定人")
    private String locker;
    /**
     * 锁定时间
     */
    @ApiModelProperty(value= "锁定时间")
    private Date lockedTime;
    @ApiModelProperty(value= "包装名称")
    private String packName;
    /**
     * 状态 1: 正常  0: 冻结  
@@ -265,35 +209,27 @@
    public StockItem() {}
    public StockItem(Long stockId,Long matnrId,Long asnItemId, String code,String matnrk,Double anfme,Double workQty,Double qty,Double weight,String unit,Long shipperId,String splrId,String brand,String batch,String prodTime,Long inspectId,String splrBtch,String asnOrder,String erpToken,String erpOrder,String erpStkAdr,Long locId,String barcode,Double purPrice,String lockReason,Short lockStatus,String locker,Date lockedTime,Integer status,Integer deleted,Integer tenantId,Long createBy,Date createTime,Long updateBy,Date updateTime,String memo) {
        this.stockId = stockId;
    public StockItem(Long orderId,String orderCode,Long sourceItemId,Long matnrId,String matnrCode,String maktx,Double anfme,String stockUnit,Double workQty,Double purQty,String purUnit,Double qty,String splrCode,String batch,String splrBatch,String splrName,String trackCode,String barcode,String prodTime,String packName,Integer status,Integer deleted,Integer tenantId,Long createBy,Date createTime,Long updateBy,Date updateTime,String memo) {
        this.stockId = orderId;
        this.stockCode = orderCode;
        this.sourceItemId = sourceItemId;
        this.matnrId = matnrId;
        this.asnItemId = asnItemId;
        this.matnrCode = code;
        this.maktx = matnrk;
        this.matnrCode = matnrCode;
        this.maktx = maktx;
        this.anfme = anfme;
        this.stockUnit = stockUnit;
        this.workQty = workQty;
        this.purQty = purQty;
        this.purUnit = purUnit;
        this.qty = qty;
        this.weight = weight;
        this.unit = unit;
        this.shipperId = shipperId;
        this.splrId = splrId;
        this.brand = brand;
        this.splrCode = splrCode;
        this.batch = batch;
        this.prodTime = prodTime;
        this.inspectId = inspectId;
        this.splrBtch = splrBtch;
        this.asnOrder = asnOrder;
        this.erpToken = erpToken;
        this.erpOrder = erpOrder;
        this.erpStkAdr = erpStkAdr;
        this.locId = locId;
        this.splrBatch = splrBatch;
        this.splrName = splrName;
        this.trackCode = trackCode;
        this.barcode = barcode;
        this.purPrice = purPrice;
        this.lockReason = lockReason;
        this.lockStatus = lockStatus;
        this.locker = locker;
        this.lockedTime = lockedTime;
        this.prodTime = prodTime;
        this.packName = packName;
        this.status = status;
        this.deleted = deleted;
        this.tenantId = tenantId;
@@ -342,14 +278,14 @@
//            null    // 备注
//    );
    public String getStockId$(){
        StockService service = SpringUtils.getBean(StockService.class);
        Stock stock = service.getById(this.stockId);
        if (!Cools.isEmpty(stock)){
            return String.valueOf(stock.getId());
        }
        return null;
    }
//    public String getStockId$(){
//        StockService service = SpringUtils.getBean(StockService.class);
//        Stock stock = service.getById(this.stockId);
//        if (!Cools.isEmpty(stock)){
//            return String.valueOf(stock.getId());
//        }
//        return null;
//    }
    public String getMatnrId$(){
        MatnrService service = SpringUtils.getBean(MatnrService.class);
@@ -360,14 +296,14 @@
        return null;
    }
    public String getShipperId$(){
        CompanysService service = SpringUtils.getBean(CompanysService.class);
        Companys shipper = service.getById(this.shipperId);
        if (!Cools.isEmpty(shipper)){
            return String.valueOf(shipper.getName());
        }
        return null;
    }
//    public String getShipperId$(){
//        CompanysService service = SpringUtils.getBean(CompanysService.class);
//        Companys shipper = service.getById(this.shipperId);
//        if (!Cools.isEmpty(shipper)){
//            return String.valueOf(shipper.getName());
//        }
//        return null;
//    }
//    public String getSplrId$(){
//        SupplierService service = SpringUtils.getBean(SupplierService.class);
@@ -378,30 +314,30 @@
//        return null;
//    }
//
    public String getInspectId$(){
        QlyInspectService service = SpringUtils.getBean(QlyInspectService.class);
        QlyInspect qlyInspect = service.getById(this.inspectId);
        if (!Cools.isEmpty(qlyInspect)){
            return String.valueOf(qlyInspect.getCode());
        }
        return null;
    }
    public String getLocId$(){
        LocService service = SpringUtils.getBean(LocService.class);
        Loc loc = service.getById(this.locId);
        if (!Cools.isEmpty(loc)){
            return String.valueOf(loc.getCode());
        }
        return null;
    }
    public String getLockedTime$(){
        if (Cools.isEmpty(this.lockedTime)){
            return "";
        }
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.lockedTime);
    }
//    public String getInspectId$(){
//        QlyInspectService service = SpringUtils.getBean(QlyInspectService.class);
//        QlyInspect qlyInspect = service.getById(this.inspectId);
//        if (!Cools.isEmpty(qlyInspect)){
//            return String.valueOf(qlyInspect.getCode());
//        }
//        return null;
//    }
//
//    public String getLocId$(){
//        LocService service = SpringUtils.getBean(LocService.class);
//        Loc loc = service.getById(this.locId);
//        if (!Cools.isEmpty(loc)){
//            return String.valueOf(loc.getCode());
//        }
//        return null;
//    }
//
//    public String getLockedTime$(){
//        if (Cools.isEmpty(this.lockedTime)){
//            return "";
//        }
//        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.lockedTime);
//    }
    public String getStatus$(){
        if (null == this.status){ return null; }
rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/TaskItem.java
@@ -67,6 +67,9 @@
    @ApiModelProperty("单据类型")
    private String orderType;
    @ApiModelProperty("业务类型")
    private Short wkType;
    @ApiModelProperty("单据明细ID")
    private Long orderItemId;
    /**
rsf-server/src/main/java/com/vincent/rsf/server/manager/mapper/LocItemMapper.java
New file
@@ -0,0 +1,12 @@
package com.vincent.rsf.server.manager.mapper;
import com.vincent.rsf.server.manager.entity.LocItem;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
@Mapper
@Repository
public interface LocItemMapper extends BaseMapper<LocItem> {
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/schedules/ScheduleJobs.java
@@ -184,7 +184,6 @@
     * @return
     * @time 2025/3/29 12:36
     */
//    @Scheduled(cron = "0 0/05 * * * ?  ")
    @Scheduled(cron = "0/25 * * * * ?")
    @Transactional(rollbackFor = Exception.class)
    public void pakinLog() {
rsf-server/src/main/java/com/vincent/rsf/server/manager/schedules/TaskSchedules.java
@@ -50,6 +50,10 @@
    private StockService stockService;
    @Autowired
    private LocService locService;
    @Autowired
    private OrderService orderService;
    @Autowired
    private OrderItemService orderItemService;
    /**
    * @author Ryan
    * @description 完成入库,更新库存
@@ -88,6 +92,7 @@
        if (taskItems.isEmpty()) {
            return;
        }
        List<TaskLog> taskLogs = new ArrayList<>();
        tasks.forEach(task -> {
            TaskLog taskLog = new TaskLog();
@@ -99,15 +104,18 @@
            throw new CoolException("任务历史档保存失败!!");
        }
        List<TaskItemLog >itemLogs = new ArrayList<>();
        taskItems.forEach(item -> {
            TaskItemLog itemLog = new TaskItemLog();
            BeanUtils.copyProperties(item, itemLog);
            itemLog.setId(null).setTaskItemId(item.getId());
            itemLogs.add(itemLog);
        });
        if (!taskItemLogService.saveBatch(itemLogs)) {
            throw new CoolException("任务明细历史档保存失败!!");
        }
        if (!taskService.removeByIds(list)) {
            throw new CoolException("原始任务删除失败!!");
        }
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/LocItemService.java
New file
@@ -0,0 +1,8 @@
package com.vincent.rsf.server.manager.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.vincent.rsf.server.manager.entity.LocItem;
public interface LocItemService extends IService<LocItem> {
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/LocItemServiceImpl.java
New file
@@ -0,0 +1,12 @@
package com.vincent.rsf.server.manager.service.impl;
import com.vincent.rsf.server.manager.mapper.LocItemMapper;
import com.vincent.rsf.server.manager.entity.LocItem;
import com.vincent.rsf.server.manager.service.LocItemService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
@Service("locItemService")
public class LocItemServiceImpl extends ServiceImpl<LocItemMapper, LocItem> implements LocItemService {
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/TaskServiceImpl.java
@@ -53,6 +53,14 @@
    @Autowired
    private DeviceSiteService deviceSiteService;
    @Autowired
    private OrderService orderService;
    @Autowired
    private OrderItemService orderItemService;
    @Autowired
    private LocItemService locItemService;
    /**
@@ -113,8 +121,13 @@
            waitPakinItems.forEach(item -> {
                TaskItem taskItem = new TaskItem();
                BeanUtils.copyProperties(item, taskItem);
                AsnOrder order = asnOrderService.getOne(new LambdaQueryWrapper<AsnOrder>().eq(AsnOrder::getId, item.getAsnId()));
                if (Objects.isNull(order)) {
                    throw new CoolException("单据不存在!!");
                }
                taskItem.setTaskId(task.getId())
                        .setOrderType(OrderType.ORDER_RECEIPT.type)
                        .setWkType(Short.parseShort(order.getWkType()))
                        .setSource(item.getId())
                        .setTrackCode(item.getTrackCode())
                        .setCreateBy(loginUserId)
@@ -139,7 +152,7 @@
    }
    /**
     * 完成任务
     * 完成任务 更新库位明细信息,将单据库存更新到单据库存表
     * @param tasks
     * @throws Exception
     */
@@ -152,59 +165,36 @@
        List<Long> list = tasks.stream().map(Task::getId).collect(Collectors.toList());
        List<TaskItem> taskItems = taskItemService.list(new LambdaQueryWrapper<TaskItem>().eq(TaskItem::getTaskId, list));
        if (taskItems.isEmpty()) {
            throw new CoolException("任务明细不能为空!!");
            throw new CoolException("任务明细不存在!!");
        }
        List<String> locCodes = tasks.stream().map(Task::getTargLoc).collect(Collectors.toList());
        Map<Long, List<TaskItem>> listMap = taskItems.stream().collect(Collectors.groupingBy(TaskItem::getTaskId));
        /**对任务明细按任务主单进行分组*/
        listMap.keySet().forEach(key -> {
            List<TaskItem> items = listMap.get(key);
            //更新库位明细
            try {
                saveLocItem(items, key);
            } catch (Exception e) {
                throw new CoolException("库位明细更新失败!!");
            }
        });
        /**对任务明细按订单进行分组*/
        Map<Long, List<TaskItem>> orderMap = taskItems.stream().collect(Collectors.groupingBy(TaskItem::getOrderId));
        List<StockItem> stockItems = new ArrayList<>();
        orderMap.keySet().forEach(key -> {
            AsnOrder order = asnOrderService.getOne(new LambdaQueryWrapper<AsnOrder>()
                    .eq(AsnOrder::getId, key)
                    .select(AsnOrder::getId, AsnOrder::getPoCode, AsnOrder::getCode));
            Stock stock = new Stock();
            if (!Objects.isNull(order.getPoCode()) && StringUtils.isNotBlank(order.getPoCode())) {
                Purchase purchase = purchaseService.getOne(new LambdaQueryWrapper<Purchase>().eq(Purchase::getCode, order.getPoCode()));
                if (!Objects.isNull(purchase)) {
                    stock.setPlatOrderNo(purchase.getPlatCode()).setPlatToken(purchase.getPlatId());
                }
            }
            String ruleCode = SerialRuleUtils.generateRuleCode(SerialRuleCode.SYS_STOCK_CODE, null);
            if (StringUtils.isBlank(ruleCode)) {
                throw new CoolException("当前业务:" + SerialRuleCode.SYS_STOCK_CODE + ",编码规则不存在!!");
            }
            stock.setAsnId(order.getId()).setAsnCode(order.getCode());
            if (!stockService.save(stock)) {
                throw new CoolException("库存保存失败!!");
            }
            List<TaskItem> items = orderMap.get(key);
            for (TaskItem item : items) {
                /**通过任务明细中的taskId查询,获取TASK的目标库位信息*/
                Task taskServiceOne = this.getOne(new LambdaQueryWrapper<Task>()
                        .select(Task::getId, Task::getTargLoc, Task::getOrgLoc, Task::getBarcode)
                        .eq(Task::getId, item.getTaskId()));
                Loc loc = locService.getOne(new LambdaQueryWrapper<Loc>().eq(Loc::getCode, taskServiceOne.getTargLoc()));
                if (Objects.isNull(loc)) {
                    throw new CoolException("库位不存在!!");
                }
                AsnOrderItem orderItem = asnOrderItemService.getOne(new LambdaQueryWrapper<AsnOrderItem>().eq(AsnOrderItem::getId, item.getOrderItemId()));
                if (Objects.isNull(orderItem)) {
                    throw new CoolException("单据明细不存在!!");
                }
                StockItem stockItem = new StockItem();
                BeanUtils.copyProperties(orderItem, stockItem);
                stockItem.setAsnItemId(item.getOrderItemId())
                        .setBarcode(taskServiceOne.getBarcode())
                        .setLocId(loc.getId())
                        .setId(null)
                        .setStockId(stock.getId());
                stockItems.add(stockItem);
            }
            if (!stockItemService.saveBatch(stockItems)) {
                throw new CoolException("库存修改架失败!!");
            //保存库存明细
            try {
                saveStockItems(items, order);
            } catch (Exception e) {
                throw new CoolException("库存管理保存更新失败!!");
            }
        });
        /**修改库位状态为F.在库*/
        List<String> locCodes = tasks.stream().map(Task::getTargLoc).collect(Collectors.toList());
        if (!locService.update(new LambdaUpdateWrapper<Loc>().set(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_F.type).in(Loc::getCode, locCodes))) {
            throw new CoolException("库位状态修改失败!!");
        }
@@ -212,4 +202,96 @@
            throw new CoolException("任务状态修改失败!!");
        }
    }
    /**
     * @author Ryan
     * @description 更新库位明细
     * @param
     * @return
     * @time 2025/4/15 15:28
     */
    @Transactional(rollbackFor = Exception.class)
    private void saveLocItem(List<TaskItem> items, Long taskId) throws Exception {
        Task task = this.getById(taskId);
        if (Objects.isNull(task)) {
            throw new CoolException("任务不存在!!");
        }
        List<LocItem> locItems = new ArrayList<>();
        items.forEach(taskItem -> {
            Loc loc = locService.getOne(new LambdaQueryWrapper<Loc>().eq(Loc::getCode, task.getTargLoc()));
            LocItem item = new LocItem();
            BeanUtils.copyProperties(taskItem, item);
            item.setLocId(loc.getId()).setType(taskItem.getOrderType());
            locItems.add(item);
        });
        if (!locItemService.saveBatch(locItems)) {
            throw new CoolException("库位明细更新失败!!");
        }
    }
    /**
     * 生成库存明细
     * @param items
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    private void saveStockItems(List<TaskItem> items, AsnOrder order) throws Exception {
        Stock stock = new Stock();
//        if (!Objects.isNull(order.getPoCode()) && StringUtils.isNotBlank(order.getPoCode())) {
//            Purchase purchase = purchaseService.getOne(new LambdaQueryWrapper<Purchase>().eq(Purchase::getCode, order.getPoCode()));
//            if (!Objects.isNull(purchase)) {
//                stock.setPlatOrderNo(purchase.getPlatCode()).setPlatToken(purchase.getPlatId());
//            }
//        }
        String ruleCode = SerialRuleUtils.generateRuleCode(SerialRuleCode.SYS_STOCK_CODE, null);
        if (StringUtils.isBlank(ruleCode)) {
            throw new CoolException("当前业务:" + SerialRuleCode.SYS_STOCK_CODE + ",编码规则不存在!!");
        }
        stock.setSourceId(order.getId()).setSourceCode(order.getCode());
        if (!stockService.save(stock)) {
            throw new CoolException("库存保存失败!!");
        }
        List<StockItem> stockItems = new ArrayList<>();
        for (TaskItem item : items) {
            /**通过任务明细中的taskId查询,获取TASK的目标库位信息*/
            AsnOrderItem orderItem = asnOrderItemService.getOne(new LambdaQueryWrapper<AsnOrderItem>().eq(AsnOrderItem::getId, item.getOrderItemId()));
            if (Objects.isNull(orderItem)) {
                throw new CoolException("单据明细不存在!!");
            }
            StockItem stockItem = new StockItem();
            BeanUtils.copyProperties(orderItem, stockItem);
            stockItem.setSourceItemId(item.getOrderItemId())
                    .setStockCode(stock.getCode())
                    .setSourceItemId(orderItem.getId())
                    .setId(null)
                    .setStockId(stock.getId());
            stockItems.add(stockItem);
        }
        if (!stockItemService.saveBatch(stockItems)) {
            throw new CoolException("库存修改架失败!!");
        }
    }
//    public void generateOrders() {
//        Map<Long, List<TaskItem>> listMap = taskItems.stream().collect(Collectors.groupingBy(TaskItem::getOrderId));
//        listMap.keySet().forEach(key -> {
//            double sum = listMap.get(key).stream().mapToDouble(TaskItem::getAnfme).sum();
//            listMap.get(key).forEach(taskItem -> {
//                Order order = new Order();
//                String ruleCode = SerialRuleUtils.generateRuleCode(SerialRuleCode.SYS_MANAGE_ORDER_CODE, taskItem);
//                if (Objects.isNull(ruleCode) || StringUtils.isBlank(ruleCode)) {
//                    throw new CoolException("编码规则错误:" + "请查看编码:" + "「SYS_MANAGE_ORDER_CODE」" + "是否设置");
//                }
//                order.setCode(ruleCode).setAnfme(sum).setSourceId(taskItem.getOrderId());
//            });
//        });
//
//        if (!orderItemService.saveBatch(orderItems)) {
//            throw new CoolException("单据明细保存失败!!");
//        }
//    }
}
rsf-server/src/main/java/com/vincent/rsf/server/system/constant/SerialRuleCode.java
@@ -53,4 +53,9 @@
     * 仓库编码规则
     */
    public final static String SYS_STOCK_CODE = "sys_stock_code";
    /**
     * 综合订单编码规则
     */
    public final static String SYS_MANAGE_ORDER_CODE = "sys_manage_order_code";
}
rsf-server/src/main/java/locItem.sql
New file
@@ -0,0 +1,37 @@
-- save locItem record
-- mysql
insert into `sys_menu` ( `name`, `parent_id`, `route`, `component`, `type`, `sort`, `tenant_id`, `status`) values ( 'menu.locItem', '0', '/manager/locItem', 'locItem', '0' , '0', '1' , '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Query 库位明细', '', '1', 'manager:locItem:list', '0', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Create 库位明细', '', '1', 'manager:locItem:save', '1', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Update 库位明细', '', '1', 'manager:locItem:update', '2', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Delete 库位明细', '', '1', 'manager:locItem:remove', '3', '1', '1');
-- locale menu name
locItem: 'LocItem',
-- locale field
locItem: {
    locId: "locId",
    orderId: "orderId",
    type: "type",
    orderItemId: "orderItemId",
    wkType: "wkType",
    matnrId: "matnrId",
    maktx: "maktx",
    matnrCode: "matnrCode",
    trackCode: "trackCode",
    unit: "unit",
    anfme: "anfme",
    batch: "batch",
    splrBatch: "splrBatch",
    spec: "spec",
    model: "model",
    fieldsIndex: "fieldsIndex",
},
-- ResourceContent
import locItem from './locItem';
case 'locItem':
    return locItem;
rsf-server/src/main/resources/mapper/manager/LocItemMapper.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.vincent.rsf.server.manager.mapper.LocItemMapper">
</mapper>