skyouc
2025-03-15 d17254e25cfaf8361c08eea6f16d99571a49174f
Merge branch 'front' into devlop
7个文件已添加
22个文件已修改
2159 ■■■■ 已修改文件
rsf-admin/.env 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/package.json 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/pnpm-lock.yaml 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/i18n/en.js 23 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/i18n/zh.js 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/ResourceContent.js 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/asnOrder/AsnOrderList.jsx 55 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/asnOrder/AsnOrderModal.jsx 389 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/asnOrder/AsnOrderPanel.jsx 242 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/asnOrder/AsnWareModal.jsx 198 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/asnOrderItem/AsnOrderItemCreate.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/asnOrderItem/AsnOrderItemEdit.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/asnOrderItem/AsnOrderItemList.jsx 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/asnOrderItem/AsnOrderItemPanel.jsx 34 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/basicInfo/warehouse/WarehouseCreate.jsx 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/login/Login.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/purchase/PurchasePanel.jsx 273 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/purchaseItem/PurchaseItemPanel.jsx 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/qlyInspect/QlyInspectCreate.jsx 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/qlyInspect/QlyInspectEdit.jsx 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/qlyInspect/QlyInspectList.jsx 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/qlyInspect/QlyInspectPanel.jsx 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/qlyInspect/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/qlyIsptItem/QlyIsptItemCreate.jsx 190 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/qlyIsptItem/QlyIsptItemEdit.jsx 162 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/qlyIsptItem/QlyIsptItemList.jsx 174 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/qlyIsptItem/QlyIsptItemPanel.jsx 123 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/qlyIsptItem/index.jsx 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/vite.config.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/.env
@@ -1,2 +1,3 @@
VITE_BASE_IP=192.168.4.24
# VITE_BASE_IP=47.76.147.249
VITE_BASE_PORT=8080
rsf-admin/package.json
@@ -15,6 +15,7 @@
    "@mui/icons-material": "^5.16.7",
    "@mui/material": "^5.16.7",
    "@mui/system": "^6.4.7",
    "@mui/x-data-grid": "^7.27.3",
    "@mui/x-tree-view": "^7.16.0",
    "@tweenjs/tween.js": "^21.0.0",
    "axios": "^1.7.4",
rsf-admin/pnpm-lock.yaml
@@ -23,6 +23,9 @@
      '@mui/system':
        specifier: ^6.4.7
        version: 6.4.7(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1)
      '@mui/x-data-grid':
        specifier: ^7.27.3
        version: 7.27.3(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1))(@mui/material@5.16.14(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mui/system@6.4.7(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
      '@mui/x-tree-view':
        specifier: ^7.16.0
        version: 7.26.0(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1))(@mui/material@5.16.14(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mui/system@6.4.7(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
@@ -601,6 +604,22 @@
      react: ^17.0.0 || ^18.0.0 || ^19.0.0
    peerDependenciesMeta:
      '@types/react':
        optional: true
  '@mui/x-data-grid@7.27.3':
    resolution: {integrity: sha512-7zbDbFrhV6ODjyn3ImOZG34nbMbCvmHgqYTYP273TNAj8hMy4BiLyiKFFZTzVddIj3KQ6qLzBpByhqifGgEDOg==}
    engines: {node: '>=14.0.0'}
    peerDependencies:
      '@emotion/react': ^11.9.0
      '@emotion/styled': ^11.8.1
      '@mui/material': ^5.15.14 || ^6.0.0
      '@mui/system': ^5.15.14 || ^6.0.0
      react: ^17.0.0 || ^18.0.0 || ^19.0.0
      react-dom: ^17.0.0 || ^18.0.0 || ^19.0.0
    peerDependenciesMeta:
      '@emotion/react':
        optional: true
      '@emotion/styled':
        optional: true
  '@mui/x-internals@7.26.0':
@@ -2216,6 +2235,9 @@
  remove-accents@0.4.4:
    resolution: {integrity: sha512-EpFcOa/ISetVHEXqu+VwI96KZBmq+a8LJnGkaeFw45epGlxIZz5dhEEnNZMsQXgORu3qaMoLX4qJCzOik6ytAg==}
  reselect@5.1.1:
    resolution: {integrity: sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==}
  resolve-from@4.0.0:
    resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
    engines: {node: '>=4'}
@@ -3006,6 +3028,25 @@
      react-is: 19.0.0
    optionalDependencies:
      '@types/react': 18.3.18
  '@mui/x-data-grid@7.27.3(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1))(@mui/material@5.16.14(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mui/system@6.4.7(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
    dependencies:
      '@babel/runtime': 7.26.9
      '@mui/material': 5.16.14(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
      '@mui/system': 6.4.7(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1)
      '@mui/utils': 6.4.6(@types/react@18.3.18)(react@18.3.1)
      '@mui/x-internals': 7.26.0(@types/react@18.3.18)(react@18.3.1)
      clsx: 2.1.1
      prop-types: 15.8.1
      react: 18.3.1
      react-dom: 18.3.1(react@18.3.1)
      reselect: 5.1.1
      use-sync-external-store: 1.4.0(react@18.3.1)
    optionalDependencies:
      '@emotion/react': 11.14.0(@types/react@18.3.18)(react@18.3.1)
      '@emotion/styled': 11.14.0(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1)
    transitivePeerDependencies:
      - '@types/react'
  '@mui/x-internals@7.26.0(@types/react@18.3.18)(react@18.3.1)':
    dependencies:
@@ -4831,6 +4872,8 @@
  remove-accents@0.4.4: {}
  reselect@5.1.1: {}
  resolve-from@4.0.0: {}
  resolve@1.22.10:
rsf-admin/src/i18n/en.js
@@ -367,12 +367,25 @@
            },
            qlyInspect: {
                code: "code",
                name: "name",
                barcode: "barcode",
                asnItemId: "asnItemId",
                poItemId: "poItemId",
                wkType: "wkType",
                safeQty: "safeQty",
                dlyQty: "dlyQty",
                rcptQty: "rcptQty",
                isptQty: "isptQty",
            },
            qlyIsptItem: {
                ispectId: "ispectId",
                matnrCode: "matnrCode",
                maktx: "maktx",
                label: "label",
                splrName: "splrName",
                splrBatch: "splrBatch",
                stockBatch: "stockBatch",
                rcptQty: "rcptQty",
                dlyQty: "dlyQty",
                disQty: "disQty",
                safeQty: "safeQty",
                picPath: "picPath",
            },
            dictType: {
                code: "Code",
@@ -447,7 +460,7 @@
                poDetlId: "poDetlId",
                poDetlCode: "poDetlCode",
                matnrId: "matnrId",
                matnk: "matnk",
                maktx: "maktx",
                anfme: "anfme",
                stockUnit: "stockUnit",
                purQty: "purQty",
rsf-admin/src/i18n/zh.js
@@ -283,15 +283,15 @@
                parentId: "父类标识",
            },
            warehouse: {
                name: "名称",
                name: "仓库名称",
                code: "编码",
                factory: "工厂",
                address: "地址",
                longitude: "经度",
                latgitude: "纬度",
                length: "长",
                width: "宽",
                height: "高",
                length: "长(m)",
                width: "宽(m)",
                height: "高(m)",
            },
            warehouseAreas: {
                uuid: "唯一编码",
@@ -367,12 +367,25 @@
            },
            qlyInspect: {
                code: "编码",
                name: "名称",
                barcode: "标签码",
                asnItemId: "通知单明细标识",
                poItemId: "PO单明细标识",
                wkType: "wkType",
                safeQty: "合格数量",
                disQty: "不合格数量",
                dlyQty: "dlyQty",
                rcptQty: "rcptQty",
                isptQty: "isptQty",
            },
            qlyIsptItem: {
                ispectId: "ispectId",
                matnrCode: "matnrCode",
                maktx: "maktx",
                label: "label",
                splrName: "splrName",
                splrBatch: "splrBatch",
                stockBatch: "stockBatch",
                rcptQty: "rcptQty",
                dlyQty: "dlyQty",
                disQty: "disQty",
                safeQty: "safeQty",
                picPath: "picPath",
            },
            dictType: {
                code: "字典编码",
@@ -447,7 +460,7 @@
                poDetlId: "PO单标识",
                poDetlCode: "PO单编码",
                matnrId: "物料标识",
                matnk: "物料名称",
                maktx: "物料名称",
                anfme: "数量",
                stockUnit: "库存单位",
                purQty: "采购数量",
rsf-admin/src/page/ResourceContent.js
@@ -21,6 +21,7 @@
import container from './container';
import contract from './contract';
import qlyInspect from './qlyInspect';
import qlyIsptItem from './qlyIsptItem';
import dictType from './system/dicts/dictType';
import dictData from './system/dicts/dictData';
import companys from './basicInfo/companys';
@@ -73,6 +74,8 @@
            return contract;
        case 'qlyInspect':
            return qlyInspect;
        case 'qlyIsptItem':
            return qlyIsptItem;
        case 'dictType':
            return dictType;
        case 'dictData':
rsf-admin/src/page/asnOrder/AsnOrderList.jsx
@@ -31,11 +31,11 @@
  ReferenceArrayInput,
  AutocompleteInput,
  DeleteButton,
  Button
  Button,
} from 'react-admin';
import { Box, Typography, Card, Stack } from '@mui/material';
import { styled } from '@mui/material/styles';
import AsnOrderCreate from "./AsnOrderCreate";
import AsnOrderModal from "./AsnOrderModal";
import AsnOrderPanel from "./AsnOrderPanel";
import EmptyData from "../components/EmptyData";
import MyCreateButton from "../components/MyCreateButton";
@@ -46,6 +46,8 @@
import * as Common from '@/utils/common';
import ConstructionIcon from "@mui/icons-material/Construction";
import FileDownloadIcon from '@mui/icons-material/FileDownload';
import EditIcon from '@mui/icons-material/Edit';
const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({
@@ -98,16 +100,17 @@
  const [createDialog, setCreateDialog] = useState(false);
  const [drawerVal, setDrawerVal] = useState(false);
  const [modalType, setmodalType] = useState(0);
  const navigate = useNavigate();
  const assign = (record) => {
    navigate(`/asnOrderItem?asnId=${record.id}`);
  };
  const importList = () => { };
  const inspection = () => { };
  const inspection = () => { };
  const print = () => { };
  return (
    <Box display="flex">
@@ -121,7 +124,7 @@
          marginRight: drawerVal ? `${PAGE_DRAWER_WIDTH}px` : 0,
        }}
        title={"menu.asnOrder"}
        empty={<EmptyData onClick={() => { setCreateDialog(true) }} />}
        empty={<EmptyData onClick={() => { setCreateDialog(true); setmodalType(0) }} />}
        filters={filters}
        sort={{ field: "create_time", order: "desc" }}
        actions={(
@@ -131,7 +134,7 @@
              <ConstructionIcon />
            </Button>
            <FilterButton />
            <MyCreateButton onClick={() => { setCreateDialog(true) }} />
            <MyCreateButton onClick={() => { setCreateDialog(true); setmodalType(0) }} />
            <SelectColumnsButton preferenceKey='asnOrder' />
            <MyExportButton />
@@ -143,7 +146,7 @@
          preferenceKey='asnOrder'
          bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />}
          rowClick={(id, resource, record) => false}
          expand={() => <AsnOrderPanel />}
          expand={(e) => <AsnOrderPanel key={Math.floor(Math.random() * 100)} />}
          expandSingle={true}
          omit={['id', 'createTime', 'createBy', 'memo']}
        >
@@ -176,18 +179,28 @@
          <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">
          <WrapperField cellClassName="opt" label="common.field.opt" >
            <Button label="toolbar.print" onClick={print}>
              <FileDownloadIcon />
            </Button>
            <EditButton sx={{ padding: '1px', fontSize: '.75rem' }} />
            {/* <EditButton sx={{ padding: '1px', fontSize: '.75rem' }} /> */}
            <MyButton setCreateDialog={setCreateDialog} setmodalType={setmodalType} />
            {/* <Button
              color="primary"
              startIcon={<EditIcon />}
              onClick={(event, record) => handleEditClick(record)}
              sx={{ ml: 1 }}
              label={'ra.action.edit'}
            >
            </Button> */}
            <DeleteButton sx={{ padding: '1px', fontSize: '.75rem' }} mutationMode={OPERATE_MODE} />
          </WrapperField>
        </StyledDatagrid>
      </List>
      <AsnOrderCreate
      <AsnOrderModal
        open={createDialog}
        setOpen={setCreateDialog}
        asnId={modalType}
      />
      <PageDrawer
        title='AsnOrder Detail'
@@ -195,7 +208,27 @@
        setDrawerVal={setDrawerVal}
      >
      </PageDrawer>
    </Box>
    </Box >
  )
}
export default AsnOrderList;
const MyButton = ({ setCreateDialog, setmodalType }) => {
  const record = useRecordContext();
  const handleEditClick = () => {
    const id = record.id;
    setmodalType(id);
    setCreateDialog(true);
  };
  return (
    <Button
      color="primary"
      startIcon={<EditIcon />}
      onClick={() => handleEditClick()}
      sx={{ ml: 1 }}
      label={'ra.action.edit'}
    >
    </Button>
  )
}
rsf-admin/src/page/asnOrder/AsnOrderModal.jsx
New file
@@ -0,0 +1,389 @@
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
} from '@mui/material';
import DialogCloseButton from "../components/DialogCloseButton";
import StatusSelectInput from "../components/StatusSelectInput";
import ConfirmButton from "../components/ConfirmButton";
import AsnWareModal from "./AsnWareModal";
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 _ from 'lodash';
import { DataGrid } from '@mui/x-data-grid';
const AsnOrderModal = (props) => {
    const { open, setOpen, asnId } = props;
    const translate = useTranslate();
    const notify = useNotify();
    const refresh = useRefresh();
    const [createDialog, setCreateDialog] = useState(false);
    useEffect(() => {
        if (open && asnId !== 0) {
            requestGetHead()
            requestGetBody()
        }
    }, [open])
    const handleClose = (event, reason) => {
        if (reason !== "backdropClick") {
            setOpen(false);
            refresh();
            setFormData({ type: '' })
            setTableData([])
        }
    };
    const [formData, setFormData] = useState({
        type: '',
    });
    const [tabelData, setTableData] = useState([]);
    const handleChange = (e) => {
        const { name, value } = e.target;
        setFormData((prevData) => ({
            ...prevData,
            [name]: value
        }));
    };
    const handleSubmit = async () => {
        if (asnId === 0) {
            const parmas = {
                "orders": formData,
                "items": tabelData,
            }
            const res = await request.post(`/asnOrder/items/save`, parmas);
            if (res?.data?.code === 200) {
                setOpen(false);
                refresh();
            } else {
                notify(res.data.msg);
            }
        } else {
            setOpen(false);
        }
    };
    const handleDelete = async () => {
        const res = await request.post(`/asnOrder/remove/${asnId}`);
        if (res?.data?.code === 200) {
            setOpen(false);
            refresh();
        } else {
            notify(res.data.msg);
        }
    };
    const requestGetHead = async () => {
        const res = await request.get(`/asnOrder/${asnId}`);
        if (res?.data?.code === 200) {
            setFormData(res.data.data)
        } else {
            notify(res.data.msg);
        }
    }
    const requestGetBody = async () => {
        const res = await request.post(`/asnOrderItem/page`, { asnId });
        if (res?.data?.code === 200) {
            setTableData(res.data.data.records)
        } else {
            notify(res.data.msg);
        }
    }
    const requestSetHead = async () => {
        if (asnId !== 0) {
            const res = await request.post(`/asnOrder/update`, { ...formData });
            refresh()
        }
    }
    return (
        <>
            <Dialog
                open={open}
                onClose={handleClose}
                aria-labelledby="form-dialog-title"
                aria-hidden
                fullWidth
                disableRestoreFocus
                maxWidth="md"   // '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 component="form" sx={{ display: 'flex', flexDirection: 'column', gap: 3 }}>
                        <form>
                            <Grid container spacing={2}>
                                <Grid item xs={4}>
                                    <TextField
                                        label={translate('table.field.asnOrder.type')}
                                        name="type"
                                        value={formData.type}
                                        onChange={handleChange}
                                        onBlur={requestSetHead}
                                        variant="outlined"
                                        size="small"
                                        validate={required()}
                                    />
                                </Grid>
                                {/* <Grid item xs={4}>
                                <TextField
                                    label={translate('table.field.asnOrder.wkType')}
                                    name="wkType"
                                    value={formData.wkType}
                                    onChange={handleChange}
                                    variant="outlined"
                                    size="small"
                                />
                            </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} />}
                        </Stack>
                    </Box>
                    <Box sx={{ mt: 2 }}>
                        <AsnOrderModalTable tabelData={tabelData} setTableData={setTableData} asnId={asnId} ></AsnOrderModalTable>
                    </Box>
                </DialogContent>
                <DialogActions sx={{ position: 'sticky', bottom: 0, backgroundColor: 'background.paper', zIndex: 1000 }}>
                    <Toolbar sx={{ width: '100%', justifyContent: 'space-between' }}  >
                        <Button onClick={handleSubmit} variant="contained" startIcon={<SaveIcon />}>
                            确认
                        </Button>
                    </Toolbar>
                </DialogActions>
            </Dialog>
            <AsnWareModal
                open={createDialog}
                setOpen={setCreateDialog}
                data={tabelData}
                setData={setTableData}
            />
        </>
    )
}
export default AsnOrderModal;
const AsnOrderModalTable = ({ tabelData, setTableData, asnId }) => {
    const translate = useTranslate();
    const columns = [
        {
            field: 'action',
            headerName: '操作',
            minWidth: 100,
            sticky: 'right',
            flex: 1,
            renderCell: (params) => (
                <Tooltip title="Delete">
                    <IconButton onClick={() => handleDelete(params.row)}>
                        <Delete />
                    </IconButton>
                </Tooltip>
            ),
        },
        {
            field: 'matnrId',
            headerName: translate('table.field.asnOrderItem.matnrId'),
            minWidth: 100,
            flex: 1,
            editable: false,
        },
        {
            field: 'maktx',
            headerName: translate('table.field.asnOrderItem.maktx'),
            minWidth: 100,
            flex: 1,
            editable: true,
        },
        {
            field: 'poDetlId',
            headerName: translate('table.field.asnOrderItem.poDetlId'),
            minWidth: 100,
            flex: 1,
        },
        {
            field: 'poDetlCode',
            headerName: translate('table.field.asnOrderItem.poDetlCode'),
            minWidth: 100,
            flex: 1,
        },
        {
            field: 'anfme',
            headerName: translate('table.field.asnOrderItem.anfme'),
            minWidth: 100,
            flex: 1,
            editable: true,
        },
        {
            field: 'stockUnit',
            headerName: translate('table.field.asnOrderItem.stockUnit'),
            minWidth: 100,
            flex: 1,
            editable: true,
        },
        {
            field: 'purQty',
            headerName: translate('table.field.asnOrderItem.purQty'),
            minWidth: 100,
            flex: 1,
            editable: true,
        },
        {
            field: 'purUnit',
            headerName: translate('table.field.asnOrderItem.purUnit'),
            minWidth: 100,
            flex: 1,
            editable: true,
        },
        {
            field: 'splrCode',
            headerName: translate('table.field.asnOrderItem.splrCode'),
            minWidth: 100,
            flex: 1,
            editable: true,
        },
        {
            field: 'splrName',
            headerName: translate('table.field.asnOrderItem.splrName'),
            minWidth: 100,
            flex: 1,
            editable: true,
        },
        {
            field: 'qrcode',
            headerName: translate('table.field.asnOrderItem.qrcode'),
            minWidth: 100,
            flex: 1,
            editable: true,
        },
        {
            field: 'barcode',
            headerName: translate('table.field.asnOrderItem.barcode'),
            minWidth: 100,
            flex: 1,
            editable: true,
        },
        {
            field: 'packName',
            headerName: translate('table.field.asnOrderItem.packName'),
            minWidth: 100,
            flex: 1,
            editable: true,
        },
    ];
    const requestSetBody = async (row) => {
        if (asnId !== 0) {
            const res = await request.post(`/asnOrderItem/update`, row);
        }
    }
    const handleDelete = (row) => {
        const newData = _.filter(tabelData, (item) => item.matnrId !== row.matnrId);
        setTableData(newData);
    };
    const processRowUpdate = (newRow, oldRow) => {
        setTableData((prevData) =>
            prevData.map((r) =>
                r.matnrId === newRow.matnrId ? { ...newRow } : r
            )
        );
        requestSetBody(newRow)
        return newRow;
    };
    return (
        <div style={{ height: 400, width: '100%' }}>
            <DataGrid
                rows={tabelData}
                columns={columns}
                disableRowSelectionOnClick
                getRowId={(row) => row.matnrId}
                disableColumnFilter
                disableColumnSelector
                disableColumnSorting
                disableMultipleColumnsSorting
                processRowUpdate={processRowUpdate}
            />
        </div>
    );
};
rsf-admin/src/page/asnOrder/AsnOrderPanel.jsx
@@ -1,93 +1,179 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import { Box, Card, CardContent, Grid, Typography, Tooltip } from '@mui/material';
import { Box, Card, CardContent, Grid, Typography, Tooltip, Paper, TableContainer, Table, TableBody, TableCell, TableHead, TableRow } from '@mui/material';
import {
    useTranslate,
    useRecordContext,
    useNotify
} from 'react-admin';
import PanelTypography from "../components/PanelTypography";
import * as Common from '@/utils/common'
import { styled } from "@mui/material/styles";
import request from '@/utils/request';
const AsnOrderPanel = () => {
    const record = useRecordContext();
    if (!record) return null;
    const translate = useTranslate();
    const notify = useNotify();
    const [rows, setRows] = useState([]);
    const asnId = record.id;
    useEffect(() => {
        http();
    }, [asnId]);
    const http = async () => {
        const res = await request.post('/asnOrderItem/page', { asnId });
        if (res?.data?.code === 200) {
            setRows(res.data.data.records)
        } else {
            notify(res.data.msg);
        }
    }
    const StyledTableRow = styled(TableRow)(({ theme }) => ({
        "& .MuiButtonBase-root.": {
            padding: "0px 0px",
        },
    }));
    const StyledTableCell = styled(TableCell)(({ theme }) => ({
        "& .MuiButtonBase-root": {
            padding: "0px 0px",
        },
        overflow: "hidden",
        textOverflow: "ellipsis",
        whiteSpace: "nowrap",
        maxWidth: 600,
    }));
    const columns = [
        {
            id: 'asnId',
            label: 'table.field.asnOrderItem.asnId',
            minWidth: 100,
        },
        {
            id: 'asnCode',
            label: 'table.field.asnOrderItem.asnCode',
            minWidth: 100,
        },
        {
            id: 'poDetlId',
            label: 'table.field.asnOrderItem.poDetlId',
            minWidth: 100,
        },
        {
            id: 'poDetlCode',
            label: 'table.field.asnOrderItem.poDetlCode',
            minWidth: 100,
        },
        {
            id: 'matnrId',
            label: 'table.field.asnOrderItem.matnrId',
            minWidth: 100,
        },
        {
            id: 'maktx',
            label: 'table.field.asnOrderItem.maktx',
            minWidth: 100,
        },
        {
            id: 'anfme',
            label: 'table.field.asnOrderItem.anfme',
            minWidth: 100,
        },
        {
            id: 'stockUnit',
            label: 'table.field.asnOrderItem.stockUnit',
            minWidth: 100,
        },
        {
            id: 'purQty',
            label: 'table.field.asnOrderItem.purQty',
            minWidth: 100,
        },
        {
            id: 'purUnit',
            label: 'table.field.asnOrderItem.purUnit',
            minWidth: 100,
        },
        {
            id: 'qty',
            label: 'table.field.asnOrderItem.qty',
            minWidth: 100,
        },
        {
            id: 'splrCode',
            label: 'table.field.asnOrderItem.splrCode',
            minWidth: 100,
        },
        {
            id: 'splrName',
            label: 'table.field.asnOrderItem.splrName',
            minWidth: 100,
        },
        {
            id: 'qrcode',
            label: 'table.field.asnOrderItem.qrcode',
            minWidth: 100,
        },
        {
            id: 'barcode',
            label: 'table.field.asnOrderItem.barcode',
            minWidth: 100,
        },
        {
            id: 'packName',
            label: 'table.field.asnOrderItem.packName',
            minWidth: 100,
        }]
    return (
        <>
            <Card sx={{ width: { xs: 300, sm: 500, md: 600, lg: 800 }, margin: 'auto' }}>
                <CardContent>
                    <Grid container spacing={2}>
                        <Grid item xs={12} container alignContent="flex-end">
                            <Typography variant="caption" color="textSecondary" sx={{ wordWrap: 'break-word', wordBreak: 'break-all' }}>
                                {Common.camelToPascalWithSpaces(translate('common.field.memo'))}:{record.memo}
                            </Typography>
                        </Grid>
                    </Grid>
                    <Box height={20}>&nbsp;</Box>
                    <Grid container spacing={2}>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.asnOrder.code"
                                property={record.code}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.asnOrder.poCode"
                                property={record.poCode}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.asnOrder.poId"
                                property={record.poId}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.asnOrder.type"
                                property={record.type}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.asnOrder.wkType"
                                property={record.wkType}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.asnOrder.anfme"
                                property={record.anfme}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.asnOrder.qty"
                                property={record.qty}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.asnOrder.logisNo"
                                property={record.logisNo}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.asnOrder.arrTime"
                                property={record.arrTime$}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.asnOrder.rleStatus"
                                property={record.rleStatus$}
                            />
                        </Grid>
                    </Grid>
                </CardContent>
            </Card >
        </>
        <Box sx={{
            position: 'relative',
            padding: '5px 10px'
        }}>
            <TableContainer component={Paper} >
                <Table size="small" >
                    <TableHead>
                        <StyledTableRow key={'head'}>
                            {columns.map((column, idx) => {
                                const value = column.label;
                                return (
                                    <>
                                        <StyledTableCell
                                            key={column.id}
                                            align={column.align || "left"}
                                        // style={{ paddingLeft: idx === 0 && (depth * 16 + 16) }}
                                        >
                                            {column.format ? column.format(value) : translate(value)}
                                        </StyledTableCell>
                                    </>
                                );
                            })}
                        </StyledTableRow>
                    </TableHead>
                    <TableBody>
                        {rows.map((row) => (
                            <StyledTableRow key={row.id + Math.random()}>
                                {columns.map((column) => (
                                    <StyledTableCell key={column.id} >
                                        {row[column.id]}
                                    </StyledTableCell>
                                ))}
                            </StyledTableRow>
                        ))}
                    </TableBody>
                </Table>
            </TableContainer>
        </Box>
    );
};
rsf-admin/src/page/asnOrder/AsnWareModal.jsx
New file
@@ -0,0 +1,198 @@
import React, { useState, useEffect } from "react";
import {
    Dialog,
    DialogActions,
    DialogContent,
    DialogTitle,
    Stack,
    Grid,
    TextField,
    Box,
    Button,
    Paper,
    styled
} from '@mui/material';
import DialogCloseButton from "../components/DialogCloseButton";
import ConfirmButton from "../components/ConfirmButton";
import { useTranslate, useNotify, useRefresh } from 'react-admin';
import request from '@/utils/request';
import { DataGrid } from '@mui/x-data-grid';
import SaveIcon from '@mui/icons-material/Save';
const AsnWareModal = (props) => {
    const { open, setOpen, data, setData } = props;
    const translate = useTranslate();
    const notify = useNotify();
    const refresh = useRefresh();
    const asnId = '';
    const handleClose = (event, reason) => {
        if (reason !== "backdropClick") {
            setOpen(false);
        }
    };
    const [formData, setFormData] = useState({
        name: '',
        code: ''
    });
    const [tableData, setTableData] = useState([]);
    const [selectedRows, setSelectedRows] = useState([]);
    const handleChange = (e) => {
        const { name, value } = e.target;
        setFormData((prevData) => ({
            ...prevData,
            [name]: value
        }));
    };
    const handleSubmit = () => {
        const selectedData = selectedRows.map(id => tableData.find(row => row.id === id));
        const value = selectedData.map((el => {
            return {
                matnrId: el.id,
                maktx: el.name,
                stockUnit: el.stockUnit || '',
                purUnit: el.purchaseUnit || '',
            }
        }))
        setData(value);
        setOpen(false);
        // refresh();
    };
    const getData = async () => {
        const res = await request.post(`/matnr/page`, {
            ...formData,
            pageSize: 199
        });
        if (res?.data?.code === 200) {
            setTableData(res.data.data.records);
        } else {
            notify(res.data.msg);
        }
    };
    useEffect(() => {
        getData();
    }, []);
    const handleSearch = () => {
        getData()
    };
    return (
        <Dialog
            open={open}
            onClose={handleClose}
            aria-labelledby="form-dialog-title"
            fullWidth
            disableRestoreFocus
            maxWidth="lg"
        >
            <DialogTitle id="form-dialog-title" sx={{
                position: 'sticky',
                top: 0,
                backgroundColor: 'background.paper',
                zIndex: 1000
            }}>
                选择物料
                <Box sx={{ position: 'absolute', top: 8, right: 8, zIndex: 1001 }}>
                    <DialogCloseButton onClose={handleClose} />
                </Box>
            </DialogTitle>
            <DialogContent sx={{ mt: 2 }}>
                <Box component="form" onSubmit={handleSubmit} sx={{ display: 'flex', flexDirection: 'column', gap: 3 }}>
                    <Grid container spacing={2}>
                        <Grid item xs={4}>
                            <TextField
                                label={translate('table.field.matnr.name')}
                                name="name"
                                value={formData.name}
                                onChange={handleChange}
                                variant="outlined"
                                size="small"
                            />
                        </Grid>
                        <Grid item xs={4}>
                            <TextField
                                label={translate('table.field.matnr.code')}
                                name="code"
                                value={formData.code}
                                onChange={handleChange}
                                variant="outlined"
                                size="small"
                            />
                        </Grid>
                    </Grid>
                </Box>
                <Box sx={{ mt: 2 }}>
                    <Stack direction="row" spacing={2}>
                        <Button variant="contained" onClick={handleSearch}>搜索</Button>
                    </Stack>
                </Box>
                <Box sx={{ mt: 2, height: 400, width: '100%' }}>
                    <AsnWareModalTable tableData={tableData} setTableData={setTableData}
                        selectedRows={selectedRows}
                        setSelectedRows={setSelectedRows} />
                </Box>
            </DialogContent>
            <DialogActions sx={{ position: 'sticky', bottom: 0, backgroundColor: 'background.paper', zIndex: 1000 }}>
                <Box sx={{ width: '100%', display: 'flex', justifyContent: 'space-between' }}>
                    <Button onClick={handleSubmit} variant="contained" startIcon={<SaveIcon />}>
                        确认
                    </Button>
                </Box>
            </DialogActions>
        </Dialog>
    );
};
export default AsnWareModal;
const AsnWareModalTable = ({ tableData, setTableData, selectedRows, setSelectedRows }) => {
    const translate = useTranslate();
    const columns = [
        { field: 'id', headerName: 'ID', width: 100 },
        { field: 'name', headerName: translate('table.field.matnr.name'), width: 100 },
        { field: 'code', headerName: translate('table.field.matnr.code'), width: 100 },
        { field: 'spec', headerName: translate('table.field.matnr.spec'), width: 100 },
        { field: 'model', headerName: translate('table.field.matnr.model'), width: 100 },
        { field: 'weight', headerName: translate('table.field.matnr.weight'), width: 100 },
        { field: 'color', headerName: translate('table.field.matnr.color'), width: 100 },
        { field: 'size', headerName: translate('table.field.matnr.size'), width: 100 },
        { field: 'describle', headerName: translate('table.field.matnr.describle'), width: 100 },
        { field: 'nromNum', headerName: translate('table.field.matnr.nromNum'), width: 100 },
        { field: 'unit', headerName: translate('table.field.matnr.unit'), width: 100 },
        { field: 'purchaseUnit', headerName: translate('table.field.matnr.purUnit'), width: 100 },
        { field: 'stockUnit', headerName: translate('table.field.matnr.stockUnit'), width: 100 },
        { field: 'stockLeval$', headerName: translate('table.field.matnr.stockLevel'), width: 100, sortable: false },
    ];
    const handleSelectionChange = (ids) => {
        setSelectedRows(ids)
    };
    return (
        <div style={{ height: 400, width: '100%' }}>
            <DataGrid
                size="small"
                rows={tableData}
                columns={columns}
                checkboxSelection
                onRowSelectionModelChange={handleSelectionChange}
                selectionModel={selectedRows}
                disableColumnMenu={true}
                disableColumnSorting
                disableMultipleColumnsSorting
                columnBufferPx={100}
            />
        </div>
    );
};
rsf-admin/src/page/asnOrderItem/AsnOrderItemCreate.jsx
@@ -121,8 +121,8 @@
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.asnOrderItem.matnk"
                                        source="matnk"
                                        label="table.field.asnOrderItem.maktx"
                                        source="maktx"
                                        parse={v => v}
                                    />
                                </Grid>
rsf-admin/src/page/asnOrderItem/AsnOrderItemEdit.jsx
@@ -100,8 +100,8 @@
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.asnOrderItem.matnk"
                                source="matnk"
                                label="table.field.asnOrderItem.maktx"
                                source="maktx"
                                parse={v => v}
                            />
                        </Stack>
rsf-admin/src/page/asnOrderItem/AsnOrderItemList.jsx
@@ -50,7 +50,8 @@
const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({
  '& .css-1vooibu-MuiSvgIcon-root': {
    height: '.9em'
    height: '.9em',
  },
  '& .RaDatagrid-row': {
    cursor: 'auto'
@@ -70,7 +71,7 @@
  <TextInput source="poDetlId" label="table.field.asnOrderItem.poDetlId" />,
  <TextInput source="poDetlCode" label="table.field.asnOrderItem.poDetlCode" />,
  <TextInput source="matnrId" label="table.field.asnOrderItem.matnrId" />,
  <TextInput source="matnk" label="table.field.asnOrderItem.matnk" />,
  <TextInput source="maktx" label="table.field.asnOrderItem.maktx" />,
  <NumberInput source="anfme" label="table.field.asnOrderItem.anfme" />,
  <TextInput source="stockUnit" label="table.field.asnOrderItem.stockUnit" />,
  <NumberInput source="purQty" label="table.field.asnOrderItem.purQty" />,
@@ -151,7 +152,7 @@
            <TextField source="poDetlId" label="table.field.asnOrderItem.poDetlId" />
            <TextField source="poDetlCode" label="table.field.asnOrderItem.poDetlCode" />
            <TextField source="matnrId" label="table.field.asnOrderItem.matnrId" />
            <TextField source="matnk" label="table.field.asnOrderItem.matnk" />
            <TextField source="maktx" label="table.field.asnOrderItem.maktx" />
            <NumberField source="anfme" label="table.field.asnOrderItem.anfme" />
            <TextField source="stockUnit" label="table.field.asnOrderItem.stockUnit" />
            <NumberField source="purQty" label="table.field.asnOrderItem.purQty" />
rsf-admin/src/page/asnOrderItem/AsnOrderItemPanel.jsx
@@ -42,97 +42,97 @@
                    <Grid container spacing={2}>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.asnOrderItem.asnId"
                                title="table.field.asnOrderItem.asnId"
                                property={record.asnId}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.asnOrderItem.asnCode"
                                title="table.field.asnOrderItem.asnCode"
                                property={record.asnCode}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.asnOrderItem.poDetlId"
                                title="table.field.asnOrderItem.poDetlId"
                                property={record.poDetlId}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.asnOrderItem.poDetlCode"
                                title="table.field.asnOrderItem.poDetlCode"
                                property={record.poDetlCode}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.asnOrderItem.matnrId"
                                title="table.field.asnOrderItem.matnrId"
                                property={record.matnrId}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.asnOrderItem.matnk"
                                property={record.matnk}
                                title="table.field.asnOrderItem.maktx"
                                property={record.maktx}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.asnOrderItem.anfme"
                                title="table.field.asnOrderItem.anfme"
                                property={record.anfme}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.asnOrderItem.stockUnit"
                                title="table.field.asnOrderItem.stockUnit"
                                property={record.stockUnit}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.asnOrderItem.purQty"
                                title="table.field.asnOrderItem.purQty"
                                property={record.purQty}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.asnOrderItem.purUnit"
                                title="table.field.asnOrderItem.purUnit"
                                property={record.purUnit}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.asnOrderItem.qty"
                                title="table.field.asnOrderItem.qty"
                                property={record.qty}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.asnOrderItem.splrCode"
                                title="table.field.asnOrderItem.splrCode"
                                property={record.splrCode}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.asnOrderItem.splrName"
                                title="table.field.asnOrderItem.splrName"
                                property={record.splrName}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.asnOrderItem.qrcode"
                                title="table.field.asnOrderItem.qrcode"
                                property={record.qrcode}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.asnOrderItem.barcode"
                                title="table.field.asnOrderItem.barcode"
                                property={record.barcode}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.asnOrderItem.packName"
                                title="table.field.asnOrderItem.packName"
                                property={record.packName}
                            />
                        </Grid>
rsf-admin/src/page/basicInfo/warehouse/WarehouseCreate.jsx
@@ -124,7 +124,7 @@
                                        source="longitude"
                                        parse={v => v}
                                    />
                                     <TextInput
                                    <TextInput
                                        label="table.field.warehouse.latgitude"
                                        source="latgitude"
                                        parse={v => v}
@@ -135,7 +135,7 @@
                                        label="table.field.warehouse.length"
                                        source="length"
                                    />
                                     <NumberInput
                                    <NumberInput
                                        label="table.field.warehouse.width"
                                        source="width"
                                    />
@@ -148,10 +148,20 @@
                                <Grid item xs={6} display="flex" gap={1}>
                                    <StatusSelectInput />
                                </Grid>
                                <Grid item xs={12} display="flex" gap={1}>
                                    <Stack direction="column" spacing={1} width={'100%'}>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="common.field.memo"
                                        source="memo"
                                        parse={v => v}
                                        fullWidth
                                        multiline
                                        minRows={2}
                                        autoFocus
                                        {...props}
                                    />
                                    {/* <Stack direction="column" spacing={1} width={'100%'}>
                                        <MemoInput />
                                    </Stack>
                                    </Stack> */}
                                </Grid>
                            </Grid>
                        </DialogContent>
rsf-admin/src/page/login/Login.jsx
@@ -179,9 +179,9 @@
                    </Button>
                </Stack>
                <Box mt={1} mb={1} sx={{ textAlign: 'center' }}>or</Box>
                {/* <Box mt={1} mb={1} sx={{ textAlign: 'center' }}>or</Box> */}
                <ProviderChoices type="LOG IN" />
                {/* <ProviderChoices type="LOG IN" /> */}
            </Box >
        </>
    )
rsf-admin/src/page/purchase/PurchasePanel.jsx
@@ -1,122 +1,181 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import { Box, Card, CardContent, Grid, Typography, Tooltip } from '@mui/material';
import { Box, Card, CardContent, Grid, Typography, Tooltip, Paper, TableContainer, Table, TableBody, TableCell, TableHead, TableRow } from '@mui/material';
import {
    useTranslate,
    useRecordContext,
    useNotify
} from 'react-admin';
import PanelTypography from "../components/PanelTypography";
import * as Common from '@/utils/common'
import { styled } from "@mui/material/styles";
import request from '@/utils/request';
const PurchasePanel = () => {
    const record = useRecordContext();
    if (!record) return null;
    const translate = useTranslate();
    return (
        <>
            <Card sx={{ width: { xs: 300, sm: 500, md: 600, lg: 800 }, margin: 'auto' }}>
                <CardContent>
                    <Grid container spacing={2}>
                        <Grid item xs={12} sx={{ display: 'flex', justifyContent: 'space-between' }}>
                            <Typography variant="h6" gutterBottom align="left" sx={{
                                maxWidth: { xs: '100px', sm: '180px', md: '260px', lg: '360px' },
                                whiteSpace: 'nowrap',
                                overflow: 'hidden',
                                textOverflow: 'ellipsis',
                            }}>
                                {Common.camelToPascalWithSpaces(translate('table.field.purchase.id'))}: {record.id}
                            </Typography>
                            {/*  inherit, primary, secondary, textPrimary, textSecondary, error */}
                            <Typography variant="h6" gutterBottom align="right" >
                                ID: {record.id}
                            </Typography>
                        </Grid>
                    </Grid>
                    <Grid container spacing={2}>
                        <Grid item xs={12} container alignContent="flex-end">
                            <Typography variant="caption" color="textSecondary" sx={{ wordWrap: 'break-word', wordBreak: 'break-all' }}>
                                {Common.camelToPascalWithSpaces(translate('common.field.memo'))}:{record.memo}
                            </Typography>
                        </Grid>
                    </Grid>
                    <Box height={20}>&nbsp;</Box>
                    <Grid container spacing={2}>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.purchase.code"
                                property={record.code}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.purchase.type"
                                property={record.type}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.purchase.source"
                                property={record.source}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.purchase.preArr"
                                property={record.preArr$}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.purchase.anfme"
                                property={record.anfme}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.purchase.qty"
                                property={record.qty}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.purchase.workQty"
                                property={record.workQty}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.purchase.channel"
                                property={record.channel}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.purchase.platCode"
                                property={record.platCode}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.purchase.startTime"
                                property={record.startTime$}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.purchase.endTime"
                                property={record.endTime$}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.purchase.project"
                                property={record.project}
                            />
                        </Grid>
    const notify = useNotify();
    const [rows, setRows] = useState([]);
    const poId = record.id;
                    </Grid>
                </CardContent>
            </Card >
        </>
    useEffect(() => {
        http();
    }, [poId]);
    const http = async () => {
        const res = await request.post('/purchaseItem/page', { purchaseId: poId });
        if (res?.data?.code === 200) {
            setRows(res.data.data.records)
        } else {
            notify(res.data.msg);
        }
    }
    const StyledTable = styled(TableRow)(({ theme }) => ({
        "& .MuiButtonBase-root.": {
            padding: "0px 0px",
        },
    }));
    const StyledTableRow = styled(TableRow)(({ theme }) => ({
        "& .MuiButtonBase-root.": {
            padding: "0px 0px",
        },
    }));
    const StyledTableCell = styled(TableCell)(({ theme }) => ({
        "& .MuiButtonBase-root": {
            padding: "0px 0px",
        },
        overflow: "hidden",
        textOverflow: "ellipsis",
        whiteSpace: "nowrap",
        maxWidth: 600,
    }));
    const columns = [
        {
            id: 'purchaseId',
            label: 'table.field.purchaseItem.purchaseId',
            minWidth: 100
        },
        {
            id: 'platItemId',
            label: 'table.field.purchaseItem.platItemId',
            minWidth: 100
        },
        {
            id: 'matnrCode',
            label: 'table.field.purchaseItem.matnrCode',
            minWidth: 100
        },
        {
            id: 'matnrName',
            label: 'table.field.purchaseItem.matnrName',
            minWidth: 100
        },
        {
            id: 'unit',
            label: 'table.field.purchaseItem.unit',
            minWidth: 100
        },
        {
            id: 'anfme',
            label: 'table.field.purchaseItem.anfme',
            minWidth: 100
        },
        {
            id: 'qty',
            label: 'table.field.purchaseItem.qty',
            minWidth: 100
        },
        {
            id: 'nromQty',
            label: 'table.field.purchaseItem.nromQty',
            minWidth: 100
        },
        {
            id: 'asnQty',
            label: 'table.field.purchaseItem.asnQty',
            minWidth: 100
        },
        {
            id: 'printQty',
            label: 'table.field.purchaseItem.printQty',
            minWidth: 100
        },
        {
            id: 'splrName',
            label: 'table.field.purchaseItem.splrName',
            minWidth: 100
        },
        {
            id: 'splrCode',
            label: 'table.field.purchaseItem.splrCode',
            minWidth: 100
        },
        {
            id: 'splrBatch',
            label: 'table.field.purchaseItem.splrBatch',
            minWidth: 100
        },
        {
            id: 'statusBool',
            label: 'common.field.status',
            minWidth: 100,
            formatter: (value) => value ? 'Yes' : 'No'
        },
        {
            id: 'memo',
            label: 'common.field.memo',
            minWidth: 100
        }
    ];
    return (
        <Box sx={{
            position: 'relative',
            padding: '5px 10px'
        }}>
            <TableContainer component={Paper} >
                <Table size="small" >
                    <TableHead>
                        <StyledTableRow key={'head'}>
                            {columns.map((column, idx) => {
                                const value = column.label;
                                return (
                                    <>
                                        <StyledTableCell
                                            key={column.id}
                                            align={column.align || "left"}
                                        // style={{ paddingLeft: idx === 0 && (depth * 16 + 16) }}
                                        >
                                            {column.format ? column.format(value) : translate(value)}
                                        </StyledTableCell>
                                    </>
                                );
                            })}
                        </StyledTableRow>
                    </TableHead>
                    <TableBody>
                        {rows.map((row) => (
                            <StyledTableRow key={row.id || Math.random()}>
                                {columns.map((column) => (
                                    <StyledTableCell key={column.id} >
                                        {row[column.id]}
                                    </StyledTableCell>
                                ))}
                            </StyledTableRow>
                        ))}
                    </TableBody>
                </Table>
            </TableContainer>
        </Box>
    );
};
rsf-admin/src/page/purchaseItem/PurchaseItemPanel.jsx
@@ -42,7 +42,7 @@
                    <Grid container spacing={2}>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.purchaseItem.purchaseId"
                                title="table.field.purchaseItem.purchaseId"
                                property={record.purchaseId}
                            />
                        </Grid>
@@ -54,31 +54,31 @@
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.purchaseItem.matnrCode"
                                title="table.field.purchaseItem.matnrCode"
                                property={record.matnrCode}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.purchaseItem.matnrName"
                                title="table.field.purchaseItem.matnrName"
                                property={record.matnrName}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.purchaseItem.unit"
                                title="table.field.purchaseItem.unit"
                                property={record.unit}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.purchaseItem.anfme"
                                title="table.field.purchaseItem.anfme"
                                property={record.anfme}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.purchaseItem.qty"
                                title="table.field.purchaseItem.qty"
                                property={record.qty}
                            />
                        </Grid>
@@ -90,13 +90,13 @@
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.purchaseItem.asnQty"
                                title="table.field.purchaseItem.asnQty"
                                property={record.asnQty}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.purchaseItem.printQty"
                                title="table.field.purchaseItem.printQty"
                                property={record.printQty}
                            />
                        </Grid>
rsf-admin/src/page/qlyInspect/QlyInspectCreate.jsx
@@ -95,28 +95,9 @@
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.qlyInspect.name"
                                        source="name"
                                        label="table.field.qlyInspect.wkType"
                                        source="wkType"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.qlyInspect.barcode"
                                        source="barcode"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.qlyInspect.asnItemId"
                                        source="asnItemId"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.qlyInspect.poItemId"
                                        source="poItemId"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
@@ -127,8 +108,20 @@
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.qlyInspect.disQty"
                                        source="disQty"
                                        label="table.field.qlyInspect.dlyQty"
                                        source="dlyQty"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.qlyInspect.rcptQty"
                                        source="rcptQty"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.qlyInspect.isptQty"
                                        source="isptQty"
                                    />
                                </Grid>
rsf-admin/src/page/qlyInspect/QlyInspectEdit.jsx
@@ -74,28 +74,9 @@
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.qlyInspect.name"
                                source="name"
                                label="table.field.qlyInspect.wkType"
                                source="wkType"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.qlyInspect.barcode"
                                source="barcode"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.qlyInspect.asnItemId"
                                source="asnItemId"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.qlyInspect.poItemId"
                                source="poItemId"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
@@ -106,8 +87,20 @@
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.qlyInspect.disQty"
                                source="disQty"
                                label="table.field.qlyInspect.dlyQty"
                                source="dlyQty"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.qlyInspect.rcptQty"
                                source="rcptQty"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.qlyInspect.isptQty"
                                source="isptQty"
                            />
                        </Stack>
rsf-admin/src/page/qlyInspect/QlyInspectList.jsx
@@ -64,12 +64,11 @@
    <DateInput label='common.time.before' source="timeEnd" alwaysOn />,
    <TextInput source="code" label="table.field.qlyInspect.code" />,
    <TextInput source="name" label="table.field.qlyInspect.name" />,
    <TextInput source="barcode" label="table.field.qlyInspect.barcode" />,
    <NumberInput source="asnItemId" label="table.field.qlyInspect.asnItemId" />,
    <NumberInput source="poItemId" label="table.field.qlyInspect.poItemId" />,
    <TextInput source="wkType" label="table.field.qlyInspect.wkType" />,
    <NumberInput source="safeQty" label="table.field.qlyInspect.safeQty" />,
    <NumberInput source="disQty" label="table.field.qlyInspect.disQty" />,
    <NumberInput source="dlyQty" label="table.field.qlyInspect.dlyQty" />,
    <NumberInput source="rcptQty" label="table.field.qlyInspect.rcptQty" />,
    <NumberInput source="isptQty" label="table.field.qlyInspect.isptQty" />,
    <TextInput label="common.field.memo" source="memo" />,
    <SelectInput
@@ -124,12 +123,11 @@
                >
                    <NumberField source="id" />
                    <TextField source="code" label="table.field.qlyInspect.code" />
                    <TextField source="name" label="table.field.qlyInspect.name" />
                    <TextField source="barcode" label="table.field.qlyInspect.barcode" />
                    <NumberField source="asnItemId" label="table.field.qlyInspect.asnItemId" />
                    <NumberField source="poItemId" label="table.field.qlyInspect.poItemId" />
                    <TextField source="wkType" label="table.field.qlyInspect.wkType" />
                    <NumberField source="safeQty" label="table.field.qlyInspect.safeQty" />
                    <NumberField source="disQty" label="table.field.qlyInspect.disQty" />
                    <NumberField source="dlyQty" label="table.field.qlyInspect.dlyQty" />
                    <NumberField source="rcptQty" label="table.field.qlyInspect.rcptQty" />
                    <NumberField source="isptQty" label="table.field.qlyInspect.isptQty" />
                    <ReferenceField source="updateBy" label="common.field.updateBy" reference="user" link={false} sortable={false}>
                        <TextField source="nickname" />
rsf-admin/src/page/qlyInspect/QlyInspectPanel.jsx
@@ -23,7 +23,7 @@
                                overflow: 'hidden',
                                textOverflow: 'ellipsis',
                            }}>
                                {Common.camelToPascalWithSpaces(translate('table.field.qlyInspect.name'))}: {record.name}
                                {Common.camelToPascalWithSpaces(translate('table.field.qlyInspect.id'))}: {record.id}
                            </Typography>
                            {/*  inherit, primary, secondary, textPrimary, textSecondary, error */}
                            <Typography variant="h6" gutterBottom align="right" >
@@ -48,26 +48,8 @@
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.qlyInspect.name"
                                property={record.name}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.qlyInspect.barcode"
                                property={record.barcode}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.qlyInspect.asnItemId"
                                property={record.asnItemId}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.qlyInspect.poItemId"
                                property={record.poItemId}
                                title="table.field.qlyInspect.wkType"
                                property={record.wkType}
                            />
                        </Grid>
                        <Grid item xs={6}>
@@ -78,8 +60,20 @@
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.qlyInspect.disQty"
                                property={record.disQty}
                                title="table.field.qlyInspect.dlyQty"
                                property={record.dlyQty}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.qlyInspect.rcptQty"
                                property={record.rcptQty}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.qlyInspect.isptQty"
                                property={record.isptQty}
                            />
                        </Grid>
rsf-admin/src/page/qlyInspect/index.jsx
@@ -13,6 +13,6 @@
    edit: QlyInspectEdit,
    show: ShowGuesser,
    recordRepresentation: (record) => {
        return `${record.name}`
        return `${record.id}`
    }
};
rsf-admin/src/page/qlyIsptItem/QlyIsptItemCreate.jsx
New file
@@ -0,0 +1,190 @@
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 QlyIsptItemCreate = (props) => {
    const { open, setOpen } = props;
    const translate = useTranslate();
    const notify = useNotify();
    const handleClose = (event, reason) => {
        if (reason !== "backdropClick") {
            setOpen(false);
        }
    };
    const handleSuccess = async (data) => {
        setOpen(false);
        notify('common.response.success');
    };
    const handleError = async (error) => {
        notify(error.message || 'common.response.fail', { type: 'error', messageArgs: { _: error.message } });
    };
    return (
        <>
            <CreateBase
                record={{}}
                transform={(data) => {
                    return data;
                }}
                mutationOptions={{ onSuccess: handleSuccess, onError: handleError }}
            >
                <Dialog
                    open={open}
                    onClose={handleClose}
                    aria-labelledby="form-dialog-title"
                    fullWidth
                    disableRestoreFocus
                    maxWidth="md"   // 'xs' | 'sm' | 'md' | 'lg' | 'xl'
                >
                    <Form>
                        <DialogTitle id="form-dialog-title" sx={{
                            position: 'sticky',
                            top: 0,
                            backgroundColor: 'background.paper',
                            zIndex: 1000
                        }}
                        >
                            {translate('create.title')}
                            <Box sx={{ position: 'absolute', top: 8, right: 8, zIndex: 1001 }}>
                                <DialogCloseButton onClose={handleClose} />
                            </Box>
                        </DialogTitle>
                        <DialogContent sx={{ mt: 2 }}>
                            <Grid container rowSpacing={2} columnSpacing={2}>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.qlyIsptItem.ispectId"
                                        source="ispectId"
                                        autoFocus
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.qlyIsptItem.matnrCode"
                                        source="matnrCode"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.qlyIsptItem.maktx"
                                        source="maktx"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.qlyIsptItem.label"
                                        source="label"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.qlyIsptItem.splrName"
                                        source="splrName"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.qlyIsptItem.splrBatch"
                                        source="splrBatch"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.qlyIsptItem.stockBatch"
                                        source="stockBatch"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.qlyIsptItem.rcptQty"
                                        source="rcptQty"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.qlyIsptItem.dlyQty"
                                        source="dlyQty"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.qlyIsptItem.disQty"
                                        source="disQty"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.qlyIsptItem.safeQty"
                                        source="safeQty"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.qlyIsptItem.picPath"
                                        source="picPath"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <StatusSelectInput />
                                </Grid>
                                <Grid item xs={12} display="flex" gap={1}>
                                    <Stack direction="column" spacing={1} width={'100%'}>
                                        <MemoInput />
                                    </Stack>
                                </Grid>
                            </Grid>
                        </DialogContent>
                        <DialogActions sx={{ position: 'sticky', bottom: 0, backgroundColor: 'background.paper', zIndex: 1000 }}>
                            <Toolbar sx={{ width: '100%', justifyContent: 'space-between' }}  >
                                <SaveButton />
                            </Toolbar>
                        </DialogActions>
                    </Form>
                </Dialog>
            </CreateBase>
        </>
    )
}
export default QlyIsptItemCreate;
rsf-admin/src/page/qlyIsptItem/QlyIsptItemEdit.jsx
New file
@@ -0,0 +1,162 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import {
    Edit,
    SimpleForm,
    FormDataConsumer,
    useTranslate,
    TextInput,
    NumberInput,
    BooleanInput,
    DateInput,
    SelectInput,
    ReferenceInput,
    ReferenceArrayInput,
    AutocompleteInput,
    SaveButton,
    Toolbar,
    Labeled,
    NumberField,
    required,
    useRecordContext,
    DeleteButton,
} from 'react-admin';
import { useWatch, useFormContext } from "react-hook-form";
import { Stack, Grid, Box, Typography } from '@mui/material';
import * as Common from '@/utils/common';
import { EDIT_MODE, REFERENCE_INPUT_PAGESIZE } from '@/config/setting';
import EditBaseAside from "../components/EditBaseAside";
import CustomerTopToolBar from "../components/EditTopToolBar";
import MemoInput from "../components/MemoInput";
import StatusSelectInput from "../components/StatusSelectInput";
const FormToolbar = () => {
    const { getValues } = useFormContext();
    return (
        <Toolbar sx={{ justifyContent: 'space-between' }}>
            <SaveButton />
            <DeleteButton mutationMode="optimistic" />
        </Toolbar>
    )
}
const QlyIsptItemEdit = () => {
    const translate = useTranslate();
    return (
        <Edit
            redirect="list"
            mutationMode={EDIT_MODE}
            actions={<CustomerTopToolBar />}
            aside={<EditBaseAside />}
        >
            <SimpleForm
                shouldUnregister
                warnWhenUnsavedChanges
                toolbar={<FormToolbar />}
                mode="onTouched"
                defaultValues={{}}
            // validate={(values) => { }}
            >
                <Grid container width={{ xs: '100%', xl: '80%' }} rowSpacing={3} columnSpacing={3}>
                    <Grid item xs={12} md={8}>
                        <Typography variant="h6" gutterBottom>
                            {translate('common.edit.title.main')}
                        </Typography>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.qlyIsptItem.ispectId"
                                source="ispectId"
                                autoFocus
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.qlyIsptItem.matnrCode"
                                source="matnrCode"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.qlyIsptItem.maktx"
                                source="maktx"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.qlyIsptItem.label"
                                source="label"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.qlyIsptItem.splrName"
                                source="splrName"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.qlyIsptItem.splrBatch"
                                source="splrBatch"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.qlyIsptItem.stockBatch"
                                source="stockBatch"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.qlyIsptItem.rcptQty"
                                source="rcptQty"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.qlyIsptItem.dlyQty"
                                source="dlyQty"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.qlyIsptItem.disQty"
                                source="disQty"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.qlyIsptItem.safeQty"
                                source="safeQty"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.qlyIsptItem.picPath"
                                source="picPath"
                                parse={v => v}
                            />
                        </Stack>
                    </Grid>
                    <Grid item xs={12} md={4}>
                        <Typography variant="h6" gutterBottom>
                            {translate('common.edit.title.common')}
                        </Typography>
                        <StatusSelectInput />
                        <Box mt="2em" />
                        <MemoInput />
                    </Grid>
                </Grid>
            </SimpleForm>
        </Edit >
    )
}
export default QlyIsptItemEdit;
rsf-admin/src/page/qlyIsptItem/QlyIsptItemList.jsx
New file
@@ -0,0 +1,174 @@
import React, { useState, useRef, useEffect, useMemo, useCallback } from "react";
import { useNavigate } from 'react-router-dom';
import {
    List,
    DatagridConfigurable,
    SearchInput,
    TopToolbar,
    SelectColumnsButton,
    EditButton,
    FilterButton,
    CreateButton,
    ExportButton,
    BulkDeleteButton,
    WrapperField,
    useRecordContext,
    useTranslate,
    useNotify,
    useListContext,
    FunctionField,
    TextField,
    NumberField,
    DateField,
    BooleanField,
    ReferenceField,
    TextInput,
    DateTimeInput,
    DateInput,
    SelectInput,
    NumberInput,
    ReferenceInput,
    ReferenceArrayInput,
    AutocompleteInput,
    DeleteButton,
} from 'react-admin';
import { Box, Typography, Card, Stack } from '@mui/material';
import { styled } from '@mui/material/styles';
import QlyIsptItemCreate from "./QlyIsptItemCreate";
import QlyIsptItemPanel from "./QlyIsptItemPanel";
import EmptyData from "../components/EmptyData";
import MyCreateButton from "../components/MyCreateButton";
import MyExportButton from '../components/MyExportButton';
import PageDrawer from "../components/PageDrawer";
import MyField from "../components/MyField";
import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting';
import * as Common from '@/utils/common';
const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({
    '& .css-1vooibu-MuiSvgIcon-root': {
        height: '.9em'
    },
    '& .RaDatagrid-row': {
        cursor: 'auto'
    },
    '& .column-name': {
    },
    '& .opt': {
        width: 200
    },
}));
const filters = [
    <SearchInput source="condition" alwaysOn />,
    <DateInput label='common.time.after' source="timeStart" alwaysOn />,
    <DateInput label='common.time.before' source="timeEnd" alwaysOn />,
    <NumberInput source="ispectId" label="table.field.qlyIsptItem.ispectId" />,
    <TextInput source="matnrCode" label="table.field.qlyIsptItem.matnrCode" />,
    <TextInput source="maktx" label="table.field.qlyIsptItem.maktx" />,
    <TextInput source="label" label="table.field.qlyIsptItem.label" />,
    <TextInput source="splrName" label="table.field.qlyIsptItem.splrName" />,
    <TextInput source="splrBatch" label="table.field.qlyIsptItem.splrBatch" />,
    <TextInput source="stockBatch" label="table.field.qlyIsptItem.stockBatch" />,
    <NumberInput source="rcptQty" label="table.field.qlyIsptItem.rcptQty" />,
    <NumberInput source="dlyQty" label="table.field.qlyIsptItem.dlyQty" />,
    <NumberInput source="disQty" label="table.field.qlyIsptItem.disQty" />,
    <NumberInput source="safeQty" label="table.field.qlyIsptItem.safeQty" />,
    <TextInput source="picPath" label="table.field.qlyIsptItem.picPath" />,
    <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 QlyIsptItemList = () => {
    const translate = useTranslate();
    const [createDialog, setCreateDialog] = useState(false);
    const [drawerVal, setDrawerVal] = useState(false);
    return (
        <Box display="flex">
            <List
                sx={{
                    flexGrow: 1,
                    transition: (theme) =>
                        theme.transitions.create(['all'], {
                            duration: theme.transitions.duration.enteringScreen,
                        }),
                    marginRight: !!drawerVal ? `${PAGE_DRAWER_WIDTH}px` : 0,
                }}
                title={"menu.qlyIsptItem"}
                empty={<EmptyData onClick={() => { setCreateDialog(true) }} />}
                filters={filters}
                sort={{ field: "create_time", order: "desc" }}
                actions={(
                    <TopToolbar>
                        <FilterButton />
                        <MyCreateButton onClick={() => { setCreateDialog(true) }} />
                        <SelectColumnsButton preferenceKey='qlyIsptItem' />
                        <MyExportButton />
                    </TopToolbar>
                )}
                perPage={DEFAULT_PAGE_SIZE}
            >
                <StyledDatagrid
                    preferenceKey='qlyIsptItem'
                    bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />}
                    rowClick={(id, resource, record) => false}
                    expand={() => <QlyIsptItemPanel />}
                    expandSingle={true}
                    omit={['id', 'createTime', 'createBy', 'memo']}
                >
                    <NumberField source="id" />
                    <NumberField source="ispectId" label="table.field.qlyIsptItem.ispectId" />
                    <TextField source="matnrCode" label="table.field.qlyIsptItem.matnrCode" />
                    <TextField source="maktx" label="table.field.qlyIsptItem.maktx" />
                    <TextField source="label" label="table.field.qlyIsptItem.label" />
                    <TextField source="splrName" label="table.field.qlyIsptItem.splrName" />
                    <TextField source="splrBatch" label="table.field.qlyIsptItem.splrBatch" />
                    <TextField source="stockBatch" label="table.field.qlyIsptItem.stockBatch" />
                    <NumberField source="rcptQty" label="table.field.qlyIsptItem.rcptQty" />
                    <NumberField source="dlyQty" label="table.field.qlyIsptItem.dlyQty" />
                    <NumberField source="disQty" label="table.field.qlyIsptItem.disQty" />
                    <NumberField source="safeQty" label="table.field.qlyIsptItem.safeQty" />
                    <TextField source="picPath" label="table.field.qlyIsptItem.picPath" />
                    <ReferenceField source="updateBy" label="common.field.updateBy" reference="user" link={false} sortable={false}>
                        <TextField source="nickname" />
                    </ReferenceField>
                    <DateField source="updateTime" label="common.field.updateTime" showTime />
                    <ReferenceField source="createBy" label="common.field.createBy" reference="user" link={false} sortable={false}>
                        <TextField source="nickname" />
                    </ReferenceField>
                    <DateField source="createTime" label="common.field.createTime" showTime />
                    <BooleanField source="statusBool" label="common.field.status" sortable={false} />
                    <TextField source="memo" label="common.field.memo" sortable={false} />
                    <WrapperField cellClassName="opt" label="common.field.opt">
                        <EditButton sx={{ padding: '1px', fontSize: '.75rem' }} />
                        <DeleteButton sx={{ padding: '1px', fontSize: '.75rem' }} mutationMode={OPERATE_MODE} />
                    </WrapperField>
                </StyledDatagrid>
            </List>
            <QlyIsptItemCreate
                open={createDialog}
                setOpen={setCreateDialog}
            />
            <PageDrawer
                title='QlyIsptItem Detail'
                drawerVal={drawerVal}
                setDrawerVal={setDrawerVal}
            >
            </PageDrawer>
        </Box>
    )
}
export default QlyIsptItemList;
rsf-admin/src/page/qlyIsptItem/QlyIsptItemPanel.jsx
New file
@@ -0,0 +1,123 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import { Box, Card, CardContent, Grid, Typography, Tooltip } from '@mui/material';
import {
    useTranslate,
    useRecordContext,
} from 'react-admin';
import PanelTypography from "../components/PanelTypography";
import * as Common from '@/utils/common'
const QlyIsptItemPanel = () => {
    const record = useRecordContext();
    if (!record) return null;
    const translate = useTranslate();
    return (
        <>
            <Card sx={{ width: { xs: 300, sm: 500, md: 600, lg: 800 }, margin: 'auto' }}>
                <CardContent>
                    <Grid container spacing={2}>
                        <Grid item xs={12} sx={{ display: 'flex', justifyContent: 'space-between' }}>
                            <Typography variant="h6" gutterBottom align="left" sx={{
                                maxWidth: { xs: '100px', sm: '180px', md: '260px', lg: '360px' },
                                whiteSpace: 'nowrap',
                                overflow: 'hidden',
                                textOverflow: 'ellipsis',
                            }}>
                                {Common.camelToPascalWithSpaces(translate('table.field.qlyIsptItem.id'))}: {record.id}
                            </Typography>
                            {/*  inherit, primary, secondary, textPrimary, textSecondary, error */}
                            <Typography variant="h6" gutterBottom align="right" >
                                ID: {record.id}
                            </Typography>
                        </Grid>
                    </Grid>
                    <Grid container spacing={2}>
                        <Grid item xs={12} container alignContent="flex-end">
                            <Typography variant="caption" color="textSecondary" sx={{ wordWrap: 'break-word', wordBreak: 'break-all' }}>
                                {Common.camelToPascalWithSpaces(translate('common.field.memo'))}:{record.memo}
                            </Typography>
                        </Grid>
                    </Grid>
                    <Box height={20}>&nbsp;</Box>
                    <Grid container spacing={2}>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.qlyIsptItem.ispectId"
                                property={record.ispectId}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.qlyIsptItem.matnrCode"
                                property={record.matnrCode}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.qlyIsptItem.maktx"
                                property={record.maktx}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.qlyIsptItem.label"
                                property={record.label}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.qlyIsptItem.splrName"
                                property={record.splrName}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.qlyIsptItem.splrBatch"
                                property={record.splrBatch}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.qlyIsptItem.stockBatch"
                                property={record.stockBatch}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.qlyIsptItem.rcptQty"
                                property={record.rcptQty}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.qlyIsptItem.dlyQty"
                                property={record.dlyQty}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.qlyIsptItem.disQty"
                                property={record.disQty}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.qlyIsptItem.safeQty"
                                property={record.safeQty}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.qlyIsptItem.picPath"
                                property={record.picPath}
                            />
                        </Grid>
                    </Grid>
                </CardContent>
            </Card >
        </>
    );
};
export default QlyIsptItemPanel;
rsf-admin/src/page/qlyIsptItem/index.jsx
New file
@@ -0,0 +1,18 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import {
    ListGuesser,
    EditGuesser,
    ShowGuesser,
} from "react-admin";
import QlyIsptItemList from "./QlyIsptItemList";
import QlyIsptItemEdit from "./QlyIsptItemEdit";
export default {
    list: QlyIsptItemList,
    edit: QlyIsptItemEdit,
    show: ShowGuesser,
    recordRepresentation: (record) => {
        return `${record.id}`
    }
};
rsf-admin/vite.config.js
@@ -20,6 +20,10 @@
        '/rsf-server': {
          target: `http://${env.VITE_BASE_IP}:${env.VITE_BASE_PORT}`,
          changeOrigin: true,
          bypass: (req, res, options) => {
            const proxyUrl = `${options.target}${req.url}`;
            res.setHeader('x-rel-url', proxyUrl);
          }
          // rewrite: (path) => path.replace(/^\/api/, ''),
        },
        '/ws': {