From d734647a726a0fc1e693619ad6b1b112f2ff0997 Mon Sep 17 00:00:00 2001
From: skyouc
Date: 星期五, 08 八月 2025 16:32:46 +0800
Subject: [PATCH] 日出入库汇总统计报表

---
 rsf-admin/src/page/statistics/deadTime/LocItemDeadList.jsx                                       |    7 
 rsf-admin/src/page/statistics/inStockItem/InStockItemList.jsx                                    |  145 ++++++++++
 rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/StockStatisticController.java |    7 
 rsf-admin/src/page/statistics/outStockNum/OutStockNumList.jsx                                    |  140 ++++++++++
 rsf-admin/src/page/statistics/inStockItem/index.jsx                                              |   16 +
 rsf-admin/src/page/statistics/stockStatisticNum/index.jsx                                        |   16 +
 rsf-admin/src/page/statistics/outStockItem/OutStockItemList.jsx                                  |  145 ++++++++++
 rsf-admin/src/page/statistics/outStockItem/index.jsx                                             |   16 +
 rsf-admin/src/page/statistics/stockStatisticNum/stockStatisticList.jsx                           |  140 ++++++++++
 rsf-admin/src/page/statistics/outStockNum/index.jsx                                              |   16 +
 rsf-admin/src/i18n/zh.js                                                                         |   39 +-
 rsf-admin/src/i18n/en.js                                                                         |   32 +
 rsf-admin/src/page/ResourceContent.js                                                            |   15 +
 rsf-admin/src/page/statistics/inStockNum/InStockNumList.jsx                                      |  102 ++----
 14 files changed, 742 insertions(+), 94 deletions(-)

diff --git a/rsf-admin/src/i18n/en.js b/rsf-admin/src/i18n/en.js
index 32dd056..501e315 100644
--- a/rsf-admin/src/i18n/en.js
+++ b/rsf-admin/src/i18n/en.js
@@ -215,6 +215,8 @@
         statisticReport: 'Statistical Report',
         locDeadReport: 'Locs Dead Report',
         stockStatistic: 'Stock Statistic',
+        statisticCount: 'Statistic Count',
+
     },
     table: {
         field: {
@@ -826,18 +828,24 @@
                 startTime: "startTime",
                 endTime: "endTime",
             },
-          stockStatistic: {
-            id: "id",
-            dayTime: "dayTime",
-            taskType: "taskType",
-            taskStatus: "taskStatus",
-            maktx: "maktx",
-            matnrCode: "matnrCode",
-            count: "count",
-            batch: "batch",
-            anfme: "anfme",
-            unit: "unit",
-          },
+            stockStatistic: {
+                id: "id",
+                dayTime: "dayTime",
+                taskType: "taskType",
+                taskStatus: "taskStatus",
+                maktx: "maktx",
+                matnrCode: "matnrCode",
+                count: "count",
+                inAnfmeCount: 'In Anfme Count',
+                outAnfmeCount: 'Count Anfme Count',
+                inAnfme: 'In Anfme',
+                outAnfme: 'Out Anfme',
+                locCode: 'Loc Code',
+                barcode: 'Barcode',
+                batch: "batch",
+                anfme: "anfme",
+                unit: "unit",
+            },
             delivery: {
                 code: "code",
                 platId: "platId",
diff --git a/rsf-admin/src/i18n/zh.js b/rsf-admin/src/i18n/zh.js
index e30ae5a..320d013 100644
--- a/rsf-admin/src/i18n/zh.js
+++ b/rsf-admin/src/i18n/zh.js
@@ -220,8 +220,13 @@
         transferItem: '璋冩嫈鍗曟槑缁�',
         locRevise: '搴撳瓨璋冩暣',
         statisticReport: '鏃ュ織鎶ヨ〃',
-        locDeadReport : '搴撳瓨鍋滄粸鎶ヨ〃',
-        stockStatistic: '鏃ュ簱瀛樼粺璁�',
+        locDeadReport: '搴撳瓨鍋滄粸鎶ヨ〃',
+        stockStatistic: '鏃ュ叆搴撴眹鎬绘煡璇�',
+        outStatistic: '鏃ュ嚭搴撴眹鎬绘煡璇�',
+        inStatistic: '鏃ュ叆搴撴眹鎬绘煡璇�', 
+        inStatisticItem: '鏃ュ叆搴撴槑缁嗘煡璇�',
+        outStatisticItem: '鏃ュ嚭搴撴槑缁嗘煡璇�',
+        statisticCount: '鏃ュ嚭鍏ュ簱姹囨�荤粺璁�',
     },
     table: {
         field: {
@@ -480,18 +485,24 @@
                 useStatus: '搴撲綅鐘舵��',
                 locAreaId: '閫昏緫鍒嗗尯'
             },
-          stockStatistic: {
-            id: "id",
-            dayTime: "鏃ユ湡",
-            taskType: "浠诲姟绫诲瀷",
-            taskStatus: "浠诲姟鐘舵��",
-            maktx: "鐗╂枡鍚嶇О",
-            matnrCode: "鐗╂枡缂栫爜",
-            count: "娆℃暟",
-            batch: "鎵规",
-            anfme: "鏁伴噺",
-            unit: "鍗曚綅",
-          },
+            stockStatistic: {
+                id: "id",
+                dayTime: "鏃ユ湡",
+                taskType: "浠诲姟绫诲瀷",
+                taskStatus: "浠诲姟鐘舵��",
+                inAnfmeCount: '鍏ュ簱娆℃暟',
+                outAnfmeCount: '鍑哄簱娆℃暟',
+                inAnfme: '鍏ュ簱閲�',
+                outAnfme: '鍑哄簱閲�',
+                maktx: "鐗╂枡鍚嶇О",
+                matnrCode: "鐗╂枡缂栫爜",
+                locCode: '搴撲綅',
+                barcode: '鎵樼洏鐮�',
+                count: "鎬绘鏁�",
+                batch: "鎵规",
+                anfme: "鏁伴噺",
+                unit: "鍗曚綅",
+            },
             locType: {
                 name: "搴撲綅绫诲瀷",
                 code: "缂栧彿",
diff --git a/rsf-admin/src/page/ResourceContent.js b/rsf-admin/src/page/ResourceContent.js
index 211fb4b..5b835c3 100644
--- a/rsf-admin/src/page/ResourceContent.js
+++ b/rsf-admin/src/page/ResourceContent.js
@@ -58,6 +58,11 @@
 import transfer from "./orders/transfer";
 import locRevise from './stockManage/locRevise';
 import locDeadReport from './statistics/deadTime';
+import inStatistic from './statistics/inStockNum';
+import outStatistic from './statistics/outStockNum';
+import outStatisticItem from './statistics/outStockItem';
+import inStatisticItem from './statistics/inStockItem';
+import statisticCount from './statistics/stockStatisticNum';
 
 const ResourceContent = (node) => {
   switch (node.component) {
@@ -169,6 +174,16 @@
       return locRevise;
     case "locDeadReport": 
       return locDeadReport;
+    case "inStatistic":
+      return inStatistic;
+    case "outStatistic": 
+      return outStatistic;
+    case "outStatisticItem": 
+      return outStatisticItem;
+    case "inStatisticItem":
+      return inStatisticItem;
+    case "statisticCount":
+      return statisticCount;
     default:
       return {
         list: ListGuesser,
diff --git a/rsf-admin/src/page/statistics/deadTime/LocItemDeadList.jsx b/rsf-admin/src/page/statistics/deadTime/LocItemDeadList.jsx
index b9a85d3..82bbf32 100644
--- a/rsf-admin/src/page/statistics/deadTime/LocItemDeadList.jsx
+++ b/rsf-admin/src/page/statistics/deadTime/LocItemDeadList.jsx
@@ -47,16 +47,15 @@
     '& .RaDatagrid-row': {
         cursor: 'auto'
     },
+
     '& .column-deadTime': {
         width: 140,
         textAlign: 'center',
         color: 'red',
     },
-
     '& .RaDatagrid-headerCell': {
         color: 'black',
     },
-
     '& .column-maktx': {
         width: 150
     },
@@ -105,7 +104,7 @@
     return (
         <Box display="flex">
             <List
-                resource="inStock/num"
+                resource="locItem"
                 sx={{
                     flexGrow: 1,
                     transition: (theme) =>
@@ -126,7 +125,7 @@
                 perPage={DEFAULT_PAGE_SIZE}
             >
                 <StyledDatagrid
-                    preferenceKey='InStockNumList'
+                    preferenceKey='locDeadReport'
                     bulkActionButtons={false}
                     rowClick={(id, resource, record) => false}
                     expand={false}
diff --git a/rsf-admin/src/page/statistics/inStockItem/InStockItemList.jsx b/rsf-admin/src/page/statistics/inStockItem/InStockItemList.jsx
new file mode 100644
index 0000000..a278687
--- /dev/null
+++ b/rsf-admin/src/page/statistics/inStockItem/InStockItemList.jsx
@@ -0,0 +1,145 @@
+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,
+    useGetRecordId,
+} from 'react-admin';
+
+import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_ITEM_PAGE_SIZE, DEFAULT_PAGE_SIZE } from '@/config/setting';
+import { Box, Typography, Card, Stack } from '@mui/material';
+import { styled } from '@mui/material/styles';
+
+const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({
+    '& .css-1vooibu-MuiSvgIcon-root': {
+        height: '.9em'
+    },
+    '& .RaDatagrid-row': {
+        cursor: 'auto'
+    },
+
+    '& .column-dayTime': {
+        width: 120,
+        textAlign: 'center',
+    },
+
+    '& .column-taskType$': {
+        width: 130,
+    },
+
+    '& .column-matnrCode': {
+        width: 150,
+        textAlign: 'center',
+    },
+
+    '& .RaDatagrid-headerCell': {
+        color: 'black',
+    },
+
+    '& .column-maktx': {
+        width: 350
+    },
+}));
+
+const InStockItemList = () => {
+    const translate = useTranslate();
+    const [createDialog, setCreateDialog] = useState(false);
+    const [drawerVal, setDrawerVal] = useState(false);
+    const dict = JSON.parse(localStorage.getItem('sys_dicts'))?.filter(dict => (dict.dictTypeCode == 'sys_task_type' && dict.group == 3)) || [];
+
+
+    const filters = [
+        <SearchInput source="condition" alwaysOn />,
+        <DateInput label='common.time.before' source="dayTime" alwaysOn />,
+        // <AutocompleteInput optionText="label"
+        //     choices={dict}
+        //     optionValue="value"
+        //     label="table.field.stockStatistic.taskType"
+        //     filter
+        //     source="taskType"
+        //     alwaysOn />,
+        <TextInput source="maktx" label="table.field.locItem.maktx" />,
+        <TextInput source="matnrCode" label="table.field.locItem.matnrCode" alwaysOn />,
+        <TextInput source="batch" label="table.field.locItem.batch" />,
+    ]
+
+    return (
+        <Box display="flex">
+            <List
+                resource="inStatisticItem"
+                sx={{
+                    flexGrow: 1,
+                    transition: (theme) =>
+                        theme.transitions.create(['all'], {
+                            duration: theme.transitions.duration.enteringScreen,
+                        }),
+                }}
+                title={false}
+                empty={false}
+                filter={{ taskType: 1, taskStatus: 100 }}
+                filters={filters}
+                sort={{ field: "day_time", order: "desc" }}
+                actions={(
+                    <TopToolbar>
+                        <FilterButton />
+                        <SelectColumnsButton preferenceKey='inStatisticItem' />
+                    </TopToolbar>
+                )}
+                perPage={DEFAULT_PAGE_SIZE}
+            >
+                <StyledDatagrid
+                    preferenceKey='inStatisticItem'
+                    bulkActionButtons={false}
+                    rowClick={(id, resource, record) => false}
+                    expand={false}
+                    expandSingle={true}
+                    omit={['id']}
+                >
+                    <TextField source="id" key="id-key" />
+                    {/* <TextField source="taskType$" label="table.field.stockStatistic.taskType" /> */}
+                    <TextField source="locCode" label="table.field.stockStatistic.locCode" />
+                    <TextField source="matnrCode" label="table.field.locItem.matnrCode" />
+                    <TextField source="maktx" label="table.field.locItem.maktx" />
+                    <NumberField source="anfme" label="table.field.locItem.anfme" />
+                    <TextField source="batch" label="table.field.locItem.batch" />
+                    <TextField source="unit" label="table.field.locItem.unit" />
+                    <TextField source="barcode" label="table.field.stockStatistic.barcode" />
+                    <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 />
+                </StyledDatagrid>
+            </List>
+        </Box>
+    )
+}
+
+export default InStockItemList;
diff --git a/rsf-admin/src/page/statistics/inStockItem/index.jsx b/rsf-admin/src/page/statistics/inStockItem/index.jsx
new file mode 100644
index 0000000..ef0b5ab
--- /dev/null
+++ b/rsf-admin/src/page/statistics/inStockItem/index.jsx
@@ -0,0 +1,16 @@
+import React, { useState, useRef, useEffect, useMemo } from "react";
+import {
+    ListGuesser,
+    EditGuesser,
+    ShowGuesser,
+} from "react-admin";
+
+import InStockItemList from "./InStockItemList";
+
+export default {
+    list: InStockItemList,
+    show: ShowGuesser,
+    recordRepresentation: (record) => {
+        return `${record.id}`
+    }
+};
diff --git a/rsf-admin/src/page/statistics/inStockNum/InStockNumList.jsx b/rsf-admin/src/page/statistics/inStockNum/InStockNumList.jsx
index 662b688..b5c4a57 100644
--- a/rsf-admin/src/page/statistics/inStockNum/InStockNumList.jsx
+++ b/rsf-admin/src/page/statistics/inStockNum/InStockNumList.jsx
@@ -37,8 +37,6 @@
 import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_ITEM_PAGE_SIZE, DEFAULT_PAGE_SIZE } from '@/config/setting';
 import { Box, Typography, Card, Stack } from '@mui/material';
 import { styled } from '@mui/material/styles';
-import { display, width } from "@mui/system";
-import { color } from "framer-motion";
 
 const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({
     '& .css-1vooibu-MuiSvgIcon-root': {
@@ -47,10 +45,19 @@
     '& .RaDatagrid-row': {
         cursor: 'auto'
     },
-    '& .column-deadTime': {
-        width: 140,
+
+    '& .column-dayTime': {
+        width: 120,
         textAlign: 'center',
-        color: 'red',
+    },
+
+    '& .column-taskType$': {
+        width: 130,
+    },
+
+    '& .column-matnrCode': {
+        width: 150,
+        textAlign: 'center',
     },
 
     '& .RaDatagrid-headerCell': {
@@ -58,103 +65,72 @@
     },
 
     '& .column-maktx': {
-        width: 150
-    },
-    '& .opt': {
-        width: 200
+        width: 350
     },
 }));
-
-const filters = [
-    <SearchInput source="condition" alwaysOn />,
-    <DateInput label='common.time.after' source="timeStart" />,
-    <DateInput label='common.time.before' source="timeEnd" />,
-    <NumberInput source="locId" label="table.field.locItem.locId" />,
-    <NumberInput source="orderId" label="table.field.locItem.orderId" />,
-    <TextInput source="type$" label="table.field.locItem.type" />,
-    <NumberInput source="orderItemId" label="table.field.locItem.orderItemId" />,
-    <NumberInput source="wkType$" label="table.field.locItem.wkType" />,
-    <NumberInput source="matnrId" label="table.field.locItem.matnrId" />,
-    <TextInput source="maktx" label="table.field.locItem.maktx" />,
-    <TextInput source="matnrCode" label="table.field.locItem.matnrCode" />,
-    <TextInput source="trackCode" label="table.field.locItem.trackCode" />,
-    <TextInput source="unit" label="table.field.locItem.unit" />,
-    <NumberInput source="anfme" label="table.field.locItem.anfme" />,
-    <TextInput source="batch" label="table.field.locItem.batch" />,
-    <TextInput source="splrBatch" label="table.field.locItem.splrBatch" />,
-    <TextInput source="spec" label="table.field.locItem.spec" />,
-    <TextInput source="model" label="table.field.locItem.model" />,
-    <TextInput source="fieldsIndex" label="table.field.locItem.fieldsIndex" />,
-    <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 InStockNumList = () => {
     const translate = useTranslate();
     const [createDialog, setCreateDialog] = useState(false);
     const [drawerVal, setDrawerVal] = useState(false);
+    const dict = JSON.parse(localStorage.getItem('sys_dicts'))?.filter(dict => (dict.dictTypeCode == 'sys_task_type' && dict.group == 3)) || [];
+
+
+    const filters = [
+        <SearchInput source="condition" alwaysOn />,
+        <DateInput label='common.time.before' source="dayTime" alwaysOn />,
+        // <AutocompleteInput optionText="label"
+        //     choices={dict}
+        //     optionValue="value"
+        //     label="table.field.stockStatistic.taskType"
+        //     filter
+        //     source="taskType"
+        //     alwaysOn />,
+        <TextInput source="maktx" label="table.field.locItem.maktx" />,
+        <TextInput source="matnrCode" label="table.field.locItem.matnrCode" alwaysOn/>,
+        <TextInput source="batch" label="table.field.locItem.batch" />,
+    ]
 
     return (
         <Box display="flex">
             <List
-                resource="locItem"
+                resource="inStatistic"
                 sx={{
                     flexGrow: 1,
                     transition: (theme) =>
                         theme.transitions.create(['all'], {
                             duration: theme.transitions.duration.enteringScreen,
                         }),
-                    marginRight: !!drawerVal ? `${PAGE_DRAWER_WIDTH}px` : 0,
                 }}
-                title={"menu.locItem"}
+                title={false}
                 empty={false}
+                filter={{taskType: 1, taskStatus: 100}}
                 filters={filters}
-                sort={{ field: "create_time", order: "asc" }}
+                sort={{ field: "day_time", order: "desc" }}
                 actions={(
                     <TopToolbar>
                         <FilterButton />
-                        <SelectColumnsButton preferenceKey='locItem' />
+                        <SelectColumnsButton preferenceKey='stockStatistic' />
                     </TopToolbar>
                 )}
                 perPage={DEFAULT_PAGE_SIZE}
             >
                 <StyledDatagrid
-                    preferenceKey='locDeadReport'
+                    preferenceKey='stockStatistics'
                     bulkActionButtons={false}
                     rowClick={(id, resource, record) => false}
                     expand={false}
                     expandSingle={true}
                     omit={['id', 'locId', 'orderId', 'orderItemId', 'matnrId', 'trackCode', 'fieldsIndex', 'splrBatch', 'memo']}
                 >
-                    <NumberField source="id" />
-                    <TextField source="locCode" label="table.field.locItem.locCode" />
-                    <NumberField source="deadTime" label="table.field.locItem.deadTime" />
-                    <NumberField source="locId" label="table.field.locItem.locId" />
-                    <NumberField source="matnrId" label="table.field.locItem.matnrId" />
+                    <NumberField source="id" key="id-key"/>
+                    {/* <TextField source="taskType$" label="table.field.stockStatistic.taskType" /> */}
+                    <TextField source="dayTime" label="table.field.stockStatistic.dayTime" />
                     <TextField source="matnrCode" label="table.field.locItem.matnrCode" />
                     <TextField source="maktx" label="table.field.locItem.maktx" />
                     <NumberField source="anfme" label="table.field.locItem.anfme" />
                     <TextField source="batch" label="table.field.locItem.batch" />
-                    <TextField source="trackCode" label="table.field.locItem.trackCode" />
                     <TextField source="unit" label="table.field.locItem.unit" />
-                    <TextField source="splrBatch" label="table.field.locItem.splrBatch" />
-                    <TextField source="spec" label="table.field.locItem.spec" />
-                    <TextField source="model" label="table.field.locItem.model" />
-                    <TextField source="fieldsIndex" label="table.field.locItem.fieldsIndex" />
-                    <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>
             </List>
         </Box>
diff --git a/rsf-admin/src/page/statistics/outStockItem/OutStockItemList.jsx b/rsf-admin/src/page/statistics/outStockItem/OutStockItemList.jsx
new file mode 100644
index 0000000..e3508ca
--- /dev/null
+++ b/rsf-admin/src/page/statistics/outStockItem/OutStockItemList.jsx
@@ -0,0 +1,145 @@
+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,
+    useGetRecordId,
+} from 'react-admin';
+
+import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_ITEM_PAGE_SIZE, DEFAULT_PAGE_SIZE } from '@/config/setting';
+import { Box, Typography, Card, Stack } from '@mui/material';
+import { styled } from '@mui/material/styles';
+
+const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({
+    '& .css-1vooibu-MuiSvgIcon-root': {
+        height: '.9em'
+    },
+    '& .RaDatagrid-row': {
+        cursor: 'auto'
+    },
+
+    '& .column-dayTime': {
+        width: 120,
+        textAlign: 'center',
+    },
+
+    '& .column-taskType$': {
+        width: 130,
+    },
+
+    '& .column-matnrCode': {
+        width: 150,
+        textAlign: 'center',
+    },
+
+    '& .RaDatagrid-headerCell': {
+        color: 'black',
+    },
+
+    '& .column-maktx': {
+        width: 350
+    },
+}));
+
+const OutStockNumList = () => {
+    const translate = useTranslate();
+    const [createDialog, setCreateDialog] = useState(false);
+    const [drawerVal, setDrawerVal] = useState(false);
+    // const dict = JSON.parse(localStorage.getItem('sys_dicts'))?.filter(dict => (dict.dictTypeCode == 'sys_task_type' && dict.group == 3)) || [];
+
+
+    const filters = [
+        <SearchInput source="condition" alwaysOn />,
+        <DateInput label='common.time.before' source="dayTime" alwaysOn />,
+        // <AutocompleteInput optionText="label"
+        //     choices={dict}
+        //     optionValue="value"
+        //     label="table.field.stockStatistic.taskType"
+        //     filter
+        //     source="taskType"
+        //     alwaysOn />,
+        <TextInput source="maktx" label="table.field.locItem.maktx" />,
+        <TextInput source="matnrCode" label="table.field.locItem.matnrCode" alwaysOn />,
+        <TextInput source="batch" label="table.field.locItem.batch" />,
+    ]
+
+    return (
+        <Box display="flex">
+            <List
+                resource="outStatisticItem"
+                sx={{
+                    flexGrow: 1,
+                    transition: (theme) =>
+                        theme.transitions.create(['all'], {
+                            duration: theme.transitions.duration.enteringScreen,
+                        }),
+                }}
+                title={false}
+                empty={false}
+                filter={{ taskType: 101, taskStatus: 200 }}
+                filters={filters}
+                sort={{ field: "day_time", order: "desc" }}
+                actions={(
+                    <TopToolbar>
+                        <FilterButton />
+                        <SelectColumnsButton preferenceKey='outStatisticItem' />
+                    </TopToolbar>
+                )}
+                perPage={DEFAULT_PAGE_SIZE}
+            >
+                <StyledDatagrid
+                    preferenceKey='outStatisticItem'
+                    bulkActionButtons={false}
+                    rowClick={(id, resource, record) => false}
+                    expand={false}
+                    expandSingle={true}
+                    omit={['id', 'memo']}
+                >
+                    <TextField source="id" key="id-key" />
+                    <TextField source="dayTime" label="table.field.stockStatistic.dayTime" />
+                    <TextField source="locCode" label="table.field.stockStatistic.locCode" />
+                    <TextField source="matnrCode" label="table.field.locItem.matnrCode" />
+                    <TextField source="maktx" label="table.field.locItem.maktx" />
+                    <NumberField source="anfme" label="table.field.locItem.anfme" />
+                    <TextField source="batch" label="table.field.locItem.batch" />
+                    <TextField source="unit" label="table.field.locItem.unit" />
+                    <TextField source="barcode" label="table.field.stockStatistic.barcode" />
+                    <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 />
+                </StyledDatagrid>
+            </List>
+        </Box>
+    )
+}
+
+export default OutStockNumList;
diff --git a/rsf-admin/src/page/statistics/outStockItem/index.jsx b/rsf-admin/src/page/statistics/outStockItem/index.jsx
new file mode 100644
index 0000000..428b379
--- /dev/null
+++ b/rsf-admin/src/page/statistics/outStockItem/index.jsx
@@ -0,0 +1,16 @@
+import React, { useState, useRef, useEffect, useMemo } from "react";
+import {
+    ListGuesser,
+    EditGuesser,
+    ShowGuesser,
+} from "react-admin";
+
+import OutStockItemList from "./OutStockItemList";
+
+export default {
+    list: OutStockItemList,
+    show: ShowGuesser,
+    recordRepresentation: (record) => {
+        return `${record.id}`
+    }
+};
diff --git a/rsf-admin/src/page/statistics/outStockNum/OutStockNumList.jsx b/rsf-admin/src/page/statistics/outStockNum/OutStockNumList.jsx
new file mode 100644
index 0000000..574553a
--- /dev/null
+++ b/rsf-admin/src/page/statistics/outStockNum/OutStockNumList.jsx
@@ -0,0 +1,140 @@
+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,
+    useGetRecordId,
+} from 'react-admin';
+
+import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_ITEM_PAGE_SIZE, DEFAULT_PAGE_SIZE } from '@/config/setting';
+import { Box, Typography, Card, Stack } from '@mui/material';
+import { styled } from '@mui/material/styles';
+
+const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({
+    '& .css-1vooibu-MuiSvgIcon-root': {
+        height: '.9em'
+    },
+    '& .RaDatagrid-row': {
+        cursor: 'auto'
+    },
+
+    '& .column-dayTime': {
+        width: 120,
+        textAlign: 'center',
+    },
+
+    '& .column-taskType$': {
+        width: 130,
+    },
+
+    '& .column-matnrCode': {
+        width: 150,
+        textAlign: 'center',
+    },
+
+    '& .RaDatagrid-headerCell': {
+        color: 'black',
+    },
+
+    '& .column-maktx': {
+        width: 350
+    },
+}));
+
+const OutStockNumList = () => {
+    const translate = useTranslate();
+    const [createDialog, setCreateDialog] = useState(false);
+    const [drawerVal, setDrawerVal] = useState(false);
+    // const dict = JSON.parse(localStorage.getItem('sys_dicts'))?.filter(dict => (dict.dictTypeCode == 'sys_task_type' && dict.group == 3)) || [];
+
+
+    const filters = [
+        <SearchInput source="condition" alwaysOn />,
+        <DateInput label='common.time.before' source="dayTime" alwaysOn />,
+        // <AutocompleteInput optionText="label"
+        //     choices={dict}
+        //     optionValue="value"
+        //     label="table.field.stockStatistic.taskType"
+        //     filter
+        //     source="taskType"
+        //     alwaysOn />,
+        <TextInput source="maktx" label="table.field.locItem.maktx" />,
+        <TextInput source="matnrCode" label="table.field.locItem.matnrCode" alwaysOn/>,
+        <TextInput source="batch" label="table.field.locItem.batch" />,
+    ]
+
+    return (
+        <Box display="flex">
+            <List
+                resource="outStatistic"
+                sx={{
+                    flexGrow: 1,
+                    transition: (theme) =>
+                        theme.transitions.create(['all'], {
+                            duration: theme.transitions.duration.enteringScreen,
+                        }),
+                }}
+                title={false}
+                empty={false}
+                filter={{taskType: 101, taskStatus: 200}}
+                filters={filters}
+                sort={{ field: "day_time", order: "desc" }}
+                actions={(
+                    <TopToolbar>
+                        <FilterButton />
+                        <SelectColumnsButton preferenceKey='outStatistic' />
+                    </TopToolbar>
+                )}
+                perPage={DEFAULT_PAGE_SIZE}
+            >
+                <StyledDatagrid
+                    preferenceKey='outStatistic'
+                    bulkActionButtons={false}
+                    rowClick={(id, resource, record) => false}
+                    expand={false}
+                    expandSingle={true}
+                    omit={['id', 'memo']}
+                >
+                    <NumberField source="id" key="id-key"/>
+                    {/* <TextField source="taskType$" label="table.field.stockStatistic.taskType" /> */}
+                    <TextField source="dayTime" label="table.field.stockStatistic.dayTime" />
+                    <TextField source="matnrCode" label="table.field.locItem.matnrCode" />
+                    <TextField source="maktx" label="table.field.locItem.maktx" />
+                    <NumberField source="anfme" label="table.field.locItem.anfme" />
+                    <TextField source="batch" label="table.field.locItem.batch" />
+                    <TextField source="unit" label="table.field.locItem.unit" />
+                </StyledDatagrid>
+            </List>
+        </Box>
+    )
+}
+
+export default OutStockNumList;
diff --git a/rsf-admin/src/page/statistics/outStockNum/index.jsx b/rsf-admin/src/page/statistics/outStockNum/index.jsx
new file mode 100644
index 0000000..70f7a68
--- /dev/null
+++ b/rsf-admin/src/page/statistics/outStockNum/index.jsx
@@ -0,0 +1,16 @@
+import React, { useState, useRef, useEffect, useMemo } from "react";
+import {
+    ListGuesser,
+    EditGuesser,
+    ShowGuesser,
+} from "react-admin";
+
+import OutStockNumList from "./OutStockNumList";
+
+export default {
+    list: OutStockNumList,
+    show: ShowGuesser,
+    recordRepresentation: (record) => {
+        return `${record.id}`
+    }
+};
diff --git a/rsf-admin/src/page/statistics/stockStatisticNum/index.jsx b/rsf-admin/src/page/statistics/stockStatisticNum/index.jsx
new file mode 100644
index 0000000..ae7d7ed
--- /dev/null
+++ b/rsf-admin/src/page/statistics/stockStatisticNum/index.jsx
@@ -0,0 +1,16 @@
+import React, { useState, useRef, useEffect, useMemo } from "react";
+import {
+    ListGuesser,
+    EditGuesser,
+    ShowGuesser,
+} from "react-admin";
+
+import StockStatistic from "./stockStatisticList";
+
+export default {
+    list: StockStatistic,
+    show: ShowGuesser,
+    recordRepresentation: (record) => {
+        return `${record.id}`
+    }
+};
diff --git a/rsf-admin/src/page/statistics/stockStatisticNum/stockStatisticList.jsx b/rsf-admin/src/page/statistics/stockStatisticNum/stockStatisticList.jsx
new file mode 100644
index 0000000..e6eeff5
--- /dev/null
+++ b/rsf-admin/src/page/statistics/stockStatisticNum/stockStatisticList.jsx
@@ -0,0 +1,140 @@
+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,
+    useGetRecordId,
+} from 'react-admin';
+
+import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_ITEM_PAGE_SIZE, DEFAULT_PAGE_SIZE } from '@/config/setting';
+import { Box, Typography, Card, Stack } from '@mui/material';
+import { styled } from '@mui/material/styles';
+
+const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({
+    '& .css-1vooibu-MuiSvgIcon-root': {
+        height: '.9em'
+    },
+    '& .RaDatagrid-row': {
+        cursor: 'auto'
+    },
+
+    '& .column-dayTime': {
+        width: 120,
+        textAlign: 'center',
+    },
+
+    '& .column-taskType$': {
+        width: 130,
+    },
+
+    '& .column-matnrCode': {
+        width: 150,
+        textAlign: 'center',
+    },
+
+    '& .RaDatagrid-headerCell': {
+        color: 'black',
+    },
+
+    '& .column-maktx': {
+        width: 350
+    },
+}));
+
+const stockStatisticList = () => {
+    const translate = useTranslate();
+    const [createDialog, setCreateDialog] = useState(false);
+    const [drawerVal, setDrawerVal] = useState(false);
+    // const dict = JSON.parse(localStorage.getItem('sys_dicts'))?.filter(dict => (dict.dictTypeCode == 'sys_task_type' && dict.group == 3)) || [];
+
+
+    const filters = [
+        <SearchInput source="condition" alwaysOn />,
+        <DateInput label='common.time.before' source="dayTime" alwaysOn />,
+        // <AutocompleteInput optionText="label"
+        //     choices={dict}
+        //     optionValue="value"
+        //     label="table.field.stockStatistic.taskType"
+        //     filter
+        //     source="taskType"
+        //     alwaysOn />,
+        <TextInput source="maktx" label="table.field.locItem.maktx" />,
+        <TextInput source="matnrCode" label="table.field.locItem.matnrCode" alwaysOn />,
+        <TextInput source="batch" label="table.field.locItem.batch" />,
+    ]
+
+    return (
+        <Box display="flex">
+            <List
+                resource="statistic/num"
+                sx={{
+                    flexGrow: 1,
+                    transition: (theme) =>
+                        theme.transitions.create(['all'], {
+                            duration: theme.transitions.duration.enteringScreen,
+                        }),
+                }}
+                title={false}
+                empty={false}
+                filter={{ taskType: 101, taskStatus: 200 }}
+                filters={filters}
+                sort={{ field: "day_time", order: "desc" }}
+                actions={(
+                    <TopToolbar>
+                        <FilterButton />
+                        <SelectColumnsButton preferenceKey='outStatisticCount' />
+                    </TopToolbar>
+                )}
+                perPage={DEFAULT_PAGE_SIZE}
+            >
+                <StyledDatagrid
+                    preferenceKey='outStatisticCount'
+                    bulkActionButtons={false}
+                    rowClick={(id, resource, record) => false}
+                    expand={false}
+                    expandSingle={true}
+                    omit={['id', 'memo']}
+                >
+                    <NumberField source="id" key="id-key" />
+                    <TextField source="dayTime" label="table.field.stockStatistic.dayTime" />
+                    <NumberField source="count" label="table.field.stockStatistic.count" />
+                    <TextField source="inAnfmeCount" label="table.field.stockStatistic.inAnfmeCount" />
+                    <TextField source="outAnfmeCount" label="table.field.stockStatistic.outAnfmeCount" />
+                    <NumberField source="anfme" label="table.field.stockStatistic.anfme" />
+                    <NumberField source="inAnfme" label="table.field.stockStatistic.inAnfme" />
+                    <TextField source="outAnfme" label="table.field.stockStatistic.outAnfme" />
+                </StyledDatagrid>
+            </List>
+        </Box>
+    )
+}
+
+export default stockStatisticList;
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/StockStatisticController.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/StockStatisticController.java
index c4bf3c7..19f0baf 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/StockStatisticController.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/StockStatisticController.java
@@ -84,7 +84,12 @@
         BaseParam baseParam = buildParam(map, BaseParam.class);
         PageParam<StockStatistic, BaseParam> pageParam = new PageParam<>(baseParam, StockStatistic.class);
         QueryWrapper<StockStatistic> wrapper = pageParam.buildWrapper(true);
-        wrapper.select("id, day_time, COUNT( barcode ) `count`, SUM( anfme ) anfme, COUNT(IF (task_type = 1, 0, NULL)) in_anfme_count, COUNT(IF ( task_type = 101, 0, NULL)) out_anfme_count, SUM(CASE WHEN task_type = 1 THEN)");
+        wrapper.select("id, day_time, COUNT( barcode ) `count`, " +
+                "SUM( anfme ) anfme," +
+                "COUNT(IF (task_type = 1, 0, NULL)) in_anfme_count, " +
+                "COUNT(IF ( task_type = 101, 0, NULL)) out_anfme_count, " +
+                "SUM( CASE WHEN task_type = 1 THEN anfme ELSE 0 END ) in_anfme," +
+                "SUM( CASE WHEN task_type = 101 THEN anfme ELSE 0 END ) out_anfme");
         wrapper.groupBy("barcode, day_time");
         return R.ok().add(stockStatisticService.page(pageParam, wrapper));
     }

--
Gitblit v1.9.1