From c73bfe563e19aee0fcf2465a0982bb307cc4c249 Mon Sep 17 00:00:00 2001
From: skyouc
Date: 星期五, 11 七月 2025 17:09:44 +0800
Subject: [PATCH] no message
---
rsf-server/src/main/java/com/vincent/rsf/server/manager/schedules/TaskSchedules.java | 6
rsf-server/src/main/java/com/vincent/rsf/server/system/constant/SerialRuleCode.java | 3
rsf-admin/src/page/orders/check/CheckOrderList.jsx | 313 ++++++
rsf-admin/src/page/orders/check/CheckOrderCreate.jsx | 221 ++++
rsf-admin/src/page/orders/check/OutOrderPreview.jsx | 141 ++
rsf-admin/src/page/warehouseAreas/WarehouseAreasList.jsx | 127 ++
rsf-admin/src/page/orders/check/CheckOrderItemCreate.jsx | 200 ++++
rsf-admin/src/page/orders/check/SelectMatnrModal.jsx | 585 +++++++++++
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/CheckOrderController.java | 125 ++
rsf-server/src/main/java/com/vincent/rsf/server/manager/mapper/CheckOrderMapper.java | 12
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/CheckOrderService.java | 8
rsf-admin/src/page/orders/check/index.jsx | 18
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/CheckOrderServiceImpl.java | 12
rsf-admin/src/page/orders/check/CheckOrderItemList.jsx | 185 +++
rsf-admin/src/i18n/zh.js | 17
rsf-admin/src/page/orders/check/CheckOrderEdit.jsx | 138 ++
rsf-admin/src/i18n/en.js | 15
rsf-admin/src/page/ResourceContent.js | 3
rsf-admin/src/page/orders/check/OutOrderModal.jsx | 279 +++++
rsf-admin/src/page/orders/check/OutStockPublic.jsx | 480 +++++++++
rsf-server/src/main/java/com/vincent/rsf/server/manager/enums/OrderType.java | 1
rsf-server/src/main/resources/application-dev.yml | 2
22 files changed, 2,859 insertions(+), 32 deletions(-)
diff --git a/rsf-admin/src/i18n/en.js b/rsf-admin/src/i18n/en.js
index 8dcd005..f78e81e 100644
--- a/rsf-admin/src/i18n/en.js
+++ b/rsf-admin/src/i18n/en.js
@@ -606,6 +606,21 @@
ntyStatus: "Notify",
exceStatus: 'bill status'
},
+ checkOrder: {
+ code: "Check Code",
+ poCode: "Po Code",
+ poId: "Po Id",
+ type: "Type",
+ wkType: "Work Type",
+ anfme: "Anfme",
+ workQty: 'Work Qty',
+ qty: "Qty",
+ logisNo: "Logis No",
+ arrTime: "arrived Time",
+ rleStatus: "閲婃斁鐘舵��",
+ ntyStatus: "涓婃姤鐘舵��",
+ exceStatus: '鍗曟嵁鐘舵��'
+ },
outStockItem: {
asnId: "ID",
asnCode: "Out Code",
diff --git a/rsf-admin/src/i18n/zh.js b/rsf-admin/src/i18n/zh.js
index 18807a3..331427a 100644
--- a/rsf-admin/src/i18n/zh.js
+++ b/rsf-admin/src/i18n/zh.js
@@ -213,7 +213,7 @@
checkOutBound: '鐩樼偣鍑哄簱',
stockTransfer: '搴撲綅杞Щ',
waveRule: '娉㈡绛栫暐',
-
+ checkOrder: '鐩樼偣鍗�',
},
table: {
field: {
@@ -631,6 +631,21 @@
ntyStatus: "涓婃姤鐘舵��",
exceStatus: '鍗曟嵁鐘舵��'
},
+ checkOrder: {
+ code: "鐩樼偣鍗曞彿",
+ poCode: "DO鍗曞彿",
+ poId: "DO鏍囪瘑",
+ type: "绫诲瀷",
+ wkType: "涓氬姟绫诲瀷",
+ anfme: "鏁伴噺",
+ workQty: '鎵ц鏁�',
+ qty: "瀹屾垚鏁�",
+ logisNo: "鐗╂祦鍗曞彿",
+ arrTime: "棰勮鍒拌揪鏃堕棿",
+ rleStatus: "閲婃斁鐘舵��",
+ ntyStatus: "涓婃姤鐘舵��",
+ exceStatus: '鍗曟嵁鐘舵��'
+ },
asnOrderItem: {
asnId: "涓诲崟鏍囪瘑",
asnCode: "鍗曞彿",
diff --git a/rsf-admin/src/page/ResourceContent.js b/rsf-admin/src/page/ResourceContent.js
index 34a1747..6ff29cf 100644
--- a/rsf-admin/src/page/ResourceContent.js
+++ b/rsf-admin/src/page/ResourceContent.js
@@ -53,6 +53,7 @@
import checkOutBound from "./work/checkOutBound";
import stockTransfer from "./work/stockTransfer";
import waveRule from './waveRule';
+import check from './orders/check';
const ResourceContent = (node) => {
switch (node.component) {
@@ -154,6 +155,8 @@
return stockTransfer;
case 'waveRule':
return waveRule;
+ case 'check':
+ return check;
default:
return {
list: ListGuesser,
diff --git a/rsf-admin/src/page/orders/check/CheckOrderCreate.jsx b/rsf-admin/src/page/orders/check/CheckOrderCreate.jsx
new file mode 100644
index 0000000..40fba47
--- /dev/null
+++ b/rsf-admin/src/page/orders/check/CheckOrderCreate.jsx
@@ -0,0 +1,221 @@
+import React, { useState, useRef, useEffect, useMemo } from "react";
+import {
+ CreateBase,
+ useTranslate,
+ TextInput,
+ NumberInput,
+ BooleanInput,
+ TextField,
+ WrapperField,
+ NumberField,
+ DateInput,
+ TopToolbar,
+ SelectColumnsButton,
+ DatagridConfigurable,
+ SaveButton,
+ SelectInput,
+ ReferenceInput,
+ ReferenceArrayInput,
+ AutocompleteInput,
+ Toolbar,
+ required,
+ useDataProvider,
+ useNotify,
+ Form,
+ useCreateController,
+ useGetList,
+ useList,
+ ListContextProvider,
+ useListContext,
+ Button,
+ useRecordContext,
+} from 'react-admin';
+import {
+ Dialog,
+ DialogActions,
+ DialogContent,
+ DialogTitle,
+ Stack,
+ Grid,
+ Box,
+} from '@mui/material';
+import DialogCloseButton from "../../components/DialogCloseButton";
+import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting';
+import { styled } from '@mui/material/styles';
+import StatusSelectInput from "../../components/StatusSelectInput";
+import OutOrderItemList from "./OutOrderItemList";
+import MemoInput from "../../components/MemoInput";
+import AddIcon from '@mui/icons-material/Add';
+import SelectMatnrModal from "./SelectMatnrModal";
+
+const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({
+ '& .css-1vooibu-MuiSvgIcon-root': {
+ height: '.9em'
+ },
+ '& .RaDatagrid-row': {
+ cursor: 'auto'
+ },
+ '& .column-name': {
+ },
+ '& .opt': {
+ width: 200
+ },
+}));
+
+
+const OutOrderCreate = (props) => {
+ const { open, setOpen, record } = props;
+ const dicts = JSON.parse(localStorage.getItem('sys_dicts'))?.filter(dict => (dict.dictTypeCode == 'sys_order_type')) || [];
+ const business = JSON.parse(localStorage.getItem('sys_dicts'))?.filter(dict => (dict.dictTypeCode == 'sys_business_type')) || [];
+ const translate = useTranslate();
+ const notify = useNotify();
+ const [drawerVal, setDrawerVal] = useState(false);
+ const [matCreate, setMatCreate] = useState(false);
+
+ const handleClose = (event, reason) => {
+ if (reason !== "backdropClick") {
+ setOpen(false);
+ }
+ };
+
+ const handleSuccess = async (data) => {
+ setOpen(false);
+ notify('common.response.success');
+ };
+
+ const handleError = async (error) => {
+ notify(error.message || 'common.response.fail', { type: 'error', messageArgs: { _: error.message } });
+ };
+
+ const { data, total, isPending, error, refetch, meta } = useGetList('/wave/locs/preview', { filter: { waveId: record?.id } });
+ const listContext = useList({ data, isPending });
+
+ return (
+ <>
+ <CreateBase
+ record={{}}
+ transform={(data) => {
+ return data;
+ }}
+ mutationOptions={{ onSuccess: handleSuccess, onError: handleError }}
+ >
+ <Dialog
+ open={open}
+ onClose={handleClose}
+ aria-labelledby="form-dialog-title"
+ fullWidth
+ disableRestoreFocus
+ maxWidth="xl" // 'xs' | 'sm' | 'md' | 'lg' | 'xl'
+ >
+ <Form
+ resource="outStock"
+ >
+ <DialogTitle id="form-dialog-title" sx={{
+ position: 'sticky',
+ top: 0,
+ backgroundColor: 'background.paper',
+ zIndex: 1000
+ }}
+ >
+ {translate('create.title')}
+ <Box sx={{ position: 'absolute', top: 8, right: 8, zIndex: 1001 }}>
+ <DialogCloseButton onClose={handleClose} />
+ </Box>
+ </DialogTitle>
+ <DialogContent sx={{ mt: 2 }}>
+ <>
+ <Grid container>
+ <Grid item xs={12} display="flex" gap={1}>
+ <TextInput
+ label="table.field.asnOrder.poCode"
+ source="poCode"
+ parse={v => v}
+ />
+ <NumberInput
+ label="table.field.asnOrder.poId"
+ source="poId"
+ />
+ {/* <AutocompleteInput
+ choices={dicts}
+ optionText="label"
+ label="table.field.asnOrder.type"
+ source="type"
+ optionValue="value"
+ validate={required()}
+ parse={v => v}
+ /> */}
+ <AutocompleteInput
+ choices={business}
+ optionText="label"
+ label="table.field.asnOrder.wkType"
+ source="wkType"
+ optionValue="value"
+ validate={required()}
+ parse={v => v}
+ />
+ <NumberInput
+ label="table.field.asnOrder.anfme"
+ source="anfme"
+ validate={required()}
+ />
+
+ </Grid>
+ <Grid item xs={12} display="flex" gap={1}>
+ <NumberInput
+ label="table.field.asnOrder.qty"
+ source="qty"
+ />
+ <TextInput
+ label="table.field.asnOrder.logisNo"
+ source="logisNo"
+ parse={v => v}
+ />
+ <DateInput
+ label="table.field.asnOrder.arrTime"
+ source="arrTime"
+ />
+ <SelectInput
+ label="table.field.asnOrder.rleStatus"
+ source="rleStatus"
+ choices={[
+ { id: 0, name: ' 姝e父' },
+ { id: 1, name: ' 宸查噴鏀�' },
+ ]}
+ />
+ </Grid>
+ </Grid>
+ <SelectMatnrModal open={matCreate} setOpen={setMatCreate} />
+ <DialogActions sx={{ position: 'sticky', bottom: 0, backgroundColor: 'background.paper', zIndex: 1000 }}>
+ <Toolbar sx={{ width: '100%', justifyContent: 'end' }} >
+ <AddOutOrderButton setMatCreate={setMatCreate} />
+ <SaveButton />
+ </Toolbar>
+ </DialogActions>
+ <Box>
+
+ </Box>
+ </>
+ </DialogContent>
+ </Form>
+ </Dialog>
+ </CreateBase>
+ </>
+ )
+}
+
+export default OutOrderCreate;
+
+
+const AddOutOrderButton = (setMatCreate) => {
+ const record = useRecordContext();
+ const addMats = (event) => {
+ event.stopPropagation();
+ setMatCreate(true)
+ }
+
+ return (
+ <Button label={"common.action.newAddMats"} onClick={addMats} variant="contained" sx={{ padding: '0.6em', marginRight: '1em' }}>
+ <AddIcon />
+ </Button>
+ );
+}
diff --git a/rsf-admin/src/page/orders/check/CheckOrderEdit.jsx b/rsf-admin/src/page/orders/check/CheckOrderEdit.jsx
new file mode 100644
index 0000000..0844f23
--- /dev/null
+++ b/rsf-admin/src/page/orders/check/CheckOrderEdit.jsx
@@ -0,0 +1,138 @@
+import React, { useState, useRef, useEffect, useMemo } from "react";
+import {
+ Edit,
+ SimpleForm,
+ useTranslate,
+ TextInput,
+ DateInput,
+ SelectInput,
+ AutocompleteInput,
+ SaveButton,
+ Toolbar,
+ required,
+ DeleteButton,
+} from 'react-admin';
+import { Stack, Grid, Box, Typography } from '@mui/material';
+import { EDIT_MODE, REFERENCE_INPUT_PAGESIZE } from '@/config/setting';
+import EditBaseAside from "../../components/EditBaseAside";
+import CustomerTopToolBar from "../../components/EditTopToolBar";
+import CheckOrderItemList from "./CheckOrderItemList";
+
+
+const CheckOrderEdit = () => {
+ const translate = useTranslate();
+ const dicts = JSON.parse(localStorage.getItem('sys_dicts'))?.filter(dict => (dict.dictTypeCode == 'sys_order_type')) || [];
+ const business = JSON.parse(localStorage.getItem('sys_dicts'))?.filter(dict => (dict.dictTypeCode == 'sys_business_type')) || [];
+
+ return (
+ <>
+ <Edit
+ redirect="list"
+ mutationMode={EDIT_MODE}
+ actions={<CustomerTopToolBar />}
+ aside={<EditBaseAside />}
+ >
+ <SimpleForm
+ shouldUnregister
+ warnWhenUnsavedChanges
+ toolbar={false}
+ mode="onTouched"
+ defaultValues={{}}
+ >
+ <Grid container width={{ xs: '100%', xl: '100%' }} rowSpacing={3} columnSpacing={3}
+ sx={{
+ "& .MuiFormLabel-root.MuiInputLabel-root.Mui-disabled": {
+ bgcolor: 'white',
+ WebkitTextFillColor: "rgba(0, 0, 0)"
+ },
+
+ "& .MuiInputBase-input.MuiFilledInput-input.Mui-disabled": {
+ bgcolor: 'white',
+ WebkitTextFillColor: "rgba(0, 0, 0)"
+ },
+ "& .MuiFilledInput-root.MuiInputBase-sizeSmall": {
+ bgcolor: 'white',
+ }
+ }}
+ >
+ <Grid item xs={24} md={12} >
+ <Typography variant="h6" gutterBottom>
+ {translate('common.edit.title.main')}
+ </Typography>
+ <Stack direction='row' gap={2}>
+ <TextInput
+ label="table.field.outStock.code"
+ source="code"
+ readOnly
+ parse={v => v}
+ />
+ <TextInput
+ label="table.field.outStock.poCode"
+ source="poCode"
+ readOnly
+ parse={v => v}
+ />
+ <AutocompleteInput
+ choices={dicts}
+ optionText="label"
+ label="table.field.outStock.type"
+ source="type"
+ optionValue="value"
+ parse={v => v}
+ readOnly
+ />
+ <AutocompleteInput
+ choices={business}
+ optionText="label"
+ label="table.field.outStock.wkType"
+ source="wkType"
+ optionValue="value"
+ parse={v => v}
+ readOnly
+ />
+ </Stack>
+ <Stack direction='row' gap={2}>
+ <TextInput
+ label="table.field.outStock.logisNo"
+ source="logisNo"
+ readOnly
+ parse={v => v}
+ />
+ <TextInput
+ label="table.field.outStock.anfme"
+ source="anfme"
+ readOnly
+ parse={v => v}
+ />
+ <TextInput
+ label="table.field.outStock.qty"
+ source="qty"
+ readOnly
+ parse={v => v}
+ />
+ <DateInput
+ label="table.field.outStock.arrTime"
+ source="arrTime"
+ readOnly
+ />
+ <SelectInput
+ label="table.field.outStock.rleStatus"
+ source="rleStatus"
+ readOnly
+ choices={[
+ { id: 0, name: ' 姝e父' },
+ { id: 1, name: ' 宸查噴鏀�' },
+ ]}
+ validate={required()}
+ />
+ </Stack>
+ </Grid>
+ </Grid>
+ </SimpleForm>
+ </Edit >
+ <CheckOrderItemList />
+ </>
+ )
+}
+
+export default CheckOrderEdit;
diff --git a/rsf-admin/src/page/orders/check/CheckOrderItemCreate.jsx b/rsf-admin/src/page/orders/check/CheckOrderItemCreate.jsx
new file mode 100644
index 0000000..f77b096
--- /dev/null
+++ b/rsf-admin/src/page/orders/check/CheckOrderItemCreate.jsx
@@ -0,0 +1,200 @@
+import React, { useState, useRef, useEffect, useMemo } from "react";
+import {
+ CreateBase,
+ useTranslate,
+ TextInput,
+ NumberInput,
+ BooleanInput,
+ DateInput,
+ SaveButton,
+ SelectInput,
+ ReferenceInput,
+ ReferenceArrayInput,
+ AutocompleteInput,
+ Toolbar,
+ required,
+ useDataProvider,
+ useNotify,
+ Form,
+ useCreateController,
+} from 'react-admin';
+import {
+ Dialog,
+ DialogActions,
+ DialogContent,
+ DialogTitle,
+ Stack,
+ Grid,
+ Box,
+} from '@mui/material';
+import DialogCloseButton from "../../components/DialogCloseButton";
+import StatusSelectInput from "../../components/StatusSelectInput";
+import MemoInput from "../../components/MemoInput";
+
+
+
+const CheckOrderItemCreate = (props) => {
+ const { open, setOpen, record } = props;
+ const translate = useTranslate();
+ const notify = useNotify();
+ const handleClose = (event, reason) => {
+ if (reason !== "backdropClick") {
+ setOpen(false);
+ }
+ };
+
+ const handleSuccess = async (data) => {
+ setOpen(false);
+ notify('common.response.success');
+ };
+
+ const handleError = async (error) => {
+ notify(error.message || 'common.response.fail', { type: 'error', messageArgs: { _: error.message } });
+ };
+
+ return (
+ <>
+ <CreateBase
+ resource="outStockItem"
+ record={{}}
+ transform={(data) => {
+ return data;
+ }}
+ mutationOptions={{ onSuccess: handleSuccess, onError: handleError }}
+ >
+ <Dialog
+ open={open}
+ onClose={handleClose}
+ aria-labelledby="form-dialog-title"
+ fullWidth
+ disableRestoreFocus
+ maxWidth="md" // 'xs' | 'sm' | 'md' | 'lg' | 'xl'
+ >
+ <Form>
+ <DialogTitle id="form-dialog-title" sx={{
+ position: 'sticky',
+ top: 0,
+ backgroundColor: 'background.paper',
+ zIndex: 1000
+ }}
+ >
+ {translate('create.title')}
+ <Box sx={{ position: 'absolute', top: 8, right: 8, zIndex: 1001 }}>
+ <DialogCloseButton onClose={handleClose} />
+ </Box>
+ </DialogTitle>
+ <DialogContent sx={{ mt: 2 }}>
+ <Grid>
+ <Grid item xs={6} display="flex" gap={2}>
+ <NumberInput
+ label="table.field.outStockItem.asnId"
+ source="asnId"
+ readOnly
+ hidden
+ defaultValue={record?.id}
+ />
+ <TextInput
+ label="table.field.outStockItem.asnCode"
+ source="asnCode"
+ readOnly
+ defaultValue={record?.code}
+ parse={v => v}
+ />
+ <TextInput
+ label="table.field.outStockItem.poDetlId"
+ source="poDetlId"
+ parse={v => v}
+ />
+ </Grid>
+ <Grid item xs={6} display="flex" gap={1}>
+ <TextInput
+ label="table.field.outStockItem.matnrId"
+ source="matnrId"
+ parse={v => v}
+ />
+ <TextInput
+ label="table.field.outStockItem.maktx"
+ source="maktx"
+ parse={v => v}
+ />
+ <NumberInput
+ label="table.field.outStockItem.anfme"
+ source="anfme"
+ validate={required()}
+ />
+ </Grid>
+ <Grid item xs={6} display="flex" gap={1}>
+ <TextInput
+ label="table.field.outStockItem.stockUnit"
+ source="stockUnit"
+ parse={v => v}
+ />
+ <NumberInput
+ label="table.field.outStockItem.purQty"
+ source="purQty"
+ validate={required()}
+ />
+ <TextInput
+ label="table.field.outStockItem.purUnit"
+ source="purUnit"
+ parse={v => v}
+ />
+ </Grid>
+ <Grid item xs={6} display="flex" gap={1}>
+ <NumberInput
+ label="table.field.outStockItem.qty"
+ source="qty"
+ />
+ <TextInput
+ label="table.field.outStockItem.splrCode"
+ source="splrCode"
+ parse={v => v}
+ />
+ <TextInput
+ label="table.field.outStockItem.splrName"
+ source="splrName"
+ parse={v => v}
+ />
+
+ </Grid>
+ <Grid item xs={6} display="flex" gap={1}>
+ <TextInput
+ label="table.field.outStockItem.qrcode"
+ source="qrcode"
+ parse={v => v}
+ />
+ <TextInput
+ label="table.field.outStockItem.barcode"
+ source="barcode"
+ parse={v => v}
+ />
+ <TextInput
+ label="table.field.outStockItem.packName"
+ source="packName"
+ parse={v => v}
+ />
+ </Grid>
+
+ <Grid item xs={4} display="flex" gap={1}>
+ <StatusSelectInput />
+ </Grid>
+ <Grid item xs={4} display="flex" gap={1}>
+ <Stack direction="column" spacing={1}>
+ <MemoInput />
+ </Stack>
+ </Grid>
+ </Grid>
+ </DialogContent>
+ <DialogActions sx={{ position: 'sticky', bottom: 0, backgroundColor: 'background.paper', zIndex: 1000 }}>
+ <Toolbar sx={{ width: '100%', justifyContent: 'space-between' }} >
+ <SaveButton />
+ </Toolbar>
+ </DialogActions>
+ </Form>
+ </Dialog>
+ </CreateBase>
+ </>
+ )
+}
+
+export default CheckOrderItemCreate;
diff --git a/rsf-admin/src/page/orders/check/CheckOrderItemList.jsx b/rsf-admin/src/page/orders/check/CheckOrderItemList.jsx
new file mode 100644
index 0000000..095f269
--- /dev/null
+++ b/rsf-admin/src/page/orders/check/CheckOrderItemList.jsx
@@ -0,0 +1,185 @@
+import React, { useState, useRef, useEffect, useMemo, useCallback } from "react";
+import { useNavigate, useLocation } from 'react-router-dom';
+import {
+ List,
+ DatagridConfigurable,
+ SearchInput,
+ TopToolbar,
+ SelectColumnsButton,
+ EditButton,
+ FilterButton,
+ CreateButton,
+ ExportButton,
+ BulkDeleteButton,
+ WrapperField,
+ useRecordContext,
+ useTranslate,
+ useNotify,
+ useListContext,
+ FunctionField,
+ TextField,
+ NumberField,
+ DateField,
+ BooleanField,
+ ReferenceField,
+ TextInput,
+ DateTimeInput,
+ DateInput,
+ SelectInput,
+ NumberInput,
+ ReferenceInput,
+ ReferenceArrayInput,
+ AutocompleteInput,
+ DeleteButton,
+ Button,
+ useEditContext,
+ useGetRecordId,
+ useGetOne
+} from 'react-admin';
+import { Box, Typography, Card, Stack, Dialog, DialogActions, DialogTitle } from '@mui/material';
+import { styled } from '@mui/material/styles';
+import PageDrawer from "../../components/PageDrawer";
+import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE, DEFAULT_ITEM_PAGE_SIZE } from '@/config/setting';
+
+
+const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({
+ '& .css-1vooibu-MuiSvgIcon-root': {
+ height: '.9em',
+ },
+ '& .RaDatagrid-row': {
+ cursor: 'auto'
+ },
+ '& .column-name': {
+ },
+ '& .opt': {
+ width: 200
+ },
+}));
+
+const filters = [
+ <SearchInput source="condition" alwaysOn />,
+ <NumberInput source="asnId" label="table.field.outStockItem.asnId" />,
+ <TextInput source="asnCode" label="table.field.outStockItem.asnCode" alwaysOn />,
+ <TextInput source="poDetlId" label="table.field.outStockItem.poDetlId" />,
+ <TextInput source="matnrId" label="table.field.outStockItem.matnrId" />,
+ <TextInput source="maktx" label="table.field.outStockItem.maktx" alwaysOn />,
+ <TextInput source="matnrCode" label="table.field.outStockItem.matnrCode" alwaysOn />,
+ <NumberInput source="anfme" label="table.field.outStockItem.anfme" />,
+ <TextInput source="stockUnit" label="table.field.outStockItem.stockUnit" />,
+ <NumberInput source="purQty" label="table.field.outStockItem.purQty" />,
+ <TextInput source="purUnit" label="table.field.outStockItem.purUnit" />,
+ <NumberInput source="qty" label="table.field.outStockItem.qty" />,
+ <TextInput source="splrCode" label="table.field.outStockItem.splrCode" />,
+ <TextInput source="splrName" label="table.field.outStockItem.splrName" />,
+ <TextInput source="qrcode" label="table.field.outStockItem.qrcode" />,
+ <TextInput source="trackCode" label="table.field.outStockItem.barcode" />,
+ <TextInput source="packName" label="table.field.outStockItem.packName" />,
+ <TextInput label="common.field.memo" source="memo" />,
+ <SelectInput
+ label="common.field.status"
+ source="status"
+ choices={[
+ { id: '1', name: 'common.enums.statusTrue' },
+ { id: '0', name: 'common.enums.statusFalse' },
+ ]}
+ resettable
+ />,
+]
+
+const OutOrderItemList = () => {
+ const translate = useTranslate();
+ const [createDialog, setCreateDialog] = useState(false);
+ const [editDialog, setEditDialog] = useState(false);
+ const [drawerVal, setDrawerVal] = useState(false);
+ const [select, setSelect] = useState({});
+ const asnId = useGetRecordId();
+ const { data: dicts, isPending, error } = useGetOne('outStock', { id: asnId });
+
+ return (
+ <>
+ <Box display="flex">
+ <List
+ resource="outStockItem"
+ storeKey='outStockItem'
+ sx={{
+ flexGrow: 1,
+ transition: (theme) =>
+ theme.transitions.create(['all'], {
+ duration: theme.transitions.duration.enteringScreen,
+ }),
+ marginRight: drawerVal ? `${PAGE_DRAWER_WIDTH}px` : 0,
+ }}
+ title={"menu.outStockItem"}
+ empty={false}
+ filter={{ asnId: asnId, deleted: 0 }}
+ filters={filters}
+ sort={{ field: "create_time", order: "desc" }}
+ actions={(
+ <TopToolbar>
+ <FilterButton />
+ <SelectColumnsButton preferenceKey='outStockItem' />
+ </TopToolbar>
+ )}
+ perPage={DEFAULT_ITEM_PAGE_SIZE}
+ >
+ <StyledDatagrid
+ preferenceKey='outStockItem'
+ bulkActionButtons={false}
+ rowClick={false}
+ omit={['id', 'createTime', 'createBy', 'memo', 'poDetlId', 'purQty', 'purUnit', 'trackCode', 'packName', 'qrcode', 'splrName', 'matnrId', 'asnId']}
+ >
+ <NumberField source="id" />
+ <NumberField source="asnId" label="table.field.outStockItem.asnId" />
+ <TextField source="asnCode" label="table.field.outStockItem.asnCode" />
+ <TextField source="poCode" label="table.field.outStockItem.poCode" />
+ <TextField source="poDetlId" label="table.field.outStockItem.poDetlId" />
+ <TextField source="matnrId" label="table.field.outStockItem.matnrId" />
+ <TextField source="matnrCode" label="table.field.outStockItem.matnrCode" />
+ <TextField source="maktx" label="table.field.outStockItem.maktx" />
+ <TextField source="platOrderCode" label="table.field.outStockItem.platOrderCode" />
+ <NumberField source="anfme" label="table.field.outStockItem.anfme" />
+ <NumberField source="purQty" label="table.field.outStockItem.purQty" />
+ <NumberField source="workQty" label="table.field.outStockItem.workQty" />
+ <NumberField source="qty" label="table.field.outStockItem.qty" />
+ <TextField source="stockUnit" label="table.field.outStockItem.stockUnit" />
+ <TextField source="splrBatch" label="table.field.outStockItem.splrBatch" />
+ <TextField source="purUnit" label="table.field.outStockItem.purUnit" />
+ <TextField source="splrCode" label="table.field.outStockItem.splrCode" />
+ <TextField source="splrName" label="table.field.outStockItem.splrName" />
+ <TextField source="qrcode" label="table.field.outStockItem.qrcode" />
+ <TextField source="trackCode" label="table.field.outStockItem.barcode" />
+ <TextField source="packName" label="table.field.outStockItem.packName" />
+ <DateField source="updateTime" label="common.field.updateTime" showTime />
+ <ReferenceField source="updateBy" label="common.field.updateBy" reference="user" link={false} sortable={false}>
+ <TextField source="nickname" />
+ </ReferenceField>,
+ <ReferenceField source="createBy" label="common.field.createBy" reference="user" link={false} sortable={false}>
+ <TextField source="nickname" />
+ </ReferenceField>,
+ <DateField source="createTime" label="common.field.createTime" showTime />
+ <TextField source="memo" label="common.field.memo" sortable={false} />
+ </StyledDatagrid>
+ </List>
+ {/* <OutOrderItemCreate
+ open={createDialog}
+ setOpen={setCreateDialog}
+ record={dicts}
+ />
+ <OutOrderItemEdit
+ open={editDialog}
+ setOpen={setEditDialog}
+ record={select}
+ /> */}
+ <PageDrawer
+ title='OutStockItem Detail'
+ drawerVal={drawerVal}
+ setDrawerVal={setDrawerVal}
+ >
+ </PageDrawer>
+ </Box>
+ </>
+ )
+}
+OutOrderItemList.Context = React.createContext()
+
+export default OutOrderItemList;
diff --git a/rsf-admin/src/page/orders/check/CheckOrderList.jsx b/rsf-admin/src/page/orders/check/CheckOrderList.jsx
new file mode 100644
index 0000000..36a9b6d
--- /dev/null
+++ b/rsf-admin/src/page/orders/check/CheckOrderList.jsx
@@ -0,0 +1,313 @@
+import React, { useState, useRef, useEffect, useMemo, useCallback } from "react";
+import { useLocation, useNavigate } from 'react-router-dom';
+import {
+ List,
+ DatagridConfigurable,
+ SearchInput,
+ TopToolbar,
+ Toolbar,
+ SelectColumnsButton,
+ EditButton,
+ FilterButton,
+ CreateButton,
+ ExportButton,
+ BulkDeleteButton,
+ useDataProvider,
+ WrapperField,
+ useRecordContext,
+ useTranslate,
+ useNotify,
+ useRefresh,
+ useListContext,
+ FunctionField,
+ TextField,
+ NumberField,
+ DateField,
+ BooleanField,
+ ReferenceField,
+ TextInput,
+ DateTimeInput,
+ DateInput,
+ SelectInput,
+ NumberInput,
+ ReferenceInput,
+ ReferenceArrayInput,
+ AutocompleteInput,
+ DeleteButton,
+ Button,
+ useRedirect,
+ useUnselectAll,
+ useRecordSelection,
+} from 'react-admin';
+import { styled } from '@mui/material/styles';
+import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting';
+import CancelOutlinedIcon from '@mui/icons-material/CancelOutlined';
+import { Box, Typography, Card, Stack, Drawer } from '@mui/material';
+import DictionarySelect from "../../components/DictionarySelect";
+import BillStatusField from '../../components/BillStatusField';
+import MyCreateButton from "../../components/MyCreateButton";
+import ConfirmButton from '../../components/ConfirmButton';
+import ImportButton from "../../components/ImportButton";
+import DetailsIcon from '@mui/icons-material/Details';
+import AddTaskIcon from '@mui/icons-material/AddTask';
+import PublicIcon from '@mui/icons-material/Public';
+import EditIcon from '@mui/icons-material/Edit';
+import AddIcon from '@mui/icons-material/Add';
+import request from '@/utils/request';
+
+const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({
+ '& .css-1vooibu-MuiSvgIcon-root': {
+ height: '.9em'
+ },
+ '& .RaDatagrid-row': {
+ cursor: 'auto'
+ },
+ '& .column-name': {
+ },
+ '& .opt': {
+ width: 220
+ },
+ '& .wkType': {
+ width: 110
+ },
+ '& .status': {
+ width: 90
+ },
+}));
+
+const filters = [
+ <SearchInput source="condition" alwaysOn />,
+ <TextInput source="code" label="table.field.outStock.code" alwaysOn />,
+ <TextInput source="poCode" label="table.field.outStock.poCode" />,
+ <NumberInput source="poId" label="table.field.outStock.poId" />,
+ <ReferenceInput source="type" reference="dictData" filter={{ dictTypeCode: 'sys_order_type', group: '2' }} label="table.field.outStock.type" alwaysOn>
+ <AutocompleteInput label="table.field.outStock.type" optionValue="value" />
+ </ReferenceInput>,
+ <ReferenceInput source="wkType" reference="dictData" filter={{ dictTypeCode: 'sys_business_type', group: '2' }} label="table.field.outStock.wkType" alwaysOn>
+ <AutocompleteInput label="table.field.outStock.wkType" optionValue="value" />
+ </ReferenceInput>,
+ <NumberInput source="anfme" label="table.field.outStock.anfme" />,
+ <NumberInput source="qty" label="table.field.outStock.qty" />,
+ <TextInput source="logisNo" label="table.field.outStock.logisNo" />,
+ <DateInput source="arrTime" label="table.field.outStock.arrTime" />,
+ <SelectInput source="rleStatus" label="table.field.outStock.rleStatus"
+ choices={[
+ { id: 0, name: ' 姝e父' },
+ { id: 1, name: ' 宸查噴鏀�' },
+ ]}
+ />,
+
+ <TextInput label="common.field.memo" source="memo" />,
+ <DictionarySelect
+ label='table.field.outStock.exceStatus'
+ name="exceStatus"
+ dictTypeCode="sys_asn_exce_status"
+ alwaysOn
+ />,
+]
+
+const CheckOrderList = (props) => {
+ const translate = useTranslate();
+ const refresh = useRefresh();
+ const notify = useNotify();
+
+ const [createDialog, setCreateDialog] = useState(false);
+ const [manualDialog, setManualDialog] = useState(false);
+ const [selectIds, setSelectIds] = useState([]);
+ const [preview, setPreview] = useState(false);
+ const [waveRule, setWaveRule] = useState(false);
+ const [drawerVal, setDrawerVal] = useState(false);
+ const [modalType, setmodalType] = useState(0);
+ const [select, setSelect] = useState(0);
+ const billReload = useRef();
+ const dicts = JSON.parse(localStorage.getItem('sys_dicts'))?.filter(dict => (dict.dictTypeCode == 'sys_business_type')) || [];
+
+ //鑾峰彇娉㈡瑙勫垯
+ // const closeDialog = async (value) => {
+ // setWaveRule(false)
+ // const res = await request.post(`/outStock/generate/wave`, { ids: selectIds, waveRuleId: value.id });
+ // if (res?.data?.code === 200) {
+ // notify(res.data.msg);
+ // } else {
+ // notify(res.data.msg);
+ // }
+ // refresh()
+ // }
+
+ return (
+ <Box display="flex">
+ <List
+ resource="check"
+ sx={{
+ flexGrow: 1,
+ transition: (theme) =>
+ theme.transitions.create(['all'], {
+ duration: theme.transitions.duration.enteringScreen,
+ }),
+ }}
+ title={"menu.checkOrder"}
+ empty={false}
+ filters={filters}
+ filter={{ deleted: 0, type: 'check' }}
+ sort={{ field: "create_time", order: "desc" }}
+ actions={(
+ <TopToolbar>
+ <FilterButton />
+ <CreateByOrderButton setCreateDialog={setCreateDialog} />
+ <MyCreateButton onClick={() => { setManualDialog(true); setmodalType(0) }} />
+ <SelectColumnsButton preferenceKey='check' />
+ <ImportButton value={'outStockItem'} />
+ </TopToolbar>
+ )}
+ perPage={DEFAULT_PAGE_SIZE}
+ >
+ <StyledDatagrid
+ preferenceKey='check'
+ bulkActionButtons={<PublicTaskButton setWaveRule={setWaveRule} setSelectIds={setSelectIds} />}
+ rowClick={false}
+ expandSingle={true}
+ omit={['id', 'createTime', 'createBy', 'memo', 'rleStatus$']}
+ >
+ <NumberField source="id" />
+ <TextField source="code" label="table.field.checkOrder.code" />
+ <TextField source="poCode" label="table.field.checkOrder.poCode" />
+ <TextField source="type$" label="table.field.checkOrder.type" />
+ <TextField cellClassName="wkType" source="wkType$" label="table.field.checkOrder.wkType" />
+ <NumberField source="anfme" label="table.field.checkOrder.anfme" />
+ <NumberField source="workQty" label="table.field.checkOrder.workQty" />
+ <NumberField source="qty" label="table.field.checkOrder.qty" />
+ <TextField source="logisNo" label="table.field.checkOrder.logisNo" />
+ <TextField source="rleStatus$" label="table.field.checkOrder.rleStatus" sortable={false} />
+ <TextField source="updateBy$" label="common.field.updateBy" />
+ <DateField source="updateTime" label="common.field.updateTime" showTime />
+ <TextField source="createBy$" label="common.field.createBy" />
+ <DateField source="createTime" label="common.field.createTime" showTime />
+ <BillStatusField cellClassName="status" source="exceStatus" label="table.field.checkOrder.exceStatus" />
+ <TextField source="memo" label="common.field.memo" sortable={false} />
+ <WrapperField cellClassName="opt" label="common.field.opt" >
+ <MyButton setCreateDialog={setManualDialog} setmodalType={setmodalType} />
+ <EditButton label="toolbar.detail" icon={(<DetailsIcon />)}></EditButton>
+ <CancelButton />
+ <PublicButton setDrawerVal={setDrawerVal} drawerVal={drawerVal} setSelect={setSelect} />
+ </WrapperField>
+ </StyledDatagrid>
+ </List>
+ {/* <OutOrderCreate
+ open={manualDialog}
+ setOpen={setManualDialog}
+ /> */}
+ {/* <SelectMatnrModal
+ asnId={modalType}
+ billReload={billReload}
+ open={manualDialog}
+ setOpen={setManualDialog}
+ />
+ <OutOrderModal
+ open={createDialog}
+ setOpen={setCreateDialog}
+ preview={preview}
+ setPreview={setPreview}
+ />
+ <OutStockWaveDialog open={waveRule} setOpen={setWaveRule} onClose={closeDialog} />
+ <OutOrderPreview open={preview} setOpen={setPreview} />
+ <PageEditDrawer
+ title={"toolbar.publicWorking"}
+ drawerVal={drawerVal}
+ setDrawerVal={setDrawerVal}
+ >
+ <OutStockPublic record={select} open={drawerVal} setOpen={setDrawerVal} />
+ </PageEditDrawer> */}
+ </Box >
+ )
+}
+export default CheckOrderList;
+
+
+const PublicTaskButton = ({ setWaveRule, setSelectIds }) => {
+ const record = useRecordContext();
+ const { selectedIds, onUnselectItems } = useListContext();
+ const notify = useNotify();
+ const redirect = useRedirect();
+
+ const pubClick = async () => {
+ onUnselectItems();
+ setWaveRule(true);
+ setSelectIds(selectedIds)
+ }
+
+ return (
+ <Button
+ onClick={pubClick}
+ label={"toolbar.createWave"}
+ startIcon={<PublicIcon />}
+ />
+ );
+}
+
+const MyButton = ({ setCreateDialog, setmodalType }) => {
+ const record = useRecordContext();
+ const handleEditClick = (btn) => {
+ btn.stopPropagation();
+ const id = record.id;
+ setmodalType(id);
+ setCreateDialog(true);
+ };
+ return (
+ <Button
+ color="primary"
+ startIcon={<EditIcon />}
+ onClick={(btn) => handleEditClick(btn)}
+ sx={{ ml: 1 }}
+ label={'ra.action.edit'}
+ >
+ </Button>
+ )
+}
+
+const CreateByOrderButton = ({ setCreateDialog }) => {
+ const record = useRecordContext();
+ const notify = useNotify();
+ const refresh = useRefresh();
+ const createByOrder = async (event) => {
+ event.stopPropagation();
+ setCreateDialog(true);
+ }
+
+ return (
+ <Button onClick={createByOrder} label={'toolbar.asnCreate'}> <AddIcon /> </Button>
+ )
+}
+
+const CancelButton = () => {
+ const record = useRecordContext();
+ const notify = useNotify();
+ const refresh = useRefresh();
+ const cancelOrder = async () => {
+ const { data: { code, data, msg } } = await request.get(`/outStock/cancel/${record?.id}`);
+ if (code === 200) {
+ notify(msg);
+ refresh()
+ } else {
+ notify(msg);
+ }
+ }
+
+ return (
+ record?.exceStatus == 10 ? <ConfirmButton label={"toolbar.cancel"} startIcon={<CancelOutlinedIcon />} onConfirm={cancelOrder} size={"small"} /> : <></>
+ )
+}
+
+//涓嬪彂鎵ц
+const PublicButton = ({ setDrawerVal, setSelect }) => {
+ const record = useRecordContext();
+ const refresh = useRefresh();
+ const taskEvent = () => {
+ setDrawerVal(true)
+ setSelect(record)
+ refresh();
+ }
+
+ return (
+ record.workQty < record.anfme ? <Button label={"toolbar.publicWorking"} startIcon={<AddTaskIcon />} onClick={taskEvent} size={"small"} /> : <></>
+ )
+}
diff --git a/rsf-admin/src/page/orders/check/OutOrderModal.jsx b/rsf-admin/src/page/orders/check/OutOrderModal.jsx
new file mode 100644
index 0000000..6bea1bd
--- /dev/null
+++ b/rsf-admin/src/page/orders/check/OutOrderModal.jsx
@@ -0,0 +1,279 @@
+import { Dialog, DialogActions, DialogContent, DialogTitle, Box, LinearProgress } from "@mui/material";
+import React, { useState, useRef, useEffect, useMemo } from "react";
+import {
+ List,
+ DatagridConfigurable,
+ SearchInput,
+ TopToolbar,
+ Toolbar,
+ Button,
+ SelectColumnsButton,
+ EditButton,
+ FilterButton,
+ CreateButton,
+ ExportButton,
+ BulkDeleteButton,
+ WrapperField,
+ useRecordContext,
+ useTranslate,
+ useNotify,
+ useListContext,
+ FunctionField,
+ TextField,
+ NumberField,
+ DateField,
+ BooleanField,
+ ReferenceField,
+ TextInput,
+ DateTimeInput,
+ DateInput,
+ SelectInput,
+ NumberInput,
+ ReferenceInput,
+ ReferenceArrayInput,
+ AutocompleteInput,
+ DeleteButton,
+ SimpleForm,
+ Form,
+ SaveButton,
+ useRefresh,
+ useGetList,
+} from 'react-admin';
+import DialogCloseButton from "../../components/DialogCloseButton";
+import { styled } from '@mui/material/styles';
+import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting';
+import { Grid, margin, Stack, width } from "@mui/system";
+import request from '@/utils/request';
+import SaveIcon from '@mui/icons-material/Save';
+import CheckCircleIcon from '@mui/icons-material/CheckCircle';
+import EditableTextField from "../../components/EditableTextField";
+import OutOrderPreview from "./OutOrderPreview";
+
+const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({
+ '& .css-1vooibu-MuiSvgIcon-root': {
+ height: '.9em'
+ },
+ '& .RaDatagrid-row': {
+ cursor: 'auto'
+ },
+ '& .status': {
+ width: 90
+ },
+}));
+
+const StyledForm = styled(Form)(({ theme }) => ({
+ width: '100%',
+ marginBottom: '45px',
+
+ '& .MuiGrid-root': {
+ margin: '0 10px'
+ }
+}));
+
+
+const filters = [
+ <SearchInput source="condition" alwaysOn />,
+ <DateInput label='common.time.after' source="timeStart" />,
+ <DateInput label='common.time.before' source="timeEnd" />,
+ <TextInput source="code" label="table.field.delivery.code" />,
+ <TextInput source="platId" label="table.field.delivery.platId" />,
+ <TextInput source="type" label="table.field.delivery.type" />,
+ <TextInput source="wkType" label="table.field.delivery.wkType" />,
+ <TextInput source="source" label="table.field.delivery.source" />,
+ <SelectInput
+ label="common.field.status"
+ source="status"
+ choices={[
+ { id: '1', name: 'common.enums.statusTrue' },
+ { id: '0', name: 'common.enums.statusFalse' },
+ ]}
+ resettable
+ />,
+]
+
+const OutOrderModal = (props) => {
+ const { open, setOpen, preview, setPreview, record } = props;
+ const translate = useTranslate();
+ const [params, setParams] = useState({});
+ const [select, setSelect] = useState([]);
+ const [drawerVal, setDrawerVal] = useState(false);
+ const refresh = useRefresh();
+ const handleClose = (event, reason) => {
+ if (reason !== "backdropClick") {
+ setOpen(false);
+ }
+ };
+ const CustomFilter = () => {
+ const { filterValues, setFilters, refetch } = useListContext();
+ const [formValues, setFormValues] = useState(filterValues);
+ const handleChange = (event) => {
+ if (event.target == undefined || event.target == null) { return }
+ setFormValues(formValues => ({
+ ...formValues,
+ [event.target.name]: event.target.value,
+ }));
+ };
+
+ const handleSubmit = (event) => {
+ setParams(formValues)
+ };
+
+ return (
+ <StyledForm>
+ <Grid container rowSpacing={3} columnSpacing={3} >
+ <Stack>
+ <TextInput
+ source="condition"
+ label="common.action.search"
+ resettable
+ defaultValue={params?.condition}
+ onChange={handleChange} />
+ </Stack>
+ <Stack>
+ <TextInput
+ source="deliveryCode"
+ label="table.field.deliveryItem.deliveryCode"
+ defaultValue={params?.deliveryCode}
+ onChange={handleChange}
+ resettable
+ />
+ </Stack>
+ <Stack>
+ <TextInput
+ source="maktx"
+ label="table.field.deliveryItem.matnrName"
+ defaultValue={params?.maktx}
+ onChange={handleChange}
+ resettable
+ />
+ </Stack>
+ <Stack>
+ <TextInput
+ source="matnrCode"
+ label="table.field.deliveryItem.matnrCode"
+ defaultValue={params?.matnrCode}
+ resettable
+ onChange={handleChange} />
+ </Stack>
+ <Stack>
+ <TextInput
+ source="splrName"
+ label="table.field.deliveryItem.splrName"
+ defaultValue={params?.splrName}
+ resettable
+ onChange={handleChange} />
+ </Stack>
+ </Grid>
+ <DialogActions>
+ <Toolbar sx={{ width: '100%', justifyContent: 'end' }} >
+ <SaveButton onClick={handleSubmit} label={"toolbar.query"} />
+ </Toolbar>
+ </DialogActions>
+ </StyledForm>
+ );
+ };
+ return (
+ <Dialog
+ open={open}
+ onClose={handleClose}
+ aria-labelledby="form-dialog-title"
+ aria-hidden
+ fullWidth
+ disableRestoreFocus
+ maxWidth="xl"
+ >
+ <DialogTitle id="form-dialog-title" sx={{
+ position: 'sticky',
+ top: 0,
+ backgroundColor: 'background.paper',
+ zIndex: 1000
+ }}>
+ {translate('create.title')}
+ <Box sx={{ position: 'absolute', top: 8, right: 8, zIndex: 1001 }}>
+ <DialogCloseButton onClose={handleClose} />
+ </Box>
+ </DialogTitle>
+ <Grid container rowSpacing={2} columnSpacing={2}>
+ <DialogContent>
+ <Grid item sx={24}>
+ <List
+ resource="/deliveryItem/filters"
+ sx={{
+ flexGrow: 1,
+ transition: (theme) =>
+ theme.transitions.create(['all'], {
+ duration: theme.transitions.duration.enteringScreen,
+ }),
+ marginRight: drawerVal ? `${PAGE_DRAWER_WIDTH}px` : 0,
+ }}
+ filters={<CustomFilter />}
+ queryOptions={{ meta: { ...params } }}
+ empty={false}
+ sort={{ field: "create_time", order: "desc" }}
+ actions={(
+ <TopToolbar>
+ <></>
+ </TopToolbar>
+ )}
+ perPage={DEFAULT_PAGE_SIZE}
+ >
+ <Box sx={{ position: 'relative', minHeight: "60vh", }}>
+ <LinearProgress
+ sx={{ height: "2px", position: 'absolute', top: 0, left: 0, right: 0, }}
+ />
+ <StyledDatagrid
+ preferenceKey='deliveryItem'
+ bulkActionButtons={<AddOutStockButton setOpen={setOpen} setPreview={setPreview} setSelect={setSelect} />}
+ rowClick={(id, resource, record) => false}
+ expand={false}
+ expandSingle={true}
+ omit={['id', 'createTime', 'createBy', 'memo', 'startTime', 'endTime', 'updateBy', 'createTime']}
+ >
+ <NumberField source="id" />
+ <TextField source="deliveryCode" label="table.field.deliveryItem.deliveryCode" />
+ <TextField source="matnrCode" label="table.field.deliveryItem.matnrCode" />
+ <TextField source="maktx" label="table.field.deliveryItem.matnrName" />
+ <TextField source="unit" label="table.field.deliveryItem.unit" />
+ <NumberField source="anfme" label="table.field.deliveryItem.anfme" />
+ <NumberField source="workQty" label="table.field.outStockItem.workQty" />
+ <TextField source="splrName" label="table.field.deliveryItem.splrName" />
+ <TextField source="splrBatch" label="table.field.deliveryItem.splrBatch" />
+ <TextField source="updateBy$" label="common.field.updateBy" />
+ <DateField source="updateTime" label="common.field.updateTime" showTime />
+ <TextField source="createBy$" label="common.field.createBy" />
+ <DateField source="createTime" label="common.field.createTime" showTime />
+ <BooleanField source="statusBool" label="common.field.status" sortable={false} />
+ <TextField source="memo" label="common.field.memo" sortable={false} />
+ </StyledDatagrid>
+ </Box>
+ </List>
+ </Grid>
+ </DialogContent>
+ </Grid>
+ <Grid>
+ <OutOrderPreview open={preview} setOpen={setPreview} selectedIds={select} setCloseParent={setOpen} />
+ </Grid>
+ </Dialog >
+ )
+}
+
+export default OutOrderModal;
+
+const AddOutStockButton = (props) => {
+ const { setOpen, setPreview, setSelect } = props;
+ const { selectedIds, onUnselectItems } = useListContext();
+ const notify = useNotify();
+ const refresh = useRefresh();
+ const confirm = async (event) => {
+ setPreview(true)
+ setSelect(selectedIds);
+ onUnselectItems();
+ // refresh();
+ }
+
+ return (
+ <Button label={"toolbar.confirmSelect"} onClick={confirm}>
+ <CheckCircleIcon />
+ </Button>
+ )
+}
\ No newline at end of file
diff --git a/rsf-admin/src/page/orders/check/OutOrderPreview.jsx b/rsf-admin/src/page/orders/check/OutOrderPreview.jsx
new file mode 100644
index 0000000..ea4cb20
--- /dev/null
+++ b/rsf-admin/src/page/orders/check/OutOrderPreview.jsx
@@ -0,0 +1,141 @@
+import { Dialog, DialogActions, DialogContent, DialogTitle, Box, LinearProgress, Grid, } from "@mui/material";
+import React, { useState, useRef, useEffect, useMemo, memo } from "react";
+import {
+ Toolbar,
+ Button,
+ useTranslate,
+ useNotify,
+ useRefresh,
+ useGetList,
+} from 'react-admin';
+import request from '@/utils/request';
+import { styled } from '@mui/material/styles';
+import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting';
+import { DataGrid, useGridApiContext, GridActionsCellItem, useGridApiRef } from '@mui/x-data-grid';
+import DialogCloseButton from "../../components/DialogCloseButton";
+
+
+const OutOrderPreview = (props) => {
+ const { open, setOpen, record, selectedIds, setCloseParent } = props;
+ const translate = useTranslate();
+ const gridRef = useGridApiRef();
+ const [rows, setRows] = useState([]);
+ const notify = useNotify();
+ const refresh = useRefresh();
+ const handleClose = async (event, reason) => {
+ if (reason !== "backdropClick") {
+ // const res = await request.get(`/outStock/items/cancel/` + selectedIds);
+ setOpen(false);
+ setCloseParent(false)
+ }
+ };
+
+ if (!selectedIds) { return }
+
+ const { data, isLoading, error } = useGetList('/deliveryItem/edit', {
+ pagination: { page: 1, perPage: 1000 },
+ filter: { deleted: 0, ids: selectedIds }
+ });
+
+ return (
+ <Dialog
+ open={open}
+ onClose={handleClose}
+ aria-labelledby="form-dialog-title"
+ aria-hidden
+ fullWidth
+ maxWidth="lg"
+ >
+ <DialogTitle id="form-dialog-title" sx={{
+ position: 'sticky',
+ top: 0,
+ backgroundColor: 'background.paper',
+ zIndex: 1000
+ }}>
+ {translate('create.title')}
+ <Box sx={{ position: 'absolute', top: 8, right: 8, zIndex: 1001 }}>
+ <DialogCloseButton onClose={handleClose} />
+ </Box>
+ </DialogTitle>
+ <DialogContent>
+ <Grid container xl={12}>
+ <Grid item xl={12}>
+ <Box display="flex" sx={{ height: 400, width: '100%', '& .RaConfigurable-root': { width: '100%' } }}>
+ <LinearProgress sx={{ height: "2px", position: 'absolute', top: 0, left: 0, right: 0, }} />
+ <OrderPreview rows={data} gridRef={gridRef} />
+ </Box >
+ </Grid>
+ </Grid>
+ <Toolbar sx={{ justifyContent: 'end' }}>
+ <ConfirmButton label="toolbar.confirm" variant="contained" size="large" gridRef={gridRef} setOpen={setOpen} setCloseParent={setCloseParent}/>
+ </Toolbar>
+ </DialogContent>
+ </Dialog>
+ )
+}
+
+export default OutOrderPreview;
+
+const ConfirmButton = ({ gridRef, setOpen, setCloseParent }) => {
+ const refresh = useRefresh();
+ const notify = useNotify();
+ const confirm = async () => {
+ const items = gridRef.current?.getSortedRows();
+ const { data: { code, msg } } = await request.post(`/outStock/generate/orders`, { ids: items });
+ if (code === 200) {
+ notify(msg);
+ refresh()
+ setOpen(false)
+ setCloseParent(false)
+ } else {
+ notify(msg);
+ }
+ }
+
+ return (
+ <Button label="toolbar.confirm" variant="contained" size="large" onClick={confirm} />
+ )
+}
+
+const OrderPreview = ({ rows, gridRef }) => {
+ gridRef.current = useGridApiRef();
+
+ const columns = [
+ { field: 'matnrCode', headerName: '鐗╂枡缂栫爜', width: 110 },
+ { field: 'maktx', headerName: '鐗╂枡鍚嶇О', width: 190 },
+ {
+ field: 'anfme', headerName: '鍑哄簱鏁伴噺', width: 110, type: 'number', editable: true,
+ valueGetter: (value, row) => {
+ return row.anfme - row.workQty - row.qty;
+ },
+ },
+ {
+ field: 'workQty', headerName: '鍓╀綑鏁伴噺', width: 110, type: 'number',
+ valueGetter: (value, row) => {
+ return row.anfme - row.workQty - row.qty;
+ },
+ },
+ { field: 'unit', headerName: '鍗曚綅', width: 110 },
+ { field: 'splrBatch', headerName: '鎵规', width: 110 },
+ { field: 'splrName', headerName: '渚涘簲鍟�', width: 110 },
+ { field: 'updateTime', headerName: '鏇存柊鏃堕棿', width: 110 },
+ { field: 'updateBy$', headerName: '鏇存柊浜哄憳', width: 110 },
+ ]
+
+ return (
+ <DataGrid
+ storeKey={"outOrderItemPreview"}
+ rows={rows}
+ columns={columns}
+ apiRef={gridRef}
+ disableRowSelectionOnClick
+ hideFooterPagination={true} // 闅愯棌鍒嗛〉鎺т欢
+ hideFooter={true}
+ onRowSelectionModelChange={(ids) => {
+ setSelectedIds(ids)
+ }}
+ />
+ )
+}
+
+
diff --git a/rsf-admin/src/page/orders/check/OutStockPublic.jsx b/rsf-admin/src/page/orders/check/OutStockPublic.jsx
new file mode 100644
index 0000000..6bb6a6d
--- /dev/null
+++ b/rsf-admin/src/page/orders/check/OutStockPublic.jsx
@@ -0,0 +1,480 @@
+import { Box, Card, Grid, LinearProgress, Select, MenuItem, ListItemText } from "@mui/material";
+import React, { useState, useRef, useEffect, useMemo } from "react";
+import {
+ List,
+ DatagridConfigurable,
+ SearchInput,
+ TopToolbar,
+ Button,
+ SelectColumnsButton,
+ EditButton,
+ FilterButton,
+ CreateButton,
+ ExportButton,
+ BulkDeleteButton,
+ WrapperField,
+ useRecordContext,
+ useTranslate,
+ useNotify,
+ useListContext,
+ FunctionField,
+ TextField,
+ NumberField,
+ DateField,
+ BooleanField,
+ ReferenceField,
+ TextInput,
+ DateTimeInput,
+ DateInput,
+ SelectInput,
+ NumberInput,
+ ReferenceInput,
+ ReferenceArrayInput,
+ AutocompleteInput,
+ DeleteButton,
+ SimpleForm,
+ required,
+ Form,
+ useRefresh,
+ useRedirect,
+} from 'react-admin';
+import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE, DEFAULT_ITEM_PAGE_SIZE, DEFAULT_TYPE } from '@/config/setting';
+import { styled } from '@mui/material/styles';
+import { DataGrid, useGridApiContext, GridActionsCellItem, useGridApiRef } from '@mui/x-data-grid';
+import request from '@/utils/request';
+import ConfirmationNumberOutlinedIcon from '@mui/icons-material/ConfirmationNumberOutlined';
+import CloseSharpIcon from '@mui/icons-material/CloseSharp';
+import ConfirmButton from '../../components/ConfirmButton';
+import { Delete, Edit, Add } from '@mui/icons-material';
+import OutStockSiteDialog from "./OutStockSiteDialog";
+
+const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({
+ '& .css-1vooibu-MuiSvgIcon-root': {
+ height: '.9em'
+ },
+ '& .RaDatagrid-row': {
+ cursor: 'auto'
+ },
+ '& .column-maktx': {
+ width: 200
+ },
+
+ mt: '60px'
+ // '& .RaBulkActionsToolbar-toolbar': {
+ // display: 'none'
+ // }
+
+}));
+
+const OutStockPublic = (props) => {
+ const { record, open, setOpen, setManualDialog } = props;
+ const notify = useNotify();
+ const gridRef = useGridApiRef();
+ const [rows, setRows] = useState([]);
+ const [fetchRows, setFetchRows] = useState([]);
+ const translate = useTranslate();
+ const [rowSelectedIds, setRowSelectedIds] = useState([]);
+ const [selectedMatnr, setSelectedMatnr] = useState([]);
+ const [selectedIds, setSelectedIds] = useState([]);
+ const [formData, setFormData] = useState({ orderId: record?.id, waveId: DEFAULT_TYPE });
+ const [dialog, setDialog] = useState(false);
+ const [selectedValue, setSelectedValue] = useState({});
+
+ useEffect(() => {
+ if (selectedMatnr.length < 1) {
+ setRows(fetchRows)
+ } else {
+ const mas = fetchRows.filter(item => selectedMatnr.includes(item.matnrCode));
+ setRows(mas)
+ }
+ }, [selectedMatnr])
+
+
+ const ComfirmButton = () => {
+ const { selectedIds, data } = useListContext();
+ const handleRowClick = () => {
+ const ids = data.filter(item => selectedIds.includes(item.id)).map(item => item.id);
+ setRowSelectedIds(ids);
+ const mas = data.filter(item => selectedIds.includes(item.id)).map(item => item.matnrCode);
+ //璁剧疆搴撲綅淇℃伅绛涢�夋潯浠�
+ setSelectedMatnr(mas);
+ }
+
+ return (
+ <Button label="toolbar.confirm" size="medium" onClick={handleRowClick} />
+ )
+ };
+
+ const handleClickOpen = () => {
+ setDialog(true);
+ };
+
+ const handleClose = (value) => {
+ setDialog(false);
+ setSelectedValue(value);
+ if (selectedIds.length == 0) {
+ const newRows = rows.map(item => {
+ return {
+ ...item,
+ siteNo: value?.site
+ }
+ })
+ setRows(newRows);
+ } else {
+ const newRows = rows.map(item => {
+ return selectedIds.includes(item?.id) ? {
+ ...item,
+ siteNo: value?.site
+ } : item
+ })
+ setRows(newRows);
+ }
+ };
+
+ useEffect(() => {
+ getWaveRule()
+ }, [open])
+
+ const getWaveRule = async () => {
+ if (formData.waveId == null && formData.waveId == undefined) {
+ return
+ }
+ const { data: { code, data, msg } } = await request.post('/outStock/order/getOutTaskItems', { ...formData });
+ if (code === 200) {
+ // setRows(data)
+ setFetchRows(data)
+ } else {
+ notify(msg);
+ }
+ }
+
+ const handleChange = (value, name) => {
+ setFormData((prevData) => ({
+ ...prevData,
+ [name]: value
+ }));
+ };
+
+
+ return (
+ <>
+ <Box>
+ <Grid sx={{ display: "flex" }} container rowSpacing={2} columnSpacing={2}>
+ <Grid item xl={5.7} gap={2} >
+ <Card>
+ <Form>
+ <ReferenceInput
+ source="type"
+ reference="waveRule"
+ >
+ <AutocompleteInput
+ label="table.field.waveRule.type"
+ onChange={(e) => handleChange(e, 'waveId')}
+ defaultValue={15}
+ value={formData.type}
+ validate={required()}
+ />
+ </ReferenceInput>
+ </Form>
+ <List
+ resource="outStockItem"
+ storeKey='outStockItem'
+ sx={{
+ flexGrow: 1,
+ transition: (theme) =>
+ theme.transitions.create(['all'], {
+ duration: theme.transitions.duration.enteringScreen,
+ }),
+ }}
+ title={"menu.outStockItem"}
+ empty={false}
+ filter={{ asnId: record?.id, deleted: 0 }}
+ sort={{ field: "create_time", order: "desc" }}
+ actions={false}
+ pagination={false}
+ perPage={DEFAULT_ITEM_PAGE_SIZE}
+ >
+ <LinearProgress
+ sx={{ height: "2px", position: 'absolute', top: 0, left: 0, right: 0, }}
+ />
+ <StyledDatagrid
+ storeKey={"outStockPublic"}
+ preferenceKey='outStockItem'
+ bulkActionButtons={<>
+ <ComfirmButton />
+ </>}
+ omit={['id', 'splrName', 'qty', 'poCode',]}
+ >
+ <NumberField source="id" />
+ <TextField source="asnCode" label="table.field.outStockItem.asnCode" />
+ <TextField source="poCode" label="table.field.outStockItem.poCode" />
+ <TextField source="matnrCode" label="table.field.outStockItem.matnrCode" />
+ <TextField source="maktx" label="table.field.outStockItem.maktx" />
+ <NumberField source="anfme" label="table.field.outStockItem.anfme" />
+ <NumberField source="workQty" label="table.field.outStockItem.workQty" />
+ <NumberField source="qty" label="table.field.outStockItem.qty" />
+ <TextField source="stockUnit" label="table.field.outStockItem.stockUnit" />
+ <TextField source="splrName" label="table.field.outStockItem.splrName" />
+ </StyledDatagrid>
+ </List>
+ </Card>
+ </Grid>
+ <Grid item xl={6.3} gap={2}>
+ <Card sx={{ minHeight: 1050, height: 'calc(100% - 10px)', width: '100%' }}>
+ <Box>
+ <PreviewTable
+ rows={rows}
+ gridRef={gridRef}
+ setRows={setRows}
+ record={record}
+ formData={formData}
+ selectedIds={selectedIds}
+ setDialog={setDialog}
+ setSelectedIds={setSelectedIds}
+ />
+ </Box>
+ <Box sx={{ textAlign: 'center' }}>
+ <CloseButton setOpen={setOpen} />
+ <SubmitButton selectedIds={selectedIds} setSelectedIds={setSelectedIds} gridRef={gridRef} record={record} />
+ </Box>
+ </Card>
+ </Grid>
+ </Grid>
+ <Grid>
+ <OutStockSiteDialog
+ selectedValue={selectedValue}
+ open={dialog}
+ onClose={handleClose}
+ />
+ </Grid>
+ </Box>
+ </>
+ );
+}
+
+const PreviewTable = ({ rows, gridRef, setRows, record, selectedIds, setSelectedIds, setDialog, formData }) => {
+ gridRef.current = useGridApiRef();
+ const translate = useTranslate();
+
+ useEffect(() => {
+ if (selectedIds.length > 0) {
+ console.log(selectedIds);
+ }
+ }, [selectedIds])
+
+ const baseColumns = [
+ // { field: 'id', headerName: 'ID', width: 40 },
+ { field: 'locCode', headerName: '搴撲綅', width: 110 },
+ { field: 'barcode', headerName: '瀹瑰櫒', width: 120 },
+ { field: 'matnrCode', headerName: '鐗╂枡缂栫爜', width: 120 },
+ { field: 'batch', headerName: '鎵规', width: 90 },
+ { field: 'unit', headerName: '鍗曚綅', width: 60 },
+ { field: 'outQty', headerName: '鍑哄簱鏁伴噺', width: 110, },
+ {
+ field: 'anfme', headerName: '搴撳瓨鏁伴噺', width: 110,
+ renderCell: (params) => (
+ <OutStockAnfme value={params.value} />
+ )
+ },
+ {
+ field: 'siteNo',
+ headerName: '鍑哄簱鍙�',
+ width: 90,
+ type: 'singleSelect',
+ editable: true,
+ renderCell: (params) => (
+ <OutStockSiteNo value={params.value} />
+ ),
+ renderEditCell: (params) => (
+ <OutStockSite {...params} />
+ ),
+ },
+ ]
+
+ const optAction = {
+ field: 'actions',
+ type: 'actions',
+ headerName: translate('common.field.opt'),
+ with: 120,
+ getActions: (params) => [
+ <GridActionsCellItem
+ icon={<Delete />}
+ label="Delete"
+ onClick={() => handleDelete(params.row, rows, setRows)}
+ />,
+ ]
+ }
+
+ const columns = (formData.waveId == 15 || formData.waveId == 16) ? [...baseColumns] : [...baseColumns, optAction];
+
+ /**
+ * 鍒犻櫎浜嬩欢
+ * @param {*} params
+ */
+ const handleDelete = (params, rows, setRows) => {
+ const outRows = rows.filter(row => {
+ return row.id !== params.id
+ })
+ setRows(outRows)
+ }
+
+ const OutStockAnfme = React.memo(function OutStockAnfme(props) {
+ const { value } = props;
+ return (
+ value > 0 ?
+ <Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
+ <span>{value}</span>
+ </Box>
+ :
+ <Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
+ <span style={{ color: 'red' }}>{translate('common.edit.title.insuffInventory')}</span>
+ </Box>
+ );
+ });
+
+ const OutStockSiteNo = React.memo(function OutStockSiteNo(props) {
+ const { value } = props;
+ if (!value) {
+ return null;
+ }
+ return (
+ <Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
+ <span>{value}</span>
+ </Box>
+ );
+ });
+
+ const CustomToolBar = () => {
+ const selectSiteNo = () => {
+ setDialog(true)
+ }
+ return (
+ <Box sx={{
+ p: 1,
+ display: 'flex',
+ justifyContent: 'flex-end',
+ borderTop: '1px solid rgba(224, 224, 224, 1)'
+ }}>
+ <Button
+ onClick={selectSiteNo}
+ variant="outlined"
+ label="toolbar.modiftySite"
+ size="medium"
+ sx={{ mr: 1 }} />
+ </Box>
+ );
+ }
+
+ const OutStockSite = (params) => {
+ const { id, field, siteNo, row: { staNos } } = params;
+ const apiRef = useGridApiContext();
+ const handleChange = async (event) => {
+ await apiRef.current.setEditCellValue(
+ { id, field, value: event.target.value },
+ event,
+ );
+ apiRef.current.stopCellEditMode({ id, field });
+ };
+
+ const handleClose = (event, reason) => {
+ if (reason === 'backdropClick') {
+ apiRef.current.stopCellEditMode({ id, field });
+ }
+ };
+
+ return (
+ <Select
+ value={siteNo}
+ onChange={handleChange}
+ MenuProps={{
+ onClose: handleClose,
+ }}
+ sx={{
+ height: '100%',
+ '& .MuiSelect-select': {
+ display: 'flex',
+ alignItems: 'center',
+ pl: 1,
+ },
+ }}
+ autoFocus
+ fullWidth
+ open
+ >
+ {staNos.map((option) => {
+ return (
+ <MenuItem
+ key={option}
+ value={option.staNo}
+ >
+ <ListItemText sx={{ overflow: 'hidden' }} primary={option.staNo} />
+ </MenuItem>
+ );
+ })}
+ </Select >
+ )
+ }
+
+ return (
+ <DataGrid
+ storeKey={"locItemPreview"}
+ rows={rows}
+ columns={columns}
+ slots={{ toolbar: CustomToolBar }}
+ apiRef={gridRef}
+ checkboxSelection
+ disableRowSelectionOnClick
+ hideFooterPagination={true} // 闅愯棌鍒嗛〉鎺т欢
+ hideFooter={false}
+ onRowSelectionModelChange={(ids) => {
+ setSelectedIds(ids)
+ }}
+ />
+ )
+}
+
+
+//鎻愪氦鎸夐挳
+const SubmitButton = ({ selectedIds, setSelectedIds, gridRef, record }) => {
+ const notify = useNotify();
+ const refresh = useRefresh();
+ const redirect = useRedirect();
+ const submit = async () => {
+ const items = gridRef.current?.getSortedRows();
+ const { data: { code, data, msg } } = await request.post('/outStock/generate/tasks', { items, outId: record?.id });
+ if (code == 200) {
+ refresh();
+ redirect("/task")
+ } else {
+ notify(msg);
+ }
+ }
+ return (
+ <ConfirmButton
+ label="toolbar.allComfirm"
+ variant="contained"
+ size="medium"
+ onConfirm={submit}
+ />
+ )
+}
+
+//鍏抽棴鎸夐挳
+const CloseButton = ({ setOpen }) => {
+ const close = () => {
+ setOpen(false)
+ }
+ return (
+ <Button
+ label="toolbar.close"
+ variant="outlined"
+ size="medium"
+ onClick={close}
+ startIcon={<CloseSharpIcon />}
+ sx={{ margin: '3.5em' }} />
+ )
+}
+
+export default OutStockPublic;
+
+
diff --git a/rsf-admin/src/page/orders/check/SelectMatnrModal.jsx b/rsf-admin/src/page/orders/check/SelectMatnrModal.jsx
new file mode 100644
index 0000000..08e9a61
--- /dev/null
+++ b/rsf-admin/src/page/orders/check/SelectMatnrModal.jsx
@@ -0,0 +1,585 @@
+import React, { useState, useRef, useEffect, useMemo } from "react";
+import {
+ CreateBase,
+ useTranslate,
+ TextInput,
+ NumberInput,
+ BooleanInput,
+ DateInput,
+ SaveButton,
+ SelectInput,
+ ReferenceInput,
+ ReferenceArrayInput,
+ AutocompleteInput,
+ Toolbar,
+ required,
+ useDataProvider,
+ useNotify,
+ Form,
+ useCreateController,
+ useListContext,
+ useRefresh,
+} from 'react-admin';
+import {
+ Dialog,
+ DialogActions,
+ DialogContent,
+ DialogTitle,
+ Stack,
+ Grid,
+ TextField,
+ Box,
+ Button,
+ Paper,
+ TableContainer,
+ Table,
+ TableHead,
+ TableBody,
+ TableRow,
+ TableCell,
+ Tooltip,
+ IconButton,
+ styled,
+ Select,
+ MenuItem
+} from '@mui/material';
+import DialogCloseButton from "../../components/DialogCloseButton";
+import StatusSelectInput from "../../components/StatusSelectInput";
+import ConfirmButton from "../../components/ConfirmButton";
+import MatnrInfoModal from "./MatnrInfoModal";
+import { useForm, Controller, useWatch, FormProvider, useFormContext } from "react-hook-form";
+import SaveIcon from '@mui/icons-material/Save';
+import request from '@/utils/request';
+import { Add, Edit, Delete } from '@mui/icons-material';
+import _, { set } from 'lodash';
+import { DataGrid, useGridApiRef } from '@mui/x-data-grid';
+import DictionarySelect from "../../components/DictionarySelect";
+import DictSelect from "../../components/DictSelect";
+import "./asnOrder.css";
+
+const SelectMatnrModal = (props) => {
+ const { open, setOpen, asnId, billReload } = props;
+
+ const translate = useTranslate();
+ const notify = useNotify();
+ const refresh = useRefresh();
+ const [disabled, setDisabled] = useState(false)
+ const [createDialog, setCreateDialog] = useState(false);
+
+ const tableRef = useRef();
+
+ useEffect(() => {
+ if (open && asnId !== 0) {
+ requestGetHead()
+ requestGetBody()
+ }
+ setDisabled(false)
+ }, [open])
+
+ const handleClose = (event, reason) => {
+ if (reason !== "backdropClick") {
+ setOpen(false);
+ refresh();
+ setFormData({ type: '', wkType: '' })
+ setTableData([])
+ }
+ };
+
+ const [formData, setFormData] = useState({
+ type: '',
+ wkType: '',
+ poCode: '',
+ logisNo: '',
+ arrTime: ''
+ });
+
+ const [tabelData, setTableData] = useState([]);
+
+ const handleChange = (value, name) => {
+ setFormData((prevData) => ({
+ ...prevData,
+ [name]: value
+ }));
+ };
+
+ const resetData = () => {
+ setFormData({
+ type: '',
+ wkType: '',
+ poCode: '',
+ logisNo: '',
+ arrTime: ''
+ })
+ setTableData([])
+ }
+
+ const setFinally = () => {
+ const rows = tableRef.current.state.editRows;
+ for (const key in rows) {
+ const find = tabelData.find(item => item.matnrId === +key);
+ find.anfme = rows[key].anfme.value;
+ }
+ setTableData([...tabelData]);
+ }
+
+ const handleSubmit = async () => {
+ setFinally()
+ setDisabled(true)
+
+ if (asnId === 0) {
+ const parmas = {
+ "orders": formData,
+ "items": tabelData,
+ }
+ const res = await request.post(`/outStock/items/save`, parmas);
+ if (res?.data?.code === 200) {
+ setOpen(false);
+ refresh();
+ resetData()
+ } else {
+ notify(res.data.msg);
+ }
+ } else {
+ const parmas = {
+ "orders": formData,
+ "items": tabelData,
+ }
+ const res = await request.post(`/outStock/items/update`, parmas);
+ if (res?.data?.code === 200) {
+ setOpen(false);
+ refresh();
+ resetData()
+ } else {
+ notify(res.data.msg);
+ }
+ }
+ setDisabled(false)
+
+ };
+
+
+ const handleDelete = async () => {
+ const res = await request.post(`/outStock/remove/${asnId}`);
+ if (res?.data?.code === 200) {
+ setOpen(false);
+ refresh();
+ } else {
+ notify(res.data.msg);
+ }
+ };
+
+ const requestGetHead = async () => {
+ const res = await request.get(`/outStock/${asnId}`);
+ if (res?.data?.code === 200) {
+ setFormData(res.data.data)
+ } else {
+ notify(res.data.msg);
+ }
+ }
+
+ const requestGetBody = async () => {
+ const res = await request.post(`/outStockItem/page`, { asnId });
+ if (res?.data?.code === 200) {
+ setTableData(res.data.data.records)
+ } else {
+ notify(res.data.msg);
+ }
+ }
+
+ const [selectedRows, setSelectedRows] = useState([]);
+
+ const handleDeleteItem = () => {
+ const newTableData = _.filter(tabelData, (item) => !selectedRows.includes(item.matnrId));
+ setTableData(newTableData);
+ }
+
+ return (
+ <>
+ <Dialog
+ open={open}
+ onClose={handleClose}
+ aria-labelledby="form-dialog-title"
+ aria-hidden
+ fullWidth
+ disableRestoreFocus
+ maxWidth="lg" // 'xs' | 'sm' | 'md' | 'lg' | 'xl'
+ >
+ <DialogTitle id="form-dialog-title" sx={{
+ position: 'sticky',
+ top: 0,
+ backgroundColor: 'background.paper',
+ zIndex: 1000
+ }}>
+ {translate('create.title')}
+ <Box sx={{ position: 'absolute', top: 8, right: 8, zIndex: 1001 }}>
+ <DialogCloseButton onClose={handleClose} />
+ </Box>
+ </DialogTitle>
+ <DialogContent sx={{ mt: 2 }}>
+ <Box sx={{ display: 'flex', flexDirection: 'column', gap: 3 }}>
+ <Form defaultValues={formData}>
+ <Grid container spacing={2}>
+ {/* <Grid item md={2}>
+ <DictSelect
+ label={translate("table.field.asnOrder.type")}
+ value={formData.type}
+ onChange={(e) => handleChange(e.target.value, 'type')}
+ dictTypeCode="sys_order_type"
+ required
+ />
+ </Grid> */}
+ <Grid item md={2}>
+ <DictSelect
+ label={translate("table.field.outStock.wkType")}
+ value={formData.wkType}
+ variant="filled"
+ group='2'
+ onChange={(e) => handleChange(e.target.value, 'wkType')}
+ dictTypeCode="sys_business_type"
+ required
+ />
+ </Grid>
+ <Grid item md={2}>
+ <TextField
+ label={translate("table.field.outStock.poCode")}
+ value={formData.poCode}
+ variant="filled"
+ size='small'
+ onChange={(e) => handleChange(e.target.value, 'poCode')}
+ />
+ </Grid>
+ <Grid item md={2}>
+ <TextField
+ label={translate("table.field.outStock.logisNo")}
+ value={formData.logisNo}
+ variant="filled"
+ size='small'
+ onChange={(e) => handleChange(e.target.value, 'logisNo')}
+ />
+ </Grid>
+ <Grid item md={2}>
+ <DateInput
+ source="arrTime"
+ label="table.field.outStock.arrTime"
+ size='small'
+ variant="filled"
+ value={formData.arrTime}
+ onChange={(e) => handleChange(e.target.value, 'arrTime')}
+ />
+ </Grid>
+ </Grid>
+ </Form>
+ </Box>
+
+ <Box sx={{ mt: 2 }}>
+ <Stack direction="row" spacing={2}>
+ <Button variant="contained" onClick={() => setCreateDialog(true)}>鏂板鐗╂枡</Button>
+ {/* {asnId !== '' && <ConfirmButton label={'鍒犻櫎'} variant="outlined" color="error" onConfirm={handleDelete} />} */}
+ <ConfirmButton label={'鍒犻櫎'} variant="outlined" color="error" onConfirm={handleDeleteItem} />
+ </Stack>
+ </Box>
+ <Box sx={{ mt: 2 }}>
+ <AsnOrderModalTable tabelData={tabelData} setTableData={setTableData} asnId={asnId} selectedRows={selectedRows} setSelectedRows={setSelectedRows} tableRef={tableRef}></AsnOrderModalTable>
+ </Box>
+ </DialogContent>
+ <DialogActions sx={{ position: 'sticky', bottom: 0, backgroundColor: 'background.paper', zIndex: 1000 }}>
+ <Toolbar sx={{ width: '100%', justifyContent: 'space-between' }} >
+ <Button disabled={disabled} onClick={handleSubmit} variant="contained" startIcon={<SaveIcon />}>
+ {translate('toolbar.confirm')}
+ </Button>
+ </Toolbar>
+ </DialogActions>
+ </Dialog>
+ <MatnrInfoModal
+ open={createDialog}
+ setOpen={setCreateDialog}
+ data={tabelData}
+ setData={setTableData}
+ />
+ </>
+ )
+}
+
+export default SelectMatnrModal;
+
+const SelectInputSplrNameEditCell = (params) => {
+ const [formData, setFormData] = useState([{}])
+ useEffect(() => {
+ getOptions();
+ }, []);
+ const getOptions = async () => {
+ const parmas = {
+ "type": "supplier"
+ }
+ const {
+ data: { code, data, msg },
+ } = await request.post("companys/page", parmas);
+ if (code === 200) {
+ setFormData(data.records)
+ } else {
+ notify(msg);
+ }
+ }
+
+ return (
+ <Select
+ value={params.value}
+ onChange={(e) => {
+ params.api.setEditCellValue({
+ id: params.id,
+ field: params.field,
+ value: e.target.value,
+ })
+ // 鎵惧埌閫変腑鐨勪緵搴斿晢璁板綍
+ const selectedSupplier = formData.find(supplier => supplier.name === e.target.value);
+
+ // 濡傛灉鎵惧埌瀵瑰簲鐨勪緵搴斿晢璁板綍锛屽悓鏃舵洿鏂皊plrCode瀛楁
+ if (selectedSupplier) {
+ params.api.setEditCellValue({
+ id: params.id,
+ field: 'splrCode',
+ value: selectedSupplier.id,
+ });
+ }
+ }}
+ fullWidth
+ >
+ {formData.map(e => {
+ return (
+ <MenuItem value={e.name} children={e.name} key={e.id} />
+ );
+
+ })}
+
+ </Select>
+ );
+};
+
+const SelectInputSplrCodeEditCell = (params) => {
+ const [formData, setFormData] = useState([{}])
+ useEffect(() => {
+ getOptions();
+ }, []);
+ const getOptions = async () => {
+ const parmas = {
+ "type": "supplier"
+ }
+ const {
+ data: { code, data, msg },
+ } = await request.post("companys/page", parmas);
+ if (code === 200) {
+ setFormData(data.records)
+ } else {
+ notify(msg);
+ }
+ }
+
+ return (
+ <Select
+ value={params.value}
+ onChange={(e) => {
+ params.api.setEditCellValue({
+ id: params.id,
+ field: params.field,
+ value: e.target.value,
+ })
+ const selectedSupplier = formData.find(supplier => supplier.id === e.target.value);
+
+ // 濡傛灉鎵惧埌瀵瑰簲鐨勪緵搴斿晢璁板綍锛屽悓鏃舵洿鏂皊plrCode瀛楁
+ if (selectedSupplier) {
+ params.api.setEditCellValue({
+ id: params.id,
+ field: 'splrName',
+ value: selectedSupplier.name,
+ });
+ }
+ }}
+ fullWidth
+
+ >
+ {formData.map(e => {
+ return (
+ <MenuItem value={e.id} children={e.name} key={e.id} />
+ );
+
+ })}
+
+ </Select>
+ );
+};
+
+
+
+
+const AsnOrderModalTable = ({ tabelData, setTableData, asnId, selectedRows, setSelectedRows, tableRef }) => {
+ const translate = useTranslate();
+ const notify = useNotify();
+
+ const [columns, setColumns] = useState([
+ {
+ field: 'maktx',
+ headerName: translate('table.field.outStockItem.maktx'),
+ width: 250,
+ editable: false,
+ },
+ {
+ field: 'matnrCode',
+ headerName: translate('table.field.outStockItem.matnrCode'),
+ width: 130,
+ editable: false,
+ },
+ {
+ field: 'anfme',
+ headerName: translate('table.field.outStockItem.anfme') + "*",
+ type: 'number',
+ minWidth: 100,
+ flex: 1,
+ editable: true,
+ valueFormatter: (val) => val < 0 ? 0 : val,
+ headerClassName: "custom",
+ },
+ {
+ field: 'splrCode',
+ headerName: translate('table.field.outStockItem.splrCode') + "*",
+ minWidth: 100,
+ flex: 1,
+ editable: true,
+ renderEditCell: (params) => (
+ <SelectInputSplrCodeEditCell {...params} />
+ ),
+ headerClassName: "custom",
+ },
+ {
+ field: 'splrName',
+ headerName: translate('table.field.outStockItem.splrName') + "*",
+ minWidth: 100,
+ flex: 1,
+ editable: true,
+ renderEditCell: (params) => (
+ <SelectInputSplrNameEditCell {...params} />
+ ),
+ headerClassName: "custom",
+ },
+ {
+ field: 'splrBatch',
+ headerName: translate('table.field.outStockItem.splrBatch'),
+ minWidth: 100,
+ flex: 1,
+ editable: true,
+ },
+ {
+ field: 'poCode',
+ headerName: translate('table.field.outStockItem.poDetlCode'),
+ minWidth: 100,
+ flex: 1,
+ editable: true,
+ },
+ {
+ field: 'stockUnit',
+ headerName: translate('table.field.outStockItem.stockUnit'),
+ minWidth: 100,
+ flex: 1,
+ editable: true,
+ },
+ ])
+
+ const action = {
+ field: 'action',
+ headerName: '鎿嶄綔',
+ width: 70,
+ lockPosition: 'left',
+ renderCell: (params) => (
+ <Tooltip title="Delete">
+ <IconButton onClick={() => handleDelete(params.row)}>
+ <Delete />
+ </IconButton>
+ </Tooltip>
+ ),
+
+ }
+
+ let cdata = useRef([]);
+
+ useEffect(() => {
+ getDynamicFields();
+ }, []);
+
+ useEffect(() => {
+ cdata.current = tabelData
+ }, [tabelData]);
+
+
+ const getDynamicFields = async () => {
+ const {
+ data: { code, data, msg },
+ } = await request.get("/fields/enable/list");
+ if (code === 200) {
+ const cols = data.map(el => ({
+ field: el.fields,
+ headerName: el.fieldsAlise,
+ minWidth: 100,
+ flex: 1,
+ editable: false
+ }))
+ setColumns([...columns, ...cols, action])
+ } else {
+ notify(msg);
+ }
+ }
+
+
+ const handleDelete = (row) => {
+ const newData = _.filter(cdata.current, (item) => item.matnrId !== row.matnrId);
+ setTableData(newData);
+ };
+
+
+ const processRowUpdate = (newRow, oldRow) => {
+ const rows = tabelData.map((r) =>
+ r.matnrId === newRow.matnrId ? { ...newRow } : r
+ )
+ setTableData(rows)
+ return newRow;
+ };
+
+ const handleSelectionChange = (ids) => {
+ setSelectedRows(ids)
+ };
+
+ tableRef.current = useGridApiRef();
+
+ return (
+ <div style={{ height: 400, width: '100%' }}>
+ <DataGrid
+ apiRef={tableRef}
+ rows={tabelData}
+ columns={columns}
+ disableRowSelectionOnClick
+ getRowId={(row) => row.matnrId ? row.matnrId : row.id}
+ disableColumnFilter
+ disableColumnSelector
+ disableColumnSorting
+ disableMultipleColumnsSorting
+ processRowUpdate={processRowUpdate}
+ initialState={{
+ pagination: {
+ paginationModel: {
+ pageSize: 25,
+ },
+ },
+ }}
+ pageSizeOptions={[15, 25, 50, 100]}
+ editMode="row"
+ checkboxSelection
+ onRowSelectionModelChange={handleSelectionChange}
+ selectionModel={selectedRows}
+ sx={{
+ '& .MuiDataGrid-cell input': {
+ border: '1px solid #ccc'
+ },
+ }}
+ />
+ </div>
+ );
+};
+
diff --git a/rsf-admin/src/page/orders/check/index.jsx b/rsf-admin/src/page/orders/check/index.jsx
new file mode 100644
index 0000000..7c2b86e
--- /dev/null
+++ b/rsf-admin/src/page/orders/check/index.jsx
@@ -0,0 +1,18 @@
+import React, { useState, useRef, useEffect, useMemo } from "react";
+import {
+ ListGuesser,
+ EditGuesser,
+ ShowGuesser,
+} from "react-admin";
+
+import CheckOrderList from "./CheckOrderList";
+import CheckOrderEdit from "./CheckOrderEdit";
+
+export default {
+ list: CheckOrderList,
+ edit: CheckOrderEdit,
+ show: ShowGuesser,
+ recordRepresentation: (record) => {
+ return `${record.name}`
+ }
+};
diff --git a/rsf-admin/src/page/warehouseAreas/WarehouseAreasList.jsx b/rsf-admin/src/page/warehouseAreas/WarehouseAreasList.jsx
index cf5d60c..9a4d3bd 100644
--- a/rsf-admin/src/page/warehouseAreas/WarehouseAreasList.jsx
+++ b/rsf-admin/src/page/warehouseAreas/WarehouseAreasList.jsx
@@ -31,6 +31,7 @@
ReferenceArrayInput,
AutocompleteInput,
DeleteButton,
+ Datagrid,
useRefresh,
Button
} from 'react-admin';
@@ -44,21 +45,84 @@
import PageDrawer from "../components/PageDrawer";
import BatchModal from "./BatchModal";
import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting';
-import * as Common from '@/utils/common';
import EditIcon from '@mui/icons-material/Edit';
+import { minWidth } from "@mui/system";
+
+
+const ScrollableDatagrid = styled(Datagrid)(({ theme }) => ({
+ '& .MuiTable-root': {
+ minWidth: '100%', // 纭繚琛ㄦ牸瀹藉害瓒冲
+ tableLayout: 'fixed', // 鍥哄畾琛ㄦ牸甯冨眬
+ },
+ '& .RaDatagrid-rowCell': {
+ textAlign: 'center',
+ whiteSpace: 'nowrap',
+ textOverflow: 'ellipsis',
+ },
+
+ '& .RaDatagrid-headerCell': {
+ whiteSpace: 'nowrap',
+ overflowX: 'auto',
+ },
+
+ '& .opt': {
+ width: 200,
+ position: 'sticky',
+ zIndex: 3,
+ right: 0,
+
+ },
+}));
+
const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({
- '& .css-1vooibu-MuiSvgIcon-root': {
- height: '.9em'
- },
- '& .RaDatagrid-row': {
- cursor: 'auto'
- },
- '& .column-name': {
- },
+ // height: '.9em'
+ // },
+ // '& .RaDatagrid-row': {
+ // cursor: 'auto'
+ // },
'& .opt': {
- width: 200
+ width: 200,
+ position: 'sticky',
+ right: 0,
},
+
+ '& .MuiTableContainer-root': {
+ overflowX: 'auto',
+ '&::-webkit-scrollbar': {
+ height: '8px',
+ },
+ '&::-webkit-scrollbar-thumb': {
+ backgroundColor: theme.palette.action.hover,
+ borderRadius: '4px',
+ },
+ },
+ // '& .MuiTable-root': {
+ // minWidth: '100%', // 纭繚琛ㄦ牸瀹藉害瓒冲
+ // tableLayout: 'fixed', // 鍥哄畾琛ㄦ牸甯冨眬
+ // },
+ // '& .MuiTableCell-root': {
+ // whiteSpace: 'nowrap',
+ // overflow: 'hidden',
+ // textOverflow: 'ellipsis',
+ // position: 'relative', // 涓哄浐瀹氬垪鎻愪緵瀹氫綅涓婁笅鏂�
+ // },
+ // '& .MuiTableCell-actions': {
+ // position: 'sticky',
+ // right: 0,
+ // background: theme.palette.background.paper,
+ // zIndex: 2,
+ // width: '150px',
+ // minWidth: '150px',
+ // boxShadow: '-2px 0 4px rgba(0,0,0,0.1)',
+ // '& button': {
+ // marginLeft: theme.spacing(1),
+ // }
+ // },
+ // '& .MuiTableHead-root .MuiTableCell-actions': {
+ // zIndex: 3, // 琛ㄥご姣斿唴瀹归珮涓�灞�
+ // }
+
}));
const filters = [
@@ -127,6 +191,13 @@
duration: theme.transitions.duration.enteringScreen,
}),
marginRight: drawerVal ? `${PAGE_DRAWER_WIDTH}px` : 0,
+ '& .RaList-content': {
+ position: 'sticky',
+ overflow: 'auto',
+ width: 'auto',
+ righ: '0px',
+ minWidth: '100%'
+ }
}}
title={"menu.warehouseAreas"}
empty={<EmptyData onClick={() => { setCreateDialog(true) }} />}
@@ -142,7 +213,7 @@
)}
perPage={DEFAULT_PAGE_SIZE}
>
- <StyledDatagrid
+ <ScrollableDatagrid
preferenceKey='warehouseAreas'
bulkActionButtons={
<>
@@ -157,33 +228,33 @@
>
<NumberField source="id" />
{/* <TextField source="uuid" label="table.field.warehouseAreas.uuid" /> */}
- <TextField source="name" label="table.field.warehouseAreas.name" />
- <TextField source="code" label="table.field.warehouseAreas.code" />
- <TextField source="type$" label="table.field.warehouseAreas.type"/>
+ <TextField source="name" label="table.field.warehouseAreas.name" width="10%" />
+ <TextField source="code" label="table.field.warehouseAreas.code" width="10%" />
+ <TextField source="type$" label="table.field.warehouseAreas.type" width="10%" />
{/* <ReferenceField source="shipperId" label="table.field.warehouseAreas.shipperId" reference="shipper" link={false} sortable={false}>
<TextField source="name" />
</ReferenceField> */}
- <TextField source="warehouseId$" label="table.field.warehouseAreas.wareId" />
- <TextField source="shipperId$" label="table.field.warehouseAreas.shipperId" />
- <NumberField source="supplierId" label="table.field.warehouseAreas.supplierId" />
- <TextField source="flagMinus$" label="table.field.warehouseAreas.flagMinus" sortable={false} />
- <TextField source="flagLabelMange$" label="table.field.warehouseAreas.flagLabelMange" sortable={false} />
- <TextField source="flagMix$" label="table.field.warehouseAreas.flagMix" sortable={false} />
- <ReferenceField source="updateBy" label="common.field.updateBy" reference="user" link={false} sortable={false}>
+ <TextField source="warehouseId$" label="table.field.warehouseAreas.wareId" width="10%" />
+ <TextField source="shipperId$" label="table.field.warehouseAreas.shipperId" width="10%" />
+ <NumberField source="supplierId" label="table.field.warehouseAreas.supplierId" width="10%" />
+ <TextField source="flagMinus$" label="table.field.warehouseAreas.flagMinus" sortable={false} width="10%" />
+ <TextField source="flagLabelMange$" label="table.field.warehouseAreas.flagLabelMange" sortable={false} width="10%" />
+ <TextField source="flagMix$" label="table.field.warehouseAreas.flagMix" sortable={false} width="10%" />
+ <ReferenceField source="updateBy" label="common.field.updateBy" reference="user" link={false} sortable={false} width="10%">
<TextField source="nickname" />
</ReferenceField>
- <DateField source="updateTime" label="common.field.updateTime" showTime />
- <ReferenceField source="createBy" label="common.field.createBy" reference="user" link={false} sortable={false}>
+ <DateField source="updateTime" label="common.field.updateTime" showTime width="10%" />
+ <ReferenceField source="createBy" label="common.field.createBy" reference="user" link={false} sortable={false} width="10%">
<TextField source="nickname" />
</ReferenceField>
- <DateField source="createTime" label="common.field.createTime" showTime />
- <BooleanField source="statusBool" label="common.field.status" sortable={false} />
- <TextField source="memo" label="common.field.memo" sortable={false} />
- <WrapperField cellClassName="opt" label="common.field.opt">
+ <DateField source="createTime" label="common.field.createTime" showTime width="10%" />
+ <BooleanField source="statusBool" label="common.field.status" sortable={false} width="10%" />
+ <TextField source="memo" label="common.field.memo" sortable={false} width="10%" />
+ <WrapperField source="opt" cellClassName="opt" label="common.field.opt">
<EditButton sx={{ padding: '1px', fontSize: '.75rem' }} />
<DeleteButton sx={{ padding: '1px', fontSize: '.75rem' }} mutationMode={OPERATE_MODE} />
</WrapperField>
- </StyledDatagrid>
+ </ScrollableDatagrid>
</List>
<WarehouseAreasCreate
open={createDialog}
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/CheckOrderController.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/CheckOrderController.java
new file mode 100644
index 0000000..51845f5
--- /dev/null
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/CheckOrderController.java
@@ -0,0 +1,125 @@
+package com.vincent.rsf.server.manager.controller;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.vincent.rsf.framework.common.Cools;
+import com.vincent.rsf.framework.common.R;
+import com.vincent.rsf.server.common.annotation.OperationLog;
+import com.vincent.rsf.server.common.domain.BaseParam;
+import com.vincent.rsf.server.common.domain.KeyValVo;
+import com.vincent.rsf.server.common.domain.PageParam;
+import com.vincent.rsf.server.common.utils.ExcelUtil;
+import com.vincent.rsf.server.manager.entity.AsnOrder;
+import com.vincent.rsf.server.manager.enums.OrderType;
+import com.vincent.rsf.server.manager.service.CheckOrderService;
+import com.vincent.rsf.server.system.constant.SerialRuleCode;
+import com.vincent.rsf.server.system.controller.BaseController;
+import com.vincent.rsf.server.system.utils.SerialRuleUtils;
+import io.swagger.annotations.Api;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+import javax.servlet.http.HttpServletResponse;
+import java.util.*;
+
+@Api("鐩樼偣")
+@RestController
+public class CheckOrderController extends BaseController {
+
+ @Autowired
+ private CheckOrderService checkOrderService;
+
+
+ @PreAuthorize("hasAuthority('manager:check:list')")
+ @PostMapping("/check/page")
+ public R page(@RequestBody Map<String, Object> map) {
+ BaseParam baseParam = buildParam(map, BaseParam.class);
+ PageParam<AsnOrder, BaseParam> pageParam = new PageParam<>(baseParam, AsnOrder.class);
+ QueryWrapper<AsnOrder> wrapper = pageParam.buildWrapper(true);
+ wrapper.eq("type", OrderType.ORDER_CHECK.type);
+ return R.ok().add(checkOrderService.page(pageParam, wrapper));
+ }
+
+ @PreAuthorize("hasAuthority('manager:check:list')")
+ @PostMapping("/check/list")
+ public R list(@RequestBody Map<String, Object> map) {
+ return R.ok().add(checkOrderService.list());
+ }
+
+ @PreAuthorize("hasAuthority('manager:check:list')")
+ @PostMapping({"/check/many/{ids}", "/check/many/{ids}"})
+ public R many(@PathVariable Long[] ids) {
+ return R.ok().add(checkOrderService.listByIds(Arrays.asList(ids)));
+ }
+
+ @PreAuthorize("hasAuthority('manager:check:list')")
+ @GetMapping("/check/{id}")
+ public R get(@PathVariable("id") Long id) {
+ return R.ok().add(checkOrderService.getById(id));
+ }
+
+ @PreAuthorize("hasAuthority('manager:check:save')")
+ @OperationLog("Create 瀛楀吀鏁版嵁闆�")
+ @PostMapping("/check/save")
+ public R save(@RequestBody AsnOrder order) {
+ order.setType(OrderType.ORDER_CHECK.type);
+ String ruleCode = SerialRuleUtils.generateRuleCode(SerialRuleCode.SYS_CHECK_RULE_CODE, order);
+ if (Objects.isNull(ruleCode)) {
+ throw new RuntimeException("鐩樼偣鍗曞彿鐢熸垚澶辫触锛侊紒");
+ }
+ if (!checkOrderService.save(order)) {
+ return R.error("Save Fail");
+ }
+ return R.ok("Save Success").add(order);
+ }
+
+ @PreAuthorize("hasAuthority('manager:check:update')")
+ @OperationLog("Update 瀛楀吀鏁版嵁闆�")
+ @PostMapping("/check/update")
+ public R update(@RequestBody AsnOrder order) {
+ order.setUpdateTime(null);
+ order.setUpdateBy(getLoginUserId());
+ if (!checkOrderService.updateById(order)) {
+ return R.error("Update Fail");
+ }
+ return R.ok("Update Success").add(order);
+ }
+
+ @PreAuthorize("hasAuthority('manager:check:remove')")
+ @OperationLog("Delete 瀛楀吀鏁版嵁闆�")
+ @PostMapping("/check/remove/{ids}")
+ public R remove(@PathVariable Long[] ids) {
+ if (!checkOrderService.removeByIds(Arrays.asList(ids))) {
+ return R.error("Delete Fail");
+ }
+ return R.ok("Delete Success").add(ids);
+ }
+
+ @PreAuthorize("hasAuthority('manager:check:list')")
+ @PostMapping("/check/query")
+ public R query(@RequestParam(required = false) String condition) {
+ List<KeyValVo> vos = new ArrayList<>();
+ LambdaQueryWrapper<AsnOrder> wrapper = new LambdaQueryWrapper<>();
+ if (!Cools.isEmpty(condition)) {
+ wrapper.like(AsnOrder::getCode, condition);
+ }
+ checkOrderService.page(new Page<>(1, 30), wrapper).getRecords().forEach(
+ item -> vos.add(new KeyValVo(item.getId(), item.getCode()))
+ );
+ return R.ok().add(vos);
+ }
+
+ @PreAuthorize("hasAuthority('manager:check:list')")
+ @PostMapping("/check/export")
+ public void export(@RequestBody Map<String, Object> map, HttpServletResponse response) throws Exception {
+ List<AsnOrder> orders = new ArrayList<>();
+ if (!Objects.isNull(map.get("ids"))) {
+ orders = checkOrderService.list(new LambdaQueryWrapper<AsnOrder>().in(AsnOrder::getId, map.get("ids")));
+ } else {
+ orders = checkOrderService.list();
+ }
+ ExcelUtil.build(ExcelUtil.create(orders, AsnOrder.class), response);
+ }
+
+}
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/enums/OrderType.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/enums/OrderType.java
index 70eb44f..7a53b72 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/enums/OrderType.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/enums/OrderType.java
@@ -11,6 +11,7 @@
//璁㈠崟绫诲瀷
ORDER_OUT("out", "鍑哄簱鍗�"),
ORDER_IN("in", "鍏ュ簱鍗�"),
+ ORDER_CHECK("check", "鐩樼偣鍗�");
;
OrderType(String type, String desc) {
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/mapper/CheckOrderMapper.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/mapper/CheckOrderMapper.java
new file mode 100644
index 0000000..24bbb88
--- /dev/null
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/mapper/CheckOrderMapper.java
@@ -0,0 +1,12 @@
+package com.vincent.rsf.server.manager.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.vincent.rsf.server.manager.entity.AsnOrder;
+import org.apache.ibatis.annotations.Mapper;
+import org.springframework.stereotype.Repository;
+
+@Mapper
+@Repository
+public interface CheckOrderMapper extends BaseMapper<AsnOrder> {
+
+}
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/schedules/TaskSchedules.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/schedules/TaskSchedules.java
index dc2c516..396b10b 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/schedules/TaskSchedules.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/schedules/TaskSchedules.java
@@ -93,6 +93,7 @@
/**
* 浠诲姟鑷姩涓嬪彂
+ *
* @throws Exception
*/
@Scheduled(cron = "0/5 * * * * ? ")
@@ -101,8 +102,9 @@
Long loginUserId = SystemAuthUtils.getLoginUserId();
List<Integer> list = Arrays.asList(TaskType.TASK_TYPE_IN.type, TaskType.TASK_TYPE_OUT.type);
List<Integer> integers = Arrays.asList(TaskStsType.GENERATE_IN.id, TaskStsType.GENERATE_OUT.id);
- List<Task> tasks = taskService.list(new LambdaQueryWrapper<Task>().in(Task::getTaskType, list)
- .in(Task::getTaskStatus, integers)
+ List<Task> tasks = taskService.list(new LambdaQueryWrapper<Task>()
+ .in(Task::getTaskType, list)
+ .in(Task::getTaskStatus, integers)
.orderByDesc(Task::getSort));
for (Task task : tasks) {
Loc loc = locService.getOne(new LambdaQueryWrapper<Loc>().eq(Loc::getBarcode, task.getBarcode()));
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/CheckOrderService.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/CheckOrderService.java
new file mode 100644
index 0000000..6f4fa8e
--- /dev/null
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/CheckOrderService.java
@@ -0,0 +1,8 @@
+package com.vincent.rsf.server.manager.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.vincent.rsf.server.manager.entity.AsnOrder;
+
+public interface CheckOrderService extends IService<AsnOrder> {
+
+}
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/CheckOrderServiceImpl.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/CheckOrderServiceImpl.java
new file mode 100644
index 0000000..2c31210
--- /dev/null
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/CheckOrderServiceImpl.java
@@ -0,0 +1,12 @@
+package com.vincent.rsf.server.manager.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.vincent.rsf.server.manager.entity.AsnOrder;
+import com.vincent.rsf.server.manager.mapper.CheckOrderMapper;
+import com.vincent.rsf.server.manager.service.CheckOrderService;
+import org.springframework.stereotype.Service;
+
+@Service("checkOrderService")
+public class CheckOrderServiceImpl extends ServiceImpl<CheckOrderMapper, AsnOrder> implements CheckOrderService {
+
+}
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/system/constant/SerialRuleCode.java b/rsf-server/src/main/java/com/vincent/rsf/server/system/constant/SerialRuleCode.java
index 3d1d48c..c0e28de 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/system/constant/SerialRuleCode.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/system/constant/SerialRuleCode.java
@@ -85,5 +85,8 @@
*/
public final static String SYS_WAVE_RULE_CODE = "sys_wave_type";
+ /**鐩樼偣鍗曞彿*/
+ public final static String SYS_CHECK_RULE_CODE = "sys_check_rule_code";
+
}
diff --git a/rsf-server/src/main/resources/application-dev.yml b/rsf-server/src/main/resources/application-dev.yml
index 203032b..95669f3 100644
--- a/rsf-server/src/main/resources/application-dev.yml
+++ b/rsf-server/src/main/resources/application-dev.yml
@@ -13,9 +13,9 @@
datasource:
driver-class-name: com.mysql.jdbc.Driver
# url: jdbc:mysql://47.76.147.249:3306/rsf?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
+# username: rsf
username: root
url: jdbc:mysql://127.0.0.1:3306/rsf?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
-# username: rsf
password: 34821015
type: com.alibaba.druid.pool.DruidDataSource
druid:
--
Gitblit v1.9.1