skyouc
3 天以前 c73bfe563e19aee0fcf2465a0982bb307cc4c249
no message
8个文件已修改
14个文件已添加
2891 ■■■■■ 已修改文件
rsf-admin/src/i18n/en.js 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/i18n/zh.js 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/ResourceContent.js 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/check/CheckOrderCreate.jsx 221 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/check/CheckOrderEdit.jsx 138 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/check/CheckOrderItemCreate.jsx 200 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/check/CheckOrderItemList.jsx 185 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/check/CheckOrderList.jsx 313 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/check/OutOrderModal.jsx 279 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/check/OutOrderPreview.jsx 141 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/check/OutStockPublic.jsx 480 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/check/SelectMatnrModal.jsx 585 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/check/index.jsx 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/warehouseAreas/WarehouseAreasList.jsx 127 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/CheckOrderController.java 125 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/enums/OrderType.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/mapper/CheckOrderMapper.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/schedules/TaskSchedules.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/CheckOrderService.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/CheckOrderServiceImpl.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/system/constant/SerialRuleCode.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/resources/application-dev.yml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/i18n/en.js
@@ -606,6 +606,21 @@
                ntyStatus: "Notify",
                exceStatus: 'bill status'
            },
            checkOrder: {
                code: "Check Code",
                poCode: "Po Code",
                poId: "Po Id",
                type: "Type",
                wkType: "Work Type",
                anfme: "Anfme",
                workQty: 'Work Qty',
                qty: "Qty",
                logisNo: "Logis No",
                arrTime: "arrived Time",
                rleStatus: "释放状态",
                ntyStatus: "上报状态",
                exceStatus: '单据状态'
            },
            outStockItem: {
                asnId: "ID",
                asnCode: "Out Code",
rsf-admin/src/i18n/zh.js
@@ -213,7 +213,7 @@
        checkOutBound: '盘点出库',
        stockTransfer: '库位转移',
        waveRule: '波次策略',
        checkOrder: '盘点单',
    },
    table: {
        field: {
@@ -631,6 +631,21 @@
                ntyStatus: "上报状态",
                exceStatus: '单据状态'
            },
            checkOrder: {
                code: "盘点单号",
                poCode: "DO单号",
                poId: "DO标识",
                type: "类型",
                wkType: "业务类型",
                anfme: "数量",
                workQty: '执行数',
                qty: "完成数",
                logisNo: "物流单号",
                arrTime: "预计到达时间",
                rleStatus: "释放状态",
                ntyStatus: "上报状态",
                exceStatus: '单据状态'
            },
            asnOrderItem: {
                asnId: "主单标识",
                asnCode: "单号",
rsf-admin/src/page/ResourceContent.js
@@ -53,6 +53,7 @@
import checkOutBound from "./work/checkOutBound";
import stockTransfer from "./work/stockTransfer";
import waveRule from './waveRule';
import check from './orders/check';
const ResourceContent = (node) => {
    switch (node.component) {
@@ -154,6 +155,8 @@
            return stockTransfer;
        case 'waveRule':
            return waveRule;
        case 'check':
            return check;
        default:
            return {
                list: ListGuesser,
rsf-admin/src/page/orders/check/CheckOrderCreate.jsx
New file
@@ -0,0 +1,221 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import {
    CreateBase,
    useTranslate,
    TextInput,
    NumberInput,
    BooleanInput,
    TextField,
    WrapperField,
    NumberField,
    DateInput,
    TopToolbar,
    SelectColumnsButton,
    DatagridConfigurable,
    SaveButton,
    SelectInput,
    ReferenceInput,
    ReferenceArrayInput,
    AutocompleteInput,
    Toolbar,
    required,
    useDataProvider,
    useNotify,
    Form,
    useCreateController,
    useGetList,
    useList,
    ListContextProvider,
    useListContext,
    Button,
    useRecordContext,
} from 'react-admin';
import {
    Dialog,
    DialogActions,
    DialogContent,
    DialogTitle,
    Stack,
    Grid,
    Box,
} from '@mui/material';
import DialogCloseButton from "../../components/DialogCloseButton";
import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting';
import { styled } from '@mui/material/styles';
import StatusSelectInput from "../../components/StatusSelectInput";
import OutOrderItemList from "./OutOrderItemList";
import MemoInput from "../../components/MemoInput";
import AddIcon from '@mui/icons-material/Add';
import SelectMatnrModal from "./SelectMatnrModal";
const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({
    '& .css-1vooibu-MuiSvgIcon-root': {
        height: '.9em'
    },
    '& .RaDatagrid-row': {
        cursor: 'auto'
    },
    '& .column-name': {
    },
    '& .opt': {
        width: 200
    },
}));
const OutOrderCreate = (props) => {
    const { open, setOpen, record } = props;
    const dicts = JSON.parse(localStorage.getItem('sys_dicts'))?.filter(dict => (dict.dictTypeCode == 'sys_order_type')) || [];
    const business = JSON.parse(localStorage.getItem('sys_dicts'))?.filter(dict => (dict.dictTypeCode == 'sys_business_type')) || [];
    const translate = useTranslate();
    const notify = useNotify();
    const [drawerVal, setDrawerVal] = useState(false);
    const [matCreate, setMatCreate] = useState(false);
    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 } });
    };
    const { data, total, isPending, error, refetch, meta } = useGetList('/wave/locs/preview', { filter: { waveId: record?.id } });
    const listContext = useList({ data, isPending });
    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="xl"   // 'xs' | 'sm' | 'md' | 'lg' | 'xl'
                >
                    <Form
                        resource="outStock"
                    >
                        <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>
                                    <Grid item xs={12} display="flex" gap={1}>
                                        <TextInput
                                            label="table.field.asnOrder.poCode"
                                            source="poCode"
                                            parse={v => v}
                                        />
                                        <NumberInput
                                            label="table.field.asnOrder.poId"
                                            source="poId"
                                        />
                                        {/* <AutocompleteInput
                                        choices={dicts}
                                        optionText="label"
                                        label="table.field.asnOrder.type"
                                        source="type"
                                        optionValue="value"
                                        validate={required()}
                                        parse={v => v}
                                    /> */}
                                        <AutocompleteInput
                                            choices={business}
                                            optionText="label"
                                            label="table.field.asnOrder.wkType"
                                            source="wkType"
                                            optionValue="value"
                                            validate={required()}
                                            parse={v => v}
                                        />
                                        <NumberInput
                                            label="table.field.asnOrder.anfme"
                                            source="anfme"
                                            validate={required()}
                                        />
                                    </Grid>
                                    <Grid item xs={12} display="flex" gap={1}>
                                        <NumberInput
                                            label="table.field.asnOrder.qty"
                                            source="qty"
                                        />
                                        <TextInput
                                            label="table.field.asnOrder.logisNo"
                                            source="logisNo"
                                            parse={v => v}
                                        />
                                        <DateInput
                                            label="table.field.asnOrder.arrTime"
                                            source="arrTime"
                                        />
                                        <SelectInput
                                            label="table.field.asnOrder.rleStatus"
                                            source="rleStatus"
                                            choices={[
                                                { id: 0, name: ' 正常' },
                                                { id: 1, name: ' 已释放' },
                                            ]}
                                        />
                                    </Grid>
                                </Grid>
                                <SelectMatnrModal open={matCreate} setOpen={setMatCreate} />
                                <DialogActions sx={{ position: 'sticky', bottom: 0, backgroundColor: 'background.paper', zIndex: 1000 }}>
                                    <Toolbar sx={{ width: '100%', justifyContent: 'end' }}  >
                                        <AddOutOrderButton setMatCreate={setMatCreate} />
                                        <SaveButton />
                                    </Toolbar>
                                </DialogActions>
                                <Box>
                                </Box>
                            </>
                        </DialogContent>
                    </Form>
                </Dialog>
            </CreateBase>
        </>
    )
}
export default OutOrderCreate;
const AddOutOrderButton = (setMatCreate) => {
    const record = useRecordContext();
    const addMats = (event) => {
        event.stopPropagation();
        setMatCreate(true)
    }
    return (
        <Button label={"common.action.newAddMats"} onClick={addMats} variant="contained" sx={{ padding: '0.6em', marginRight: '1em' }}>
            <AddIcon />
        </Button>
    );
}
rsf-admin/src/page/orders/check/CheckOrderEdit.jsx
New file
@@ -0,0 +1,138 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import {
    Edit,
    SimpleForm,
    useTranslate,
    TextInput,
    DateInput,
    SelectInput,
    AutocompleteInput,
    SaveButton,
    Toolbar,
    required,
    DeleteButton,
} from 'react-admin';
import { Stack, Grid, Box, Typography } from '@mui/material';
import { EDIT_MODE, REFERENCE_INPUT_PAGESIZE } from '@/config/setting';
import EditBaseAside from "../../components/EditBaseAside";
import CustomerTopToolBar from "../../components/EditTopToolBar";
import CheckOrderItemList from "./CheckOrderItemList";
const CheckOrderEdit = () => {
    const translate = useTranslate();
    const dicts = JSON.parse(localStorage.getItem('sys_dicts'))?.filter(dict => (dict.dictTypeCode == 'sys_order_type')) || [];
    const business = JSON.parse(localStorage.getItem('sys_dicts'))?.filter(dict => (dict.dictTypeCode == 'sys_business_type')) || [];
    return (
        <>
            <Edit
                redirect="list"
                mutationMode={EDIT_MODE}
                actions={<CustomerTopToolBar />}
                aside={<EditBaseAside />}
            >
                <SimpleForm
                    shouldUnregister
                    warnWhenUnsavedChanges
                    toolbar={false}
                    mode="onTouched"
                    defaultValues={{}}
                >
                    <Grid container width={{ xs: '100%', xl: '100%' }} rowSpacing={3} columnSpacing={3}
                        sx={{
                            "& .MuiFormLabel-root.MuiInputLabel-root.Mui-disabled": {
                                bgcolor: 'white',
                                WebkitTextFillColor: "rgba(0, 0, 0)"
                            },
                            "& .MuiInputBase-input.MuiFilledInput-input.Mui-disabled": {
                                bgcolor: 'white',
                                WebkitTextFillColor: "rgba(0, 0, 0)"
                            },
                            "& .MuiFilledInput-root.MuiInputBase-sizeSmall": {
                                bgcolor: 'white',
                            }
                        }}
                    >
                        <Grid item xs={24} md={12} >
                            <Typography variant="h6" gutterBottom>
                                {translate('common.edit.title.main')}
                            </Typography>
                            <Stack direction='row' gap={2}>
                                <TextInput
                                    label="table.field.outStock.code"
                                    source="code"
                                    readOnly
                                    parse={v => v}
                                />
                                <TextInput
                                    label="table.field.outStock.poCode"
                                    source="poCode"
                                    readOnly
                                    parse={v => v}
                                />
                                <AutocompleteInput
                                    choices={dicts}
                                    optionText="label"
                                    label="table.field.outStock.type"
                                    source="type"
                                    optionValue="value"
                                    parse={v => v}
                                    readOnly
                                />
                                <AutocompleteInput
                                    choices={business}
                                    optionText="label"
                                    label="table.field.outStock.wkType"
                                    source="wkType"
                                    optionValue="value"
                                    parse={v => v}
                                    readOnly
                                />
                            </Stack>
                            <Stack direction='row' gap={2}>
                                <TextInput
                                    label="table.field.outStock.logisNo"
                                    source="logisNo"
                                    readOnly
                                    parse={v => v}
                                />
                                <TextInput
                                    label="table.field.outStock.anfme"
                                    source="anfme"
                                    readOnly
                                    parse={v => v}
                                />
                                <TextInput
                                    label="table.field.outStock.qty"
                                    source="qty"
                                    readOnly
                                    parse={v => v}
                                />
                                <DateInput
                                    label="table.field.outStock.arrTime"
                                    source="arrTime"
                                    readOnly
                                />
                                <SelectInput
                                    label="table.field.outStock.rleStatus"
                                    source="rleStatus"
                                    readOnly
                                    choices={[
                                        { id: 0, name: ' 正常' },
                                        { id: 1, name: ' 已释放' },
                                    ]}
                                    validate={required()}
                                />
                            </Stack>
                        </Grid>
                    </Grid>
                </SimpleForm>
            </Edit >
            <CheckOrderItemList />
        </>
    )
}
export default CheckOrderEdit;
rsf-admin/src/page/orders/check/CheckOrderItemCreate.jsx
New file
@@ -0,0 +1,200 @@
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 CheckOrderItemCreate = (props) => {
    const { open, setOpen, record } = 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
                resource="outStockItem"
                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>
                                <Grid item xs={6} display="flex" gap={2}>
                                    <NumberInput
                                        label="table.field.outStockItem.asnId"
                                        source="asnId"
                                        readOnly
                                        hidden
                                        defaultValue={record?.id}
                                    />
                                    <TextInput
                                        label="table.field.outStockItem.asnCode"
                                        source="asnCode"
                                        readOnly
                                        defaultValue={record?.code}
                                        parse={v => v}
                                    />
                                    <TextInput
                                        label="table.field.outStockItem.poDetlId"
                                        source="poDetlId"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.outStockItem.matnrId"
                                        source="matnrId"
                                        parse={v => v}
                                    />
                                    <TextInput
                                        label="table.field.outStockItem.maktx"
                                        source="maktx"
                                        parse={v => v}
                                    />
                                    <NumberInput
                                        label="table.field.outStockItem.anfme"
                                        source="anfme"
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.outStockItem.stockUnit"
                                        source="stockUnit"
                                        parse={v => v}
                                    />
                                    <NumberInput
                                        label="table.field.outStockItem.purQty"
                                        source="purQty"
                                        validate={required()}
                                    />
                                    <TextInput
                                        label="table.field.outStockItem.purUnit"
                                        source="purUnit"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.outStockItem.qty"
                                        source="qty"
                                    />
                                    <TextInput
                                        label="table.field.outStockItem.splrCode"
                                        source="splrCode"
                                        parse={v => v}
                                    />
                                    <TextInput
                                        label="table.field.outStockItem.splrName"
                                        source="splrName"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.outStockItem.qrcode"
                                        source="qrcode"
                                        parse={v => v}
                                    />
                                    <TextInput
                                        label="table.field.outStockItem.barcode"
                                        source="barcode"
                                        parse={v => v}
                                    />
                                    <TextInput
                                        label="table.field.outStockItem.packName"
                                        source="packName"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={4} display="flex" gap={1}>
                                    <StatusSelectInput />
                                </Grid>
                                <Grid item xs={4} display="flex" gap={1}>
                                    <Stack direction="column" spacing={1}>
                                        <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 CheckOrderItemCreate;
rsf-admin/src/page/orders/check/CheckOrderItemList.jsx
New file
@@ -0,0 +1,185 @@
import React, { useState, useRef, useEffect, useMemo, useCallback } from "react";
import { useNavigate, useLocation } 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,
  Button,
  useEditContext,
  useGetRecordId,
  useGetOne
} from 'react-admin';
import { Box, Typography, Card, Stack, Dialog, DialogActions, DialogTitle } from '@mui/material';
import { styled } from '@mui/material/styles';
import PageDrawer from "../../components/PageDrawer";
import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE, DEFAULT_ITEM_PAGE_SIZE } from '@/config/setting';
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 />,
  <NumberInput source="asnId" label="table.field.outStockItem.asnId" />,
  <TextInput source="asnCode" label="table.field.outStockItem.asnCode" alwaysOn />,
  <TextInput source="poDetlId" label="table.field.outStockItem.poDetlId" />,
  <TextInput source="matnrId" label="table.field.outStockItem.matnrId" />,
  <TextInput source="maktx" label="table.field.outStockItem.maktx" alwaysOn />,
  <TextInput source="matnrCode" label="table.field.outStockItem.matnrCode" alwaysOn />,
  <NumberInput source="anfme" label="table.field.outStockItem.anfme" />,
  <TextInput source="stockUnit" label="table.field.outStockItem.stockUnit" />,
  <NumberInput source="purQty" label="table.field.outStockItem.purQty" />,
  <TextInput source="purUnit" label="table.field.outStockItem.purUnit" />,
  <NumberInput source="qty" label="table.field.outStockItem.qty" />,
  <TextInput source="splrCode" label="table.field.outStockItem.splrCode" />,
  <TextInput source="splrName" label="table.field.outStockItem.splrName" />,
  <TextInput source="qrcode" label="table.field.outStockItem.qrcode" />,
  <TextInput source="trackCode" label="table.field.outStockItem.barcode" />,
  <TextInput source="packName" label="table.field.outStockItem.packName" />,
  <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 OutOrderItemList = () => {
  const translate = useTranslate();
  const [createDialog, setCreateDialog] = useState(false);
  const [editDialog, setEditDialog] = useState(false);
  const [drawerVal, setDrawerVal] = useState(false);
  const [select, setSelect] = useState({});
  const asnId = useGetRecordId();
  const { data: dicts, isPending, error } = useGetOne('outStock', { id: asnId });
  return (
    <>
      <Box display="flex">
        <List
          resource="outStockItem"
          storeKey='outStockItem'
          sx={{
            flexGrow: 1,
            transition: (theme) =>
              theme.transitions.create(['all'], {
                duration: theme.transitions.duration.enteringScreen,
              }),
            marginRight: drawerVal ? `${PAGE_DRAWER_WIDTH}px` : 0,
          }}
          title={"menu.outStockItem"}
          empty={false}
          filter={{ asnId: asnId, deleted: 0 }}
          filters={filters}
          sort={{ field: "create_time", order: "desc" }}
          actions={(
            <TopToolbar>
              <FilterButton />
              <SelectColumnsButton preferenceKey='outStockItem' />
            </TopToolbar>
          )}
          perPage={DEFAULT_ITEM_PAGE_SIZE}
        >
          <StyledDatagrid
            preferenceKey='outStockItem'
            bulkActionButtons={false}
            rowClick={false}
            omit={['id', 'createTime', 'createBy', 'memo', 'poDetlId', 'purQty', 'purUnit', 'trackCode', 'packName', 'qrcode', 'splrName', 'matnrId', 'asnId']}
          >
            <NumberField source="id" />
            <NumberField source="asnId" label="table.field.outStockItem.asnId" />
            <TextField source="asnCode" label="table.field.outStockItem.asnCode" />
            <TextField source="poCode" label="table.field.outStockItem.poCode" />
            <TextField source="poDetlId" label="table.field.outStockItem.poDetlId" />
            <TextField source="matnrId" label="table.field.outStockItem.matnrId" />
            <TextField source="matnrCode" label="table.field.outStockItem.matnrCode" />
            <TextField source="maktx" label="table.field.outStockItem.maktx" />
            <TextField source="platOrderCode" label="table.field.outStockItem.platOrderCode" />
            <NumberField source="anfme" label="table.field.outStockItem.anfme" />
            <NumberField source="purQty" label="table.field.outStockItem.purQty" />
            <NumberField source="workQty" label="table.field.outStockItem.workQty" />
            <NumberField source="qty" label="table.field.outStockItem.qty" />
            <TextField source="stockUnit" label="table.field.outStockItem.stockUnit" />
            <TextField source="splrBatch" label="table.field.outStockItem.splrBatch" />
            <TextField source="purUnit" label="table.field.outStockItem.purUnit" />
            <TextField source="splrCode" label="table.field.outStockItem.splrCode" />
            <TextField source="splrName" label="table.field.outStockItem.splrName" />
            <TextField source="qrcode" label="table.field.outStockItem.qrcode" />
            <TextField source="trackCode" label="table.field.outStockItem.barcode" />
            <TextField source="packName" label="table.field.outStockItem.packName" />
            <DateField source="updateTime" label="common.field.updateTime" showTime />
            <ReferenceField source="updateBy" label="common.field.updateBy" reference="user" link={false} sortable={false}>
              <TextField source="nickname" />
            </ReferenceField>,
            <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 />
            <TextField source="memo" label="common.field.memo" sortable={false} />
          </StyledDatagrid>
        </List>
        {/* <OutOrderItemCreate
          open={createDialog}
          setOpen={setCreateDialog}
          record={dicts}
        />
        <OutOrderItemEdit
          open={editDialog}
          setOpen={setEditDialog}
          record={select}
        /> */}
        <PageDrawer
          title='OutStockItem Detail'
          drawerVal={drawerVal}
          setDrawerVal={setDrawerVal}
        >
        </PageDrawer>
      </Box>
    </>
  )
}
OutOrderItemList.Context = React.createContext()
export default OutOrderItemList;
rsf-admin/src/page/orders/check/CheckOrderList.jsx
New file
@@ -0,0 +1,313 @@
import React, { useState, useRef, useEffect, useMemo, useCallback } from "react";
import { useLocation, useNavigate } from 'react-router-dom';
import {
  List,
  DatagridConfigurable,
  SearchInput,
  TopToolbar,
  Toolbar,
  SelectColumnsButton,
  EditButton,
  FilterButton,
  CreateButton,
  ExportButton,
  BulkDeleteButton,
  useDataProvider,
  WrapperField,
  useRecordContext,
  useTranslate,
  useNotify,
  useRefresh,
  useListContext,
  FunctionField,
  TextField,
  NumberField,
  DateField,
  BooleanField,
  ReferenceField,
  TextInput,
  DateTimeInput,
  DateInput,
  SelectInput,
  NumberInput,
  ReferenceInput,
  ReferenceArrayInput,
  AutocompleteInput,
  DeleteButton,
  Button,
  useRedirect,
  useUnselectAll,
  useRecordSelection,
} from 'react-admin';
import { styled } from '@mui/material/styles';
import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting';
import CancelOutlinedIcon from '@mui/icons-material/CancelOutlined';
import { Box, Typography, Card, Stack, Drawer } from '@mui/material';
import DictionarySelect from "../../components/DictionarySelect";
import BillStatusField from '../../components/BillStatusField';
import MyCreateButton from "../../components/MyCreateButton";
import ConfirmButton from '../../components/ConfirmButton';
import ImportButton from "../../components/ImportButton";
import DetailsIcon from '@mui/icons-material/Details';
import AddTaskIcon from '@mui/icons-material/AddTask';
import PublicIcon from '@mui/icons-material/Public';
import EditIcon from '@mui/icons-material/Edit';
import AddIcon from '@mui/icons-material/Add';
import request from '@/utils/request';
const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({
  '& .css-1vooibu-MuiSvgIcon-root': {
    height: '.9em'
  },
  '& .RaDatagrid-row': {
    cursor: 'auto'
  },
  '& .column-name': {
  },
  '& .opt': {
    width: 220
  },
  '& .wkType': {
    width: 110
  },
  '& .status': {
    width: 90
  },
}));
const filters = [
  <SearchInput source="condition" alwaysOn />,
  <TextInput source="code" label="table.field.outStock.code" alwaysOn />,
  <TextInput source="poCode" label="table.field.outStock.poCode" />,
  <NumberInput source="poId" label="table.field.outStock.poId" />,
  <ReferenceInput source="type" reference="dictData" filter={{ dictTypeCode: 'sys_order_type', group: '2' }} label="table.field.outStock.type" alwaysOn>
    <AutocompleteInput label="table.field.outStock.type" optionValue="value" />
  </ReferenceInput>,
  <ReferenceInput source="wkType" reference="dictData" filter={{ dictTypeCode: 'sys_business_type', group: '2' }} label="table.field.outStock.wkType" alwaysOn>
    <AutocompleteInput label="table.field.outStock.wkType" optionValue="value" />
  </ReferenceInput>,
  <NumberInput source="anfme" label="table.field.outStock.anfme" />,
  <NumberInput source="qty" label="table.field.outStock.qty" />,
  <TextInput source="logisNo" label="table.field.outStock.logisNo" />,
  <DateInput source="arrTime" label="table.field.outStock.arrTime" />,
  <SelectInput source="rleStatus" label="table.field.outStock.rleStatus"
    choices={[
      { id: 0, name: ' 正常' },
      { id: 1, name: ' 已释放' },
    ]}
  />,
  <TextInput label="common.field.memo" source="memo" />,
  <DictionarySelect
    label='table.field.outStock.exceStatus'
    name="exceStatus"
    dictTypeCode="sys_asn_exce_status"
    alwaysOn
  />,
]
const CheckOrderList = (props) => {
  const translate = useTranslate();
  const refresh = useRefresh();
  const notify = useNotify();
  const [createDialog, setCreateDialog] = useState(false);
  const [manualDialog, setManualDialog] = useState(false);
  const [selectIds, setSelectIds] = useState([]);
  const [preview, setPreview] = useState(false);
  const [waveRule, setWaveRule] = useState(false);
  const [drawerVal, setDrawerVal] = useState(false);
  const [modalType, setmodalType] = useState(0);
  const [select, setSelect] = useState(0);
  const billReload = useRef();
  const dicts = JSON.parse(localStorage.getItem('sys_dicts'))?.filter(dict => (dict.dictTypeCode == 'sys_business_type')) || [];
  //获取波次规则
  // const closeDialog = async (value) => {
  //   setWaveRule(false)
  //   const res = await request.post(`/outStock/generate/wave`, { ids: selectIds, waveRuleId: value.id });
  //   if (res?.data?.code === 200) {
  //     notify(res.data.msg);
  //   } else {
  //     notify(res.data.msg);
  //   }
  //   refresh()
  // }
  return (
    <Box display="flex">
      <List
        resource="check"
        sx={{
          flexGrow: 1,
          transition: (theme) =>
            theme.transitions.create(['all'], {
              duration: theme.transitions.duration.enteringScreen,
            }),
        }}
        title={"menu.checkOrder"}
        empty={false}
        filters={filters}
        filter={{ deleted: 0, type: 'check' }}
        sort={{ field: "create_time", order: "desc" }}
        actions={(
          <TopToolbar>
            <FilterButton />
            <CreateByOrderButton setCreateDialog={setCreateDialog} />
            <MyCreateButton onClick={() => { setManualDialog(true); setmodalType(0) }} />
            <SelectColumnsButton preferenceKey='check' />
            <ImportButton value={'outStockItem'} />
          </TopToolbar>
        )}
        perPage={DEFAULT_PAGE_SIZE}
      >
        <StyledDatagrid
          preferenceKey='check'
          bulkActionButtons={<PublicTaskButton setWaveRule={setWaveRule} setSelectIds={setSelectIds} />}
          rowClick={false}
          expandSingle={true}
          omit={['id', 'createTime', 'createBy', 'memo', 'rleStatus$']}
        >
          <NumberField source="id" />
          <TextField source="code" label="table.field.checkOrder.code" />
          <TextField source="poCode" label="table.field.checkOrder.poCode" />
          <TextField source="type$" label="table.field.checkOrder.type" />
          <TextField cellClassName="wkType" source="wkType$" label="table.field.checkOrder.wkType" />
          <NumberField source="anfme" label="table.field.checkOrder.anfme" />
          <NumberField source="workQty" label="table.field.checkOrder.workQty" />
          <NumberField source="qty" label="table.field.checkOrder.qty" />
          <TextField source="logisNo" label="table.field.checkOrder.logisNo" />
          <TextField source="rleStatus$" label="table.field.checkOrder.rleStatus" sortable={false} />
          <TextField source="updateBy$" label="common.field.updateBy" />
          <DateField source="updateTime" label="common.field.updateTime" showTime />
          <TextField source="createBy$" label="common.field.createBy" />
          <DateField source="createTime" label="common.field.createTime" showTime />
          <BillStatusField cellClassName="status" source="exceStatus" label="table.field.checkOrder.exceStatus" />
          <TextField source="memo" label="common.field.memo" sortable={false} />
          <WrapperField cellClassName="opt" label="common.field.opt" >
            <MyButton setCreateDialog={setManualDialog} setmodalType={setmodalType} />
            <EditButton label="toolbar.detail" icon={(<DetailsIcon />)}></EditButton>
            <CancelButton />
            <PublicButton setDrawerVal={setDrawerVal} drawerVal={drawerVal} setSelect={setSelect} />
          </WrapperField>
        </StyledDatagrid>
      </List>
      {/* <OutOrderCreate
        open={manualDialog}
        setOpen={setManualDialog}
      /> */}
      {/* <SelectMatnrModal
        asnId={modalType}
        billReload={billReload}
        open={manualDialog}
        setOpen={setManualDialog}
      />
      <OutOrderModal
        open={createDialog}
        setOpen={setCreateDialog}
        preview={preview}
        setPreview={setPreview}
      />
      <OutStockWaveDialog open={waveRule} setOpen={setWaveRule} onClose={closeDialog} />
      <OutOrderPreview open={preview} setOpen={setPreview} />
      <PageEditDrawer
        title={"toolbar.publicWorking"}
        drawerVal={drawerVal}
        setDrawerVal={setDrawerVal}
      >
        <OutStockPublic record={select} open={drawerVal} setOpen={setDrawerVal}  />
      </PageEditDrawer> */}
    </Box >
  )
}
export default CheckOrderList;
const PublicTaskButton = ({ setWaveRule, setSelectIds }) => {
  const record = useRecordContext();
  const { selectedIds, onUnselectItems } = useListContext();
  const notify = useNotify();
  const redirect = useRedirect();
  const pubClick = async () => {
    onUnselectItems();
    setWaveRule(true);
    setSelectIds(selectedIds)
  }
  return (
    <Button
      onClick={pubClick}
      label={"toolbar.createWave"}
      startIcon={<PublicIcon />}
    />
  );
}
const MyButton = ({ setCreateDialog, setmodalType }) => {
  const record = useRecordContext();
  const handleEditClick = (btn) => {
    btn.stopPropagation();
    const id = record.id;
    setmodalType(id);
    setCreateDialog(true);
  };
  return (
    <Button
      color="primary"
      startIcon={<EditIcon />}
      onClick={(btn) => handleEditClick(btn)}
      sx={{ ml: 1 }}
      label={'ra.action.edit'}
    >
    </Button>
  )
}
const CreateByOrderButton = ({ setCreateDialog }) => {
  const record = useRecordContext();
  const notify = useNotify();
  const refresh = useRefresh();
  const createByOrder = async (event) => {
    event.stopPropagation();
    setCreateDialog(true);
  }
  return (
    <Button onClick={createByOrder} label={'toolbar.asnCreate'}> <AddIcon /> </Button>
  )
}
const CancelButton = () => {
  const record = useRecordContext();
  const notify = useNotify();
  const refresh = useRefresh();
  const cancelOrder = async () => {
    const { data: { code, data, msg } } = await request.get(`/outStock/cancel/${record?.id}`);
    if (code === 200) {
      notify(msg);
      refresh()
    } else {
      notify(msg);
    }
  }
  return (
    record?.exceStatus == 10 ? <ConfirmButton label={"toolbar.cancel"} startIcon={<CancelOutlinedIcon />} onConfirm={cancelOrder} size={"small"} /> : <></>
  )
}
//下发执行
const PublicButton = ({ setDrawerVal, setSelect }) => {
  const record = useRecordContext();
  const refresh = useRefresh();
  const taskEvent = () => {
    setDrawerVal(true)
    setSelect(record)
    refresh();
  }
  return (
    record.workQty < record.anfme ? <Button label={"toolbar.publicWorking"} startIcon={<AddTaskIcon />} onClick={taskEvent} size={"small"} /> : <></>
  )
}
rsf-admin/src/page/orders/check/OutOrderModal.jsx
New file
@@ -0,0 +1,279 @@
import { Dialog, DialogActions, DialogContent, DialogTitle, Box, LinearProgress } from "@mui/material";
import React, { useState, useRef, useEffect, useMemo } from "react";
import {
    List,
    DatagridConfigurable,
    SearchInput,
    TopToolbar,
    Toolbar,
    Button,
    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,
    SimpleForm,
    Form,
    SaveButton,
    useRefresh,
    useGetList,
} from 'react-admin';
import DialogCloseButton from "../../components/DialogCloseButton";
import { styled } from '@mui/material/styles';
import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting';
import { Grid, margin, Stack, width } from "@mui/system";
import request from '@/utils/request';
import SaveIcon from '@mui/icons-material/Save';
import CheckCircleIcon from '@mui/icons-material/CheckCircle';
import EditableTextField from "../../components/EditableTextField";
import OutOrderPreview from "./OutOrderPreview";
const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({
    '& .css-1vooibu-MuiSvgIcon-root': {
        height: '.9em'
    },
    '& .RaDatagrid-row': {
        cursor: 'auto'
    },
    '& .status': {
        width: 90
    },
}));
const StyledForm = styled(Form)(({ theme }) => ({
    width: '100%',
    marginBottom: '45px',
    '& .MuiGrid-root': {
        margin: '0 10px'
    }
}));
const filters = [
    <SearchInput source="condition" alwaysOn />,
    <DateInput label='common.time.after' source="timeStart" />,
    <DateInput label='common.time.before' source="timeEnd" />,
    <TextInput source="code" label="table.field.delivery.code" />,
    <TextInput source="platId" label="table.field.delivery.platId" />,
    <TextInput source="type" label="table.field.delivery.type" />,
    <TextInput source="wkType" label="table.field.delivery.wkType" />,
    <TextInput source="source" label="table.field.delivery.source" />,
    <SelectInput
        label="common.field.status"
        source="status"
        choices={[
            { id: '1', name: 'common.enums.statusTrue' },
            { id: '0', name: 'common.enums.statusFalse' },
        ]}
        resettable
    />,
]
const OutOrderModal = (props) => {
    const { open, setOpen, preview, setPreview, record } = props;
    const translate = useTranslate();
    const [params, setParams] = useState({});
    const [select, setSelect] = useState([]);
    const [drawerVal, setDrawerVal] = useState(false);
    const refresh = useRefresh();
    const handleClose = (event, reason) => {
        if (reason !== "backdropClick") {
            setOpen(false);
        }
    };
    const CustomFilter = () => {
        const { filterValues, setFilters, refetch } = useListContext();
        const [formValues, setFormValues] = useState(filterValues);
        const handleChange = (event) => {
            if (event.target == undefined || event.target == null) { return }
            setFormValues(formValues => ({
                ...formValues,
                [event.target.name]: event.target.value,
            }));
        };
        const handleSubmit = (event) => {
            setParams(formValues)
        };
        return (
            <StyledForm>
                <Grid container rowSpacing={3} columnSpacing={3} >
                    <Stack>
                        <TextInput
                            source="condition"
                            label="common.action.search"
                            resettable
                            defaultValue={params?.condition}
                            onChange={handleChange} />
                    </Stack>
                    <Stack>
                        <TextInput
                            source="deliveryCode"
                            label="table.field.deliveryItem.deliveryCode"
                            defaultValue={params?.deliveryCode}
                            onChange={handleChange}
                            resettable
                        />
                    </Stack>
                    <Stack>
                        <TextInput
                            source="maktx"
                            label="table.field.deliveryItem.matnrName"
                            defaultValue={params?.maktx}
                            onChange={handleChange}
                            resettable
                        />
                    </Stack>
                    <Stack>
                        <TextInput
                            source="matnrCode"
                            label="table.field.deliveryItem.matnrCode"
                            defaultValue={params?.matnrCode}
                            resettable
                            onChange={handleChange} />
                    </Stack>
                    <Stack>
                        <TextInput
                            source="splrName"
                            label="table.field.deliveryItem.splrName"
                            defaultValue={params?.splrName}
                            resettable
                            onChange={handleChange} />
                    </Stack>
                </Grid>
                <DialogActions>
                    <Toolbar sx={{ width: '100%', justifyContent: 'end' }}  >
                        <SaveButton onClick={handleSubmit} label={"toolbar.query"} />
                    </Toolbar>
                </DialogActions>
            </StyledForm>
        );
    };
    return (
        <Dialog
            open={open}
            onClose={handleClose}
            aria-labelledby="form-dialog-title"
            aria-hidden
            fullWidth
            disableRestoreFocus
            maxWidth="xl"
        >
            <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>
            <Grid container rowSpacing={2} columnSpacing={2}>
                <DialogContent>
                    <Grid item sx={24}>
                        <List
                            resource="/deliveryItem/filters"
                            sx={{
                                flexGrow: 1,
                                transition: (theme) =>
                                    theme.transitions.create(['all'], {
                                        duration: theme.transitions.duration.enteringScreen,
                                    }),
                                marginRight: drawerVal ? `${PAGE_DRAWER_WIDTH}px` : 0,
                            }}
                            filters={<CustomFilter />}
                            queryOptions={{ meta: { ...params } }}
                            empty={false}
                            sort={{ field: "create_time", order: "desc" }}
                            actions={(
                                <TopToolbar>
                                    <></>
                                </TopToolbar>
                            )}
                            perPage={DEFAULT_PAGE_SIZE}
                        >
                            <Box sx={{ position: 'relative', minHeight: "60vh", }}>
                                <LinearProgress
                                    sx={{ height: "2px", position: 'absolute', top: 0, left: 0, right: 0, }}
                                />
                                <StyledDatagrid
                                    preferenceKey='deliveryItem'
                                    bulkActionButtons={<AddOutStockButton setOpen={setOpen} setPreview={setPreview} setSelect={setSelect} />}
                                    rowClick={(id, resource, record) => false}
                                    expand={false}
                                    expandSingle={true}
                                    omit={['id', 'createTime', 'createBy', 'memo', 'startTime', 'endTime', 'updateBy', 'createTime']}
                                >
                                    <NumberField source="id" />
                                    <TextField source="deliveryCode" label="table.field.deliveryItem.deliveryCode" />
                                    <TextField source="matnrCode" label="table.field.deliveryItem.matnrCode" />
                                    <TextField source="maktx" label="table.field.deliveryItem.matnrName" />
                                    <TextField source="unit" label="table.field.deliveryItem.unit" />
                                    <NumberField source="anfme" label="table.field.deliveryItem.anfme" />
                                    <NumberField source="workQty" label="table.field.outStockItem.workQty" />
                                    <TextField source="splrName" label="table.field.deliveryItem.splrName" />
                                    <TextField source="splrBatch" label="table.field.deliveryItem.splrBatch" />
                                    <TextField source="updateBy$" label="common.field.updateBy" />
                                    <DateField source="updateTime" label="common.field.updateTime" showTime />
                                    <TextField source="createBy$" label="common.field.createBy" />
                                    <DateField source="createTime" label="common.field.createTime" showTime />
                                    <BooleanField source="statusBool" label="common.field.status" sortable={false} />
                                    <TextField source="memo" label="common.field.memo" sortable={false} />
                                </StyledDatagrid>
                            </Box>
                        </List>
                    </Grid>
                </DialogContent>
            </Grid>
            <Grid>
                <OutOrderPreview open={preview} setOpen={setPreview} selectedIds={select} setCloseParent={setOpen} />
            </Grid>
        </Dialog >
    )
}
export default OutOrderModal;
const AddOutStockButton = (props) => {
    const { setOpen, setPreview, setSelect } = props;
    const { selectedIds, onUnselectItems } = useListContext();
    const notify = useNotify();
    const refresh = useRefresh();
    const confirm = async (event) => {
        setPreview(true)
        setSelect(selectedIds);
        onUnselectItems();
        // refresh();
    }
    return (
        <Button label={"toolbar.confirmSelect"} onClick={confirm}>
            <CheckCircleIcon />
        </Button>
    )
}
rsf-admin/src/page/orders/check/OutOrderPreview.jsx
New file
@@ -0,0 +1,141 @@
import { Dialog, DialogActions, DialogContent, DialogTitle, Box, LinearProgress, Grid, } from "@mui/material";
import React, { useState, useRef, useEffect, useMemo, memo } from "react";
import {
    Toolbar,
    Button,
    useTranslate,
    useNotify,
    useRefresh,
    useGetList,
} from 'react-admin';
import request from '@/utils/request';
import { styled } from '@mui/material/styles';
import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting';
import { DataGrid, useGridApiContext, GridActionsCellItem, useGridApiRef } from '@mui/x-data-grid';
import DialogCloseButton from "../../components/DialogCloseButton";
const OutOrderPreview = (props) => {
    const { open, setOpen, record, selectedIds, setCloseParent } = props;
    const translate = useTranslate();
    const gridRef = useGridApiRef();
    const [rows, setRows] = useState([]);
    const notify = useNotify();
    const refresh = useRefresh();
    const handleClose = async (event, reason) => {
        if (reason !== "backdropClick") {
            // const res = await request.get(`/outStock/items/cancel/` + selectedIds);
            setOpen(false);
            setCloseParent(false)
        }
    };
    if (!selectedIds) { return }
    const { data, isLoading, error } = useGetList('/deliveryItem/edit', {
        pagination: { page: 1, perPage: 1000 },
        filter: { deleted: 0, ids: selectedIds }
    });
    return (
        <Dialog
            open={open}
            onClose={handleClose}
            aria-labelledby="form-dialog-title"
            aria-hidden
            fullWidth
            maxWidth="lg"
        >
            <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>
                <Grid container xl={12}>
                    <Grid item xl={12}>
                        <Box display="flex" sx={{ height: 400, width: '100%', '& .RaConfigurable-root': { width: '100%' } }}>
                            <LinearProgress sx={{ height: "2px", position: 'absolute', top: 0, left: 0, right: 0, }} />
                            <OrderPreview rows={data} gridRef={gridRef} />
                        </Box >
                    </Grid>
                </Grid>
                <Toolbar sx={{ justifyContent: 'end' }}>
                    <ConfirmButton label="toolbar.confirm" variant="contained" size="large" gridRef={gridRef} setOpen={setOpen} setCloseParent={setCloseParent}/>
                </Toolbar>
            </DialogContent>
        </Dialog>
    )
}
export default OutOrderPreview;
const ConfirmButton = ({ gridRef, setOpen, setCloseParent }) => {
    const refresh = useRefresh();
    const notify = useNotify();
    const confirm = async () => {
        const items = gridRef.current?.getSortedRows();
        const { data: { code, msg } } = await request.post(`/outStock/generate/orders`, { ids: items });
        if (code === 200) {
            notify(msg);
            refresh()
            setOpen(false)
            setCloseParent(false)
        } else {
            notify(msg);
        }
    }
    return (
        <Button label="toolbar.confirm" variant="contained" size="large" onClick={confirm} />
    )
}
const OrderPreview = ({ rows, gridRef }) => {
    gridRef.current = useGridApiRef();
    const columns = [
        { field: 'matnrCode', headerName: '物料编码', width: 110 },
        { field: 'maktx', headerName: '物料名称', width: 190 },
        {
            field: 'anfme', headerName: '出库数量', width: 110, type: 'number', editable: true,
            valueGetter: (value, row) => {
                return row.anfme - row.workQty - row.qty;
            },
        },
        {
            field: 'workQty', headerName: '剩余数量', width: 110, type: 'number',
            valueGetter: (value, row) => {
                return row.anfme - row.workQty - row.qty;
            },
        },
        { field: 'unit', headerName: '单位', width: 110 },
        { field: 'splrBatch', headerName: '批次', width: 110 },
        { field: 'splrName', headerName: '供应商', width: 110 },
        { field: 'updateTime', headerName: '更新时间', width: 110 },
        { field: 'updateBy$', headerName: '更新人员', width: 110 },
    ]
    return (
        <DataGrid
            storeKey={"outOrderItemPreview"}
            rows={rows}
            columns={columns}
            apiRef={gridRef}
            disableRowSelectionOnClick
            hideFooterPagination={true}  // 隐藏分页控件
            hideFooter={true}
            onRowSelectionModelChange={(ids) => {
                setSelectedIds(ids)
            }}
        />
    )
}
rsf-admin/src/page/orders/check/OutStockPublic.jsx
New file
@@ -0,0 +1,480 @@
import { Box, Card, Grid, LinearProgress, Select, MenuItem, ListItemText } from "@mui/material";
import React, { useState, useRef, useEffect, useMemo } from "react";
import {
    List,
    DatagridConfigurable,
    SearchInput,
    TopToolbar,
    Button,
    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,
    SimpleForm,
    required,
    Form,
    useRefresh,
    useRedirect,
} from 'react-admin';
import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE, DEFAULT_ITEM_PAGE_SIZE, DEFAULT_TYPE } from '@/config/setting';
import { styled } from '@mui/material/styles';
import { DataGrid, useGridApiContext, GridActionsCellItem, useGridApiRef } from '@mui/x-data-grid';
import request from '@/utils/request';
import ConfirmationNumberOutlinedIcon from '@mui/icons-material/ConfirmationNumberOutlined';
import CloseSharpIcon from '@mui/icons-material/CloseSharp';
import ConfirmButton from '../../components/ConfirmButton';
import { Delete, Edit, Add } from '@mui/icons-material';
import OutStockSiteDialog from "./OutStockSiteDialog";
const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({
    '& .css-1vooibu-MuiSvgIcon-root': {
        height: '.9em'
    },
    '& .RaDatagrid-row': {
        cursor: 'auto'
    },
    '& .column-maktx': {
        width: 200
    },
    mt: '60px'
    // '& .RaBulkActionsToolbar-toolbar': {
    //     display: 'none'
    // }
}));
const OutStockPublic = (props) => {
    const { record, open, setOpen, setManualDialog } = props;
    const notify = useNotify();
    const gridRef = useGridApiRef();
    const [rows, setRows] = useState([]);
    const [fetchRows, setFetchRows] = useState([]);
    const translate = useTranslate();
    const [rowSelectedIds, setRowSelectedIds] = useState([]);
    const [selectedMatnr, setSelectedMatnr] = useState([]);
    const [selectedIds, setSelectedIds] = useState([]);
    const [formData, setFormData] = useState({ orderId: record?.id, waveId: DEFAULT_TYPE });
    const [dialog, setDialog] = useState(false);
    const [selectedValue, setSelectedValue] = useState({});
    useEffect(() => {
        if (selectedMatnr.length < 1) {
            setRows(fetchRows)
        } else {
            const mas = fetchRows.filter(item => selectedMatnr.includes(item.matnrCode));
            setRows(mas)
        }
    }, [selectedMatnr])
    const ComfirmButton = () => {
        const { selectedIds, data } = useListContext();
        const handleRowClick = () => {
            const ids = data.filter(item => selectedIds.includes(item.id)).map(item => item.id);
            setRowSelectedIds(ids);
            const mas = data.filter(item => selectedIds.includes(item.id)).map(item => item.matnrCode);
            //设置库位信息筛选条件
            setSelectedMatnr(mas);
        }
        return (
            <Button label="toolbar.confirm" size="medium" onClick={handleRowClick} />
        )
    };
    const handleClickOpen = () => {
        setDialog(true);
    };
    const handleClose = (value) => {
        setDialog(false);
        setSelectedValue(value);
        if (selectedIds.length == 0) {
            const newRows = rows.map(item => {
                return {
                    ...item,
                    siteNo: value?.site
                }
            })
            setRows(newRows);
        } else {
            const newRows = rows.map(item => {
                return selectedIds.includes(item?.id) ? {
                    ...item,
                    siteNo: value?.site
                } : item
            })
            setRows(newRows);
        }
    };
    useEffect(() => {
        getWaveRule()
    }, [open])
    const getWaveRule = async () => {
        if (formData.waveId == null && formData.waveId == undefined) {
            return
        }
        const { data: { code, data, msg } } = await request.post('/outStock/order/getOutTaskItems', { ...formData });
        if (code === 200) {
            // setRows(data)
            setFetchRows(data)
        } else {
            notify(msg);
        }
    }
    const handleChange = (value, name) => {
        setFormData((prevData) => ({
            ...prevData,
            [name]: value
        }));
    };
    return (
        <>
            <Box>
                <Grid sx={{ display: "flex" }} container rowSpacing={2} columnSpacing={2}>
                    <Grid item xl={5.7} gap={2} >
                        <Card>
                            <Form>
                                <ReferenceInput
                                    source="type"
                                    reference="waveRule"
                                >
                                    <AutocompleteInput
                                        label="table.field.waveRule.type"
                                        onChange={(e) => handleChange(e, 'waveId')}
                                        defaultValue={15}
                                        value={formData.type}
                                        validate={required()}
                                    />
                                </ReferenceInput>
                            </Form>
                            <List
                                resource="outStockItem"
                                storeKey='outStockItem'
                                sx={{
                                    flexGrow: 1,
                                    transition: (theme) =>
                                        theme.transitions.create(['all'], {
                                            duration: theme.transitions.duration.enteringScreen,
                                        }),
                                }}
                                title={"menu.outStockItem"}
                                empty={false}
                                filter={{ asnId: record?.id, deleted: 0 }}
                                sort={{ field: "create_time", order: "desc" }}
                                actions={false}
                                pagination={false}
                                perPage={DEFAULT_ITEM_PAGE_SIZE}
                            >
                                <LinearProgress
                                    sx={{ height: "2px", position: 'absolute', top: 0, left: 0, right: 0, }}
                                />
                                <StyledDatagrid
                                    storeKey={"outStockPublic"}
                                    preferenceKey='outStockItem'
                                    bulkActionButtons={<>
                                        <ComfirmButton />
                                    </>}
                                    omit={['id', 'splrName', 'qty', 'poCode',]}
                                >
                                    <NumberField source="id" />
                                    <TextField source="asnCode" label="table.field.outStockItem.asnCode" />
                                    <TextField source="poCode" label="table.field.outStockItem.poCode" />
                                    <TextField source="matnrCode" label="table.field.outStockItem.matnrCode" />
                                    <TextField source="maktx" label="table.field.outStockItem.maktx" />
                                    <NumberField source="anfme" label="table.field.outStockItem.anfme" />
                                    <NumberField source="workQty" label="table.field.outStockItem.workQty" />
                                    <NumberField source="qty" label="table.field.outStockItem.qty" />
                                    <TextField source="stockUnit" label="table.field.outStockItem.stockUnit" />
                                    <TextField source="splrName" label="table.field.outStockItem.splrName" />
                                </StyledDatagrid>
                            </List>
                        </Card>
                    </Grid>
                    <Grid item xl={6.3} gap={2}>
                        <Card sx={{ minHeight: 1050, height: 'calc(100% - 10px)', width: '100%' }}>
                            <Box>
                                <PreviewTable
                                    rows={rows}
                                    gridRef={gridRef}
                                    setRows={setRows}
                                    record={record}
                                    formData={formData}
                                    selectedIds={selectedIds}
                                    setDialog={setDialog}
                                    setSelectedIds={setSelectedIds}
                                />
                            </Box>
                            <Box sx={{ textAlign: 'center' }}>
                                <CloseButton setOpen={setOpen} />
                                <SubmitButton selectedIds={selectedIds} setSelectedIds={setSelectedIds} gridRef={gridRef} record={record} />
                            </Box>
                        </Card>
                    </Grid>
                </Grid>
                <Grid>
                    <OutStockSiteDialog
                        selectedValue={selectedValue}
                        open={dialog}
                        onClose={handleClose}
                    />
                </Grid>
            </Box>
        </>
    );
}
const PreviewTable = ({ rows, gridRef, setRows, record, selectedIds, setSelectedIds, setDialog, formData }) => {
    gridRef.current = useGridApiRef();
    const translate = useTranslate();
    useEffect(() => {
        if (selectedIds.length > 0) {
            console.log(selectedIds);
        }
    }, [selectedIds])
    const baseColumns = [
        // { field: 'id', headerName: 'ID', width: 40 },
        { field: 'locCode', headerName: '库位', width: 110 },
        { field: 'barcode', headerName: '容器', width: 120 },
        { field: 'matnrCode', headerName: '物料编码', width: 120 },
        { field: 'batch', headerName: '批次', width: 90 },
        { field: 'unit', headerName: '单位', width: 60 },
        { field: 'outQty', headerName: '出库数量', width: 110, },
        {
            field: 'anfme', headerName: '库存数量', width: 110,
            renderCell: (params) => (
                <OutStockAnfme value={params.value} />
            )
        },
        {
            field: 'siteNo',
            headerName: '出库口',
            width: 90,
            type: 'singleSelect',
            editable: true,
            renderCell: (params) => (
                <OutStockSiteNo value={params.value} />
            ),
            renderEditCell: (params) => (
                <OutStockSite {...params} />
            ),
        },
    ]
    const optAction = {
        field: 'actions',
        type: 'actions',
        headerName: translate('common.field.opt'),
        with: 120,
        getActions: (params) => [
            <GridActionsCellItem
                icon={<Delete />}
                label="Delete"
                onClick={() => handleDelete(params.row, rows, setRows)}
            />,
        ]
    }
    const columns = (formData.waveId == 15 || formData.waveId == 16) ? [...baseColumns] : [...baseColumns, optAction];
    /**
     * 删除事件
     * @param {*} params
     */
    const handleDelete = (params, rows, setRows) => {
        const outRows = rows.filter(row => {
            return row.id !== params.id
        })
        setRows(outRows)
    }
    const OutStockAnfme = React.memo(function OutStockAnfme(props) {
        const { value } = props;
        return (
            value > 0 ?
                <Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
                    <span>{value}</span>
                </Box>
                :
                <Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
                    <span style={{ color: 'red' }}>{translate('common.edit.title.insuffInventory')}</span>
                </Box>
        );
    });
    const OutStockSiteNo = React.memo(function OutStockSiteNo(props) {
        const { value } = props;
        if (!value) {
            return null;
        }
        return (
            <Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
                <span>{value}</span>
            </Box>
        );
    });
    const CustomToolBar = () => {
        const selectSiteNo = () => {
            setDialog(true)
        }
        return (
            <Box sx={{
                p: 1,
                display: 'flex',
                justifyContent: 'flex-end',
                borderTop: '1px solid rgba(224, 224, 224, 1)'
            }}>
                <Button
                    onClick={selectSiteNo}
                    variant="outlined"
                    label="toolbar.modiftySite"
                    size="medium"
                    sx={{ mr: 1 }} />
            </Box>
        );
    }
    const OutStockSite = (params) => {
        const { id, field, siteNo, row: { staNos } } = params;
        const apiRef = useGridApiContext();
        const handleChange = async (event) => {
            await apiRef.current.setEditCellValue(
                { id, field, value: event.target.value },
                event,
            );
            apiRef.current.stopCellEditMode({ id, field });
        };
        const handleClose = (event, reason) => {
            if (reason === 'backdropClick') {
                apiRef.current.stopCellEditMode({ id, field });
            }
        };
        return (
            <Select
                value={siteNo}
                onChange={handleChange}
                MenuProps={{
                    onClose: handleClose,
                }}
                sx={{
                    height: '100%',
                    '& .MuiSelect-select': {
                        display: 'flex',
                        alignItems: 'center',
                        pl: 1,
                    },
                }}
                autoFocus
                fullWidth
                open
            >
                {staNos.map((option) => {
                    return (
                        <MenuItem
                            key={option}
                            value={option.staNo}
                        >
                            <ListItemText sx={{ overflow: 'hidden' }} primary={option.staNo} />
                        </MenuItem>
                    );
                })}
            </Select >
        )
    }
    return (
        <DataGrid
            storeKey={"locItemPreview"}
            rows={rows}
            columns={columns}
            slots={{ toolbar: CustomToolBar }}
            apiRef={gridRef}
            checkboxSelection
            disableRowSelectionOnClick
            hideFooterPagination={true}  // 隐藏分页控件
            hideFooter={false}
            onRowSelectionModelChange={(ids) => {
                setSelectedIds(ids)
            }}
        />
    )
}
//提交按钮
const SubmitButton = ({ selectedIds, setSelectedIds, gridRef, record }) => {
    const notify = useNotify();
    const refresh = useRefresh();
    const redirect = useRedirect();
    const submit = async () => {
        const items = gridRef.current?.getSortedRows();
        const { data: { code, data, msg } } = await request.post('/outStock/generate/tasks', { items, outId: record?.id });
        if (code == 200) {
            refresh();
            redirect("/task")
        } else {
            notify(msg);
        }
    }
    return (
        <ConfirmButton
            label="toolbar.allComfirm"
            variant="contained"
            size="medium"
            onConfirm={submit}
        />
    )
}
//关闭按钮
const CloseButton = ({ setOpen }) => {
    const close = () => {
        setOpen(false)
    }
    return (
        <Button
            label="toolbar.close"
            variant="outlined"
            size="medium"
            onClick={close}
            startIcon={<CloseSharpIcon />}
            sx={{ margin: '3.5em' }} />
    )
}
export default OutStockPublic;
rsf-admin/src/page/orders/check/SelectMatnrModal.jsx
New file
@@ -0,0 +1,585 @@
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,
    useListContext,
    useRefresh,
} from 'react-admin';
import {
    Dialog,
    DialogActions,
    DialogContent,
    DialogTitle,
    Stack,
    Grid,
    TextField,
    Box,
    Button,
    Paper,
    TableContainer,
    Table,
    TableHead,
    TableBody,
    TableRow,
    TableCell,
    Tooltip,
    IconButton,
    styled,
    Select,
    MenuItem
} from '@mui/material';
import DialogCloseButton from "../../components/DialogCloseButton";
import StatusSelectInput from "../../components/StatusSelectInput";
import ConfirmButton from "../../components/ConfirmButton";
import MatnrInfoModal from "./MatnrInfoModal";
import { useForm, Controller, useWatch, FormProvider, useFormContext } from "react-hook-form";
import SaveIcon from '@mui/icons-material/Save';
import request from '@/utils/request';
import { Add, Edit, Delete } from '@mui/icons-material';
import _, { set } from 'lodash';
import { DataGrid, useGridApiRef } from '@mui/x-data-grid';
import DictionarySelect from "../../components/DictionarySelect";
import DictSelect from "../../components/DictSelect";
import "./asnOrder.css";
const SelectMatnrModal = (props) => {
    const { open, setOpen, asnId, billReload } = props;
    const translate = useTranslate();
    const notify = useNotify();
    const refresh = useRefresh();
    const [disabled, setDisabled] = useState(false)
    const [createDialog, setCreateDialog] = useState(false);
    const tableRef = useRef();
    useEffect(() => {
        if (open && asnId !== 0) {
            requestGetHead()
            requestGetBody()
        }
        setDisabled(false)
    }, [open])
    const handleClose = (event, reason) => {
        if (reason !== "backdropClick") {
            setOpen(false);
            refresh();
            setFormData({ type: '', wkType: '' })
            setTableData([])
        }
    };
    const [formData, setFormData] = useState({
        type: '',
        wkType: '',
        poCode: '',
        logisNo: '',
        arrTime: ''
    });
    const [tabelData, setTableData] = useState([]);
    const handleChange = (value, name) => {
        setFormData((prevData) => ({
            ...prevData,
            [name]: value
        }));
    };
    const resetData = () => {
        setFormData({
            type: '',
            wkType: '',
            poCode: '',
            logisNo: '',
            arrTime: ''
        })
        setTableData([])
    }
    const setFinally = () => {
        const rows = tableRef.current.state.editRows;
        for (const key in rows) {
            const find = tabelData.find(item => item.matnrId === +key);
            find.anfme = rows[key].anfme.value;
        }
        setTableData([...tabelData]);
    }
    const handleSubmit = async () => {
        setFinally()
        setDisabled(true)
        if (asnId === 0) {
            const parmas = {
                "orders": formData,
                "items": tabelData,
            }
            const res = await request.post(`/outStock/items/save`, parmas);
            if (res?.data?.code === 200) {
                setOpen(false);
                refresh();
                resetData()
            } else {
                notify(res.data.msg);
            }
        } else {
            const parmas = {
                "orders": formData,
                "items": tabelData,
            }
            const res = await request.post(`/outStock/items/update`, parmas);
            if (res?.data?.code === 200) {
                setOpen(false);
                refresh();
                resetData()
            } else {
                notify(res.data.msg);
            }
        }
        setDisabled(false)
    };
    const handleDelete = async () => {
        const res = await request.post(`/outStock/remove/${asnId}`);
        if (res?.data?.code === 200) {
            setOpen(false);
            refresh();
        } else {
            notify(res.data.msg);
        }
    };
    const requestGetHead = async () => {
        const res = await request.get(`/outStock/${asnId}`);
        if (res?.data?.code === 200) {
            setFormData(res.data.data)
        } else {
            notify(res.data.msg);
        }
    }
    const requestGetBody = async () => {
        const res = await request.post(`/outStockItem/page`, { asnId });
        if (res?.data?.code === 200) {
            setTableData(res.data.data.records)
        } else {
            notify(res.data.msg);
        }
    }
    const [selectedRows, setSelectedRows] = useState([]);
    const handleDeleteItem = () => {
        const newTableData = _.filter(tabelData, (item) => !selectedRows.includes(item.matnrId));
        setTableData(newTableData);
    }
    return (
        <>
            <Dialog
                open={open}
                onClose={handleClose}
                aria-labelledby="form-dialog-title"
                aria-hidden
                fullWidth
                disableRestoreFocus
                maxWidth="lg"   // 'xs' | 'sm' | 'md' | 'lg' | 'xl'
            >
                <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 }}>
                    <Box sx={{ display: 'flex', flexDirection: 'column', gap: 3 }}>
                        <Form defaultValues={formData}>
                            <Grid container spacing={2}>
                                {/* <Grid item md={2}>
                                    <DictSelect
                                        label={translate("table.field.asnOrder.type")}
                                        value={formData.type}
                                        onChange={(e) => handleChange(e.target.value, 'type')}
                                        dictTypeCode="sys_order_type"
                                        required
                                    />
                                </Grid> */}
                                <Grid item md={2}>
                                    <DictSelect
                                        label={translate("table.field.outStock.wkType")}
                                        value={formData.wkType}
                                        variant="filled"
                                        group='2'
                                        onChange={(e) => handleChange(e.target.value, 'wkType')}
                                        dictTypeCode="sys_business_type"
                                        required
                                    />
                                </Grid>
                                <Grid item md={2}>
                                    <TextField
                                        label={translate("table.field.outStock.poCode")}
                                        value={formData.poCode}
                                        variant="filled"
                                        size='small'
                                        onChange={(e) => handleChange(e.target.value, 'poCode')}
                                    />
                                </Grid>
                                <Grid item md={2}>
                                    <TextField
                                        label={translate("table.field.outStock.logisNo")}
                                        value={formData.logisNo}
                                        variant="filled"
                                        size='small'
                                        onChange={(e) => handleChange(e.target.value, 'logisNo')}
                                    />
                                </Grid>
                                <Grid item md={2}>
                                    <DateInput
                                        source="arrTime"
                                        label="table.field.outStock.arrTime"
                                        size='small'
                                        variant="filled"
                                        value={formData.arrTime}
                                        onChange={(e) => handleChange(e.target.value, 'arrTime')}
                                    />
                                </Grid>
                            </Grid>
                        </Form>
                    </Box>
                    <Box sx={{ mt: 2 }}>
                        <Stack direction="row" spacing={2}>
                            <Button variant="contained" onClick={() => setCreateDialog(true)}>新增物料</Button>
                            {/* {asnId !== '' && <ConfirmButton label={'删除'} variant="outlined" color="error" onConfirm={handleDelete} />} */}
                            <ConfirmButton label={'删除'} variant="outlined" color="error" onConfirm={handleDeleteItem} />
                        </Stack>
                    </Box>
                    <Box sx={{ mt: 2 }}>
                        <AsnOrderModalTable tabelData={tabelData} setTableData={setTableData} asnId={asnId} selectedRows={selectedRows} setSelectedRows={setSelectedRows} tableRef={tableRef}></AsnOrderModalTable>
                    </Box>
                </DialogContent>
                <DialogActions sx={{ position: 'sticky', bottom: 0, backgroundColor: 'background.paper', zIndex: 1000 }}>
                    <Toolbar sx={{ width: '100%', justifyContent: 'space-between' }}  >
                        <Button disabled={disabled} onClick={handleSubmit} variant="contained" startIcon={<SaveIcon />}>
                            {translate('toolbar.confirm')}
                        </Button>
                    </Toolbar>
                </DialogActions>
            </Dialog>
            <MatnrInfoModal
                open={createDialog}
                setOpen={setCreateDialog}
                data={tabelData}
                setData={setTableData}
            />
        </>
    )
}
export default SelectMatnrModal;
const SelectInputSplrNameEditCell = (params) => {
    const [formData, setFormData] = useState([{}])
    useEffect(() => {
        getOptions();
    }, []);
    const getOptions = async () => {
        const parmas = {
            "type": "supplier"
        }
        const {
            data: { code, data, msg },
        } = await request.post("companys/page", parmas);
        if (code === 200) {
            setFormData(data.records)
        } else {
            notify(msg);
        }
    }
    return (
        <Select
            value={params.value}
            onChange={(e) => {
                params.api.setEditCellValue({
                    id: params.id,
                    field: params.field,
                    value: e.target.value,
                })
                // 找到选中的供应商记录
                const selectedSupplier = formData.find(supplier => supplier.name === e.target.value);
                // 如果找到对应的供应商记录,同时更新splrCode字段
                if (selectedSupplier) {
                    params.api.setEditCellValue({
                        id: params.id,
                        field: 'splrCode',
                        value: selectedSupplier.id,
                    });
                }
            }}
            fullWidth
        >
            {formData.map(e => {
                return (
                    <MenuItem value={e.name} children={e.name} key={e.id} />
                );
            })}
        </Select>
    );
};
const SelectInputSplrCodeEditCell = (params) => {
    const [formData, setFormData] = useState([{}])
    useEffect(() => {
        getOptions();
    }, []);
    const getOptions = async () => {
        const parmas = {
            "type": "supplier"
        }
        const {
            data: { code, data, msg },
        } = await request.post("companys/page", parmas);
        if (code === 200) {
            setFormData(data.records)
        } else {
            notify(msg);
        }
    }
    return (
        <Select
            value={params.value}
            onChange={(e) => {
                params.api.setEditCellValue({
                    id: params.id,
                    field: params.field,
                    value: e.target.value,
                })
                const selectedSupplier = formData.find(supplier => supplier.id === e.target.value);
                // 如果找到对应的供应商记录,同时更新splrCode字段
                if (selectedSupplier) {
                    params.api.setEditCellValue({
                        id: params.id,
                        field: 'splrName',
                        value: selectedSupplier.name,
                    });
                }
            }}
            fullWidth
        >
            {formData.map(e => {
                return (
                    <MenuItem value={e.id} children={e.name} key={e.id} />
                );
            })}
        </Select>
    );
};
const AsnOrderModalTable = ({ tabelData, setTableData, asnId, selectedRows, setSelectedRows, tableRef }) => {
    const translate = useTranslate();
    const notify = useNotify();
    const [columns, setColumns] = useState([
        {
            field: 'maktx',
            headerName: translate('table.field.outStockItem.maktx'),
            width: 250,
            editable: false,
        },
        {
            field: 'matnrCode',
            headerName: translate('table.field.outStockItem.matnrCode'),
            width: 130,
            editable: false,
        },
        {
            field: 'anfme',
            headerName: translate('table.field.outStockItem.anfme') + "*",
            type: 'number',
            minWidth: 100,
            flex: 1,
            editable: true,
            valueFormatter: (val) => val < 0 ? 0 : val,
            headerClassName: "custom",
        },
        {
            field: 'splrCode',
            headerName: translate('table.field.outStockItem.splrCode') + "*",
            minWidth: 100,
            flex: 1,
            editable: true,
            renderEditCell: (params) => (
                <SelectInputSplrCodeEditCell {...params} />
            ),
            headerClassName: "custom",
        },
        {
            field: 'splrName',
            headerName: translate('table.field.outStockItem.splrName') + "*",
            minWidth: 100,
            flex: 1,
            editable: true,
            renderEditCell: (params) => (
                <SelectInputSplrNameEditCell {...params} />
            ),
            headerClassName: "custom",
        },
        {
            field: 'splrBatch',
            headerName: translate('table.field.outStockItem.splrBatch'),
            minWidth: 100,
            flex: 1,
            editable: true,
        },
        {
            field: 'poCode',
            headerName: translate('table.field.outStockItem.poDetlCode'),
            minWidth: 100,
            flex: 1,
            editable: true,
        },
        {
            field: 'stockUnit',
            headerName: translate('table.field.outStockItem.stockUnit'),
            minWidth: 100,
            flex: 1,
            editable: true,
        },
    ])
    const action = {
        field: 'action',
        headerName: '操作',
        width: 70,
        lockPosition: 'left',
        renderCell: (params) => (
            <Tooltip title="Delete">
                <IconButton onClick={() => handleDelete(params.row)}>
                    <Delete />
                </IconButton>
            </Tooltip>
        ),
    }
    let cdata = useRef([]);
    useEffect(() => {
        getDynamicFields();
    }, []);
    useEffect(() => {
        cdata.current = tabelData
    }, [tabelData]);
    const getDynamicFields = async () => {
        const {
            data: { code, data, msg },
        } = await request.get("/fields/enable/list");
        if (code === 200) {
            const cols = data.map(el => ({
                field: el.fields,
                headerName: el.fieldsAlise,
                minWidth: 100,
                flex: 1,
                editable: false
            }))
            setColumns([...columns, ...cols, action])
        } else {
            notify(msg);
        }
    }
    const handleDelete = (row) => {
        const newData = _.filter(cdata.current, (item) => item.matnrId !== row.matnrId);
        setTableData(newData);
    };
    const processRowUpdate = (newRow, oldRow) => {
        const rows = tabelData.map((r) =>
            r.matnrId === newRow.matnrId ? { ...newRow } : r
        )
        setTableData(rows)
        return newRow;
    };
    const handleSelectionChange = (ids) => {
        setSelectedRows(ids)
    };
    tableRef.current = useGridApiRef();
    return (
        <div style={{ height: 400, width: '100%' }}>
            <DataGrid
                apiRef={tableRef}
                rows={tabelData}
                columns={columns}
                disableRowSelectionOnClick
                getRowId={(row) => row.matnrId ? row.matnrId : row.id}
                disableColumnFilter
                disableColumnSelector
                disableColumnSorting
                disableMultipleColumnsSorting
                processRowUpdate={processRowUpdate}
                initialState={{
                    pagination: {
                        paginationModel: {
                            pageSize: 25,
                        },
                    },
                }}
                pageSizeOptions={[15, 25, 50, 100]}
                editMode="row"
                checkboxSelection
                onRowSelectionModelChange={handleSelectionChange}
                selectionModel={selectedRows}
                sx={{
                    '& .MuiDataGrid-cell input': {
                        border: '1px solid #ccc'
                    },
                }}
            />
        </div>
    );
};
rsf-admin/src/page/orders/check/index.jsx
New file
@@ -0,0 +1,18 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import {
    ListGuesser,
    EditGuesser,
    ShowGuesser,
} from "react-admin";
import CheckOrderList from "./CheckOrderList";
import CheckOrderEdit from "./CheckOrderEdit";
export default {
    list: CheckOrderList,
    edit: CheckOrderEdit,
    show: ShowGuesser,
    recordRepresentation: (record) => {
        return `${record.name}`
    }
};
rsf-admin/src/page/warehouseAreas/WarehouseAreasList.jsx
@@ -31,6 +31,7 @@
    ReferenceArrayInput,
    AutocompleteInput,
    DeleteButton,
    Datagrid,
    useRefresh,
    Button
} from 'react-admin';
@@ -44,21 +45,84 @@
import PageDrawer from "../components/PageDrawer";
import BatchModal from "./BatchModal";
import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting';
import * as Common from '@/utils/common';
import EditIcon from '@mui/icons-material/Edit';
import { minWidth } from "@mui/system";
const ScrollableDatagrid = styled(Datagrid)(({ theme }) => ({
    '& .MuiTable-root': {
        minWidth: '100%', // 确保表格宽度足够
        tableLayout: 'fixed', // 固定表格布局
    },
    '& .RaDatagrid-rowCell': {
        textAlign: 'center',
        whiteSpace: 'nowrap',
        textOverflow: 'ellipsis',
    },
    '& .RaDatagrid-headerCell': {
        whiteSpace: 'nowrap',
        overflowX: 'auto',
    },
    '& .opt': {
        width: 200,
        position: 'sticky',
        zIndex: 3,
        right: 0,
    },
}));
const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({
    '& .css-1vooibu-MuiSvgIcon-root': {
        height: '.9em'
    },
    '& .RaDatagrid-row': {
        cursor: 'auto'
    },
    '& .column-name': {
    },
    //     height: '.9em'
    // },
    // '& .RaDatagrid-row': {
    //     cursor: 'auto'
    // },
    '& .opt': {
        width: 200
        width: 200,
        position: 'sticky',
        right: 0,
    },
    '& .MuiTableContainer-root': {
        overflowX: 'auto',
        '&::-webkit-scrollbar': {
            height: '8px',
        },
        '&::-webkit-scrollbar-thumb': {
            backgroundColor: theme.palette.action.hover,
            borderRadius: '4px',
        },
    },
    // '& .MuiTable-root': {
    //     minWidth: '100%', // 确保表格宽度足够
    //     tableLayout: 'fixed', // 固定表格布局
    // },
    // '& .MuiTableCell-root': {
    //     whiteSpace: 'nowrap',
    //     overflow: 'hidden',
    //     textOverflow: 'ellipsis',
    //     position: 'relative', // 为固定列提供定位上下文
    // },
    // '& .MuiTableCell-actions': {
    //     position: 'sticky',
    //     right: 0,
    //     background: theme.palette.background.paper,
    //     zIndex: 2,
    //     width: '150px',
    //     minWidth: '150px',
    //     boxShadow: '-2px 0 4px rgba(0,0,0,0.1)',
    //     '& button': {
    //         marginLeft: theme.spacing(1),
    //     }
    // },
    // '& .MuiTableHead-root .MuiTableCell-actions': {
    //     zIndex: 3, // 表头比内容高一层
    // }
}));
const filters = [
@@ -127,6 +191,13 @@
                            duration: theme.transitions.duration.enteringScreen,
                        }),
                    marginRight: drawerVal ? `${PAGE_DRAWER_WIDTH}px` : 0,
                    '& .RaList-content': {
                        position: 'sticky',
                        overflow: 'auto',
                        width: 'auto',
                        righ: '0px',
                        minWidth: '100%'
                    }
                }}
                title={"menu.warehouseAreas"}
                empty={<EmptyData onClick={() => { setCreateDialog(true) }} />}
@@ -142,7 +213,7 @@
                )}
                perPage={DEFAULT_PAGE_SIZE}
            >
                <StyledDatagrid
                <ScrollableDatagrid
                    preferenceKey='warehouseAreas'
                    bulkActionButtons={
                        <>
@@ -157,33 +228,33 @@
                >
                    <NumberField source="id" />
                    {/* <TextField source="uuid" label="table.field.warehouseAreas.uuid" /> */}
                    <TextField source="name" label="table.field.warehouseAreas.name" />
                    <TextField source="code" label="table.field.warehouseAreas.code" />
                    <TextField source="type$" label="table.field.warehouseAreas.type"/>
                    <TextField source="name" label="table.field.warehouseAreas.name" width="10%" />
                    <TextField source="code" label="table.field.warehouseAreas.code" width="10%" />
                    <TextField source="type$" label="table.field.warehouseAreas.type" width="10%" />
                    {/* <ReferenceField source="shipperId" label="table.field.warehouseAreas.shipperId" reference="shipper" link={false} sortable={false}>
                        <TextField source="name" />
                    </ReferenceField> */}
                    <TextField source="warehouseId$" label="table.field.warehouseAreas.wareId" />
                    <TextField source="shipperId$" label="table.field.warehouseAreas.shipperId" />
                    <NumberField source="supplierId" label="table.field.warehouseAreas.supplierId" />
                    <TextField source="flagMinus$" label="table.field.warehouseAreas.flagMinus" sortable={false} />
                    <TextField source="flagLabelMange$" label="table.field.warehouseAreas.flagLabelMange" sortable={false} />
                    <TextField source="flagMix$" label="table.field.warehouseAreas.flagMix" sortable={false} />
                    <ReferenceField source="updateBy" label="common.field.updateBy" reference="user" link={false} sortable={false}>
                    <TextField source="warehouseId$" label="table.field.warehouseAreas.wareId" width="10%" />
                    <TextField source="shipperId$" label="table.field.warehouseAreas.shipperId" width="10%" />
                    <NumberField source="supplierId" label="table.field.warehouseAreas.supplierId" width="10%" />
                    <TextField source="flagMinus$" label="table.field.warehouseAreas.flagMinus" sortable={false} width="10%" />
                    <TextField source="flagLabelMange$" label="table.field.warehouseAreas.flagLabelMange" sortable={false} width="10%" />
                    <TextField source="flagMix$" label="table.field.warehouseAreas.flagMix" sortable={false} width="10%" />
                    <ReferenceField source="updateBy" label="common.field.updateBy" reference="user" link={false} sortable={false} width="10%">
                        <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}>
                    <DateField source="updateTime" label="common.field.updateTime" showTime width="10%" />
                    <ReferenceField source="createBy" label="common.field.createBy" reference="user" link={false} sortable={false} width="10%">
                        <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">
                    <DateField source="createTime" label="common.field.createTime" showTime width="10%" />
                    <BooleanField source="statusBool" label="common.field.status" sortable={false} width="10%" />
                    <TextField source="memo" label="common.field.memo" sortable={false} width="10%" />
                    <WrapperField source="opt" cellClassName="opt" label="common.field.opt">
                        <EditButton sx={{ padding: '1px', fontSize: '.75rem' }} />
                        <DeleteButton sx={{ padding: '1px', fontSize: '.75rem' }} mutationMode={OPERATE_MODE} />
                    </WrapperField>
                </StyledDatagrid>
                </ScrollableDatagrid>
            </List>
            <WarehouseAreasCreate
                open={createDialog}
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/CheckOrderController.java
New file
@@ -0,0 +1,125 @@
package com.vincent.rsf.server.manager.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
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.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.common.utils.ExcelUtil;
import com.vincent.rsf.server.manager.entity.AsnOrder;
import com.vincent.rsf.server.manager.enums.OrderType;
import com.vincent.rsf.server.manager.service.CheckOrderService;
import com.vincent.rsf.server.system.constant.SerialRuleCode;
import com.vincent.rsf.server.system.controller.BaseController;
import com.vincent.rsf.server.system.utils.SerialRuleUtils;
import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
@Api("盘点")
@RestController
public class CheckOrderController extends BaseController {
    @Autowired
    private CheckOrderService checkOrderService;
    @PreAuthorize("hasAuthority('manager:check:list')")
    @PostMapping("/check/page")
    public R page(@RequestBody Map<String, Object> map) {
        BaseParam baseParam = buildParam(map, BaseParam.class);
        PageParam<AsnOrder, BaseParam> pageParam = new PageParam<>(baseParam, AsnOrder.class);
        QueryWrapper<AsnOrder> wrapper = pageParam.buildWrapper(true);
        wrapper.eq("type", OrderType.ORDER_CHECK.type);
        return R.ok().add(checkOrderService.page(pageParam, wrapper));
    }
    @PreAuthorize("hasAuthority('manager:check:list')")
    @PostMapping("/check/list")
    public R list(@RequestBody Map<String, Object> map) {
        return R.ok().add(checkOrderService.list());
    }
    @PreAuthorize("hasAuthority('manager:check:list')")
    @PostMapping({"/check/many/{ids}", "/check/many/{ids}"})
    public R many(@PathVariable Long[] ids) {
        return R.ok().add(checkOrderService.listByIds(Arrays.asList(ids)));
    }
    @PreAuthorize("hasAuthority('manager:check:list')")
    @GetMapping("/check/{id}")
    public R get(@PathVariable("id") Long id) {
        return R.ok().add(checkOrderService.getById(id));
    }
    @PreAuthorize("hasAuthority('manager:check:save')")
    @OperationLog("Create 字典数据集")
    @PostMapping("/check/save")
    public R save(@RequestBody AsnOrder order) {
        order.setType(OrderType.ORDER_CHECK.type);
        String ruleCode = SerialRuleUtils.generateRuleCode(SerialRuleCode.SYS_CHECK_RULE_CODE, order);
        if (Objects.isNull(ruleCode)) {
            throw new RuntimeException("盘点单号生成失败!!");
        }
        if (!checkOrderService.save(order)) {
            return R.error("Save Fail");
        }
        return R.ok("Save Success").add(order);
    }
    @PreAuthorize("hasAuthority('manager:check:update')")
    @OperationLog("Update 字典数据集")
    @PostMapping("/check/update")
    public R update(@RequestBody AsnOrder order) {
        order.setUpdateTime(null);
        order.setUpdateBy(getLoginUserId());
        if (!checkOrderService.updateById(order)) {
            return R.error("Update Fail");
        }
        return R.ok("Update Success").add(order);
    }
    @PreAuthorize("hasAuthority('manager:check:remove')")
    @OperationLog("Delete 字典数据集")
    @PostMapping("/check/remove/{ids}")
    public R remove(@PathVariable Long[] ids) {
        if (!checkOrderService.removeByIds(Arrays.asList(ids))) {
            return R.error("Delete Fail");
        }
        return R.ok("Delete Success").add(ids);
    }
    @PreAuthorize("hasAuthority('manager:check:list')")
    @PostMapping("/check/query")
    public R query(@RequestParam(required = false) String condition) {
        List<KeyValVo> vos = new ArrayList<>();
        LambdaQueryWrapper<AsnOrder> wrapper = new LambdaQueryWrapper<>();
        if (!Cools.isEmpty(condition)) {
            wrapper.like(AsnOrder::getCode, condition);
        }
        checkOrderService.page(new Page<>(1, 30), wrapper).getRecords().forEach(
                item -> vos.add(new KeyValVo(item.getId(), item.getCode()))
        );
        return R.ok().add(vos);
    }
    @PreAuthorize("hasAuthority('manager:check:list')")
    @PostMapping("/check/export")
    public void export(@RequestBody Map<String, Object> map, HttpServletResponse response) throws Exception {
        List<AsnOrder> orders = new ArrayList<>();
        if (!Objects.isNull(map.get("ids"))) {
            orders = checkOrderService.list(new LambdaQueryWrapper<AsnOrder>().in(AsnOrder::getId, map.get("ids")));
        } else {
            orders = checkOrderService.list();
        }
        ExcelUtil.build(ExcelUtil.create(orders, AsnOrder.class), response);
    }
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/enums/OrderType.java
@@ -11,6 +11,7 @@
    //订单类型
    ORDER_OUT("out", "出库单"),
    ORDER_IN("in", "入库单"),
    ORDER_CHECK("check", "盘点单");
    ;
    OrderType(String type, String desc) {
rsf-server/src/main/java/com/vincent/rsf/server/manager/mapper/CheckOrderMapper.java
New file
@@ -0,0 +1,12 @@
package com.vincent.rsf.server.manager.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.vincent.rsf.server.manager.entity.AsnOrder;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
@Mapper
@Repository
public interface CheckOrderMapper extends BaseMapper<AsnOrder> {
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/schedules/TaskSchedules.java
@@ -93,6 +93,7 @@
    /**
     * 任务自动下发
     *
     * @throws Exception
     */
    @Scheduled(cron = "0/5 * * * * ?  ")
@@ -101,8 +102,9 @@
        Long loginUserId = SystemAuthUtils.getLoginUserId();
        List<Integer> list = Arrays.asList(TaskType.TASK_TYPE_IN.type, TaskType.TASK_TYPE_OUT.type);
        List<Integer> integers = Arrays.asList(TaskStsType.GENERATE_IN.id, TaskStsType.GENERATE_OUT.id);
        List<Task> tasks = taskService.list(new LambdaQueryWrapper<Task>().in(Task::getTaskType, list)
                        .in(Task::getTaskStatus, integers)
        List<Task> tasks = taskService.list(new LambdaQueryWrapper<Task>()
                .in(Task::getTaskType, list)
                .in(Task::getTaskStatus, integers)
                .orderByDesc(Task::getSort));
        for (Task task : tasks) {
            Loc loc = locService.getOne(new LambdaQueryWrapper<Loc>().eq(Loc::getBarcode, task.getBarcode()));
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/CheckOrderService.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.AsnOrder;
public interface CheckOrderService extends IService<AsnOrder> {
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/CheckOrderServiceImpl.java
New file
@@ -0,0 +1,12 @@
package com.vincent.rsf.server.manager.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.vincent.rsf.server.manager.entity.AsnOrder;
import com.vincent.rsf.server.manager.mapper.CheckOrderMapper;
import com.vincent.rsf.server.manager.service.CheckOrderService;
import org.springframework.stereotype.Service;
@Service("checkOrderService")
public class CheckOrderServiceImpl extends ServiceImpl<CheckOrderMapper, AsnOrder> implements CheckOrderService {
}
rsf-server/src/main/java/com/vincent/rsf/server/system/constant/SerialRuleCode.java
@@ -85,5 +85,8 @@
     */
    public final static String SYS_WAVE_RULE_CODE = "sys_wave_type";
    /**盘点单号*/
    public final static String SYS_CHECK_RULE_CODE = "sys_check_rule_code";
}
rsf-server/src/main/resources/application-dev.yml
@@ -13,9 +13,9 @@
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
#    url: jdbc:mysql://47.76.147.249:3306/rsf?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
#    username: rsf
    username: root
    url: jdbc:mysql://127.0.0.1:3306/rsf?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
#    username: rsf
    password: 34821015
    type: com.alibaba.druid.pool.DruidDataSource
    druid: