#新增
1. 添加库存信息页面
2. 添加库存信息明细页面
3. 添加质检信息页面
4. 添加合信息页面
5. 添加库位信息页面
6. 添加容器管理界面
5个文件已修改
72个文件已添加
7135 ■■■■■ 已修改文件
rsf-admin/src/i18n/en.js 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/i18n/zh.js 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/ResourceContent.js 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/container/ContainerCreate.jsx 213 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/container/ContainerEdit.jsx 187 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/container/ContainerList.jsx 190 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/container/ContainerPanel.jsx 141 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/container/index.jsx 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/contract/ContractCreate.jsx 133 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/contract/ContractEdit.jsx 105 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/contract/ContractList.jsx 156 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/contract/ContractPanel.jsx 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/contract/index.jsx 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/loc/LocCreate.jsx 229 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/loc/LocEdit.jsx 201 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/loc/LocList.jsx 184 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/loc/LocPanel.jsx 153 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/loc/index.jsx 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/matnr/MatnrListAside.jsx 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/qlyInspect/QlyInspectCreate.jsx 126 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/qlyInspect/QlyInspectEdit.jsx 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/qlyInspect/QlyInspectList.jsx 154 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/qlyInspect/QlyInspectPanel.jsx 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/qlyInspect/index.jsx 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/stock/StockCreate.jsx 174 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/stock/StockEdit.jsx 146 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/stock/StockList.jsx 168 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/stock/StockPanel.jsx 105 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/stock/index.jsx 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/stockItem/StockItemCreate.jsx 318 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/stockItem/StockItemEdit.jsx 294 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/stockItem/StockItemList.jsx 220 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/stockItem/StockItemPanel.jsx 213 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/stockItem/index.jsx 18 ●●●●● 补丁 | 查看 | 原始文档 | 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/ContainerController.java 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/ContractController.java 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/LocController.java 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/QlyInspectController.java 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/StockController.java 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/StockItemController.java 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/Container.java 325 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/Contract.java 194 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/Loc.java 306 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/QlyInspect.java 186 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/Stock.java 252 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/StockItem.java 452 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/mapper/ContainerMapper.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/mapper/ContractMapper.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/mapper/LocMapper.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/mapper/QlyInspectMapper.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/mapper/StockItemMapper.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/mapper/StockMapper.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/ContainerService.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/ContractService.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/LocService.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/QlyInspectService.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/StockItemService.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/StockService.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/ContainerServiceImpl.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/ContractServiceImpl.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/LocServiceImpl.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/QlyInspectServiceImpl.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/StockItemServiceImpl.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/StockServiceImpl.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/container.sql 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/contract.sql 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/loc.sql 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/qlyInspect.sql 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/stock.sql 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/stockItem.sql 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/resources/mapper/manager/ContainerMapper.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/resources/mapper/manager/ContractMapper.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/resources/mapper/manager/LocMapper.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/resources/mapper/manager/QlyInspectMapper.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/resources/mapper/manager/StockItemMapper.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/resources/mapper/manager/StockMapper.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/i18n/en.js
@@ -126,7 +126,10 @@
        matnrGroup: 'MatnrGroup',
        warehouse: 'Warehouse',
        warehouseAreas: 'WarehouseAreas',
        loc: 'Loc',
        container: 'Container',
        contract: 'Contract',
        stockItem: 'StockItem',
    },
    table: {
        field: {
@@ -288,6 +291,76 @@
                flagLabelMange: "flagLabelMange",
                flagMix: "flagMix",
            },
            loc: {
                areaId: "areaId",
                code: "code",
                type: "type",
                name: "name",
                flagLogic: "flagLogic",
                fucAtrrs: "fucAtrrs",
                barcode: "barcode",
                unit: "unit",
                size: "size",
                row: "row",
                col: "col",
                lev: "lev",
                channel: "channel",
                maxParts: "maxParts",
                maxPack: "maxPack",
                flagLabelMange: "flagLabelMange",
                locAttrs: "locAttrs",
            },
            container: {
                code: "code",
                name: "name",
                typeId: "typeId",
                used: "used",
                lenght: "lenght",
                width: "width",
                height: "height",
                rstLen: "rstLen",
                rstWid: "rstWid",
                rstWei: "rstWei",
                rstHei: "rstHei",
                panrentId: "panrentId",
                vaildTime: "vaildTime",
                flagRycle: "flagRycle",
                flagLogic: "flagLogic",
            },
            contract: {
                code: "Code",
                name: "Name",
                projectName: "ProjectName",
            },
            stockItem: {
                stockId: "stockId",
                matnrId: "matnrId",
                code: "code",
                matnrk: "matnrk",
                anfme: "anfme",
                workQty: "workQty",
                qty: "qty",
                weight: "weight",
                unit: "unit",
                shipperId: "shipperId",
                splrId: "splrId",
                brand: "brand",
                batch: "batch",
                prodTime: "prodTime",
                inspectId: "inspectId",
                splrBtch: "splrBtch",
                asnOrder: "asnOrder",
                erpToken: "erpToken",
                erpOrder: "erpOrder",
                erpStkAdr: "erpStkAdr",
                locId: "locId",
                barcode: "barcode",
                purPrice: "purPrice",
                lockReason: "lockReason",
                lockStatus: "lockStatus",
                locker: "locker",
                lockedTime: "lockedTime",
            },
        }
    },
    page: {
rsf-admin/src/i18n/zh.js
@@ -125,6 +125,12 @@
        matnrGroup: '物料分组',
        warehouse: '仓库信息',
        warehouseAreas: '仓库库区',
        loc: '基础库位',
        container: '容器管理',
        contract: '合同信息',
        stockItem: '库存明细',
        stock: '库存信息',
        qlyInspect: '质检信息',
    },
@@ -288,6 +294,85 @@
                flagLabelMange: "标签管理",
                flagMix: "混放",
            },
            loc: {
                areaId: "库区标识",
                code: "编码",
                type: "类型",
                name: "名称",
                flagLogic: "虚拟库位",
                fucAtrrs: "功能属性",
                barcode: "容器码",
                unit: "单位",
                size: "长/宽/高",
                row: "排",
                col: "列",
                lev: "层",
                channel: "通道",
                maxParts: "最大零件数",
                maxPack: "最大包装数",
                flagLabelMange: "标签管理",
                locAttrs: "属性",
            },
            container: {
                code: "编码",
                name: "名称",
                typeId: "类型",
                used: "使用次数",
                lenght: "长度",
                width: "宽",
                height: "高",
                rstLen: "限长",
                rstWid: "限宽",
                rstWei: "限重",
                rstHei: "限高",
                panrentId: "父级",
                vaildTime: "有效期",
                flagRycle: "回收",
                flagLogic: "虚拟容器",
            },
            contract: {
                code: "编码",
                name: "名称",
                projectName: "项目名称",
            },
            stock: {
                asnOrder: "库存单据",
                erpToken: "ERP凭证",
                erpOrder: "ERP单据",
                erpStkAdr: "ERP库存地",
                contractId: "合同标识",
                lockReason: "加锁原因",
                lockStatus: "加载状态",
                locker: "加锁人",
                lockedTime: "加锁时间",
            },
            stockItem: {
                stockId: "库存标识",
                matnrId: "物料标识",
                code: "物料编码",
                matnrk: "物料名称",
                anfme: "数量",
                workQty: "执行中数量",
                qty: "已完成数量",
                weight: "重量",
                unit: "单位",
                shipperId: "货主",
                splrId: "供应商",
                brand: "品牌",
                batch: "批次",
                prodTime: "生产日期",
                inspectId: "质查标识",
                splrBtch: "供应商批次",
                locId: "库位标识",
                barcode: "容器编码",
                purPrice: "采购价",
            },
            qlyInspect: {
                code: "编码",
                name: "名称",
            },
        }
    },
    page: {
rsf-admin/src/page/ResourceContent.js
@@ -19,6 +19,12 @@
import matnrGroup from './matnrGroup';
import warehouse from './warehouse';
import warehouseAreas from './warehouseAreas';
import loc from './loc';
import container from './container';
import contract from './contract';
import stockItem from './stockItem';
import stock from './stock';
import qlyInspect from './qlyInspect';
const ResourceContent = (node) => {
@@ -53,6 +59,18 @@
            return warehouse;
        case 'warehouseAreas':
            return warehouseAreas;
        case 'loc':
            return loc;
        case 'container':
            return container;
        case 'contract':
            return contract;
        case 'stockItem':
            return stockItem;
        case 'stock':
            return stock;
        case 'qlyInspect':
            return qlyInspect;
        default:
            return {
                list: ListGuesser,
rsf-admin/src/page/container/ContainerCreate.jsx
New file
@@ -0,0 +1,213 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import {
    CreateBase,
    useTranslate,
    TextInput,
    NumberInput,
    BooleanInput,
    DateInput,
    SaveButton,
    SelectInput,
    ReferenceInput,
    ReferenceArrayInput,
    AutocompleteInput,
    Toolbar,
    required,
    useDataProvider,
    useNotify,
    Form,
    useCreateController,
} from 'react-admin';
import {
    Dialog,
    DialogActions,
    DialogContent,
    DialogTitle,
    Stack,
    Grid,
    Box,
} from '@mui/material';
import DialogCloseButton from "../components/DialogCloseButton";
import StatusSelectInput from "../components/StatusSelectInput";
import MemoInput from "../components/MemoInput";
const ContainerCreate = (props) => {
    const { open, setOpen } = props;
    const translate = useTranslate();
    const notify = useNotify();
    const handleClose = (event, reason) => {
        if (reason !== "backdropClick") {
            setOpen(false);
        }
    };
    const handleSuccess = async (data) => {
        setOpen(false);
        notify('common.response.success');
    };
    const handleError = async (error) => {
        notify(error.message || 'common.response.fail', { type: 'error', messageArgs: { _: error.message } });
    };
    return (
        <>
            <CreateBase
                record={{}}
                transform={(data) => {
                    return data;
                }}
                mutationOptions={{ onSuccess: handleSuccess, onError: handleError }}
            >
                <Dialog
                    open={open}
                    onClose={handleClose}
                    aria-labelledby="form-dialog-title"
                    fullWidth
                    disableRestoreFocus
                    maxWidth="md"   // 'xs' | 'sm' | 'md' | 'lg' | 'xl'
                >
                    <Form>
                        <DialogTitle id="form-dialog-title" sx={{
                            position: 'sticky',
                            top: 0,
                            backgroundColor: 'background.paper',
                            zIndex: 1000
                        }}
                        >
                            {translate('create.title')}
                            <Box sx={{ position: 'absolute', top: 8, right: 8, zIndex: 1001 }}>
                                <DialogCloseButton onClose={handleClose} />
                            </Box>
                        </DialogTitle>
                        <DialogContent sx={{ mt: 2 }}>
                            <Grid container rowSpacing={2} columnSpacing={2}>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.container.code"
                                        source="code"
                                        parse={v => v}
                                        autoFocus
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.container.name"
                                        source="name"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.container.typeId"
                                        source="typeId"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.container.used"
                                        source="used"
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.container.lenght"
                                        source="lenght"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.container.width"
                                        source="width"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.container.height"
                                        source="height"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.container.rstLen"
                                        source="rstLen"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.container.rstWid"
                                        source="rstWid"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.container.rstWei"
                                        source="rstWei"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.container.rstHei"
                                        source="rstHei"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.container.panrentId"
                                        source="panrentId"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <DateInput
                                        label="table.field.container.vaildTime"
                                        source="vaildTime"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <SelectInput
                                        label="table.field.container.flagRycle"
                                        source="flagRycle"
                                        choices={[
                                            { id: 1, name: '是' },
                                            { id:  0, name: '否' },
                                        ]}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <SelectInput
                                        label="table.field.container.flagLogic"
                                        source="flagLogic"
                                        choices={[
                                            { id: 1, name: '是' },
                                            { id:  0, name: '否' },
                                        ]}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <StatusSelectInput />
                                </Grid>
                                <Grid item xs={12} display="flex" gap={1}>
                                    <Stack direction="column" spacing={1} width={'100%'}>
                                        <MemoInput />
                                    </Stack>
                                </Grid>
                            </Grid>
                        </DialogContent>
                        <DialogActions sx={{ position: 'sticky', bottom: 0, backgroundColor: 'background.paper', zIndex: 1000 }}>
                            <Toolbar sx={{ width: '100%', justifyContent: 'space-between' }}  >
                                <SaveButton />
                            </Toolbar>
                        </DialogActions>
                    </Form>
                </Dialog>
            </CreateBase>
        </>
    )
}
export default ContainerCreate;
rsf-admin/src/page/container/ContainerEdit.jsx
New file
@@ -0,0 +1,187 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import {
    Edit,
    SimpleForm,
    FormDataConsumer,
    useTranslate,
    TextInput,
    NumberInput,
    BooleanInput,
    DateInput,
    SelectInput,
    ReferenceInput,
    ReferenceArrayInput,
    AutocompleteInput,
    SaveButton,
    Toolbar,
    Labeled,
    NumberField,
    required,
    useRecordContext,
    DeleteButton,
} from 'react-admin';
import { useWatch, useFormContext } from "react-hook-form";
import { Stack, Grid, Box, Typography } from '@mui/material';
import * as Common from '@/utils/common';
import { EDIT_MODE, REFERENCE_INPUT_PAGESIZE } from '@/config/setting';
import EditBaseAside from "../components/EditBaseAside";
import CustomerTopToolBar from "../components/EditTopToolBar";
import MemoInput from "../components/MemoInput";
import StatusSelectInput from "../components/StatusSelectInput";
const FormToolbar = () => {
    const { getValues } = useFormContext();
    return (
        <Toolbar sx={{ justifyContent: 'space-between' }}>
            <SaveButton />
            <DeleteButton mutationMode="optimistic" />
        </Toolbar>
    )
}
const ContainerEdit = () => {
    const translate = useTranslate();
    return (
        <Edit
            redirect="list"
            mutationMode={EDIT_MODE}
            actions={<CustomerTopToolBar />}
            aside={<EditBaseAside />}
        >
            <SimpleForm
                shouldUnregister
                warnWhenUnsavedChanges
                toolbar={<FormToolbar />}
                mode="onTouched"
                defaultValues={{}}
            // validate={(values) => { }}
            >
                <Grid container width={{ xs: '100%', xl: '80%' }} rowSpacing={3} columnSpacing={3}>
                    <Grid item xs={12} md={8}>
                        <Typography variant="h6" gutterBottom>
                            {translate('common.edit.title.main')}
                        </Typography>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.container.code"
                                source="code"
                                parse={v => v}
                                autoFocus
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.container.name"
                                source="name"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.container.typeId"
                                source="typeId"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.container.used"
                                source="used"
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.container.lenght"
                                source="lenght"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.container.width"
                                source="width"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.container.height"
                                source="height"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.container.rstLen"
                                source="rstLen"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.container.rstWid"
                                source="rstWid"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.container.rstWei"
                                source="rstWei"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.container.rstHei"
                                source="rstHei"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.container.panrentId"
                                source="panrentId"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <DateInput
                                label="table.field.container.vaildTime"
                                source="vaildTime"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <SelectInput
                                label="table.field.container.flagRycle"
                                source="flagRycle"
                                choices={[
                                    { id: 1, name: '是' },
                                    { id:  0, name: '否' },
                                ]}
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <SelectInput
                                label="table.field.container.flagLogic"
                                source="flagLogic"
                                choices={[
                                    { id: 1, name: '是' },
                                    { id:  0, name: '否' },
                                ]}
                                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 >
    )
}
export default ContainerEdit;
rsf-admin/src/page/container/ContainerList.jsx
New file
@@ -0,0 +1,190 @@
import React, { useState, useRef, useEffect, useMemo, useCallback } from "react";
import { useNavigate } from 'react-router-dom';
import {
    List,
    DatagridConfigurable,
    SearchInput,
    TopToolbar,
    SelectColumnsButton,
    EditButton,
    FilterButton,
    CreateButton,
    ExportButton,
    BulkDeleteButton,
    WrapperField,
    useRecordContext,
    useTranslate,
    useNotify,
    useListContext,
    FunctionField,
    TextField,
    NumberField,
    DateField,
    BooleanField,
    ReferenceField,
    TextInput,
    DateTimeInput,
    DateInput,
    SelectInput,
    NumberInput,
    ReferenceInput,
    ReferenceArrayInput,
    AutocompleteInput,
    DeleteButton,
} from 'react-admin';
import { Box, Typography, Card, Stack } from '@mui/material';
import { styled } from '@mui/material/styles';
import ContainerCreate from "./ContainerCreate";
import ContainerPanel from "./ContainerPanel";
import EmptyData from "../components/EmptyData";
import MyCreateButton from "../components/MyCreateButton";
import MyExportButton from '../components/MyExportButton';
import PageDrawer from "../components/PageDrawer";
import MyField from "../components/MyField";
import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting';
import * as Common from '@/utils/common';
const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({
    '& .css-1vooibu-MuiSvgIcon-root': {
        height: '.9em'
    },
    '& .RaDatagrid-row': {
        cursor: 'auto'
    },
    '& .column-name': {
    },
    '& .opt': {
        width: 200
    },
}));
const filters = [
    <SearchInput source="condition" alwaysOn />,
    <DateInput label='common.time.after' source="timeStart" alwaysOn />,
    <DateInput label='common.time.before' source="timeEnd" alwaysOn />,
    <TextInput source="code" label="table.field.container.code" />,
    <TextInput source="name" label="table.field.container.name" />,
    <NumberInput source="typeId" label="table.field.container.typeId" />,
    <NumberInput source="used" label="table.field.container.used" />,
    <NumberInput source="lenght" label="table.field.container.lenght" />,
    <NumberInput source="width" label="table.field.container.width" />,
    <NumberInput source="height" label="table.field.container.height" />,
    <NumberInput source="rstLen" label="table.field.container.rstLen" />,
    <NumberInput source="rstWid" label="table.field.container.rstWid" />,
    <NumberInput source="rstWei" label="table.field.container.rstWei" />,
    <NumberInput source="rstHei" label="table.field.container.rstHei" />,
    <NumberInput source="panrentId" label="table.field.container.panrentId" />,
    <DateInput source="vaildTime" label="table.field.container.vaildTime" />,
    <SelectInput source="flagRycle" label="table.field.container.flagRycle"
        choices={[
            { id: 1, name: '是' },
            { id:  0, name: '否' },
        ]}
    />,
    <SelectInput source="flagLogic" label="table.field.container.flagLogic"
        choices={[
            { id: 1, name: '是' },
            { id:  0, name: '否' },
        ]}
    />,
    <TextInput label="common.field.memo" source="memo" />,
    <SelectInput
        label="common.field.status"
        source="status"
        choices={[
            { id: '1', name: 'common.enums.statusTrue' },
            { id: '0', name: 'common.enums.statusFalse' },
        ]}
        resettable
    />,
]
const ContainerList = () => {
    const translate = useTranslate();
    const [createDialog, setCreateDialog] = useState(false);
    const [drawerVal, setDrawerVal] = useState(false);
    return (
        <Box display="flex">
            <List
                sx={{
                    flexGrow: 1,
                    transition: (theme) =>
                        theme.transitions.create(['all'], {
                            duration: theme.transitions.duration.enteringScreen,
                        }),
                    marginRight: !!drawerVal ? `${PAGE_DRAWER_WIDTH}px` : 0,
                }}
                title={"menu.container"}
                empty={<EmptyData onClick={() => { setCreateDialog(true) }} />}
                filters={filters}
                sort={{ field: "create_time", order: "desc" }}
                actions={(
                    <TopToolbar>
                        <FilterButton />
                        <MyCreateButton onClick={() => { setCreateDialog(true) }} />
                        <SelectColumnsButton preferenceKey='container' />
                        <MyExportButton />
                    </TopToolbar>
                )}
                perPage={DEFAULT_PAGE_SIZE}
            >
                <StyledDatagrid
                    preferenceKey='container'
                    bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />}
                    rowClick={(id, resource, record) => false}
                    expand={() => <ContainerPanel />}
                    expandSingle={true}
                    omit={['id', 'createTime', 'createBy', 'memo']}
                >
                    <NumberField source="id" />
                    <TextField source="code" label="table.field.container.code" />
                    <TextField source="name" label="table.field.container.name" />
                    <NumberField source="typeId" label="table.field.container.typeId" />
                    <NumberField source="used" label="table.field.container.used" />
                    <NumberField source="lenght" label="table.field.container.lenght" />
                    <NumberField source="width" label="table.field.container.width" />
                    <NumberField source="height" label="table.field.container.height" />
                    <NumberField source="rstLen" label="table.field.container.rstLen" />
                    <NumberField source="rstWid" label="table.field.container.rstWid" />
                    <NumberField source="rstWei" label="table.field.container.rstWei" />
                    <NumberField source="rstHei" label="table.field.container.rstHei" />
                    <NumberField source="panrentId" label="table.field.container.panrentId" />
                    <DateField source="vaildTime" label="table.field.container.vaildTime" showTime />
                    <TextField source="flagRycle$" label="table.field.container.flagRycle" sortable={false} />
                    <TextField source="flagLogic$" label="table.field.container.flagLogic" sortable={false} />
                    <ReferenceField source="updateBy" label="common.field.updateBy" reference="user" link={false} sortable={false}>
                        <TextField source="nickname" />
                    </ReferenceField>
                    <DateField source="updateTime" label="common.field.updateTime" showTime />
                    <ReferenceField source="createBy" label="common.field.createBy" reference="user" link={false} sortable={false}>
                        <TextField source="nickname" />
                    </ReferenceField>
                    <DateField source="createTime" label="common.field.createTime" showTime />
                    <BooleanField source="statusBool" label="common.field.status" sortable={false} />
                    <TextField source="memo" label="common.field.memo" sortable={false} />
                    <WrapperField cellClassName="opt" label="common.field.opt">
                        <EditButton sx={{ padding: '1px', fontSize: '.75rem' }} />
                        <DeleteButton sx={{ padding: '1px', fontSize: '.75rem' }} mutationMode={OPERATE_MODE} />
                    </WrapperField>
                </StyledDatagrid>
            </List>
            <ContainerCreate
                open={createDialog}
                setOpen={setCreateDialog}
            />
            <PageDrawer
                title='Container Detail'
                drawerVal={drawerVal}
                setDrawerVal={setDrawerVal}
            >
            </PageDrawer>
        </Box>
    )
}
export default ContainerList;
rsf-admin/src/page/container/ContainerPanel.jsx
New file
@@ -0,0 +1,141 @@
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 ContainerPanel = () => {
    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.container.name'))}: {record.name}
                            </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.container.code"
                                property={record.code}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.container.name"
                                property={record.name}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.container.typeId"
                                property={record.typeId}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.container.used"
                                property={record.used}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.container.lenght"
                                property={record.lenght}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.container.width"
                                property={record.width}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.container.height"
                                property={record.height}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.container.rstLen"
                                property={record.rstLen}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.container.rstWid"
                                property={record.rstWid}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.container.rstWei"
                                property={record.rstWei}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.container.rstHei"
                                property={record.rstHei}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.container.panrentId"
                                property={record.panrentId}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.container.vaildTime"
                                property={record.vaildTime$}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.container.flagRycle"
                                property={record.flagRycle$}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.container.flagLogic"
                                property={record.flagLogic$}
                            />
                        </Grid>
                    </Grid>
                </CardContent>
            </Card >
        </>
    );
};
export default ContainerPanel;
rsf-admin/src/page/container/index.jsx
New file
@@ -0,0 +1,18 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import {
    ListGuesser,
    EditGuesser,
    ShowGuesser,
} from "react-admin";
import ContainerList from "./ContainerList";
import ContainerEdit from "./ContainerEdit";
export default {
    list: ContainerList,
    edit: ContainerEdit,
    show: ShowGuesser,
    recordRepresentation: (record) => {
        return `${record.name}`
    }
};
rsf-admin/src/page/contract/ContractCreate.jsx
New file
@@ -0,0 +1,133 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import {
    CreateBase,
    useTranslate,
    TextInput,
    NumberInput,
    BooleanInput,
    DateInput,
    SaveButton,
    SelectInput,
    ReferenceInput,
    ReferenceArrayInput,
    AutocompleteInput,
    Toolbar,
    required,
    useDataProvider,
    useNotify,
    Form,
    useCreateController,
} from 'react-admin';
import {
    Dialog,
    DialogActions,
    DialogContent,
    DialogTitle,
    Stack,
    Grid,
    Box,
} from '@mui/material';
import DialogCloseButton from "../components/DialogCloseButton";
import StatusSelectInput from "../components/StatusSelectInput";
import MemoInput from "../components/MemoInput";
const ContractCreate = (props) => {
    const { open, setOpen } = props;
    const translate = useTranslate();
    const notify = useNotify();
    const handleClose = (event, reason) => {
        if (reason !== "backdropClick") {
            setOpen(false);
        }
    };
    const handleSuccess = async (data) => {
        setOpen(false);
        notify('common.response.success');
    };
    const handleError = async (error) => {
        notify(error.message || 'common.response.fail', { type: 'error', messageArgs: { _: error.message } });
    };
    return (
        <>
            <CreateBase
                record={{}}
                transform={(data) => {
                    return data;
                }}
                mutationOptions={{ onSuccess: handleSuccess, onError: handleError }}
            >
                <Dialog
                    open={open}
                    onClose={handleClose}
                    aria-labelledby="form-dialog-title"
                    fullWidth
                    disableRestoreFocus
                    maxWidth="md"   // 'xs' | 'sm' | 'md' | 'lg' | 'xl'
                >
                    <Form>
                        <DialogTitle id="form-dialog-title" sx={{
                            position: 'sticky',
                            top: 0,
                            backgroundColor: 'background.paper',
                            zIndex: 1000
                        }}
                        >
                            {translate('create.title')}
                            <Box sx={{ position: 'absolute', top: 8, right: 8, zIndex: 1001 }}>
                                <DialogCloseButton onClose={handleClose} />
                            </Box>
                        </DialogTitle>
                        <DialogContent sx={{ mt: 2 }}>
                            <Grid container rowSpacing={2} columnSpacing={2}>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.contract.code"
                                        source="code"
                                        parse={v => v}
                                        autoFocus
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.contract.name"
                                        source="name"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.contract.projectName"
                                        source="projectName"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <StatusSelectInput />
                                </Grid>
                                <Grid item xs={12} display="flex" gap={1}>
                                    <Stack direction="column" spacing={1} width={'100%'}>
                                        <MemoInput />
                                    </Stack>
                                </Grid>
                            </Grid>
                        </DialogContent>
                        <DialogActions sx={{ position: 'sticky', bottom: 0, backgroundColor: 'background.paper', zIndex: 1000 }}>
                            <Toolbar sx={{ width: '100%', justifyContent: 'space-between' }}  >
                                <SaveButton />
                            </Toolbar>
                        </DialogActions>
                    </Form>
                </Dialog>
            </CreateBase>
        </>
    )
}
export default ContractCreate;
rsf-admin/src/page/contract/ContractEdit.jsx
New file
@@ -0,0 +1,105 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import {
    Edit,
    SimpleForm,
    FormDataConsumer,
    useTranslate,
    TextInput,
    NumberInput,
    BooleanInput,
    DateInput,
    SelectInput,
    ReferenceInput,
    ReferenceArrayInput,
    AutocompleteInput,
    SaveButton,
    Toolbar,
    Labeled,
    NumberField,
    required,
    useRecordContext,
    DeleteButton,
} from 'react-admin';
import { useWatch, useFormContext } from "react-hook-form";
import { Stack, Grid, Box, Typography } from '@mui/material';
import * as Common from '@/utils/common';
import { EDIT_MODE, REFERENCE_INPUT_PAGESIZE } from '@/config/setting';
import EditBaseAside from "../components/EditBaseAside";
import CustomerTopToolBar from "../components/EditTopToolBar";
import MemoInput from "../components/MemoInput";
import StatusSelectInput from "../components/StatusSelectInput";
const FormToolbar = () => {
    const { getValues } = useFormContext();
    return (
        <Toolbar sx={{ justifyContent: 'space-between' }}>
            <SaveButton />
            <DeleteButton mutationMode="optimistic" />
        </Toolbar>
    )
}
const ContractEdit = () => {
    const translate = useTranslate();
    return (
        <Edit
            redirect="list"
            mutationMode={EDIT_MODE}
            actions={<CustomerTopToolBar />}
            aside={<EditBaseAside />}
        >
            <SimpleForm
                shouldUnregister
                warnWhenUnsavedChanges
                toolbar={<FormToolbar />}
                mode="onTouched"
                defaultValues={{}}
            // validate={(values) => { }}
            >
                <Grid container width={{ xs: '100%', xl: '80%' }} rowSpacing={3} columnSpacing={3}>
                    <Grid item xs={12} md={8}>
                        <Typography variant="h6" gutterBottom>
                            {translate('common.edit.title.main')}
                        </Typography>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.contract.code"
                                source="code"
                                parse={v => v}
                                autoFocus
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.contract.name"
                                source="name"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.contract.projectName"
                                source="projectName"
                                parse={v => v}
                            />
                        </Stack>
                    </Grid>
                    <Grid item xs={12} md={4}>
                        <Typography variant="h6" gutterBottom>
                            {translate('common.edit.title.common')}
                        </Typography>
                        <StatusSelectInput />
                        <Box mt="2em" />
                        <MemoInput />
                    </Grid>
                </Grid>
            </SimpleForm>
        </Edit >
    )
}
export default ContractEdit;
rsf-admin/src/page/contract/ContractList.jsx
New file
@@ -0,0 +1,156 @@
import React, { useState, useRef, useEffect, useMemo, useCallback } from "react";
import { useNavigate } from 'react-router-dom';
import {
    List,
    DatagridConfigurable,
    SearchInput,
    TopToolbar,
    SelectColumnsButton,
    EditButton,
    FilterButton,
    CreateButton,
    ExportButton,
    BulkDeleteButton,
    WrapperField,
    useRecordContext,
    useTranslate,
    useNotify,
    useListContext,
    FunctionField,
    TextField,
    NumberField,
    DateField,
    BooleanField,
    ReferenceField,
    TextInput,
    DateTimeInput,
    DateInput,
    SelectInput,
    NumberInput,
    ReferenceInput,
    ReferenceArrayInput,
    AutocompleteInput,
    DeleteButton,
} from 'react-admin';
import { Box, Typography, Card, Stack } from '@mui/material';
import { styled } from '@mui/material/styles';
import ContractCreate from "./ContractCreate";
import ContractPanel from "./ContractPanel";
import EmptyData from "../components/EmptyData";
import MyCreateButton from "../components/MyCreateButton";
import MyExportButton from '../components/MyExportButton';
import PageDrawer from "../components/PageDrawer";
import MyField from "../components/MyField";
import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting';
import * as Common from '@/utils/common';
const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({
    '& .css-1vooibu-MuiSvgIcon-root': {
        height: '.9em'
    },
    '& .RaDatagrid-row': {
        cursor: 'auto'
    },
    '& .column-name': {
    },
    '& .opt': {
        width: 200
    },
}));
const filters = [
    <SearchInput source="condition" alwaysOn />,
    <DateInput label='common.time.after' source="timeStart" alwaysOn />,
    <DateInput label='common.time.before' source="timeEnd" alwaysOn />,
    <TextInput source="code" label="table.field.contract.code" />,
    <TextInput source="name" label="table.field.contract.name" />,
    <TextInput source="projectName" label="table.field.contract.projectName" />,
    <TextInput label="common.field.memo" source="memo" />,
    <SelectInput
        label="common.field.status"
        source="status"
        choices={[
            { id: '1', name: 'common.enums.statusTrue' },
            { id: '0', name: 'common.enums.statusFalse' },
        ]}
        resettable
    />,
]
const ContractList = () => {
    const translate = useTranslate();
    const [createDialog, setCreateDialog] = useState(false);
    const [drawerVal, setDrawerVal] = useState(false);
    return (
        <Box display="flex">
            <List
                sx={{
                    flexGrow: 1,
                    transition: (theme) =>
                        theme.transitions.create(['all'], {
                            duration: theme.transitions.duration.enteringScreen,
                        }),
                    marginRight: !!drawerVal ? `${PAGE_DRAWER_WIDTH}px` : 0,
                }}
                title={"menu.contract"}
                empty={<EmptyData onClick={() => { setCreateDialog(true) }} />}
                filters={filters}
                sort={{ field: "create_time", order: "desc" }}
                actions={(
                    <TopToolbar>
                        <FilterButton />
                        <MyCreateButton onClick={() => { setCreateDialog(true) }} />
                        <SelectColumnsButton preferenceKey='contract' />
                        <MyExportButton />
                    </TopToolbar>
                )}
                perPage={DEFAULT_PAGE_SIZE}
            >
                <StyledDatagrid
                    preferenceKey='contract'
                    bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />}
                    rowClick={(id, resource, record) => false}
                    expand={() => <ContractPanel />}
                    expandSingle={true}
                    omit={['id', 'createTime', 'createBy', 'memo']}
                >
                    <NumberField source="id" />
                    <TextField source="code" label="table.field.contract.code" />
                    <TextField source="name" label="table.field.contract.name" />
                    <TextField source="projectName" label="table.field.contract.projectName" />
                    <ReferenceField source="updateBy" label="common.field.updateBy" reference="user" link={false} sortable={false}>
                        <TextField source="nickname" />
                    </ReferenceField>
                    <DateField source="updateTime" label="common.field.updateTime" showTime />
                    <ReferenceField source="createBy" label="common.field.createBy" reference="user" link={false} sortable={false}>
                        <TextField source="nickname" />
                    </ReferenceField>
                    <DateField source="createTime" label="common.field.createTime" showTime />
                    <BooleanField source="statusBool" label="common.field.status" sortable={false} />
                    <TextField source="memo" label="common.field.memo" sortable={false} />
                    <WrapperField cellClassName="opt" label="common.field.opt">
                        <EditButton sx={{ padding: '1px', fontSize: '.75rem' }} />
                        <DeleteButton sx={{ padding: '1px', fontSize: '.75rem' }} mutationMode={OPERATE_MODE} />
                    </WrapperField>
                </StyledDatagrid>
            </List>
            <ContractCreate
                open={createDialog}
                setOpen={setCreateDialog}
            />
            <PageDrawer
                title='Contract Detail'
                drawerVal={drawerVal}
                setDrawerVal={setDrawerVal}
            >
            </PageDrawer>
        </Box>
    )
}
export default ContractList;
rsf-admin/src/page/contract/ContractPanel.jsx
New file
@@ -0,0 +1,69 @@
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 ContractPanel = () => {
    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.contract.name'))}: {record.name}
                            </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.contract.code"
                                property={record.code}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.contract.name"
                                property={record.name}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.contract.projectName"
                                property={record.projectName}
                            />
                        </Grid>
                    </Grid>
                </CardContent>
            </Card >
        </>
    );
};
export default ContractPanel;
rsf-admin/src/page/contract/index.jsx
New file
@@ -0,0 +1,18 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import {
    ListGuesser,
    EditGuesser,
    ShowGuesser,
} from "react-admin";
import ContractList from "./ContractList";
import ContractEdit from "./ContractEdit";
export default {
    list: ContractList,
    edit: ContractEdit,
    show: ShowGuesser,
    recordRepresentation: (record) => {
        return `${record.name}`
    }
};
rsf-admin/src/page/loc/LocCreate.jsx
New file
@@ -0,0 +1,229 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import {
    CreateBase,
    useTranslate,
    TextInput,
    NumberInput,
    BooleanInput,
    DateInput,
    SaveButton,
    SelectInput,
    ReferenceInput,
    ReferenceArrayInput,
    AutocompleteInput,
    Toolbar,
    required,
    useDataProvider,
    useNotify,
    Form,
    useCreateController,
} from 'react-admin';
import {
    Dialog,
    DialogActions,
    DialogContent,
    DialogTitle,
    Stack,
    Grid,
    Box,
} from '@mui/material';
import DialogCloseButton from "../components/DialogCloseButton";
import StatusSelectInput from "../components/StatusSelectInput";
import MemoInput from "../components/MemoInput";
const LocCreate = (props) => {
    const { open, setOpen } = props;
    const translate = useTranslate();
    const notify = useNotify();
    const handleClose = (event, reason) => {
        if (reason !== "backdropClick") {
            setOpen(false);
        }
    };
    const handleSuccess = async (data) => {
        setOpen(false);
        notify('common.response.success');
    };
    const handleError = async (error) => {
        notify(error.message || 'common.response.fail', { type: 'error', messageArgs: { _: error.message } });
    };
    return (
        <>
            <CreateBase
                record={{}}
                transform={(data) => {
                    return data;
                }}
                mutationOptions={{ onSuccess: handleSuccess, onError: handleError }}
            >
                <Dialog
                    open={open}
                    onClose={handleClose}
                    aria-labelledby="form-dialog-title"
                    fullWidth
                    disableRestoreFocus
                    maxWidth="md"   // 'xs' | 'sm' | 'md' | 'lg' | 'xl'
                >
                    <Form>
                        <DialogTitle id="form-dialog-title" sx={{
                            position: 'sticky',
                            top: 0,
                            backgroundColor: 'background.paper',
                            zIndex: 1000
                        }}
                        >
                            {translate('create.title')}
                            <Box sx={{ position: 'absolute', top: 8, right: 8, zIndex: 1001 }}>
                                <DialogCloseButton onClose={handleClose} />
                            </Box>
                        </DialogTitle>
                        <DialogContent sx={{ mt: 2 }}>
                            <Grid container rowSpacing={2} columnSpacing={2}>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.loc.areaId"
                                        source="areaId"
                                        autoFocus
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.loc.code"
                                        source="code"
                                        parse={v => v}
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.loc.type"
                                        source="type"
                                        parse={v => v}
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.loc.name"
                                        source="name"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.loc.flagLogic"
                                        source="flagLogic"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.loc.fucAtrrs"
                                        source="fucAtrrs"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.loc.barcode"
                                        source="barcode"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.loc.unit"
                                        source="unit"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.loc.size"
                                        source="size"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.loc.row"
                                        source="row"
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.loc.col"
                                        source="col"
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.loc.lev"
                                        source="lev"
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.loc.channel"
                                        source="channel"
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.loc.maxParts"
                                        source="maxParts"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.loc.maxPack"
                                        source="maxPack"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.loc.flagLabelMange"
                                        source="flagLabelMange"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.loc.locAttrs"
                                        source="locAttrs"
                                        parse={v => v}
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <StatusSelectInput />
                                </Grid>
                                <Grid item xs={12} display="flex" gap={1}>
                                    <Stack direction="column" spacing={1} width={'100%'}>
                                        <MemoInput />
                                    </Stack>
                                </Grid>
                            </Grid>
                        </DialogContent>
                        <DialogActions sx={{ position: 'sticky', bottom: 0, backgroundColor: 'background.paper', zIndex: 1000 }}>
                            <Toolbar sx={{ width: '100%', justifyContent: 'space-between' }}  >
                                <SaveButton />
                            </Toolbar>
                        </DialogActions>
                    </Form>
                </Dialog>
            </CreateBase>
        </>
    )
}
export default LocCreate;
rsf-admin/src/page/loc/LocEdit.jsx
New file
@@ -0,0 +1,201 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import {
    Edit,
    SimpleForm,
    FormDataConsumer,
    useTranslate,
    TextInput,
    NumberInput,
    BooleanInput,
    DateInput,
    SelectInput,
    ReferenceInput,
    ReferenceArrayInput,
    AutocompleteInput,
    SaveButton,
    Toolbar,
    Labeled,
    NumberField,
    required,
    useRecordContext,
    DeleteButton,
} from 'react-admin';
import { useWatch, useFormContext } from "react-hook-form";
import { Stack, Grid, Box, Typography } from '@mui/material';
import * as Common from '@/utils/common';
import { EDIT_MODE, REFERENCE_INPUT_PAGESIZE } from '@/config/setting';
import EditBaseAside from "../components/EditBaseAside";
import CustomerTopToolBar from "../components/EditTopToolBar";
import MemoInput from "../components/MemoInput";
import StatusSelectInput from "../components/StatusSelectInput";
const FormToolbar = () => {
    const { getValues } = useFormContext();
    return (
        <Toolbar sx={{ justifyContent: 'space-between' }}>
            <SaveButton />
            <DeleteButton mutationMode="optimistic" />
        </Toolbar>
    )
}
const LocEdit = () => {
    const translate = useTranslate();
    return (
        <Edit
            redirect="list"
            mutationMode={EDIT_MODE}
            actions={<CustomerTopToolBar />}
            aside={<EditBaseAside />}
        >
            <SimpleForm
                shouldUnregister
                warnWhenUnsavedChanges
                toolbar={<FormToolbar />}
                mode="onTouched"
                defaultValues={{}}
            // validate={(values) => { }}
            >
                <Grid container width={{ xs: '100%', xl: '80%' }} rowSpacing={3} columnSpacing={3}>
                    <Grid item xs={12} md={8}>
                        <Typography variant="h6" gutterBottom>
                            {translate('common.edit.title.main')}
                        </Typography>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.loc.areaId"
                                source="areaId"
                                autoFocus
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.loc.code"
                                source="code"
                                parse={v => v}
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.loc.type"
                                source="type"
                                parse={v => v}
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.loc.name"
                                source="name"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.loc.flagLogic"
                                source="flagLogic"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.loc.fucAtrrs"
                                source="fucAtrrs"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.loc.barcode"
                                source="barcode"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.loc.unit"
                                source="unit"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.loc.size"
                                source="size"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.loc.row"
                                source="row"
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.loc.col"
                                source="col"
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.loc.lev"
                                source="lev"
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.loc.channel"
                                source="channel"
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.loc.maxParts"
                                source="maxParts"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.loc.maxPack"
                                source="maxPack"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.loc.flagLabelMange"
                                source="flagLabelMange"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.loc.locAttrs"
                                source="locAttrs"
                                parse={v => v}
                                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 >
    )
}
export default LocEdit;
rsf-admin/src/page/loc/LocList.jsx
New file
@@ -0,0 +1,184 @@
import React, { useState, useRef, useEffect, useMemo, useCallback } from "react";
import { useNavigate } from 'react-router-dom';
import {
    List,
    DatagridConfigurable,
    SearchInput,
    TopToolbar,
    SelectColumnsButton,
    EditButton,
    FilterButton,
    CreateButton,
    ExportButton,
    BulkDeleteButton,
    WrapperField,
    useRecordContext,
    useTranslate,
    useNotify,
    useListContext,
    FunctionField,
    TextField,
    NumberField,
    DateField,
    BooleanField,
    ReferenceField,
    TextInput,
    DateTimeInput,
    DateInput,
    SelectInput,
    NumberInput,
    ReferenceInput,
    ReferenceArrayInput,
    AutocompleteInput,
    DeleteButton,
} from 'react-admin';
import { Box, Typography, Card, Stack } from '@mui/material';
import { styled } from '@mui/material/styles';
import LocCreate from "./LocCreate";
import LocPanel from "./LocPanel";
import EmptyData from "../components/EmptyData";
import MyCreateButton from "../components/MyCreateButton";
import MyExportButton from '../components/MyExportButton';
import PageDrawer from "../components/PageDrawer";
import MyField from "../components/MyField";
import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting';
import * as Common from '@/utils/common';
const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({
    '& .css-1vooibu-MuiSvgIcon-root': {
        height: '.9em'
    },
    '& .RaDatagrid-row': {
        cursor: 'auto'
    },
    '& .column-name': {
    },
    '& .opt': {
        width: 200
    },
}));
const filters = [
    <SearchInput source="condition" alwaysOn />,
    <DateInput label='common.time.after' source="timeStart" alwaysOn />,
    <DateInput label='common.time.before' source="timeEnd" alwaysOn />,
    <NumberInput source="areaId" label="table.field.loc.areaId" />,
    <TextInput source="code" label="table.field.loc.code" />,
    <TextInput source="type" label="table.field.loc.type" />,
    <TextInput source="name" label="table.field.loc.name" />,
    <NumberInput source="flagLogic" label="table.field.loc.flagLogic" />,
    <TextInput source="fucAtrrs" label="table.field.loc.fucAtrrs" />,
    <TextInput source="barcode" label="table.field.loc.barcode" />,
    <TextInput source="unit" label="table.field.loc.unit" />,
    <TextInput source="size" label="table.field.loc.size" />,
    <NumberInput source="row" label="table.field.loc.row" />,
    <NumberInput source="col" label="table.field.loc.col" />,
    <NumberInput source="lev" label="table.field.loc.lev" />,
    <NumberInput source="channel" label="table.field.loc.channel" />,
    <NumberInput source="maxParts" label="table.field.loc.maxParts" />,
    <NumberInput source="maxPack" label="table.field.loc.maxPack" />,
    <NumberInput source="flagLabelMange" label="table.field.loc.flagLabelMange" />,
    <TextInput source="locAttrs" label="table.field.loc.locAttrs" />,
    <TextInput label="common.field.memo" source="memo" />,
    <SelectInput
        label="common.field.status"
        source="status"
        choices={[
            { id: '1', name: 'common.enums.statusTrue' },
            { id: '0', name: 'common.enums.statusFalse' },
        ]}
        resettable
    />,
]
const LocList = () => {
    const translate = useTranslate();
    const [createDialog, setCreateDialog] = useState(false);
    const [drawerVal, setDrawerVal] = useState(false);
    return (
        <Box display="flex">
            <List
                sx={{
                    flexGrow: 1,
                    transition: (theme) =>
                        theme.transitions.create(['all'], {
                            duration: theme.transitions.duration.enteringScreen,
                        }),
                    marginRight: !!drawerVal ? `${PAGE_DRAWER_WIDTH}px` : 0,
                }}
                title={"menu.loc"}
                empty={<EmptyData onClick={() => { setCreateDialog(true) }} />}
                filters={filters}
                sort={{ field: "create_time", order: "desc" }}
                actions={(
                    <TopToolbar>
                        <FilterButton />
                        <MyCreateButton onClick={() => { setCreateDialog(true) }} />
                        <SelectColumnsButton preferenceKey='loc' />
                        <MyExportButton />
                    </TopToolbar>
                )}
                perPage={DEFAULT_PAGE_SIZE}
            >
                <StyledDatagrid
                    preferenceKey='loc'
                    bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />}
                    rowClick={(id, resource, record) => false}
                    expand={() => <LocPanel />}
                    expandSingle={true}
                    omit={['id', 'createTime', 'createBy', 'memo']}
                >
                    <NumberField source="id" />
                    <NumberField source="areaId" label="table.field.loc.areaId" />
                    <TextField source="code" label="table.field.loc.code" />
                    <TextField source="type" label="table.field.loc.type" />
                    <TextField source="name" label="table.field.loc.name" />
                    <NumberField source="flagLogic" label="table.field.loc.flagLogic" />
                    <TextField source="fucAtrrs" label="table.field.loc.fucAtrrs" />
                    <TextField source="barcode" label="table.field.loc.barcode" />
                    <TextField source="unit" label="table.field.loc.unit" />
                    <TextField source="size" label="table.field.loc.size" />
                    <NumberField source="row" label="table.field.loc.row" />
                    <NumberField source="col" label="table.field.loc.col" />
                    <NumberField source="lev" label="table.field.loc.lev" />
                    <NumberField source="channel" label="table.field.loc.channel" />
                    <NumberField source="maxParts" label="table.field.loc.maxParts" />
                    <NumberField source="maxPack" label="table.field.loc.maxPack" />
                    <NumberField source="flagLabelMange" label="table.field.loc.flagLabelMange" />
                    <TextField source="locAttrs" label="table.field.loc.locAttrs" />
                    <ReferenceField source="updateBy" label="common.field.updateBy" reference="user" link={false} sortable={false}>
                        <TextField source="nickname" />
                    </ReferenceField>
                    <DateField source="updateTime" label="common.field.updateTime" showTime />
                    <ReferenceField source="createBy" label="common.field.createBy" reference="user" link={false} sortable={false}>
                        <TextField source="nickname" />
                    </ReferenceField>
                    <DateField source="createTime" label="common.field.createTime" showTime />
                    <BooleanField source="statusBool" label="common.field.status" sortable={false} />
                    <TextField source="memo" label="common.field.memo" sortable={false} />
                    <WrapperField cellClassName="opt" label="common.field.opt">
                        <EditButton sx={{ padding: '1px', fontSize: '.75rem' }} />
                        <DeleteButton sx={{ padding: '1px', fontSize: '.75rem' }} mutationMode={OPERATE_MODE} />
                    </WrapperField>
                </StyledDatagrid>
            </List>
            <LocCreate
                open={createDialog}
                setOpen={setCreateDialog}
            />
            <PageDrawer
                title='Loc Detail'
                drawerVal={drawerVal}
                setDrawerVal={setDrawerVal}
            >
            </PageDrawer>
        </Box>
    )
}
export default LocList;
rsf-admin/src/page/loc/LocPanel.jsx
New file
@@ -0,0 +1,153 @@
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 LocPanel = () => {
    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.loc.name'))}: {record.name}
                            </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.loc.areaId"
                                property={record.areaId}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.loc.code"
                                property={record.code}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.loc.type"
                                property={record.type}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.loc.name"
                                property={record.name}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.loc.flagLogic"
                                property={record.flagLogic}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.loc.fucAtrrs"
                                property={record.fucAtrrs}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.loc.barcode"
                                property={record.barcode}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.loc.unit"
                                property={record.unit}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.loc.size"
                                property={record.size}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.loc.row"
                                property={record.row}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.loc.col"
                                property={record.col}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.loc.lev"
                                property={record.lev}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.loc.channel"
                                property={record.channel}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.loc.maxParts"
                                property={record.maxParts}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.loc.maxPack"
                                property={record.maxPack}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.loc.flagLabelMange"
                                property={record.flagLabelMange}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.loc.locAttrs"
                                property={record.locAttrs}
                            />
                        </Grid>
                    </Grid>
                </CardContent>
            </Card >
        </>
    );
};
export default LocPanel;
rsf-admin/src/page/loc/index.jsx
New file
@@ -0,0 +1,18 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import {
    ListGuesser,
    EditGuesser,
    ShowGuesser,
} from "react-admin";
import LocList from "./LocList";
import LocEdit from "./LocEdit";
export default {
    list: LocList,
    edit: LocEdit,
    show: ShowGuesser,
    recordRepresentation: (record) => {
        return `${record.name}`
    }
};
rsf-admin/src/page/matnr/MatnrListAside.jsx
@@ -3,14 +3,7 @@
import {
    SavedQueriesList,
    FilterLiveSearch,
    FilterList,
    FilterListItem,
    useStore,
    FilterFormInput,
    FilterLiveForm,
    TextInput,
    useGetList,
    useListContext
    useListContext,
} from 'react-admin';
import BookmarkIcon from '@mui/icons-material/BookmarkBorder';
import { Box, Typography, Card, CardContent, useTheme, TextField } from '@mui/material';
rsf-admin/src/page/qlyInspect/QlyInspectCreate.jsx
New file
@@ -0,0 +1,126 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import {
    CreateBase,
    useTranslate,
    TextInput,
    NumberInput,
    BooleanInput,
    DateInput,
    SaveButton,
    SelectInput,
    ReferenceInput,
    ReferenceArrayInput,
    AutocompleteInput,
    Toolbar,
    required,
    useDataProvider,
    useNotify,
    Form,
    useCreateController,
} from 'react-admin';
import {
    Dialog,
    DialogActions,
    DialogContent,
    DialogTitle,
    Stack,
    Grid,
    Box,
} from '@mui/material';
import DialogCloseButton from "../components/DialogCloseButton";
import StatusSelectInput from "../components/StatusSelectInput";
import MemoInput from "../components/MemoInput";
const QlyInspectCreate = (props) => {
    const { open, setOpen } = props;
    const translate = useTranslate();
    const notify = useNotify();
    const handleClose = (event, reason) => {
        if (reason !== "backdropClick") {
            setOpen(false);
        }
    };
    const handleSuccess = async (data) => {
        setOpen(false);
        notify('common.response.success');
    };
    const handleError = async (error) => {
        notify(error.message || 'common.response.fail', { type: 'error', messageArgs: { _: error.message } });
    };
    return (
        <>
            <CreateBase
                record={{}}
                transform={(data) => {
                    return data;
                }}
                mutationOptions={{ onSuccess: handleSuccess, onError: handleError }}
            >
                <Dialog
                    open={open}
                    onClose={handleClose}
                    aria-labelledby="form-dialog-title"
                    fullWidth
                    disableRestoreFocus
                    maxWidth="md"   // 'xs' | 'sm' | 'md' | 'lg' | 'xl'
                >
                    <Form>
                        <DialogTitle id="form-dialog-title" sx={{
                            position: 'sticky',
                            top: 0,
                            backgroundColor: 'background.paper',
                            zIndex: 1000
                        }}
                        >
                            {translate('create.title')}
                            <Box sx={{ position: 'absolute', top: 8, right: 8, zIndex: 1001 }}>
                                <DialogCloseButton onClose={handleClose} />
                            </Box>
                        </DialogTitle>
                        <DialogContent sx={{ mt: 2 }}>
                            <Grid container rowSpacing={2} columnSpacing={2}>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.qlyInspect.code"
                                        source="code"
                                        parse={v => v}
                                        autoFocus
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.qlyInspect.name"
                                        source="name"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <StatusSelectInput />
                                </Grid>
                                <Grid item xs={12} display="flex" gap={1}>
                                    <Stack direction="column" spacing={1} width={'100%'}>
                                        <MemoInput />
                                    </Stack>
                                </Grid>
                            </Grid>
                        </DialogContent>
                        <DialogActions sx={{ position: 'sticky', bottom: 0, backgroundColor: 'background.paper', zIndex: 1000 }}>
                            <Toolbar sx={{ width: '100%', justifyContent: 'space-between' }}  >
                                <SaveButton />
                            </Toolbar>
                        </DialogActions>
                    </Form>
                </Dialog>
            </CreateBase>
        </>
    )
}
export default QlyInspectCreate;
rsf-admin/src/page/qlyInspect/QlyInspectEdit.jsx
New file
@@ -0,0 +1,98 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import {
    Edit,
    SimpleForm,
    FormDataConsumer,
    useTranslate,
    TextInput,
    NumberInput,
    BooleanInput,
    DateInput,
    SelectInput,
    ReferenceInput,
    ReferenceArrayInput,
    AutocompleteInput,
    SaveButton,
    Toolbar,
    Labeled,
    NumberField,
    required,
    useRecordContext,
    DeleteButton,
} from 'react-admin';
import { useWatch, useFormContext } from "react-hook-form";
import { Stack, Grid, Box, Typography } from '@mui/material';
import * as Common from '@/utils/common';
import { EDIT_MODE, REFERENCE_INPUT_PAGESIZE } from '@/config/setting';
import EditBaseAside from "../components/EditBaseAside";
import CustomerTopToolBar from "../components/EditTopToolBar";
import MemoInput from "../components/MemoInput";
import StatusSelectInput from "../components/StatusSelectInput";
const FormToolbar = () => {
    const { getValues } = useFormContext();
    return (
        <Toolbar sx={{ justifyContent: 'space-between' }}>
            <SaveButton />
            <DeleteButton mutationMode="optimistic" />
        </Toolbar>
    )
}
const QlyInspectEdit = () => {
    const translate = useTranslate();
    return (
        <Edit
            redirect="list"
            mutationMode={EDIT_MODE}
            actions={<CustomerTopToolBar />}
            aside={<EditBaseAside />}
        >
            <SimpleForm
                shouldUnregister
                warnWhenUnsavedChanges
                toolbar={<FormToolbar />}
                mode="onTouched"
                defaultValues={{}}
            // validate={(values) => { }}
            >
                <Grid container width={{ xs: '100%', xl: '80%' }} rowSpacing={3} columnSpacing={3}>
                    <Grid item xs={12} md={8}>
                        <Typography variant="h6" gutterBottom>
                            {translate('common.edit.title.main')}
                        </Typography>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.qlyInspect.code"
                                source="code"
                                parse={v => v}
                                autoFocus
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.qlyInspect.name"
                                source="name"
                                parse={v => v}
                            />
                        </Stack>
                    </Grid>
                    <Grid item xs={12} md={4}>
                        <Typography variant="h6" gutterBottom>
                            {translate('common.edit.title.common')}
                        </Typography>
                        <StatusSelectInput />
                        <Box mt="2em" />
                        <MemoInput />
                    </Grid>
                </Grid>
            </SimpleForm>
        </Edit >
    )
}
export default QlyInspectEdit;
rsf-admin/src/page/qlyInspect/QlyInspectList.jsx
New file
@@ -0,0 +1,154 @@
import React, { useState, useRef, useEffect, useMemo, useCallback } from "react";
import { useNavigate } from 'react-router-dom';
import {
    List,
    DatagridConfigurable,
    SearchInput,
    TopToolbar,
    SelectColumnsButton,
    EditButton,
    FilterButton,
    CreateButton,
    ExportButton,
    BulkDeleteButton,
    WrapperField,
    useRecordContext,
    useTranslate,
    useNotify,
    useListContext,
    FunctionField,
    TextField,
    NumberField,
    DateField,
    BooleanField,
    ReferenceField,
    TextInput,
    DateTimeInput,
    DateInput,
    SelectInput,
    NumberInput,
    ReferenceInput,
    ReferenceArrayInput,
    AutocompleteInput,
    DeleteButton,
} from 'react-admin';
import { Box, Typography, Card, Stack } from '@mui/material';
import { styled } from '@mui/material/styles';
import QlyInspectCreate from "./QlyInspectCreate";
import QlyInspectPanel from "./QlyInspectPanel";
import EmptyData from "../components/EmptyData";
import MyCreateButton from "../components/MyCreateButton";
import MyExportButton from '../components/MyExportButton';
import PageDrawer from "../components/PageDrawer";
import MyField from "../components/MyField";
import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting';
import * as Common from '@/utils/common';
const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({
    '& .css-1vooibu-MuiSvgIcon-root': {
        height: '.9em'
    },
    '& .RaDatagrid-row': {
        cursor: 'auto'
    },
    '& .column-name': {
    },
    '& .opt': {
        width: 200
    },
}));
const filters = [
    <SearchInput source="condition" alwaysOn />,
    <DateInput label='common.time.after' source="timeStart" alwaysOn />,
    <DateInput label='common.time.before' source="timeEnd" alwaysOn />,
    <TextInput source="code" label="table.field.qlyInspect.code" />,
    <TextInput source="name" label="table.field.qlyInspect.name" />,
    <TextInput label="common.field.memo" source="memo" />,
    <SelectInput
        label="common.field.status"
        source="status"
        choices={[
            { id: '1', name: 'common.enums.statusTrue' },
            { id: '0', name: 'common.enums.statusFalse' },
        ]}
        resettable
    />,
]
const QlyInspectList = () => {
    const translate = useTranslate();
    const [createDialog, setCreateDialog] = useState(false);
    const [drawerVal, setDrawerVal] = useState(false);
    return (
        <Box display="flex">
            <List
                sx={{
                    flexGrow: 1,
                    transition: (theme) =>
                        theme.transitions.create(['all'], {
                            duration: theme.transitions.duration.enteringScreen,
                        }),
                    marginRight: !!drawerVal ? `${PAGE_DRAWER_WIDTH}px` : 0,
                }}
                title={"menu.qlyInspect"}
                empty={<EmptyData onClick={() => { setCreateDialog(true) }} />}
                filters={filters}
                sort={{ field: "create_time", order: "desc" }}
                actions={(
                    <TopToolbar>
                        <FilterButton />
                        <MyCreateButton onClick={() => { setCreateDialog(true) }} />
                        <SelectColumnsButton preferenceKey='qlyInspect' />
                        <MyExportButton />
                    </TopToolbar>
                )}
                perPage={DEFAULT_PAGE_SIZE}
            >
                <StyledDatagrid
                    preferenceKey='qlyInspect'
                    bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />}
                    rowClick={(id, resource, record) => false}
                    expand={() => <QlyInspectPanel />}
                    expandSingle={true}
                    omit={['id', 'createTime', 'createBy', 'memo']}
                >
                    <NumberField source="id" />
                    <TextField source="code" label="table.field.qlyInspect.code" />
                    <TextField source="name" label="table.field.qlyInspect.name" />
                    <ReferenceField source="updateBy" label="common.field.updateBy" reference="user" link={false} sortable={false}>
                        <TextField source="nickname" />
                    </ReferenceField>
                    <DateField source="updateTime" label="common.field.updateTime" showTime />
                    <ReferenceField source="createBy" label="common.field.createBy" reference="user" link={false} sortable={false}>
                        <TextField source="nickname" />
                    </ReferenceField>
                    <DateField source="createTime" label="common.field.createTime" showTime />
                    <BooleanField source="statusBool" label="common.field.status" sortable={false} />
                    <TextField source="memo" label="common.field.memo" sortable={false} />
                    <WrapperField cellClassName="opt" label="common.field.opt">
                        <EditButton sx={{ padding: '1px', fontSize: '.75rem' }} />
                        <DeleteButton sx={{ padding: '1px', fontSize: '.75rem' }} mutationMode={OPERATE_MODE} />
                    </WrapperField>
                </StyledDatagrid>
            </List>
            <QlyInspectCreate
                open={createDialog}
                setOpen={setCreateDialog}
            />
            <PageDrawer
                title='QlyInspect Detail'
                drawerVal={drawerVal}
                setDrawerVal={setDrawerVal}
            >
            </PageDrawer>
        </Box>
    )
}
export default QlyInspectList;
rsf-admin/src/page/qlyInspect/QlyInspectPanel.jsx
New file
@@ -0,0 +1,63 @@
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 QlyInspectPanel = () => {
    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.qlyInspect.name'))}: {record.name}
                            </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.qlyInspect.code"
                                property={record.code}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.qlyInspect.name"
                                property={record.name}
                            />
                        </Grid>
                    </Grid>
                </CardContent>
            </Card >
        </>
    );
};
export default QlyInspectPanel;
rsf-admin/src/page/qlyInspect/index.jsx
New file
@@ -0,0 +1,18 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import {
    ListGuesser,
    EditGuesser,
    ShowGuesser,
} from "react-admin";
import QlyInspectList from "./QlyInspectList";
import QlyInspectEdit from "./QlyInspectEdit";
export default {
    list: QlyInspectList,
    edit: QlyInspectEdit,
    show: ShowGuesser,
    recordRepresentation: (record) => {
        return `${record.name}`
    }
};
rsf-admin/src/page/stock/StockCreate.jsx
New file
@@ -0,0 +1,174 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import {
    CreateBase,
    useTranslate,
    TextInput,
    NumberInput,
    BooleanInput,
    DateInput,
    SaveButton,
    SelectInput,
    ReferenceInput,
    ReferenceArrayInput,
    AutocompleteInput,
    Toolbar,
    required,
    useDataProvider,
    useNotify,
    Form,
    useCreateController,
} from 'react-admin';
import {
    Dialog,
    DialogActions,
    DialogContent,
    DialogTitle,
    Stack,
    Grid,
    Box,
} from '@mui/material';
import DialogCloseButton from "../components/DialogCloseButton";
import StatusSelectInput from "../components/StatusSelectInput";
import MemoInput from "../components/MemoInput";
const StockCreate = (props) => {
    const { open, setOpen } = props;
    const translate = useTranslate();
    const notify = useNotify();
    const handleClose = (event, reason) => {
        if (reason !== "backdropClick") {
            setOpen(false);
        }
    };
    const handleSuccess = async (data) => {
        setOpen(false);
        notify('common.response.success');
    };
    const handleError = async (error) => {
        notify(error.message || 'common.response.fail', { type: 'error', messageArgs: { _: error.message } });
    };
    return (
        <>
            <CreateBase
                record={{}}
                transform={(data) => {
                    return data;
                }}
                mutationOptions={{ onSuccess: handleSuccess, onError: handleError }}
            >
                <Dialog
                    open={open}
                    onClose={handleClose}
                    aria-labelledby="form-dialog-title"
                    fullWidth
                    disableRestoreFocus
                    maxWidth="md"   // 'xs' | 'sm' | 'md' | 'lg' | 'xl'
                >
                    <Form>
                        <DialogTitle id="form-dialog-title" sx={{
                            position: 'sticky',
                            top: 0,
                            backgroundColor: 'background.paper',
                            zIndex: 1000
                        }}
                        >
                            {translate('create.title')}
                            <Box sx={{ position: 'absolute', top: 8, right: 8, zIndex: 1001 }}>
                                <DialogCloseButton onClose={handleClose} />
                            </Box>
                        </DialogTitle>
                        <DialogContent sx={{ mt: 2 }}>
                            <Grid container rowSpacing={2} columnSpacing={2}>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.stock.asnOrder"
                                        source="asnOrder"
                                        parse={v => v}
                                        autoFocus
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.stock.erpToken"
                                        source="erpToken"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.stock.erpOrder"
                                        source="erpOrder"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.stock.erpStkAdr"
                                        source="erpStkAdr"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.stock.contractId"
                                        source="contractId"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.stock.lockReason"
                                        source="lockReason"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.stock.lockStatus"
                                        source="lockStatus"
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.stock.locker"
                                        source="locker"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <DateInput
                                        label="table.field.stock.lockedTime"
                                        source="lockedTime"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <StatusSelectInput />
                                </Grid>
                                <Grid item xs={12} display="flex" gap={1}>
                                    <Stack direction="column" spacing={1} width={'100%'}>
                                        <MemoInput />
                                    </Stack>
                                </Grid>
                            </Grid>
                        </DialogContent>
                        <DialogActions sx={{ position: 'sticky', bottom: 0, backgroundColor: 'background.paper', zIndex: 1000 }}>
                            <Toolbar sx={{ width: '100%', justifyContent: 'space-between' }}  >
                                <SaveButton />
                            </Toolbar>
                        </DialogActions>
                    </Form>
                </Dialog>
            </CreateBase>
        </>
    )
}
export default StockCreate;
rsf-admin/src/page/stock/StockEdit.jsx
New file
@@ -0,0 +1,146 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import {
    Edit,
    SimpleForm,
    FormDataConsumer,
    useTranslate,
    TextInput,
    NumberInput,
    BooleanInput,
    DateInput,
    SelectInput,
    ReferenceInput,
    ReferenceArrayInput,
    AutocompleteInput,
    SaveButton,
    Toolbar,
    Labeled,
    NumberField,
    required,
    useRecordContext,
    DeleteButton,
} from 'react-admin';
import { useWatch, useFormContext } from "react-hook-form";
import { Stack, Grid, Box, Typography } from '@mui/material';
import * as Common from '@/utils/common';
import { EDIT_MODE, REFERENCE_INPUT_PAGESIZE } from '@/config/setting';
import EditBaseAside from "../components/EditBaseAside";
import CustomerTopToolBar from "../components/EditTopToolBar";
import MemoInput from "../components/MemoInput";
import StatusSelectInput from "../components/StatusSelectInput";
const FormToolbar = () => {
    const { getValues } = useFormContext();
    return (
        <Toolbar sx={{ justifyContent: 'space-between' }}>
            <SaveButton />
            <DeleteButton mutationMode="optimistic" />
        </Toolbar>
    )
}
const StockEdit = () => {
    const translate = useTranslate();
    return (
        <Edit
            redirect="list"
            mutationMode={EDIT_MODE}
            actions={<CustomerTopToolBar />}
            aside={<EditBaseAside />}
        >
            <SimpleForm
                shouldUnregister
                warnWhenUnsavedChanges
                toolbar={<FormToolbar />}
                mode="onTouched"
                defaultValues={{}}
            // validate={(values) => { }}
            >
                <Grid container width={{ xs: '100%', xl: '80%' }} rowSpacing={3} columnSpacing={3}>
                    <Grid item xs={12} md={8}>
                        <Typography variant="h6" gutterBottom>
                            {translate('common.edit.title.main')}
                        </Typography>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.stock.asnOrder"
                                source="asnOrder"
                                parse={v => v}
                                autoFocus
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.stock.erpToken"
                                source="erpToken"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.stock.erpOrder"
                                source="erpOrder"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.stock.erpStkAdr"
                                source="erpStkAdr"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.stock.contractId"
                                source="contractId"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.stock.lockReason"
                                source="lockReason"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.stock.lockStatus"
                                source="lockStatus"
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.stock.locker"
                                source="locker"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <DateInput
                                label="table.field.stock.lockedTime"
                                source="lockedTime"
                            />
                        </Stack>
                    </Grid>
                    <Grid item xs={12} md={4}>
                        <Typography variant="h6" gutterBottom>
                            {translate('common.edit.title.common')}
                        </Typography>
                        <StatusSelectInput />
                        <Box mt="2em" />
                        <MemoInput />
                    </Grid>
                </Grid>
            </SimpleForm>
        </Edit >
    )
}
export default StockEdit;
rsf-admin/src/page/stock/StockList.jsx
New file
@@ -0,0 +1,168 @@
import React, { useState, useRef, useEffect, useMemo, useCallback } from "react";
import { useNavigate } from 'react-router-dom';
import {
    List,
    DatagridConfigurable,
    SearchInput,
    TopToolbar,
    SelectColumnsButton,
    EditButton,
    FilterButton,
    CreateButton,
    ExportButton,
    BulkDeleteButton,
    WrapperField,
    useRecordContext,
    useTranslate,
    useNotify,
    useListContext,
    FunctionField,
    TextField,
    NumberField,
    DateField,
    BooleanField,
    ReferenceField,
    TextInput,
    DateTimeInput,
    DateInput,
    SelectInput,
    NumberInput,
    ReferenceInput,
    ReferenceArrayInput,
    AutocompleteInput,
    DeleteButton,
} from 'react-admin';
import { Box, Typography, Card, Stack } from '@mui/material';
import { styled } from '@mui/material/styles';
import StockCreate from "./StockCreate";
import StockPanel from "./StockPanel";
import EmptyData from "../components/EmptyData";
import MyCreateButton from "../components/MyCreateButton";
import MyExportButton from '../components/MyExportButton';
import PageDrawer from "../components/PageDrawer";
import MyField from "../components/MyField";
import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting';
import * as Common from '@/utils/common';
const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({
    '& .css-1vooibu-MuiSvgIcon-root': {
        height: '.9em'
    },
    '& .RaDatagrid-row': {
        cursor: 'auto'
    },
    '& .column-name': {
    },
    '& .opt': {
        width: 200
    },
}));
const filters = [
    <SearchInput source="condition" alwaysOn />,
    <DateInput label='common.time.after' source="timeStart" alwaysOn />,
    <DateInput label='common.time.before' source="timeEnd" alwaysOn />,
    <TextInput source="asnOrder" label="table.field.stock.asnOrder" />,
    <TextInput source="erpToken" label="table.field.stock.erpToken" />,
    <TextInput source="erpOrder" label="table.field.stock.erpOrder" />,
    <TextInput source="erpStkAdr" label="table.field.stock.erpStkAdr" />,
    <TextInput source="contractId" label="table.field.stock.contractId" />,
    <TextInput source="lockReason" label="table.field.stock.lockReason" />,
    <NumberInput source="lockStatus" label="table.field.stock.lockStatus" />,
    <TextInput source="locker" label="table.field.stock.locker" />,
    <DateInput source="lockedTime" label="table.field.stock.lockedTime" />,
    <TextInput label="common.field.memo" source="memo" />,
    <SelectInput
        label="common.field.status"
        source="status"
        choices={[
            { id: '1', name: 'common.enums.statusTrue' },
            { id: '0', name: 'common.enums.statusFalse' },
        ]}
        resettable
    />,
]
const StockList = () => {
    const translate = useTranslate();
    const [createDialog, setCreateDialog] = useState(false);
    const [drawerVal, setDrawerVal] = useState(false);
    return (
        <Box display="flex">
            <List
                sx={{
                    flexGrow: 1,
                    transition: (theme) =>
                        theme.transitions.create(['all'], {
                            duration: theme.transitions.duration.enteringScreen,
                        }),
                    marginRight: !!drawerVal ? `${PAGE_DRAWER_WIDTH}px` : 0,
                }}
                title={"menu.stock"}
                empty={<EmptyData onClick={() => { setCreateDialog(true) }} />}
                filters={filters}
                sort={{ field: "create_time", order: "desc" }}
                actions={(
                    <TopToolbar>
                        <FilterButton />
                        <MyCreateButton onClick={() => { setCreateDialog(true) }} />
                        <SelectColumnsButton preferenceKey='stock' />
                        <MyExportButton />
                    </TopToolbar>
                )}
                perPage={DEFAULT_PAGE_SIZE}
            >
                <StyledDatagrid
                    preferenceKey='stock'
                    bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />}
                    rowClick={(id, resource, record) => false}
                    expand={() => <StockPanel />}
                    expandSingle={true}
                    omit={['id', 'createTime', 'createBy', 'memo']}
                >
                    <NumberField source="id" />
                    <TextField source="asnOrder" label="table.field.stock.asnOrder" />
                    <TextField source="erpToken" label="table.field.stock.erpToken" />
                    <TextField source="erpOrder" label="table.field.stock.erpOrder" />
                    <TextField source="erpStkAdr" label="table.field.stock.erpStkAdr" />
                    <TextField source="contractId" label="table.field.stock.contractId" />
                    <TextField source="lockReason" label="table.field.stock.lockReason" />
                    <NumberField source="lockStatus" label="table.field.stock.lockStatus" />
                    <TextField source="locker" label="table.field.stock.locker" />
                    <DateField source="lockedTime" label="table.field.stock.lockedTime" showTime />
                    <ReferenceField source="updateBy" label="common.field.updateBy" reference="user" link={false} sortable={false}>
                        <TextField source="nickname" />
                    </ReferenceField>
                    <DateField source="updateTime" label="common.field.updateTime" showTime />
                    <ReferenceField source="createBy" label="common.field.createBy" reference="user" link={false} sortable={false}>
                        <TextField source="nickname" />
                    </ReferenceField>
                    <DateField source="createTime" label="common.field.createTime" showTime />
                    <BooleanField source="statusBool" label="common.field.status" sortable={false} />
                    <TextField source="memo" label="common.field.memo" sortable={false} />
                    <WrapperField cellClassName="opt" label="common.field.opt">
                        <EditButton sx={{ padding: '1px', fontSize: '.75rem' }} />
                        <DeleteButton sx={{ padding: '1px', fontSize: '.75rem' }} mutationMode={OPERATE_MODE} />
                    </WrapperField>
                </StyledDatagrid>
            </List>
            <StockCreate
                open={createDialog}
                setOpen={setCreateDialog}
            />
            <PageDrawer
                title='Stock Detail'
                drawerVal={drawerVal}
                setDrawerVal={setDrawerVal}
            >
            </PageDrawer>
        </Box>
    )
}
export default StockList;
rsf-admin/src/page/stock/StockPanel.jsx
New file
@@ -0,0 +1,105 @@
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 StockPanel = () => {
    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.stock.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.stock.asnOrder"
                                property={record.asnOrder}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.stock.erpToken"
                                property={record.erpToken}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.stock.erpOrder"
                                property={record.erpOrder}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.stock.erpStkAdr"
                                property={record.erpStkAdr}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.stock.contractId"
                                property={record.contractId$}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.stock.lockReason"
                                property={record.lockReason}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.stock.lockStatus"
                                property={record.lockStatus}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.stock.locker"
                                property={record.locker}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.stock.lockedTime"
                                property={record.lockedTime$}
                            />
                        </Grid>
                    </Grid>
                </CardContent>
            </Card >
        </>
    );
};
export default StockPanel;
rsf-admin/src/page/stock/index.jsx
New file
@@ -0,0 +1,18 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import {
    ListGuesser,
    EditGuesser,
    ShowGuesser,
} from "react-admin";
import StockList from "./StockList";
import StockEdit from "./StockEdit";
export default {
    list: StockList,
    edit: StockEdit,
    show: ShowGuesser,
    recordRepresentation: (record) => {
        return `${record.id}`
    }
};
rsf-admin/src/page/stockItem/StockItemCreate.jsx
New file
@@ -0,0 +1,318 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import {
    CreateBase,
    useTranslate,
    TextInput,
    NumberInput,
    BooleanInput,
    DateInput,
    SaveButton,
    SelectInput,
    ReferenceInput,
    ReferenceArrayInput,
    AutocompleteInput,
    Toolbar,
    required,
    useDataProvider,
    useNotify,
    Form,
    useCreateController,
} from 'react-admin';
import {
    Dialog,
    DialogActions,
    DialogContent,
    DialogTitle,
    Stack,
    Grid,
    Box,
} from '@mui/material';
import DialogCloseButton from "../components/DialogCloseButton";
import StatusSelectInput from "../components/StatusSelectInput";
import MemoInput from "../components/MemoInput";
const StockItemCreate = (props) => {
    const { open, setOpen } = props;
    const translate = useTranslate();
    const notify = useNotify();
    const handleClose = (event, reason) => {
        if (reason !== "backdropClick") {
            setOpen(false);
        }
    };
    const handleSuccess = async (data) => {
        setOpen(false);
        notify('common.response.success');
    };
    const handleError = async (error) => {
        notify(error.message || 'common.response.fail', { type: 'error', messageArgs: { _: error.message } });
    };
    return (
        <>
            <CreateBase
                record={{}}
                transform={(data) => {
                    return data;
                }}
                mutationOptions={{ onSuccess: handleSuccess, onError: handleError }}
            >
                <Dialog
                    open={open}
                    onClose={handleClose}
                    aria-labelledby="form-dialog-title"
                    fullWidth
                    disableRestoreFocus
                    maxWidth="md"   // 'xs' | 'sm' | 'md' | 'lg' | 'xl'
                >
                    <Form>
                        <DialogTitle id="form-dialog-title" sx={{
                            position: 'sticky',
                            top: 0,
                            backgroundColor: 'background.paper',
                            zIndex: 1000
                        }}
                        >
                            {translate('create.title')}
                            <Box sx={{ position: 'absolute', top: 8, right: 8, zIndex: 1001 }}>
                                <DialogCloseButton onClose={handleClose} />
                            </Box>
                        </DialogTitle>
                        <DialogContent sx={{ mt: 2 }}>
                            <Grid container rowSpacing={2} columnSpacing={2}>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.stockItem.stockId"
                                        source="stockId"
                                        parse={v => v}
                                        autoFocus
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <ReferenceInput
                                        source="matnrId"
                                        reference="matnr"
                                    >
                                        <AutocompleteInput
                                            label="table.field.stockItem.matnrId"
                                            optionText="unit"
                                            filterToQuery={(val) => ({ unit: val })}
                                            validate={required()}
                                        />
                                    </ReferenceInput>
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.stockItem.code"
                                        source="code"
                                        parse={v => v}
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.stockItem.matnrk"
                                        source="matnrk"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.stockItem.anfme"
                                        source="anfme"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.stockItem.workQty"
                                        source="workQty"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.stockItem.qty"
                                        source="qty"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.stockItem.weight"
                                        source="weight"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.stockItem.unit"
                                        source="unit"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <ReferenceInput
                                        source="shipperId"
                                        reference="shipper"
                                    >
                                        <AutocompleteInput
                                            label="table.field.stockItem.shipperId"
                                            optionText="name"
                                            filterToQuery={(val) => ({ name: val })}
                                        />
                                    </ReferenceInput>
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.stockItem.splrId"
                                        source="splrId"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.stockItem.brand"
                                        source="brand"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.stockItem.batch"
                                        source="batch"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.stockItem.prodTime"
                                        source="prodTime"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <ReferenceInput
                                        source="inspectId"
                                        reference="qlyInspect"
                                    >
                                        <AutocompleteInput
                                            label="table.field.stockItem.inspectId"
                                            optionText="name"
                                            filterToQuery={(val) => ({ name: val })}
                                        />
                                    </ReferenceInput>
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.stockItem.splrBtch"
                                        source="splrBtch"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.stockItem.asnOrder"
                                        source="asnOrder"
                                        parse={v => v}
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.stockItem.erpToken"
                                        source="erpToken"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.stockItem.erpOrder"
                                        source="erpOrder"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.stockItem.erpStkAdr"
                                        source="erpStkAdr"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <ReferenceInput
                                        source="locId"
                                        reference="loc"
                                    >
                                        <AutocompleteInput
                                            label="table.field.stockItem.locId"
                                            optionText="name"
                                            filterToQuery={(val) => ({ name: val })}
                                        />
                                    </ReferenceInput>
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.stockItem.barcode"
                                        source="barcode"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.stockItem.purPrice"
                                        source="purPrice"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.stockItem.lockReason"
                                        source="lockReason"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.stockItem.lockStatus"
                                        source="lockStatus"
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.stockItem.locker"
                                        source="locker"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <DateInput
                                        label="table.field.stockItem.lockedTime"
                                        source="lockedTime"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <StatusSelectInput />
                                </Grid>
                                <Grid item xs={12} display="flex" gap={1}>
                                    <Stack direction="column" spacing={1} width={'100%'}>
                                        <MemoInput />
                                    </Stack>
                                </Grid>
                            </Grid>
                        </DialogContent>
                        <DialogActions sx={{ position: 'sticky', bottom: 0, backgroundColor: 'background.paper', zIndex: 1000 }}>
                            <Toolbar sx={{ width: '100%', justifyContent: 'space-between' }}  >
                                <SaveButton />
                            </Toolbar>
                        </DialogActions>
                    </Form>
                </Dialog>
            </CreateBase>
        </>
    )
}
export default StockItemCreate;
rsf-admin/src/page/stockItem/StockItemEdit.jsx
New file
@@ -0,0 +1,294 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import {
    Edit,
    SimpleForm,
    FormDataConsumer,
    useTranslate,
    TextInput,
    NumberInput,
    BooleanInput,
    DateInput,
    SelectInput,
    ReferenceInput,
    ReferenceArrayInput,
    AutocompleteInput,
    SaveButton,
    Toolbar,
    Labeled,
    NumberField,
    required,
    useRecordContext,
    DeleteButton,
} from 'react-admin';
import { useWatch, useFormContext } from "react-hook-form";
import { Stack, Grid, Box, Typography } from '@mui/material';
import * as Common from '@/utils/common';
import { EDIT_MODE, REFERENCE_INPUT_PAGESIZE } from '@/config/setting';
import EditBaseAside from "../components/EditBaseAside";
import CustomerTopToolBar from "../components/EditTopToolBar";
import MemoInput from "../components/MemoInput";
import StatusSelectInput from "../components/StatusSelectInput";
const FormToolbar = () => {
    const { getValues } = useFormContext();
    return (
        <Toolbar sx={{ justifyContent: 'space-between' }}>
            <SaveButton />
            <DeleteButton mutationMode="optimistic" />
        </Toolbar>
    )
}
const StockItemEdit = () => {
    const translate = useTranslate();
    return (
        <Edit
            redirect="list"
            mutationMode={EDIT_MODE}
            actions={<CustomerTopToolBar />}
            aside={<EditBaseAside />}
        >
            <SimpleForm
                shouldUnregister
                warnWhenUnsavedChanges
                toolbar={<FormToolbar />}
                mode="onTouched"
                defaultValues={{}}
            // validate={(values) => { }}
            >
                <Grid container width={{ xs: '100%', xl: '80%' }} rowSpacing={3} columnSpacing={3}>
                    <Grid item xs={12} md={8}>
                        <Typography variant="h6" gutterBottom>
                            {translate('common.edit.title.main')}
                        </Typography>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.stockItem.stockId"
                                source="stockId"
                                parse={v => v}
                                autoFocus
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <ReferenceInput
                                source="matnrId"
                                reference="matnr"
                                perPage={REFERENCE_INPUT_PAGESIZE}
                            >
                                <AutocompleteInput
                                    label="table.field.stockItem.matnrId"
                                    optionText="unit"
                                    filterToQuery={(val) => ({ unit: val })}
                                    validate={required()}
                                />
                            </ReferenceInput>
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.stockItem.code"
                                source="code"
                                parse={v => v}
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.stockItem.matnrk"
                                source="matnrk"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.stockItem.anfme"
                                source="anfme"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.stockItem.workQty"
                                source="workQty"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.stockItem.qty"
                                source="qty"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.stockItem.weight"
                                source="weight"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.stockItem.unit"
                                source="unit"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <ReferenceInput
                                source="shipperId"
                                reference="shipper"
                                perPage={REFERENCE_INPUT_PAGESIZE}
                            >
                                <AutocompleteInput
                                    label="table.field.stockItem.shipperId"
                                    optionText="name"
                                    filterToQuery={(val) => ({ name: val })}
                                />
                            </ReferenceInput>
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.stockItem.splrId"
                                source="splrId"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.stockItem.brand"
                                source="brand"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.stockItem.batch"
                                source="batch"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.stockItem.prodTime"
                                source="prodTime"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <ReferenceInput
                                source="inspectId"
                                reference="qlyInspect"
                                perPage={REFERENCE_INPUT_PAGESIZE}
                            >
                                <AutocompleteInput
                                    label="table.field.stockItem.inspectId"
                                    optionText="name"
                                    filterToQuery={(val) => ({ name: val })}
                                />
                            </ReferenceInput>
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.stockItem.splrBtch"
                                source="splrBtch"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.stockItem.asnOrder"
                                source="asnOrder"
                                parse={v => v}
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.stockItem.erpToken"
                                source="erpToken"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.stockItem.erpOrder"
                                source="erpOrder"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.stockItem.erpStkAdr"
                                source="erpStkAdr"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <ReferenceInput
                                source="locId"
                                reference="loc"
                                perPage={REFERENCE_INPUT_PAGESIZE}
                            >
                                <AutocompleteInput
                                    label="table.field.stockItem.locId"
                                    optionText="name"
                                    filterToQuery={(val) => ({ name: val })}
                                />
                            </ReferenceInput>
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.stockItem.barcode"
                                source="barcode"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.stockItem.purPrice"
                                source="purPrice"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.stockItem.lockReason"
                                source="lockReason"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.stockItem.lockStatus"
                                source="lockStatus"
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.stockItem.locker"
                                source="locker"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <DateInput
                                label="table.field.stockItem.lockedTime"
                                source="lockedTime"
                            />
                        </Stack>
                    </Grid>
                    <Grid item xs={12} md={4}>
                        <Typography variant="h6" gutterBottom>
                            {translate('common.edit.title.common')}
                        </Typography>
                        <StatusSelectInput />
                        <Box mt="2em" />
                        <MemoInput />
                    </Grid>
                </Grid>
            </SimpleForm>
        </Edit >
    )
}
export default StockItemEdit;
rsf-admin/src/page/stockItem/StockItemList.jsx
New file
@@ -0,0 +1,220 @@
import React, { useState, useRef, useEffect, useMemo, useCallback } from "react";
import { useNavigate } from 'react-router-dom';
import {
    List,
    DatagridConfigurable,
    SearchInput,
    TopToolbar,
    SelectColumnsButton,
    EditButton,
    FilterButton,
    CreateButton,
    ExportButton,
    BulkDeleteButton,
    WrapperField,
    useRecordContext,
    useTranslate,
    useNotify,
    useListContext,
    FunctionField,
    TextField,
    NumberField,
    DateField,
    BooleanField,
    ReferenceField,
    TextInput,
    DateTimeInput,
    DateInput,
    SelectInput,
    NumberInput,
    ReferenceInput,
    ReferenceArrayInput,
    AutocompleteInput,
    DeleteButton,
} from 'react-admin';
import { Box, Typography, Card, Stack } from '@mui/material';
import { styled } from '@mui/material/styles';
import StockItemCreate from "./StockItemCreate";
import StockItemPanel from "./StockItemPanel";
import EmptyData from "../components/EmptyData";
import MyCreateButton from "../components/MyCreateButton";
import MyExportButton from '../components/MyExportButton';
import PageDrawer from "../components/PageDrawer";
import MyField from "../components/MyField";
import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting';
import * as Common from '@/utils/common';
const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({
    '& .css-1vooibu-MuiSvgIcon-root': {
        height: '.9em'
    },
    '& .RaDatagrid-row': {
        cursor: 'auto'
    },
    '& .column-name': {
    },
    '& .opt': {
        width: 200
    },
}));
const filters = [
    <SearchInput source="condition" alwaysOn />,
    <DateInput label='common.time.after' source="timeStart" alwaysOn />,
    <DateInput label='common.time.before' source="timeEnd" alwaysOn />,
    <TextInput source="stockId" label="table.field.stockItem.stockId" />,
    <ReferenceInput source="matnrId" label="table.field.stockItem.matnrId" reference="matnr">
        <AutocompleteInput label="table.field.stockItem.matnrId" optionText="unit" filterToQuery={(val) => ({ unit: val })} />
    </ReferenceInput>,
    <TextInput source="code" label="table.field.stockItem.code" />,
    <TextInput source="matnrk" label="table.field.stockItem.matnrk" />,
    <NumberInput source="anfme" label="table.field.stockItem.anfme" />,
    <NumberInput source="workQty" label="table.field.stockItem.workQty" />,
    <NumberInput source="qty" label="table.field.stockItem.qty" />,
    <NumberInput source="weight" label="table.field.stockItem.weight" />,
    <TextInput source="unit" label="table.field.stockItem.unit" />,
    <ReferenceInput source="shipperId" label="table.field.stockItem.shipperId" reference="shipper">
        <AutocompleteInput label="table.field.stockItem.shipperId" optionText="name" filterToQuery={(val) => ({ name: val })} />
    </ReferenceInput>,
    <TextInput source="splrId" label="table.field.stockItem.splrId" />,
    <TextInput source="brand" label="table.field.stockItem.brand" />,
    <TextInput source="batch" label="table.field.stockItem.batch" />,
    <TextInput source="prodTime" label="table.field.stockItem.prodTime" />,
    <ReferenceInput source="inspectId" label="table.field.stockItem.inspectId" reference="qlyInspect">
        <AutocompleteInput label="table.field.stockItem.inspectId" optionText="name" filterToQuery={(val) => ({ name: val })} />
    </ReferenceInput>,
    <TextInput source="splrBtch" label="table.field.stockItem.splrBtch" />,
    <TextInput source="asnOrder" label="table.field.stockItem.asnOrder" />,
    <TextInput source="erpToken" label="table.field.stockItem.erpToken" />,
    <TextInput source="erpOrder" label="table.field.stockItem.erpOrder" />,
    <TextInput source="erpStkAdr" label="table.field.stockItem.erpStkAdr" />,
    <ReferenceInput source="locId" label="table.field.stockItem.locId" reference="loc">
        <AutocompleteInput label="table.field.stockItem.locId" optionText="name" filterToQuery={(val) => ({ name: val })} />
    </ReferenceInput>,
    <TextInput source="barcode" label="table.field.stockItem.barcode" />,
    <NumberInput source="purPrice" label="table.field.stockItem.purPrice" />,
    <TextInput source="lockReason" label="table.field.stockItem.lockReason" />,
    <NumberInput source="lockStatus" label="table.field.stockItem.lockStatus" />,
    <TextInput source="locker" label="table.field.stockItem.locker" />,
    <DateInput source="lockedTime" label="table.field.stockItem.lockedTime" />,
    <TextInput label="common.field.memo" source="memo" />,
    <SelectInput
        label="common.field.status"
        source="status"
        choices={[
            { id: '1', name: 'common.enums.statusTrue' },
            { id: '0', name: 'common.enums.statusFalse' },
        ]}
        resettable
    />,
]
const StockItemList = () => {
    const translate = useTranslate();
    const [createDialog, setCreateDialog] = useState(false);
    const [drawerVal, setDrawerVal] = useState(false);
    return (
        <Box display="flex">
            <List
                sx={{
                    flexGrow: 1,
                    transition: (theme) =>
                        theme.transitions.create(['all'], {
                            duration: theme.transitions.duration.enteringScreen,
                        }),
                    marginRight: !!drawerVal ? `${PAGE_DRAWER_WIDTH}px` : 0,
                }}
                title={"menu.stockItem"}
                empty={<EmptyData onClick={() => { setCreateDialog(true) }} />}
                filters={filters}
                sort={{ field: "create_time", order: "desc" }}
                actions={(
                    <TopToolbar>
                        <FilterButton />
                        <MyCreateButton onClick={() => { setCreateDialog(true) }} />
                        <SelectColumnsButton preferenceKey='stockItem' />
                        <MyExportButton />
                    </TopToolbar>
                )}
                perPage={DEFAULT_PAGE_SIZE}
            >
                <StyledDatagrid
                    preferenceKey='stockItem'
                    bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />}
                    rowClick={(id, resource, record) => false}
                    expand={() => <StockItemPanel />}
                    expandSingle={true}
                    omit={['id', 'createTime', 'createBy', 'memo']}
                >
                    <NumberField source="id" />
                    <TextField source="stockId" label="table.field.stockItem.stockId" />
                    <ReferenceField source="matnrId" label="table.field.stockItem.matnrId" reference="matnr" link={false} sortable={false}>
                        <TextField source="unit" />
                    </ReferenceField>
                    <TextField source="code" label="table.field.stockItem.code" />
                    <TextField source="matnrk" label="table.field.stockItem.matnrk" />
                    <NumberField source="anfme" label="table.field.stockItem.anfme" />
                    <NumberField source="workQty" label="table.field.stockItem.workQty" />
                    <NumberField source="qty" label="table.field.stockItem.qty" />
                    <NumberField source="weight" label="table.field.stockItem.weight" />
                    <TextField source="unit" label="table.field.stockItem.unit" />
                    <ReferenceField source="shipperId" label="table.field.stockItem.shipperId" reference="shipper" link={false} sortable={false}>
                        <TextField source="name" />
                    </ReferenceField>
                    <TextField source="splrId" label="table.field.stockItem.splrId" />
                    <TextField source="brand" label="table.field.stockItem.brand" />
                    <TextField source="batch" label="table.field.stockItem.batch" />
                    <TextField source="prodTime" label="table.field.stockItem.prodTime" />
                    <ReferenceField source="inspectId" label="table.field.stockItem.inspectId" reference="qlyInspect" link={false} sortable={false}>
                        <TextField source="name" />
                    </ReferenceField>
                    <TextField source="splrBtch" label="table.field.stockItem.splrBtch" />
                    <TextField source="asnOrder" label="table.field.stockItem.asnOrder" />
                    <TextField source="erpToken" label="table.field.stockItem.erpToken" />
                    <TextField source="erpOrder" label="table.field.stockItem.erpOrder" />
                    <TextField source="erpStkAdr" label="table.field.stockItem.erpStkAdr" />
                    <ReferenceField source="locId" label="table.field.stockItem.locId" reference="loc" link={false} sortable={false}>
                        <TextField source="name" />
                    </ReferenceField>
                    <TextField source="barcode" label="table.field.stockItem.barcode" />
                    <NumberField source="purPrice" label="table.field.stockItem.purPrice" />
                    <TextField source="lockReason" label="table.field.stockItem.lockReason" />
                    <NumberField source="lockStatus" label="table.field.stockItem.lockStatus" />
                    <TextField source="locker" label="table.field.stockItem.locker" />
                    <DateField source="lockedTime" label="table.field.stockItem.lockedTime" showTime />
                    <ReferenceField source="updateBy" label="common.field.updateBy" reference="user" link={false} sortable={false}>
                        <TextField source="nickname" />
                    </ReferenceField>
                    <DateField source="updateTime" label="common.field.updateTime" showTime />
                    <ReferenceField source="createBy" label="common.field.createBy" reference="user" link={false} sortable={false}>
                        <TextField source="nickname" />
                    </ReferenceField>
                    <DateField source="createTime" label="common.field.createTime" showTime />
                    <BooleanField source="statusBool" label="common.field.status" sortable={false} />
                    <TextField source="memo" label="common.field.memo" sortable={false} />
                    <WrapperField cellClassName="opt" label="common.field.opt">
                        <EditButton sx={{ padding: '1px', fontSize: '.75rem' }} />
                        <DeleteButton sx={{ padding: '1px', fontSize: '.75rem' }} mutationMode={OPERATE_MODE} />
                    </WrapperField>
                </StyledDatagrid>
            </List>
            <StockItemCreate
                open={createDialog}
                setOpen={setCreateDialog}
            />
            <PageDrawer
                title='StockItem Detail'
                drawerVal={drawerVal}
                setDrawerVal={setDrawerVal}
            >
            </PageDrawer>
        </Box>
    )
}
export default StockItemList;
rsf-admin/src/page/stockItem/StockItemPanel.jsx
New file
@@ -0,0 +1,213 @@
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 StockItemPanel = () => {
    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.stockItem.matnrk'))}: {record.matnrk}
                            </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.stockItem.stockId"
                                property={record.stockId$}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.stockItem.matnrId"
                                property={record.matnrId$}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.stockItem.code"
                                property={record.code}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.stockItem.matnrk"
                                property={record.matnrk}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.stockItem.anfme"
                                property={record.anfme}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.stockItem.workQty"
                                property={record.workQty}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.stockItem.qty"
                                property={record.qty}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.stockItem.weight"
                                property={record.weight}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.stockItem.unit"
                                property={record.unit}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.stockItem.shipperId"
                                property={record.shipperId$}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.stockItem.splrId"
                                property={record.splrId}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.stockItem.brand"
                                property={record.brand}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.stockItem.batch"
                                property={record.batch}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.stockItem.prodTime"
                                property={record.prodTime}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.stockItem.inspectId"
                                property={record.inspectId$}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.stockItem.splrBtch"
                                property={record.splrBtch}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.stockItem.asnOrder"
                                property={record.asnOrder}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.stockItem.erpToken"
                                property={record.erpToken}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.stockItem.erpOrder"
                                property={record.erpOrder}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.stockItem.erpStkAdr"
                                property={record.erpStkAdr}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.stockItem.locId"
                                property={record.locId$}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.stockItem.barcode"
                                property={record.barcode}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.stockItem.purPrice"
                                property={record.purPrice}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.stockItem.lockReason"
                                property={record.lockReason}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.stockItem.lockStatus"
                                property={record.lockStatus}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.stockItem.locker"
                                property={record.locker}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.stockItem.lockedTime"
                                property={record.lockedTime$}
                            />
                        </Grid>
                    </Grid>
                </CardContent>
            </Card >
        </>
    );
};
export default StockItemPanel;
rsf-admin/src/page/stockItem/index.jsx
New file
@@ -0,0 +1,18 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import {
    ListGuesser,
    EditGuesser,
    ShowGuesser,
} from "react-admin";
import StockItemList from "./StockItemList";
import StockItemEdit from "./StockItemEdit";
export default {
    list: StockItemList,
    edit: StockItemEdit,
    show: ShowGuesser,
    recordRepresentation: (record) => {
        return `${record.matnrk}`
    }
};
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_warehouse_areas";
        generator.tableDesc="库区信息表";
        generator.table="man_";
        generator.tableDesc="质检信息";
        generator.packagePath="com.vincent.rsf.server.manager";
        generator.build();
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/ContainerController.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.Container;
import com.vincent.rsf.server.manager.service.ContainerService;
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 ContainerController extends BaseController {
    @Autowired
    private ContainerService containerService;
    @PreAuthorize("hasAuthority('manager:container:list')")
    @PostMapping("/container/page")
    public R page(@RequestBody Map<String, Object> map) {
        BaseParam baseParam = buildParam(map, BaseParam.class);
        PageParam<Container, BaseParam> pageParam = new PageParam<>(baseParam, Container.class);
        return R.ok().add(containerService.page(pageParam, pageParam.buildWrapper(true)));
    }
    @PreAuthorize("hasAuthority('manager:container:list')")
    @PostMapping("/container/list")
    public R list(@RequestBody Map<String, Object> map) {
        return R.ok().add(containerService.list());
    }
    @PreAuthorize("hasAuthority('manager:container:list')")
    @PostMapping({"/container/many/{ids}", "/containers/many/{ids}"})
    public R many(@PathVariable Long[] ids) {
        return R.ok().add(containerService.listByIds(Arrays.asList(ids)));
    }
    @PreAuthorize("hasAuthority('manager:container:list')")
    @GetMapping("/container/{id}")
    public R get(@PathVariable("id") Long id) {
        return R.ok().add(containerService.getById(id));
    }
    @PreAuthorize("hasAuthority('manager:container:save')")
    @OperationLog("Create 库位信息表")
    @PostMapping("/container/save")
    public R save(@RequestBody Container container) {
        container.setCreateBy(getLoginUserId());
        container.setCreateTime(new Date());
        container.setUpdateBy(getLoginUserId());
        container.setUpdateTime(new Date());
        if (!containerService.save(container)) {
            return R.error("Save Fail");
        }
        return R.ok("Save Success").add(container);
    }
    @PreAuthorize("hasAuthority('manager:container:update')")
    @OperationLog("Update 库位信息表")
    @PostMapping("/container/update")
    public R update(@RequestBody Container container) {
        container.setUpdateBy(getLoginUserId());
        container.setUpdateTime(new Date());
        if (!containerService.updateById(container)) {
            return R.error("Update Fail");
        }
        return R.ok("Update Success").add(container);
    }
    @PreAuthorize("hasAuthority('manager:container:remove')")
    @OperationLog("Delete 库位信息表")
    @PostMapping("/container/remove/{ids}")
    public R remove(@PathVariable Long[] ids) {
        if (!containerService.removeByIds(Arrays.asList(ids))) {
            return R.error("Delete Fail");
        }
        return R.ok("Delete Success").add(ids);
    }
    @PreAuthorize("hasAuthority('manager:container:list')")
    @PostMapping("/container/query")
    public R query(@RequestParam(required = false) String condition) {
        List<KeyValVo> vos = new ArrayList<>();
        LambdaQueryWrapper<Container> wrapper = new LambdaQueryWrapper<>();
        if (!Cools.isEmpty(condition)) {
            wrapper.like(Container::getName, condition);
        }
        containerService.page(new Page<>(1, 30), wrapper).getRecords().forEach(
                item -> vos.add(new KeyValVo(item.getId(), item.getName()))
        );
        return R.ok().add(vos);
    }
    @PreAuthorize("hasAuthority('manager:container:list')")
    @PostMapping("/container/export")
    public void export(@RequestBody Map<String, Object> map, HttpServletResponse response) throws Exception {
        ExcelUtil.build(ExcelUtil.create(containerService.list(), Container.class), response);
    }
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/ContractController.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.Contract;
import com.vincent.rsf.server.manager.service.ContractService;
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 ContractController extends BaseController {
    @Autowired
    private ContractService contractService;
    @PreAuthorize("hasAuthority('manager:contract:list')")
    @PostMapping("/contract/page")
    public R page(@RequestBody Map<String, Object> map) {
        BaseParam baseParam = buildParam(map, BaseParam.class);
        PageParam<Contract, BaseParam> pageParam = new PageParam<>(baseParam, Contract.class);
        return R.ok().add(contractService.page(pageParam, pageParam.buildWrapper(true)));
    }
    @PreAuthorize("hasAuthority('manager:contract:list')")
    @PostMapping("/contract/list")
    public R list(@RequestBody Map<String, Object> map) {
        return R.ok().add(contractService.list());
    }
    @PreAuthorize("hasAuthority('manager:contract:list')")
    @PostMapping({"/contract/many/{ids}", "/contracts/many/{ids}"})
    public R many(@PathVariable Long[] ids) {
        return R.ok().add(contractService.listByIds(Arrays.asList(ids)));
    }
    @PreAuthorize("hasAuthority('manager:contract:list')")
    @GetMapping("/contract/{id}")
    public R get(@PathVariable("id") Long id) {
        return R.ok().add(contractService.getById(id));
    }
    @PreAuthorize("hasAuthority('manager:contract:save')")
    @OperationLog("Create 合同信息")
    @PostMapping("/contract/save")
    public R save(@RequestBody Contract contract) {
        contract.setCreateBy(getLoginUserId());
        contract.setCreateTime(new Date());
        contract.setUpdateBy(getLoginUserId());
        contract.setUpdateTime(new Date());
        if (!contractService.save(contract)) {
            return R.error("Save Fail");
        }
        return R.ok("Save Success").add(contract);
    }
    @PreAuthorize("hasAuthority('manager:contract:update')")
    @OperationLog("Update 合同信息")
    @PostMapping("/contract/update")
    public R update(@RequestBody Contract contract) {
        contract.setUpdateBy(getLoginUserId());
        contract.setUpdateTime(new Date());
        if (!contractService.updateById(contract)) {
            return R.error("Update Fail");
        }
        return R.ok("Update Success").add(contract);
    }
    @PreAuthorize("hasAuthority('manager:contract:remove')")
    @OperationLog("Delete 合同信息")
    @PostMapping("/contract/remove/{ids}")
    public R remove(@PathVariable Long[] ids) {
        if (!contractService.removeByIds(Arrays.asList(ids))) {
            return R.error("Delete Fail");
        }
        return R.ok("Delete Success").add(ids);
    }
    @PreAuthorize("hasAuthority('manager:contract:list')")
    @PostMapping("/contract/query")
    public R query(@RequestParam(required = false) String condition) {
        List<KeyValVo> vos = new ArrayList<>();
        LambdaQueryWrapper<Contract> wrapper = new LambdaQueryWrapper<>();
        if (!Cools.isEmpty(condition)) {
            wrapper.like(Contract::getName, condition);
        }
        contractService.page(new Page<>(1, 30), wrapper).getRecords().forEach(
                item -> vos.add(new KeyValVo(item.getId(), item.getName()))
        );
        return R.ok().add(vos);
    }
    @PreAuthorize("hasAuthority('manager:contract:list')")
    @PostMapping("/contract/export")
    public void export(@RequestBody Map<String, Object> map, HttpServletResponse response) throws Exception {
        ExcelUtil.build(ExcelUtil.create(contractService.list(), Contract.class), response);
    }
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/LocController.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.Loc;
import com.vincent.rsf.server.manager.service.LocService;
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 LocController extends BaseController {
    @Autowired
    private LocService locService;
    @PreAuthorize("hasAuthority('manager:loc:list')")
    @PostMapping("/loc/page")
    public R page(@RequestBody Map<String, Object> map) {
        BaseParam baseParam = buildParam(map, BaseParam.class);
        PageParam<Loc, BaseParam> pageParam = new PageParam<>(baseParam, Loc.class);
        return R.ok().add(locService.page(pageParam, pageParam.buildWrapper(true)));
    }
    @PreAuthorize("hasAuthority('manager:loc:list')")
    @PostMapping("/loc/list")
    public R list(@RequestBody Map<String, Object> map) {
        return R.ok().add(locService.list());
    }
    @PreAuthorize("hasAuthority('manager:loc:list')")
    @PostMapping({"/loc/many/{ids}", "/locs/many/{ids}"})
    public R many(@PathVariable Long[] ids) {
        return R.ok().add(locService.listByIds(Arrays.asList(ids)));
    }
    @PreAuthorize("hasAuthority('manager:loc:list')")
    @GetMapping("/loc/{id}")
    public R get(@PathVariable("id") Long id) {
        return R.ok().add(locService.getById(id));
    }
    @PreAuthorize("hasAuthority('manager:loc:save')")
    @OperationLog("Create 库位信息表")
    @PostMapping("/loc/save")
    public R save(@RequestBody Loc loc) {
        loc.setCreateBy(getLoginUserId());
        loc.setCreateTime(new Date());
        loc.setUpdateBy(getLoginUserId());
        loc.setUpdateTime(new Date());
        if (!locService.save(loc)) {
            return R.error("Save Fail");
        }
        return R.ok("Save Success").add(loc);
    }
    @PreAuthorize("hasAuthority('manager:loc:update')")
    @OperationLog("Update 库位信息表")
    @PostMapping("/loc/update")
    public R update(@RequestBody Loc loc) {
        loc.setUpdateBy(getLoginUserId());
        loc.setUpdateTime(new Date());
        if (!locService.updateById(loc)) {
            return R.error("Update Fail");
        }
        return R.ok("Update Success").add(loc);
    }
    @PreAuthorize("hasAuthority('manager:loc:remove')")
    @OperationLog("Delete 库位信息表")
    @PostMapping("/loc/remove/{ids}")
    public R remove(@PathVariable Long[] ids) {
        if (!locService.removeByIds(Arrays.asList(ids))) {
            return R.error("Delete Fail");
        }
        return R.ok("Delete Success").add(ids);
    }
    @PreAuthorize("hasAuthority('manager:loc:list')")
    @PostMapping("/loc/query")
    public R query(@RequestParam(required = false) String condition) {
        List<KeyValVo> vos = new ArrayList<>();
        LambdaQueryWrapper<Loc> wrapper = new LambdaQueryWrapper<>();
        if (!Cools.isEmpty(condition)) {
            wrapper.like(Loc::getName, condition);
        }
        locService.page(new Page<>(1, 30), wrapper).getRecords().forEach(
                item -> vos.add(new KeyValVo(item.getId(), item.getName()))
        );
        return R.ok().add(vos);
    }
    @PreAuthorize("hasAuthority('manager:loc:list')")
    @PostMapping("/loc/export")
    public void export(@RequestBody Map<String, Object> map, HttpServletResponse response) throws Exception {
        ExcelUtil.build(ExcelUtil.create(locService.list(), Loc.class), response);
    }
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/QlyInspectController.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.QlyInspect;
import com.vincent.rsf.server.manager.service.QlyInspectService;
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 QlyInspectController extends BaseController {
    @Autowired
    private QlyInspectService qlyInspectService;
    @PreAuthorize("hasAuthority('manager:qlyInspect:list')")
    @PostMapping("/qlyInspect/page")
    public R page(@RequestBody Map<String, Object> map) {
        BaseParam baseParam = buildParam(map, BaseParam.class);
        PageParam<QlyInspect, BaseParam> pageParam = new PageParam<>(baseParam, QlyInspect.class);
        return R.ok().add(qlyInspectService.page(pageParam, pageParam.buildWrapper(true)));
    }
    @PreAuthorize("hasAuthority('manager:qlyInspect:list')")
    @PostMapping("/qlyInspect/list")
    public R list(@RequestBody Map<String, Object> map) {
        return R.ok().add(qlyInspectService.list());
    }
    @PreAuthorize("hasAuthority('manager:qlyInspect:list')")
    @PostMapping({"/qlyInspect/many/{ids}", "/qlyInspects/many/{ids}"})
    public R many(@PathVariable Long[] ids) {
        return R.ok().add(qlyInspectService.listByIds(Arrays.asList(ids)));
    }
    @PreAuthorize("hasAuthority('manager:qlyInspect:list')")
    @GetMapping("/qlyInspect/{id}")
    public R get(@PathVariable("id") Long id) {
        return R.ok().add(qlyInspectService.getById(id));
    }
    @PreAuthorize("hasAuthority('manager:qlyInspect:save')")
    @OperationLog("Create 质检信息")
    @PostMapping("/qlyInspect/save")
    public R save(@RequestBody QlyInspect qlyInspect) {
        qlyInspect.setCreateBy(getLoginUserId());
        qlyInspect.setCreateTime(new Date());
        qlyInspect.setUpdateBy(getLoginUserId());
        qlyInspect.setUpdateTime(new Date());
        if (!qlyInspectService.save(qlyInspect)) {
            return R.error("Save Fail");
        }
        return R.ok("Save Success").add(qlyInspect);
    }
    @PreAuthorize("hasAuthority('manager:qlyInspect:update')")
    @OperationLog("Update 质检信息")
    @PostMapping("/qlyInspect/update")
    public R update(@RequestBody QlyInspect qlyInspect) {
        qlyInspect.setUpdateBy(getLoginUserId());
        qlyInspect.setUpdateTime(new Date());
        if (!qlyInspectService.updateById(qlyInspect)) {
            return R.error("Update Fail");
        }
        return R.ok("Update Success").add(qlyInspect);
    }
    @PreAuthorize("hasAuthority('manager:qlyInspect:remove')")
    @OperationLog("Delete 质检信息")
    @PostMapping("/qlyInspect/remove/{ids}")
    public R remove(@PathVariable Long[] ids) {
        if (!qlyInspectService.removeByIds(Arrays.asList(ids))) {
            return R.error("Delete Fail");
        }
        return R.ok("Delete Success").add(ids);
    }
    @PreAuthorize("hasAuthority('manager:qlyInspect:list')")
    @PostMapping("/qlyInspect/query")
    public R query(@RequestParam(required = false) String condition) {
        List<KeyValVo> vos = new ArrayList<>();
        LambdaQueryWrapper<QlyInspect> wrapper = new LambdaQueryWrapper<>();
        if (!Cools.isEmpty(condition)) {
            wrapper.like(QlyInspect::getName, condition);
        }
        qlyInspectService.page(new Page<>(1, 30), wrapper).getRecords().forEach(
                item -> vos.add(new KeyValVo(item.getId(), item.getName()))
        );
        return R.ok().add(vos);
    }
    @PreAuthorize("hasAuthority('manager:qlyInspect:list')")
    @PostMapping("/qlyInspect/export")
    public void export(@RequestBody Map<String, Object> map, HttpServletResponse response) throws Exception {
        ExcelUtil.build(ExcelUtil.create(qlyInspectService.list(), QlyInspect.class), response);
    }
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/StockController.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.Stock;
import com.vincent.rsf.server.manager.service.StockService;
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 StockController extends BaseController {
    @Autowired
    private StockService stockService;
    @PreAuthorize("hasAuthority('manager:stock:list')")
    @PostMapping("/stock/page")
    public R page(@RequestBody Map<String, Object> map) {
        BaseParam baseParam = buildParam(map, BaseParam.class);
        PageParam<Stock, BaseParam> pageParam = new PageParam<>(baseParam, Stock.class);
        return R.ok().add(stockService.page(pageParam, pageParam.buildWrapper(true)));
    }
    @PreAuthorize("hasAuthority('manager:stock:list')")
    @PostMapping("/stock/list")
    public R list(@RequestBody Map<String, Object> map) {
        return R.ok().add(stockService.list());
    }
    @PreAuthorize("hasAuthority('manager:stock:list')")
    @PostMapping({"/stock/many/{ids}", "/stocks/many/{ids}"})
    public R many(@PathVariable Long[] ids) {
        return R.ok().add(stockService.listByIds(Arrays.asList(ids)));
    }
    @PreAuthorize("hasAuthority('manager:stock:list')")
    @GetMapping("/stock/{id}")
    public R get(@PathVariable("id") Long id) {
        return R.ok().add(stockService.getById(id));
    }
    @PreAuthorize("hasAuthority('manager:stock:save')")
    @OperationLog("Create 库存信息")
    @PostMapping("/stock/save")
    public R save(@RequestBody Stock stock) {
        stock.setCreateBy(getLoginUserId());
        stock.setCreateTime(new Date());
        stock.setUpdateBy(getLoginUserId());
        stock.setUpdateTime(new Date());
        if (!stockService.save(stock)) {
            return R.error("Save Fail");
        }
        return R.ok("Save Success").add(stock);
    }
    @PreAuthorize("hasAuthority('manager:stock:update')")
    @OperationLog("Update 库存信息")
    @PostMapping("/stock/update")
    public R update(@RequestBody Stock stock) {
        stock.setUpdateBy(getLoginUserId());
        stock.setUpdateTime(new Date());
        if (!stockService.updateById(stock)) {
            return R.error("Update Fail");
        }
        return R.ok("Update Success").add(stock);
    }
    @PreAuthorize("hasAuthority('manager:stock:remove')")
    @OperationLog("Delete 库存信息")
    @PostMapping("/stock/remove/{ids}")
    public R remove(@PathVariable Long[] ids) {
        if (!stockService.removeByIds(Arrays.asList(ids))) {
            return R.error("Delete Fail");
        }
        return R.ok("Delete Success").add(ids);
    }
    @PreAuthorize("hasAuthority('manager:stock:list')")
    @PostMapping("/stock/query")
    public R query(@RequestParam(required = false) String condition) {
        List<KeyValVo> vos = new ArrayList<>();
        LambdaQueryWrapper<Stock> wrapper = new LambdaQueryWrapper<>();
        if (!Cools.isEmpty(condition)) {
            wrapper.like(Stock::getId, condition);
        }
        stockService.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:stock:list')")
    @PostMapping("/stock/export")
    public void export(@RequestBody Map<String, Object> map, HttpServletResponse response) throws Exception {
        ExcelUtil.build(ExcelUtil.create(stockService.list(), Stock.class), response);
    }
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/StockItemController.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.StockItem;
import com.vincent.rsf.server.manager.service.StockItemService;
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 StockItemController extends BaseController {
    @Autowired
    private StockItemService stockItemService;
    @PreAuthorize("hasAuthority('manager:stockItem:list')")
    @PostMapping("/stockItem/page")
    public R page(@RequestBody Map<String, Object> map) {
        BaseParam baseParam = buildParam(map, BaseParam.class);
        PageParam<StockItem, BaseParam> pageParam = new PageParam<>(baseParam, StockItem.class);
        return R.ok().add(stockItemService.page(pageParam, pageParam.buildWrapper(true)));
    }
    @PreAuthorize("hasAuthority('manager:stockItem:list')")
    @PostMapping("/stockItem/list")
    public R list(@RequestBody Map<String, Object> map) {
        return R.ok().add(stockItemService.list());
    }
    @PreAuthorize("hasAuthority('manager:stockItem:list')")
    @PostMapping({"/stockItem/many/{ids}", "/stockItems/many/{ids}"})
    public R many(@PathVariable Long[] ids) {
        return R.ok().add(stockItemService.listByIds(Arrays.asList(ids)));
    }
    @PreAuthorize("hasAuthority('manager:stockItem:list')")
    @GetMapping("/stockItem/{id}")
    public R get(@PathVariable("id") Long id) {
        return R.ok().add(stockItemService.getById(id));
    }
    @PreAuthorize("hasAuthority('manager:stockItem:save')")
    @OperationLog("Create 库存明细表")
    @PostMapping("/stockItem/save")
    public R save(@RequestBody StockItem stockItem) {
        stockItem.setCreateBy(getLoginUserId());
        stockItem.setCreateTime(new Date());
        stockItem.setUpdateBy(getLoginUserId());
        stockItem.setUpdateTime(new Date());
        if (!stockItemService.save(stockItem)) {
            return R.error("Save Fail");
        }
        return R.ok("Save Success").add(stockItem);
    }
    @PreAuthorize("hasAuthority('manager:stockItem:update')")
    @OperationLog("Update 库存明细表")
    @PostMapping("/stockItem/update")
    public R update(@RequestBody StockItem stockItem) {
        stockItem.setUpdateBy(getLoginUserId());
        stockItem.setUpdateTime(new Date());
        if (!stockItemService.updateById(stockItem)) {
            return R.error("Update Fail");
        }
        return R.ok("Update Success").add(stockItem);
    }
    @PreAuthorize("hasAuthority('manager:stockItem:remove')")
    @OperationLog("Delete 库存明细表")
    @PostMapping("/stockItem/remove/{ids}")
    public R remove(@PathVariable Long[] ids) {
        if (!stockItemService.removeByIds(Arrays.asList(ids))) {
            return R.error("Delete Fail");
        }
        return R.ok("Delete Success").add(ids);
    }
    @PreAuthorize("hasAuthority('manager:stockItem:list')")
    @PostMapping("/stockItem/query")
    public R query(@RequestParam(required = false) String condition) {
        List<KeyValVo> vos = new ArrayList<>();
        LambdaQueryWrapper<StockItem> wrapper = new LambdaQueryWrapper<>();
        if (!Cools.isEmpty(condition)) {
            wrapper.like(StockItem::getMatnrk, condition);
        }
        stockItemService.page(new Page<>(1, 30), wrapper).getRecords().forEach(
                item -> vos.add(new KeyValVo(item.getId(), item.getMatnrk()))
        );
        return R.ok().add(vos);
    }
    @PreAuthorize("hasAuthority('manager:stockItem:list')")
    @PostMapping("/stockItem/export")
    public void export(@RequestBody Map<String, Object> map, HttpServletResponse response) throws Exception {
        ExcelUtil.build(ExcelUtil.create(stockItemService.list(), StockItem.class), response);
    }
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/Container.java
New file
@@ -0,0 +1,325 @@
package com.vincent.rsf.server.manager.entity;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.format.annotation.DateTimeFormat;
import com.baomidou.mybatisplus.annotation.TableLogic;
import java.text.SimpleDateFormat;
import java.util.Date;
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
@TableName("man_container")
public class Container implements Serializable {
    private static final long serialVersionUID = 1L;
    /**
     * ID
     */
    @ApiModelProperty(value= "ID")
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    /**
     * 编码
     */
    @ApiModelProperty(value= "编码")
    private String code;
    /**
     * 名称
     */
    @ApiModelProperty(value= "名称")
    private String name;
    /**
     * 容器类型标识
     */
    @ApiModelProperty(value= "容器类型标识")
    private Long typeId;
    /**
     * 使用次数
     */
    @ApiModelProperty(value= "使用次数")
    private Double used;
    /**
     * 长度
     */
    @ApiModelProperty(value= "长度")
    private Double lenght;
    /**
     * 宽度
     */
    @ApiModelProperty(value= "宽度")
    private Double width;
    /**
     * 高度
     */
    @ApiModelProperty(value= "高度")
    private Double height;
    /**
     * 限长
     */
    @ApiModelProperty(value= "限长")
    private Double rstLen;
    /**
     * 限宽
     */
    @ApiModelProperty(value= "限宽")
    private Double rstWid;
    /**
     * 限重
     */
    @ApiModelProperty(value= "限重")
    private Double rstWei;
    /**
     * 限高
     */
    @ApiModelProperty(value= "限高")
    private Double rstHei;
    /**
     * 父容器标识
     */
    @ApiModelProperty(value= "父容器标识")
    private Long panrentId;
    /**
     * 有效期
     */
    @ApiModelProperty(value= "有效期")
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
    private Date vaildTime;
    /**
     * 是否回收 1: 是   0: 否
     */
    @ApiModelProperty(value= "是否回收 1: 是   0: 否  ")
    private Short flagRycle;
    /**
     * 是否虚拟 1: 是   0: 否
     */
    @ApiModelProperty(value= "是否虚拟 1: 是   0: 否  ")
    private Short flagLogic;
    /**
     * 状态 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 Container() {}
    public Container(String code,String name,Long typeId,Double used,Double lenght,Double width,Double height,Double rstLen,Double rstWid,Double rstWei,Double rstHei,Long panrentId,Date vaildTime,Short flagRycle,Short flagLogic,Integer status,Integer deleted,Integer tenantId,Long createBy,Date createTime,Long updateBy,Date updateTime,String memo) {
        this.code = code;
        this.name = name;
        this.typeId = typeId;
        this.used = used;
        this.lenght = lenght;
        this.width = width;
        this.height = height;
        this.rstLen = rstLen;
        this.rstWid = rstWid;
        this.rstWei = rstWei;
        this.rstHei = rstHei;
        this.panrentId = panrentId;
        this.vaildTime = vaildTime;
        this.flagRycle = flagRycle;
        this.flagLogic = flagLogic;
        this.status = status;
        this.deleted = deleted;
        this.tenantId = tenantId;
        this.createBy = createBy;
        this.createTime = createTime;
        this.updateBy = updateBy;
        this.updateTime = updateTime;
        this.memo = memo;
    }
//    Container container = new Container(
//            null,    // 编码[非空]
//            null,    // 名称
//            null,    // 容器类型标识
//            null,    // 使用次数[非空]
//            null,    // 长度
//            null,    // 宽度
//            null,    // 高度
//            null,    // 限长
//            null,    // 限宽
//            null,    // 限重
//            null,    // 限高
//            null,    // 父容器标识
//            null,    // 有效期
//            null,    // 是否回收[非空]
//            null,    // 是否虚拟[非空]
//            null,    // 状态[非空]
//            null,    // 是否删除[非空]
//            null,    // 租户
//            null,    // 添加人员
//            null,    // 添加时间[非空]
//            null,    // 修改人员
//            null,    // 修改时间[非空]
//            null    // 备注
//    );
    public String getVaildTime$(){
        if (Cools.isEmpty(this.vaildTime)){
            return "";
        }
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.vaildTime);
    }
    public String getFlagRycle$(){
        if (null == this.flagRycle){ return null; }
        switch (this.flagRycle){
            case 1:
                return "是";
            case  0:
                return "否";
            default:
                return String.valueOf(this.flagRycle);
        }
    }
    public String getFlagLogic$(){
        if (null == this.flagLogic){ return null; }
        switch (this.flagLogic){
            case 1:
                return "是";
            case  0:
                return "否";
            default:
                return String.valueOf(this.flagLogic);
        }
    }
    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/Contract.java
New file
@@ -0,0 +1,194 @@
package com.vincent.rsf.server.manager.entity;
import com.baomidou.mybatisplus.annotation.TableLogic;
import java.text.SimpleDateFormat;
import java.util.Date;
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
@TableName("man_contract")
public class Contract implements Serializable {
    private static final long serialVersionUID = 1L;
    /**
     * ID
     */
    @ApiModelProperty(value= "ID")
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    /**
     * 编码
     */
    @ApiModelProperty(value= "编码")
    private String code;
    /**
     * 名称
     */
    @ApiModelProperty(value= "名称")
    private String name;
    /**
     * 项目名称
     */
    @ApiModelProperty(value= "项目名称")
    private String projectName;
    /**
     * 状态 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 Contract() {}
    public Contract(String code,String name,String projectName,Integer status,Integer deleted,Integer tenantId,Long createBy,Date createTime,Long updateBy,Date updateTime,String memo) {
        this.code = code;
        this.name = name;
        this.projectName = projectName;
        this.status = status;
        this.deleted = deleted;
        this.tenantId = tenantId;
        this.createBy = createBy;
        this.createTime = createTime;
        this.updateBy = updateBy;
        this.updateTime = updateTime;
        this.memo = memo;
    }
//    Contract contract = new Contract(
//            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/Loc.java
New file
@@ -0,0 +1,306 @@
package com.vincent.rsf.server.manager.entity;
import com.baomidou.mybatisplus.annotation.TableLogic;
import java.text.SimpleDateFormat;
import java.util.Date;
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
@TableName("man_loc")
public class Loc implements Serializable {
    private static final long serialVersionUID = 1L;
    /**
     * ID
     */
    @ApiModelProperty(value= "ID")
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    /**
     * 库区标识
     */
    @ApiModelProperty(value= "库区标识")
    private Long areaId;
    /**
     * 编号
     */
    @ApiModelProperty(value= "编号")
    private String code;
    /**
     * 库位类型
     */
    @ApiModelProperty(value= "库位类型")
    private String type;
    /**
     * 名称
     */
    @ApiModelProperty(value= "名称")
    private String name;
    /**
     * 虚拟库位
     */
    @ApiModelProperty(value= "虚拟库位")
    private Short flagLogic;
    /**
     * 功能属性
     */
    @ApiModelProperty(value= "功能属性")
    private String fucAtrrs;
    /**
     * 容器编码
     */
    @ApiModelProperty(value= "容器编码")
    private String barcode;
    /**
     * 存放单位
     */
    @ApiModelProperty(value= "存放单位")
    private String unit;
    /**
     * 长/宽/高
     */
    @ApiModelProperty(value= "长/宽/高")
    private String size;
    /**
     * 排
     */
    @ApiModelProperty(value= "排")
    private Integer row;
    /**
     * 列
     */
    @ApiModelProperty(value= "列")
    private Integer col;
    /**
     * 层
     */
    @ApiModelProperty(value= "层")
    private Integer lev;
    /**
     * 通道
     */
    @ApiModelProperty(value= "通道")
    private Integer channel;
    /**
     * 最大零件数
     */
    @ApiModelProperty(value= "最大零件数")
    private Integer maxParts;
    /**
     * 最大包装数
     */
    @ApiModelProperty(value= "最大包装数")
    private Integer maxPack;
    /**
     * 是否标签管理
     */
    @ApiModelProperty(value= "是否标签管理")
    private Short flagLabelMange;
    /**
     * 属性
     */
    @ApiModelProperty(value= "属性")
    private String locAttrs;
    /**
     * 状态 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 Loc() {}
    public Loc(Long areaId,String code,String type,String name,Short flagLogic,String fucAtrrs,String barcode,String unit,String size,Integer row,Integer col,Integer lev,Integer channel,Integer maxParts,Integer maxPack,Short flagLabelMange,String locAttrs,Integer status,Integer deleted,Integer tenantId,Long createBy,Date createTime,Long updateBy,Date updateTime,String memo) {
        this.areaId = areaId;
        this.code = code;
        this.type = type;
        this.name = name;
        this.flagLogic = flagLogic;
        this.fucAtrrs = fucAtrrs;
        this.barcode = barcode;
        this.unit = unit;
        this.size = size;
        this.row = row;
        this.col = col;
        this.lev = lev;
        this.channel = channel;
        this.maxParts = maxParts;
        this.maxPack = maxPack;
        this.flagLabelMange = flagLabelMange;
        this.locAttrs = locAttrs;
        this.status = status;
        this.deleted = deleted;
        this.tenantId = tenantId;
        this.createBy = createBy;
        this.createTime = createTime;
        this.updateBy = updateBy;
        this.updateTime = updateTime;
        this.memo = memo;
    }
//    Loc loc = new Loc(
//            null,    // 库区标识[非空]
//            null,    // 编号[非空]
//            null,    // 库位类型[非空]
//            null,    // 名称
//            null,    // 虚拟库位
//            null,    // 功能属性
//            null,    // 容器编码
//            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/QlyInspect.java
New file
@@ -0,0 +1,186 @@
package com.vincent.rsf.server.manager.entity;
import com.baomidou.mybatisplus.annotation.TableLogic;
import java.text.SimpleDateFormat;
import java.util.Date;
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
@TableName("man_qly_inspect")
public class QlyInspect implements Serializable {
    private static final long serialVersionUID = 1L;
    /**
     * ID
     */
    @ApiModelProperty(value= "ID")
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    /**
     * 编码
     */
    @ApiModelProperty(value= "编码")
    private String code;
    /**
     * 名称
     */
    @ApiModelProperty(value= "名称")
    private String name;
    /**
     * 状态 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 QlyInspect() {}
    public QlyInspect(String code,String name,Integer status,Integer deleted,Integer tenantId,Long createBy,Date createTime,Long updateBy,Date updateTime,String memo) {
        this.code = code;
        this.name = name;
        this.status = status;
        this.deleted = deleted;
        this.tenantId = tenantId;
        this.createBy = createBy;
        this.createTime = createTime;
        this.updateBy = updateBy;
        this.updateTime = updateTime;
        this.memo = memo;
    }
//    QlyInspect qlyInspect = new QlyInspect(
//            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/Stock.java
New file
@@ -0,0 +1,252 @@
package com.vincent.rsf.server.manager.entity;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.format.annotation.DateTimeFormat;
import com.baomidou.mybatisplus.annotation.TableLogic;
import java.text.SimpleDateFormat;
import java.util.Date;
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
@TableName("man_stock")
public class Stock implements Serializable {
    private static final long serialVersionUID = 1L;
    /**
     * ID
     */
    @ApiModelProperty(value= "ID")
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    /**
     * ASN单据, 带出PO单
     */
    @ApiModelProperty(value= "ASN单据, 带出PO单")
    private String asnOrder;
    /**
     * ERP凭证
     */
    @ApiModelProperty(value= "ERP凭证")
    private String erpToken;
    /**
     * ERP单号
     */
    @ApiModelProperty(value= "ERP单号")
    private String erpOrder;
    /**
     * ERP库存地址
     */
    @ApiModelProperty(value= "ERP库存地址")
    private String erpStkAdr;
    /**
     * 合同标识
     */
    @ApiModelProperty(value= "合同标识")
    private String contractId;
    /**
     * 锁定原因
     */
    @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;
    /**
     * 状态 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 Stock() {}
    public Stock(String asnOrder,String erpToken,String erpOrder,String erpStkAdr,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.asnOrder = asnOrder;
        this.erpToken = erpToken;
        this.erpOrder = erpOrder;
        this.erpStkAdr = erpStkAdr;
        this.contractId = contractId;
        this.lockReason = lockReason;
        this.lockStatus = lockStatus;
        this.locker = locker;
        this.lockedTime = lockedTime;
        this.status = status;
        this.deleted = deleted;
        this.tenantId = tenantId;
        this.createBy = createBy;
        this.createTime = createTime;
        this.updateBy = updateBy;
        this.updateTime = updateTime;
        this.memo = memo;
    }
//    Stock stock = new Stock(
//            null,    // ASN单据, 带出PO单[非空]
//            null,    // ERP凭证
//            null,    // ERP单号
//            null,    // ERP库存地址
//            null,    // 合同标识
//            null,    // 锁定原因
//            null,    // 锁定状态[非空]
//            null,    // 锁定人
//            null,    // 锁定时间
//            null,    // 状态[非空]
//            null,    // 是否删除[非空]
//            null,    // 租户
//            null,    // 添加人员
//            null,    // 添加时间[非空]
//            null,    // 修改人员
//            null,    // 修改时间[非空]
//            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; }
        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/StockItem.java
New file
@@ -0,0 +1,452 @@
package com.vincent.rsf.server.manager.entity;
import java.text.SimpleDateFormat;
import java.util.Date;
import com.vincent.rsf.server.manager.service.*;
import org.springframework.format.annotation.DateTimeFormat;
import com.baomidou.mybatisplus.annotation.TableLogic;
import java.text.SimpleDateFormat;
import java.util.Date;
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
@TableName("man_stock_item")
public class StockItem implements Serializable {
    private static final long serialVersionUID = 1L;
    /**
     * ID
     */
    @ApiModelProperty(value= "ID")
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    /**
     * 库存外键标识
     */
    @ApiModelProperty(value= "库存外键标识")
    private String stockId;
    /**
     * 物料标识
     */
    @ApiModelProperty(value= "物料标识")
    private Long matnrId;
    /**
     * 物料编码
     */
    @ApiModelProperty(value= "物料编码")
    private String code;
    /**
     * 名称
     */
    @ApiModelProperty(value= "名称")
    private String matnrk;
    /**
     * 数量
     */
    @ApiModelProperty(value= "数量")
    private Double anfme;
    /**
     * 执行中数量
     */
    @ApiModelProperty(value= "执行中数量")
    private Double workQty;
    /**
     * 完成数量
     */
    @ApiModelProperty(value= "完成数量")
    private Double qty;
    /**
     * 收货重量
     */
    @ApiModelProperty(value= "收货重量")
    private Double weight;
    /**
     * 单位
     */
    @ApiModelProperty(value= "单位")
    private String unit;
    /**
     * 货主标识
     */
    @ApiModelProperty(value= "货主标识")
    private Long shipperId;
    /**
     * 供应商标识
     */
    @ApiModelProperty(value= "供应商标识")
    private String splrId;
    /**
     * 品牌
     */
    @ApiModelProperty(value= "品牌")
    private String brand;
    /**
     * 批次
     */
    @ApiModelProperty(value= "批次")
    private String batch;
    /**
     * 生产日期
     */
    @ApiModelProperty(value= "生产日期")
    private String prodTime;
    /**
     * 质检标识
     */
    @ApiModelProperty(value= "质检标识")
    private Long inspectId;
    /**
     * 供应商批次
     */
    @ApiModelProperty(value= "供应商批次")
    private String splrBtch;
    /**
     * ASN单据,带出PO单
     */
    @ApiModelProperty(value= "ASN单据,带出PO单")
    private String asnOrder;
    /**
     * ERP凭证
     */
    @ApiModelProperty(value= "ERP凭证")
    private String erpToken;
    /**
     * ERP单号
     */
    @ApiModelProperty(value= "ERP单号")
    private String erpOrder;
    /**
     * ERP库存地址
     */
    @ApiModelProperty(value= "ERP库存地址")
    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= "锁定时间")
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
    private Date lockedTime;
    /**
     * 状态 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 StockItem() {}
    public StockItem(String stockId,Long matnrId,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;
        this.matnrId = matnrId;
        this.code = code;
        this.matnrk = matnrk;
        this.anfme = anfme;
        this.workQty = workQty;
        this.qty = qty;
        this.weight = weight;
        this.unit = unit;
        this.shipperId = shipperId;
        this.splrId = splrId;
        this.brand = brand;
        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.barcode = barcode;
        this.purPrice = purPrice;
        this.lockReason = lockReason;
        this.lockStatus = lockStatus;
        this.locker = locker;
        this.lockedTime = lockedTime;
        this.status = status;
        this.deleted = deleted;
        this.tenantId = tenantId;
        this.createBy = createBy;
        this.createTime = createTime;
        this.updateBy = updateBy;
        this.updateTime = updateTime;
        this.memo = memo;
    }
//    StockItem stockItem = new StockItem(
//            null,    // 库存外键标识[非空]
//            null,    // 物料标识[非空]
//            null,    // 物料编码[非空]
//            null,    // 名称
//            null,    // 数量
//            null,    // 执行中数量
//            null,    // 完成数量
//            null,    // 收货重量
//            null,    // 单位
//            null,    // 货主标识
//            null,    // 供应商标识
//            null,    // 品牌
//            null,    // 批次
//            null,    // 生产日期
//            null,    // 质检标识
//            null,    // 供应商批次
//            null,    // ASN单据,带出PO单[非空]
//            null,    // ERP凭证
//            null,    // ERP单号
//            null,    // ERP库存地址
//            null,    // 库位标识
//            null,    // 容器编码
//            null,    // 采购单位
//            null,    // 锁定原因
//            null,    // 锁定状态[非空]
//            null,    // 锁定人
//            null,    // 锁定时间
//            null,    // 状态[非空]
//            null,    // 是否删除[非空]
//            null,    // 租户
//            null,    // 添加人员
//            null,    // 添加时间[非空]
//            null,    // 修改人员
//            null,    // 修改时间[非空]
//            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);
        Matnr matnr = service.getById(this.matnrId);
        if (!Cools.isEmpty(matnr)){
            return String.valueOf(matnr.getUnit());
        }
        return null;
    }
    public String getShipperId$(){
        ShipperService service = SpringUtils.getBean(ShipperService.class);
        Shipper 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);
//        Supplier supplier = service.getById(this.splrId);
//        if (!Cools.isEmpty(supplier)){
//            return String.valueOf(supplier.getnull());
//        }
//        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.getName());
        }
        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.getName());
        }
        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; }
        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/mapper/ContainerMapper.java
New file
@@ -0,0 +1,12 @@
package com.vincent.rsf.server.manager.mapper;
import com.vincent.rsf.server.manager.entity.Container;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
@Mapper
@Repository
public interface ContainerMapper extends BaseMapper<Container> {
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/mapper/ContractMapper.java
New file
@@ -0,0 +1,12 @@
package com.vincent.rsf.server.manager.mapper;
import com.vincent.rsf.server.manager.entity.Contract;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
@Mapper
@Repository
public interface ContractMapper extends BaseMapper<Contract> {
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/mapper/LocMapper.java
New file
@@ -0,0 +1,12 @@
package com.vincent.rsf.server.manager.mapper;
import com.vincent.rsf.server.manager.entity.Loc;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
@Mapper
@Repository
public interface LocMapper extends BaseMapper<Loc> {
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/mapper/QlyInspectMapper.java
New file
@@ -0,0 +1,12 @@
package com.vincent.rsf.server.manager.mapper;
import com.vincent.rsf.server.manager.entity.QlyInspect;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
@Mapper
@Repository
public interface QlyInspectMapper extends BaseMapper<QlyInspect> {
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/mapper/StockItemMapper.java
New file
@@ -0,0 +1,12 @@
package com.vincent.rsf.server.manager.mapper;
import com.vincent.rsf.server.manager.entity.StockItem;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
@Mapper
@Repository
public interface StockItemMapper extends BaseMapper<StockItem> {
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/mapper/StockMapper.java
New file
@@ -0,0 +1,12 @@
package com.vincent.rsf.server.manager.mapper;
import com.vincent.rsf.server.manager.entity.Stock;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
@Mapper
@Repository
public interface StockMapper extends BaseMapper<Stock> {
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/ContainerService.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.Container;
public interface ContainerService extends IService<Container> {
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/ContractService.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.Contract;
public interface ContractService extends IService<Contract> {
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/LocService.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.Loc;
public interface LocService extends IService<Loc> {
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/QlyInspectService.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.QlyInspect;
public interface QlyInspectService extends IService<QlyInspect> {
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/StockItemService.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.StockItem;
public interface StockItemService extends IService<StockItem> {
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/StockService.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.Stock;
public interface StockService extends IService<Stock> {
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/ContainerServiceImpl.java
New file
@@ -0,0 +1,12 @@
package com.vincent.rsf.server.manager.service.impl;
import com.vincent.rsf.server.manager.mapper.ContainerMapper;
import com.vincent.rsf.server.manager.entity.Container;
import com.vincent.rsf.server.manager.service.ContainerService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
@Service("containerService")
public class ContainerServiceImpl extends ServiceImpl<ContainerMapper, Container> implements ContainerService {
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/ContractServiceImpl.java
New file
@@ -0,0 +1,12 @@
package com.vincent.rsf.server.manager.service.impl;
import com.vincent.rsf.server.manager.mapper.ContractMapper;
import com.vincent.rsf.server.manager.entity.Contract;
import com.vincent.rsf.server.manager.service.ContractService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
@Service("contractService")
public class ContractServiceImpl extends ServiceImpl<ContractMapper, Contract> implements ContractService {
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/LocServiceImpl.java
New file
@@ -0,0 +1,12 @@
package com.vincent.rsf.server.manager.service.impl;
import com.vincent.rsf.server.manager.mapper.LocMapper;
import com.vincent.rsf.server.manager.entity.Loc;
import com.vincent.rsf.server.manager.service.LocService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
@Service("locService")
public class LocServiceImpl extends ServiceImpl<LocMapper, Loc> implements LocService {
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/QlyInspectServiceImpl.java
New file
@@ -0,0 +1,12 @@
package com.vincent.rsf.server.manager.service.impl;
import com.vincent.rsf.server.manager.mapper.QlyInspectMapper;
import com.vincent.rsf.server.manager.entity.QlyInspect;
import com.vincent.rsf.server.manager.service.QlyInspectService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
@Service("qlyInspectService")
public class QlyInspectServiceImpl extends ServiceImpl<QlyInspectMapper, QlyInspect> implements QlyInspectService {
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/StockItemServiceImpl.java
New file
@@ -0,0 +1,12 @@
package com.vincent.rsf.server.manager.service.impl;
import com.vincent.rsf.server.manager.mapper.StockItemMapper;
import com.vincent.rsf.server.manager.entity.StockItem;
import com.vincent.rsf.server.manager.service.StockItemService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
@Service("stockItemService")
public class StockItemServiceImpl extends ServiceImpl<StockItemMapper, StockItem> implements StockItemService {
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/StockServiceImpl.java
New file
@@ -0,0 +1,12 @@
package com.vincent.rsf.server.manager.service.impl;
import com.vincent.rsf.server.manager.mapper.StockMapper;
import com.vincent.rsf.server.manager.entity.Stock;
import com.vincent.rsf.server.manager.service.StockService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
@Service("stockService")
public class StockServiceImpl extends ServiceImpl<StockMapper, Stock> implements StockService {
}
rsf-server/src/main/java/container.sql
New file
@@ -0,0 +1,36 @@
-- save container record
-- mysql
insert into `sys_menu` ( `name`, `parent_id`, `route`, `component`, `type`, `sort`, `tenant_id`, `status`) values ( 'menu.container', '0', '/manager/container', 'container', '0' , '0', '1' , '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Query 库位信息表', '83', '1', 'manager:container:list', '0', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Create 库位信息表', '83', '1', 'manager:container:save', '1', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Update 库位信息表', '83', '1', 'manager:container:update', '2', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Delete 库位信息表', '83', '1', 'manager:container:remove', '3', '1', '1');
-- locale menu name
container: 'Container',
-- locale field
container: {
    code: "code",
    name: "name",
    typeId: "typeId",
    used: "used",
    lenght: "lenght",
    width: "width",
    height: "height",
    rstLen: "rstLen",
    rstWid: "rstWid",
    rstWei: "rstWei",
    rstHei: "rstHei",
    panrentId: "panrentId",
    vaildTime: "vaildTime",
    flagRycle: "flagRycle",
    flagLogic: "flagLogic",
},
-- ResourceContent
import container from './container';
case 'container':
    return container;
rsf-server/src/main/java/contract.sql
New file
@@ -0,0 +1,24 @@
-- save contract record
-- mysql
insert into `sys_menu` ( `name`, `parent_id`, `route`, `component`, `type`, `sort`, `tenant_id`, `status`) values ( 'menu.contract', '0', '/manager/contract', 'contract', '0' , '0', '1' , '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Query 合同信息', '88', '1', 'manager:contract:list', '0', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Create 合同信息', '88', '1', 'manager:contract:save', '1', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Update 合同信息', '88', '1', 'manager:contract:update', '2', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Delete 合同信息', '88', '1', 'manager:contract:remove', '3', '1', '1');
-- locale menu name
contract: 'Contract',
-- locale field
contract: {
    code: "code",
    name: "name",
    projectName: "projectName",
},
-- ResourceContent
import contract from './contract';
case 'contract':
    return contract;
rsf-server/src/main/java/loc.sql
New file
@@ -0,0 +1,38 @@
-- save loc record
-- mysql
insert into `sys_menu` ( `name`, `parent_id`, `route`, `component`, `type`, `sort`, `tenant_id`, `status`) values ( 'menu.loc', '0', '/manager/loc', 'loc', '0' , '0', '1' , '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Query 库位信息表', '78', '1', 'manager:loc:list', '0', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Create 库位信息表', '78', '1', 'manager:loc:save', '1', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Update 库位信息表', '78', '1', 'manager:loc:update', '2', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Delete 库位信息表', '78', '1', 'manager:loc:remove', '3', '1', '1');
-- locale menu name
loc: 'Loc',
-- locale field
loc: {
    areaId: "areaId",
    code: "code",
    type: "type",
    name: "name",
    flagLogic: "flagLogic",
    fucAtrrs: "fucAtrrs",
    barcode: "barcode",
    unit: "unit",
    size: "size",
    row: "row",
    col: "col",
    lev: "lev",
    channel: "channel",
    maxParts: "maxParts",
    maxPack: "maxPack",
    flagLabelMange: "flagLabelMange",
    locAttrs: "locAttrs",
},
-- ResourceContent
import loc from './loc';
case 'loc':
    return loc;
rsf-server/src/main/java/qlyInspect.sql
New file
@@ -0,0 +1,23 @@
-- save qlyInspect record
-- mysql
insert into `sys_menu` ( `name`, `parent_id`, `route`, `component`, `type`, `sort`, `tenant_id`, `status`) values ( 'menu.qlyInspect', '0', '/manager/qlyInspect', 'qlyInspect', '0' , '0', '1' , '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Query 质检信息', '103', '1', 'manager:qlyInspect:list', '0', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Create 质检信息', '103', '1', 'manager:qlyInspect:save', '1', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Update 质检信息', '103', '1', 'manager:qlyInspect:update', '2', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Delete 质检信息', '103', '1', 'manager:qlyInspect:remove', '3', '1', '1');
-- locale menu name
qlyInspect: 'QlyInspect',
-- locale field
qlyInspect: {
    code: "code",
    name: "name",
},
-- ResourceContent
import qlyInspect from './qlyInspect';
case 'qlyInspect':
    return qlyInspect;
rsf-server/src/main/java/stock.sql
New file
@@ -0,0 +1,30 @@
-- save stock record
-- mysql
insert into `sys_menu` ( `name`, `parent_id`, `route`, `component`, `type`, `sort`, `tenant_id`, `status`) values ( 'menu.stock', '0', '/manager/stock', 'stock', '0' , '0', '1' , '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Query 合同信息', '93', '1', 'manager:stock:list', '0', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Create 合同信息', '93', '1', 'manager:stock:save', '1', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Update 合同信息', '93', '1', 'manager:stock:update', '2', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Delete 合同信息', '93', '1', 'manager:stock:remove', '3', '1', '1');
-- locale menu name
stock: 'Stock',
-- locale field
stock: {
    asnOrder: "asnOrder",
    erpToken: "erpToken",
    erpOrder: "erpOrder",
    erpStkAdr: "erpStkAdr",
    contractId: "contractId",
    lockReason: "lockReason",
    lockStatus: "lockStatus",
    locker: "locker",
    lockedTime: "lockedTime",
},
-- ResourceContent
import stock from './stock';
case 'stock':
    return stock;
rsf-server/src/main/java/stockItem.sql
New file
@@ -0,0 +1,48 @@
-- save stockItem record
-- mysql
insert into `sys_menu` ( `name`, `parent_id`, `route`, `component`, `type`, `sort`, `tenant_id`, `status`) values ( 'menu.stockItem', '0', '/manager/stockItem', 'stockItem', '0' , '0', '1' , '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Query 库存明细表', '98', '1', 'manager:stockItem:list', '0', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Create 库存明细表', '98', '1', 'manager:stockItem:save', '1', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Update 库存明细表', '98', '1', 'manager:stockItem:update', '2', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Delete 库存明细表', '98', '1', 'manager:stockItem:remove', '3', '1', '1');
-- locale menu name
stockItem: 'StockItem',
-- locale field
stockItem: {
    stockId: "stockId",
    matnrId: "matnrId",
    code: "code",
    matnrk: "matnrk",
    anfme: "anfme",
    workQty: "workQty",
    qty: "qty",
    weight: "weight",
    unit: "unit",
    shipperId: "shipperId",
    splrId: "splrId",
    brand: "brand",
    batch: "batch",
    prodTime: "prodTime",
    inspectId: "inspectId",
    splrBtch: "splrBtch",
    asnOrder: "asnOrder",
    erpToken: "erpToken",
    erpOrder: "erpOrder",
    erpStkAdr: "erpStkAdr",
    locId: "locId",
    barcode: "barcode",
    purPrice: "purPrice",
    lockReason: "lockReason",
    lockStatus: "lockStatus",
    locker: "locker",
    lockedTime: "lockedTime",
},
-- ResourceContent
import stockItem from './stockItem';
case 'stockItem':
    return stockItem;
rsf-server/src/main/resources/mapper/manager/ContainerMapper.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.ContainerMapper">
</mapper>
rsf-server/src/main/resources/mapper/manager/ContractMapper.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.ContractMapper">
</mapper>
rsf-server/src/main/resources/mapper/manager/LocMapper.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.LocMapper">
</mapper>
rsf-server/src/main/resources/mapper/manager/QlyInspectMapper.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.QlyInspectMapper">
</mapper>
rsf-server/src/main/resources/mapper/manager/StockItemMapper.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.StockItemMapper">
</mapper>
rsf-server/src/main/resources/mapper/manager/StockMapper.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.StockMapper">
</mapper>