skyouc
2025-05-09 18cee3f153e61fb04b17701d63fbd51a9276122a
新增收货单打印预览界面
2个文件已添加
13个文件已修改
4786 ■■■■■ 已修改文件
rsf-admin/package-lock.json 4304 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/package.json 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/i18n/en.js 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/i18n/zh.js 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/fields/FieldsList.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/asnOrder/AsnOrderItemList.jsx 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/asnOrder/AsnOrderList.jsx 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/asnOrder/AsnOrderModal.jsx 126 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/asnOrder/OrderPrintPreview.jsx 223 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/outStock/OutOrderList.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/outStock/SelectMatnrModal.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/schedules/ScheduleJobs.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/system/constant/GlobalConfigCode.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/system/entity/Config.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/system/entity/Fields.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/package-lock.json
Diff too large
rsf-admin/package.json
@@ -10,16 +10,19 @@
    "format": "prettier --write ./src"
  },
  "dependencies": {
    "@date-io/dayjs": "^3.2.0",
    "@fontsource/roboto": "^5.0.14",
    "@hello-pangea/dnd": "^16.3.0",
    "@mui/icons-material": "^5.16.7",
    "@mui/material": "^5.16.7",
    "@mui/material": "^5.17.1",
    "@mui/system": "^6.4.7",
    "@mui/x-data-grid": "^7.27.3",
    "@mui/x-date-pickers": "^8.3.0",
    "@mui/x-tree-view": "^7.16.0",
    "@tweenjs/tween.js": "^21.0.0",
    "axios": "^1.7.4",
    "date-fns": "^3.6.0",
    "dayjs": "^1.11.13",
    "framer-motion": "^12.4.10",
    "jsbarcode": "^3.11.6",
    "lodash": "^4.17.21",
@@ -27,6 +30,7 @@
    "papaparse": "^5.4.1",
    "pixi.js": "^7.4.0",
    "prop-types": "^15.8.1",
    "qrcode.react": "^4.2.0",
    "ra-i18n-polyglot": "^5.6.2",
    "ra-language-chinese": "^2.0.10",
    "ra-language-english": "^5.6.2",
@@ -39,6 +43,7 @@
    "react-router-dom": "^6.26.1",
    "react-syntax-highlighter": "^15.5.0",
    "react-to-print": "^3.0.5",
    "svgpath": "^2.6.0",
    "three": "^0.155.0",
    "tweedle.js": "^2.1.0"
  },
rsf-admin/src/i18n/en.js
@@ -174,15 +174,17 @@
        stock: 'Stock Manage',
        histories: 'Histories',
        wareWork: 'Warehouse Working',
        statistics: 'Statistics',
        statistics: 'Stock Statistics',
        logs: 'Logs',
        permissions: 'Permissions',
        delivery: 'Delivery',
        outStock: 'Out Stock',
        stockManage: 'Stock Manage',
        outStockItem: 'Out Stock Item',
        inStockPoces: 'In Stock Pocess',
        outStockPoces: 'Out Stock Pocess',
        deviceBind: 'Device Bind',
        tasks: 'Tasks',
        wave: 'Wave Manage',
    },
@@ -484,6 +486,7 @@
                value: "value",
                label: "label",
                sort: "sort",
                group: "Group",
                color: "color",
            },
            companys: {
@@ -1035,6 +1038,7 @@
        batchWarehouseAreas: "batchWarehouseAreas",
        batchLocType: "batchLocType",
        batchPrint: "batch print",
        orderPrint: 'Orders Print',
        quality: "quality",
        complete: "complete",
        close: "close",
rsf-admin/src/i18n/zh.js
@@ -160,32 +160,33 @@
        whMat: '库区物料关系',
        fields: '扩展字段',
        fieldsItem: '扩展字段明细',
        warehouseAreasItem: '库区库存信息',
        warehouseAreasItem: '收货库存',
        deviceSite: '路径管理',
        waitPakin: '组托通知档',
        waitPakinItem: '组托档明细',
        waitPakinLog: '组托历史档',
        waitPakinItemLog: '组托历史档明细',
        task: '任务工作档',
        task: '任务管理',
        taskItem: '任务档明细',
        taskLog: '任务历史档',
        taskItemLog: '任务明细历史档',
        stock: '综合单据管理',
        stock: '入出库存信息',
        stockItem: '单据明细',
        locItem: '库位明细',
        histories: '历史档',
        wareWork: '仓库作业',
        statistics: '统计查询',
        statistics: '库存查询',
        stockManage: '库存管理',
        logs: '日志',
        permissions: '权限管理',
        delivery: 'DO单',
        outStock: '出库单',
        outStockItem: '出库单明细',
        inStockPoces: '入库流程',
        outStockPoces: '出库流程',
        inStockPoces: '入库管理',
        outStockPoces: '出库管理',
        deviceBind: '设备绑定',
        tasks: '任务管理',
        wave: '波次管理',
    },
    table: {
        field: {
@@ -490,6 +491,7 @@
            dictData: {
                dictTypeId: "字典标识",
                dictTypeCode: "字典编码",
                group: "分类",
                value: "值",
                label: "别名",
                sort: "排序",
@@ -716,7 +718,7 @@
            fields: {
                fields: "字段",
                fieldsAlise: "字段别名",
                unique: "是否必填",
                unique: "数据类型",
                flagEnable: "启用",
            },
            fieldsItem: {
@@ -1058,6 +1060,7 @@
        complete: "完结",
        close: "关闭",
        asnCreate: "通过单据创建",
        orderPrint: '打印单据',
        createTask: "下发任务",
        createWave: "生成波次",
        recover: "继续收货",
rsf-admin/src/page/fields/FieldsList.jsx
@@ -65,8 +65,8 @@
    <TextInput source="fieldsAlise" label="table.field.fields.fieldsAlise" />,
    <SelectInput source="unique" label="table.field.fields.unique"
        choices={[
            { id: 0, name: ' 非必填' },
            { id: 1, name: '  必填' },
            { id: 0, name: '主数据' },
            { id: 1, name: '业务数据' },
        ]}
    />,
    <SelectInput source="flagEnable" label="table.field.fields.flagEnable"
rsf-admin/src/page/orders/asnOrder/AsnOrderItemList.jsx
@@ -40,9 +40,6 @@
import { Box, Typography, Card, Stack, Dialog, DialogActions, DialogTitle, LinearProgress } from '@mui/material';
import { styled } from '@mui/material/styles';
import AsnOrderItemCreate from "./AsnOrderItemCreate";
import EmptyData from "../../components/EmptyData";
import MyCreateButton from "../../components/MyCreateButton";
import MyExportButton from '../../components/MyExportButton';
import PageDrawer from "../../components/PageDrawer";
import request from '@/utils/request';
import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE, DEFAULT_ITEM_PAGE_SIZE } from '@/config/setting';
@@ -119,7 +116,7 @@
          }}
          title={"menu.asnOrderItem"}
          empty={false}
          filter={{ asnId: asnId, deleted: 0 }}
          filter={{ asnId: asnId}}
          filters={filters}
          sort={{ field: "create_time", order: "desc" }}
          actions={(
rsf-admin/src/page/orders/asnOrder/AsnOrderList.jsx
@@ -56,6 +56,8 @@
import DictionarySelect from "../../components/DictionarySelect";
import ExitToAppIcon from '@mui/icons-material/ExitToApp';
import ImportButton from "../../components/ImportButton";
import PrintOutlinedIcon from '@mui/icons-material/PrintOutlined';
import OrderPrintPreview from "./OrderPrintPreview";
const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({
  '& .css-1vooibu-MuiSvgIcon-root': {
@@ -112,7 +114,8 @@
  const [createDialog, setCreateDialog] = useState(false);
  const [drawerVal, setDrawerVal] = useState(false);
  const [modalType, setmodalType] = useState(0);
  const [select, setSelect] = useState(0);
  const [printOrder, setPrintOrder] = useState(false);
  const [select, setSelect] = useState({});
  const billReload = useRef();
  const notify = useNotify();
  const refresh = useRefresh();
@@ -132,7 +135,6 @@
        title={"menu.asnOrder"}
        empty={false}
        filters={filters}
        filter={{ deleted: 0 }}
        sort={{ field: "create_time", order: "desc" }}
        actions={(
          <TopToolbar>
@@ -184,6 +186,7 @@
            <InspectionButton />
            <CompleteButton />
            <ODeleteButton  />
            <PrintButton setPrintOrder={setPrintOrder} setSelect={setSelect}/>
            {/* <CloseButton /> */}
          </WrapperField>
        </StyledDatagrid>
@@ -193,6 +196,11 @@
        setOpen={setCreateDialog}
        asnId={modalType}
        billReload={billReload}
      />
      <OrderPrintPreview
        open={printOrder}
        setOpen={setPrintOrder}
        record={select}
      />
      <PageDrawer
        title='AsnOrder Detail'
@@ -205,6 +213,24 @@
}
export default AsnOrderList;
//打印按钮
const PrintButton = ({setPrintOrder, setSelect}) => {
  const record = useRecordContext();
  const printOrder = (event) => {
    event.stopPropagation();
    setPrintOrder(true)
    setSelect(record)
  }
  return (
      <Button label={"toolbar.print"} onClick={printOrder}>
          <PrintOutlinedIcon />
      </Button>
  )
}
const ODeleteButton = () => {
  const record = useRecordContext();
  return (
rsf-admin/src/page/orders/asnOrder/AsnOrderModal.jsx
@@ -43,7 +43,6 @@
    Select,
    MenuItem
} from '@mui/material';
import DialogCloseButton from "../../components/DialogCloseButton";
import StatusSelectInput from "../../components/StatusSelectInput";
@@ -54,10 +53,15 @@
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 { DataGrid, useGridApiRef, GRID_DATE_COL_DEF,  GRID_DATETIME_COL_DEF,  getGridDateOperators, useGridApiContext } from '@mui/x-data-grid';
import { LocalizationProvider, DatePicker, DateTimePicker } from '@mui/x-date-pickers';
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
import DictionarySelect from "../../components/DictionarySelect";
import DictSelect from "../../components/DictSelect";
import "./asnOrder.css";
import { 'zhCN' as locale } from 'date-fns/locale';
import { format, } from 'date-fns';
import { DemoContainer } from '@mui/x-date-pickers/internals/demo';
const AsnOrderModal = (props) => {
    const { open, setOpen, asnId, billReload } = props;
@@ -210,7 +214,7 @@
                aria-hidden
                fullWidth
                disableRestoreFocus
                maxWidth="lg"   // 'xs' | 'sm' | 'md' | 'lg' | 'xl'
                maxWidth="xl"   // 'xs' | 'sm' | 'md' | 'lg' | 'xl'
            >
                <DialogTitle id="form-dialog-title" sx={{
                    position: 'sticky',
@@ -232,7 +236,8 @@
                                        label={translate("table.field.asnOrder.type")}
                                        value={formData.type}
                                        onChange={(e) => handleChange(e.target.value, 'type')}
                                        dictTypeCode="sys_in_stock_type"
                                        dictTypeCode="sys_order_type"
                                        group='1'
                                        required
                                    />
                                </Grid>
@@ -292,9 +297,7 @@
                        </Button>
                    </Toolbar>
                </DialogActions>
            </Dialog>
            <AsnWareModal
                open={createDialog}
                setOpen={setCreateDialog}
@@ -306,6 +309,26 @@
}
export default AsnOrderModal;
const dateColumnType = {
    ...GRID_DATE_COL_DEF,
    resizable: false,
    renderEditCell: (params) => {
        return <GridEditDateCell {...params} />;
    },
    // filterOperators: getGridDateOperators(false).map((item) => ({
    //     ...item,
    //     InputComponent: GridFilterDateInput,
    //     InputComponentProps: { showTime: false },
    // })),
    // valueFormatter: (value) => {
    //     if (value) {
    //         return format(value, 'yyyy-MM-dd', { locale });
    //     }
    //     return '';
    // },
}
const SelectInputSplrNameEditCell = (params) => {
    const [formData, setFormData] = useState([{}])
@@ -364,6 +387,52 @@
        </Select>
    );
};
const GridEditDateCell = ({ id, field, value, colDef, hasFocus }) => {
    const apiRef = useGridApiContext();
    const inputRef = React.useRef(null);
    const Component = colDef.type === 'dateTime' ? DateTimePicker : DatePicker;
    const handleChange = (newValue) => {
        apiRef.current.setEditCellValue({ id, field, value: newValue });
    };
    // useEnhancedEffect(() => {
    //     if (hasFocus) {
    //         inputRef.current.focus();
    //     }
    // }, [hasFocus]);
    return (
        <LocalizationProvider dateAdapter={AdapterDayjs}>
            <DemoContainer components={['DatePicker']}>
                <DatePicker label="Basic date picker" />
            </DemoContainer>
        </LocalizationProvider>
        // <Component
        //     value={value}
        //     autoFocus
        //     onChange={handleChange}
        //     slotProps={{
        //         textField: {
        //             inputRef,
        //             variant: 'standard',
        //             fullWidth: true,
        //             sx: {
        //                 padding: '0 9px',
        //                 justifyContent: 'center',
        //             },
        //             InputProps: {
        //                 disableUnderline: true,
        //                 sx: { fontSize: 'inherit' },
        //             },
        //         },
        //     }}
        // />
    );
}
const SelectInputSplrCodeEditCell = (params) => {
    const [formData, setFormData] = useState([{}])
@@ -451,28 +520,28 @@
            valueFormatter: (val) => val < 0 ? 0 : val,
            headerClassName: "custom",
        },
        {
            field: 'splrCode',
            headerName: translate('table.field.asnOrderItem.splrCode') + "*",
            minWidth: 100,
            flex: 1,
            editable: true,
            renderEditCell: (params) => (
                <SelectInputSplrCodeEditCell {...params} />
            ),
            headerClassName: "custom",
        },
        // {
        //     field: 'splrName',
        //     headerName: translate('table.field.asnOrderItem.splrName') + "*",
        //     field: 'splrCode',
        //     headerName: translate('table.field.asnOrderItem.splrCode') + "*",
        //     minWidth: 100,
        //     flex: 1,
        //     editable: true,
        //     renderEditCell: (params) => (
        //         <SelectInputSplrNameEditCell {...params} />
        //         <SelectInputSplrCodeEditCell {...params} />
        //     ),
        //     headerClassName: "custom",
        // },
        {
            field: 'splrName',
            headerName: translate('table.field.asnOrderItem.splrName') + "*",
            minWidth: 100,
            flex: 1,
            editable: true,
            renderEditCell: (params) => (
                <SelectInputSplrNameEditCell {...params} />
            ),
            headerClassName: "custom",
        },
        // {
        //     field: 'packName',
        //     headerName: translate('table.field.asnOrderItem.packName'),
@@ -480,12 +549,7 @@
        //     flex: 1,
        //     editable: true,
        // },
        // {
        //     field: 'poDetlId',
        //     headerName: translate('table.field.asnOrderItem.poDetlId'),
        //     minWidth: 100,
        //     flex: 1,
        // },
        {
            field: 'platItemId',
            headerName: translate('table.field.asnOrderItem.platItemId') + "*",
@@ -511,6 +575,15 @@
            flex: 1,
            editable: false,
        },
        // {
        //     field: 'prodTime',
        //     headerName: translate('table.field.asnOrderItem.prodTime'),
        //     minWidth: 200,
        //     flex: 1,
        //     ...dateColumnType,
        //     editable: true,
        //     headerClassName: "custom",
        // },
        // {
        //     field: 'purQty',
        //     headerName: translate('table.field.asnOrderItem.purQty'),
@@ -597,7 +670,6 @@
        return newRow;
    };
    const handleSelectionChange = (ids) => {
rsf-admin/src/page/orders/asnOrder/OrderPrintPreview.jsx
New file
@@ -0,0 +1,223 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import {
    Edit,
    SimpleForm,
    useTranslate,
    TextInput,
    DateInput,
    SelectInput,
    AutocompleteInput,
    SaveButton,
    Toolbar,
    TopToolbar,
    Button,
    List,
    useRefresh,
    NumberField,
    ReferenceField,
    TextField,
    DateField,
    Form,
    required,
    DatagridConfigurable,
    useListContext,
    useNotify,
    DeleteButton,
    ImageField,
    InPlaceEditor,
} from 'react-admin';
import { useWatch, useFormContext } from "react-hook-form";
import { Stack, Grid, Box, Typography, Dialog, DialogActions, DialogContent, DialogTitle, LinearProgress, } from '@mui/material';
import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_ITEM_PAGE_SIZE } from '@/config/setting';
import DialogCloseButton from "../../components/DialogCloseButton";
import DictSelect from "../../components/DictSelect";
import SaveIcon from '@mui/icons-material/Save';
import request from '@/utils/request';
import { styled } from '@mui/material/styles';
import { QRCodeSVG, QRCodeCanvas } from 'qrcode.react';  // 现在必须这样用
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 OrderPrintPreview = (props) => {
    const { open, setOpen, record } = props;
    const notify = useNotify();
    const translate = useTranslate();
    const [drawerVal, setDrawerVal] = useState(false);
    const [disabled, setDisabled] = useState(false)
    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 handleClose = (event, reason) => {
        setOpen(false);
    };
    return (
        <>
            <Dialog
                open={open}
                onClose={handleClose}
                aria-labelledby="form-dialog-title"
                aria-hidden
                fullWidth
                disableRestoreFocus
                maxWidth="xl"   // 'xs' | 'sm' | 'md' | 'lg' | 'xl'
            >
                <DialogTitle id="form-dialog-title" sx={{
                    position: 'sticky',
                    top: 0,
                    textAlign: 'center',
                    backgroundColor: 'background.paper',
                    zIndex: 1000
                }}>
                    {translate('menu.asnOrder')}
                    <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={record}>
                            <Grid container spacing={2} sx={{ justifyContent: 'space-between', }}>
                                <Grid item md={2}>
                                    <Box sx={{ display: 'flex', justifyContent: 'center' }}>
                                        <Typography>单据类型:</Typography>
                                        <Typography>{record?.type$}</Typography>
                                    </Box>
                                    <Box sx={{ display: 'flex', justifyContent: 'center', padding: 1 }}></Box>
                                    <Box sx={{ display: 'flex', justifyContent: 'center' }}>
                                        <Typography>业务类型:</Typography>
                                        <Typography>{record?.wkType$}</Typography>
                                    </Box>
                                </Grid>
                                <Grid item md={2}>
                                    <QRCodeSVG value={record?.code} />
                                    <Typography>{record.code}</Typography>
                                </Grid>
                                {/* <Grid item md={2}>
                                    <TextInput source="code" label={"table.field.asnOrder.code"} />
                                </Grid> */}
                            </Grid>
                        </Form>
                        <List
                            resource="asnOrderItem"
                            sx={{
                                flexGrow: 1,
                                transition: (theme) =>
                                    theme.transitions.create(['all'], {
                                        duration: theme.transitions.duration.enteringScreen,
                                    }),
                                marginRight: drawerVal ? `${PAGE_DRAWER_WIDTH}px` : 0,
                            }}
                            title={"menu.asnOrderItem"}
                            empty={false}
                            filter={{ asnId: record?.id }}
                            sort={{ field: "create_time", order: "desc" }}
                            actions={(
                                <></>
                            )}
                            perPage={DEFAULT_ITEM_PAGE_SIZE}
                        >
                            <DynamicFields />
                        </List>
                    </Box>
                </DialogContent>
                <DialogActions sx={{ position: 'sticky', bottom: 0, backgroundColor: 'background.paper', zIndex: 1000 }}>
                    <Toolbar sx={{ width: '100%', justifyContent: 'end' }}  >
                        <Button disabled={disabled} variant="contained" startIcon={<SaveIcon />}>
                            {translate('toolbar.confirm')}
                        </Button>
                    </Toolbar>
                </DialogActions>
            </Dialog>
        </>
    )
}
export default OrderPrintPreview;
const DynamicFields = (props) => {
    const translate = useTranslate();
    const notify = useNotify();
    const [columns, setColumns] = useState([]);
    const { isLoading } = useListContext();
    const refresh = useRefresh();
    useEffect(() => {
        getDynamicFields();
    }, []);
    const getDynamicFields = async () => {
        const { data: { code, data, msg }, } = await request.get("/fields/enable/list");
        if (code == 200) {
            const arr = [
                <NumberField source="id" />,
                <NumberField source="asnId" label="table.field.asnOrderItem.asnId" />,
                <TextField source="asnCode" label="table.field.asnOrderItem.asnCode" />,
                <TextField source="poDetlId" label="table.field.asnOrderItem.poDetlId" />,
                <TextField source="poDetlCode" label="table.field.asnOrderItem.poDetlCode" />,
                <TextField source="platItemId" label="table.field.asnOrderItem.platItemId" />,
                <TextField source="matnrId" label="table.field.asnOrderItem.matnrId" />,
                <TextField source="matnrCode" label="table.field.asnOrderItem.matnrCode" />,
                <TextField source="maktx" label="table.field.asnOrderItem.maktx" />,
                <TextField source="splrBatch" label="table.field.asnOrderItem.splrBatch" />,
                <NumberField source="anfme" label="table.field.asnOrderItem.anfme" />,
                <NumberField source="qty" label="table.field.asnOrderItem.qty" />,
                <TextField source="splrName" label="table.field.asnOrderItem.splrName" />,
                <TextField source="isptResult$" label="table.field.asnOrderItem.isptResult" />,
                <TextField source="trackCode" label="table.field.asnOrderItem.barcode" />,
                <TextField source="packName" label="table.field.asnOrderItem.packName" />,
            ]
            const fields = data.map(el => <TextField key={el.fields} source={`extendFields.[${el.fields}]`} label={el.fieldsAlise} />)
            const lastArr = [
                <ReferenceField source="updateBy" label="common.field.updateBy" reference="user" link={false} sortable={false}>
                    <TextField source="nickname" />
                </ReferenceField>,
            ]
            setColumns([...arr, ...fields, ...lastArr]);
        } else {
            notify(msg);
        }
    }
    return (
        <Box sx={{ position: 'relative', minHeight: "60vh", }}>
            {isLoading && (
                <LinearProgress
                    sx={{
                        height: "2px",
                        position: 'absolute',
                        top: 0,
                        left: 0,
                        right: 0,
                    }}
                />
            )}
            {columns.length > 0 &&
                <StyledDatagrid
                    preferenceKey='asnOrderItem'
                    bulkActionButtons={false}
                    rowClick={(id, resource, record) => false}
                    omit={['id', 'asnId', 'poDetlId', 'poDetlCode', 'matnrId', 'purQty', 'purUnit', 'qrcode', 'trackCode']}
                >
                    {columns.map((column) => column)}
                </StyledDatagrid>}
        </Box>
    )
}
rsf-admin/src/page/orders/outStock/OutOrderList.jsx
@@ -83,10 +83,10 @@
  <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_business_type' }} label="table.field.outStock.type" alwaysOn>
  <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' }} label="table.field.outStock.wkType" alwaysOn>
  <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" />,
rsf-admin/src/page/orders/outStock/SelectMatnrModal.jsx
@@ -64,7 +64,6 @@
    const notify = useNotify();
    const refresh = useRefresh();
    const [disabled, setDisabled] = useState(false)
    const [createDialog, setCreateDialog] = useState(false);
    const tableRef = useRef();
@@ -237,6 +236,7 @@
                                        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
rsf-server/src/main/java/com/vincent/rsf/server/manager/schedules/ScheduleJobs.java
@@ -6,9 +6,13 @@
import com.vincent.rsf.server.common.utils.CommonUtil;
import com.vincent.rsf.server.common.utils.DateUtils;
import com.vincent.rsf.server.manager.entity.*;
import com.vincent.rsf.server.manager.enums.AsnExceStatus;
import com.vincent.rsf.server.manager.enums.PakinIOStatus;
import com.vincent.rsf.server.manager.service.*;
import com.vincent.rsf.server.system.constant.GlobalConfigCode;
import com.vincent.rsf.server.system.constant.SerialRuleCode;
import com.vincent.rsf.server.system.entity.Config;
import com.vincent.rsf.server.system.service.ConfigService;
import com.vincent.rsf.server.system.utils.SerialRuleUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
@@ -54,6 +58,35 @@
    private WaitPakinLogService waitPakinLogService;
    @Autowired
    private WaitPakinItemLogService waitPakinItemLogService;
    @Autowired
    private ConfigService configService;
    /**
     * @author Ryan
     * @date 2025/5/9
     * @description: 直接组托开关为true,将收货单直接加入临时库存
     * @version 1.0
     */
    public synchronized void IgnoreReceipt() {
        Config config = configService.getOne(new LambdaQueryWrapper<Config>().eq(Config::getFlag, GlobalConfigCode.DIRECT_WAIT_PAKIN));
        if (Objects.isNull(config)) {
            return;
        }
        if (!Boolean.getBoolean(config.getVal())) {
            return;
        }
        List<AsnOrder> orders = asnOrderService.list(new LambdaQueryWrapper<AsnOrder>().eq(AsnOrder::getExceStatus, AsnExceStatus.ASN_EXCE_STATUS_UN_EXCE.val));
        if (orders.isEmpty()) {
            for (AsnOrder order : orders) {
                List<AsnOrderItem> orderItems = asnOrderItemService.list(new LambdaQueryWrapper<AsnOrderItem>().eq(AsnOrderItem::getAsnId, order.getId()));
            }
        }
    }
    /**
rsf-server/src/main/java/com/vincent/rsf/server/system/constant/GlobalConfigCode.java
New file
@@ -0,0 +1,17 @@
package com.vincent.rsf.server.system.constant;
/**
 * @author Ryan
 * @date 2025/5/9
 * @description: 全局配置参数编码
 * @version 1.0
 */
public class GlobalConfigCode {
    public final static String EXECUTION = "Execution";
    /**直接组托*/
    public final static String DIRECT_WAIT_PAKIN = "DirectWaitPakin";
}
rsf-server/src/main/java/com/vincent/rsf/server/system/entity/Config.java
@@ -11,6 +11,7 @@
import com.vincent.rsf.server.system.service.UserService;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
@@ -18,6 +19,7 @@
import java.util.Date;
@Data
@Accessors(chain = true)
@TableName("sys_config")
public class Config implements Serializable {
rsf-server/src/main/java/com/vincent/rsf/server/system/entity/Fields.java
@@ -152,9 +152,9 @@
        if (null == this.unique){ return null; }
        switch (this.unique){
            case 0:
                return " 非唯一";
                return "主数据";
            case   1:
                return "  唯一";
                return "业务数据";
            default:
                return String.valueOf(this.unique);
        }