From 77d9cce18579fa0cb67f28fdc58d970b3448c284 Mon Sep 17 00:00:00 2001
From: luxiaotao1123 <t1341870251@163.com>
Date: 星期二, 26 三月 2024 13:49:40 +0800
Subject: [PATCH] Merge branch 'Four-Way-Rack' of http://47.97.1.152:5880/r/zy-asrs-master into Four-Way-Rack

---
 zy-asrs-flow/src/pages/device/motion/components/edit.jsx                                    |  297 +++++
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/utils/NavigateMapUtils.java                  |  186 +-
 zy-asrs-wcs/src/main/java/basShuttle.sql                                                    |    9 
 zy-asrs-wcs/src/main/resources/mapper/rcs/MotionMapper.xml                                  |    5 
 zy-asrs-wcs/src/main/resources/mapper/core/BasShuttleMapper.xml                             |    5 
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/service/impl/BasShuttleServiceImpl.java      |   12 
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/service/BasShuttleService.java               |    8 
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/entity/BasShuttle.java                       |  230 ++++
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/controller/DevicePlcController.java           |    3 
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/controller/MotionCtgController.java           |    3 
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/controller/MotionController.java              |  102 +
 zy-asrs-flow/src/pages/device/motionSts/components/edit.jsx                                 |  148 ++
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/controller/BasShuttleController.java         |  102 +
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/controller/DeviceController.java              |    3 
 zy-asrs-flow/src/pages/device/motionCtg/components/edit.jsx                                 |  160 ++
 zy-asrs-flow/src/pages/device/motion/index.jsx                                              |  682 +++++++++++
 zy-asrs-flow/src/pages/device/motionSts/index.jsx                                           |  428 +++++++
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/controller/MotionStsController.java           |    3 
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/service/impl/MotionServiceImpl.java           |   12 
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/mapper/BasShuttleMapper.java                 |   12 
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/mapper/MotionMapper.java                      |   12 
 /dev/null                                                                                   |    9 
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/controller/ShuttleDeviceStatusController.java |    3 
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/controller/DeviceTypeController.java          |    3 
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/utils/Utils.java                             |   41 
 zy-asrs-flow/src/pages/device/motionCtg/index.jsx                                           |  442 +++++++
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/entity/Motion.java                            |  440 +++++++
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/service/MotionService.java                    |    8 
 28 files changed, 3,260 insertions(+), 108 deletions(-)

diff --git a/zy-asrs-flow/src/pages/device/motion/components/edit.jsx b/zy-asrs-flow/src/pages/device/motion/components/edit.jsx
new file mode 100644
index 0000000..dd3cb90
--- /dev/null
+++ b/zy-asrs-flow/src/pages/device/motion/components/edit.jsx
@@ -0,0 +1,297 @@
+import React, { useState, useRef, useEffect } from 'react';
+import {
+    ProForm,
+    ProFormDigit,
+    ProFormText,
+    ProFormSelect,
+    ProFormDateTimePicker
+} from '@ant-design/pro-components';
+import { Form, Modal } from 'antd';
+import { FormattedMessage, useIntl } from '@umijs/max';
+import moment from 'moment';
+import Http from '@/utils/http';
+
+const Edit = (props) => {
+    const intl = useIntl();
+    const [form] = Form.useForm();
+    const { } = props;
+
+    useEffect(() => {
+        form.resetFields();
+        form.setFieldsValue({
+            ...props.values
+        })
+    }, [form, props])
+
+    const handleCancel = () => {
+        props.onCancel();
+    };
+
+    const handleOk = () => {
+        form.submit();
+    }
+
+    const handleFinish = async (values) => {
+        props.onSubmit({ ...values });
+    }
+
+    return (
+        <>
+            <Modal
+                title={
+                    Object.keys(props.values).length > 0
+                        ? intl.formatMessage({ id: 'page.edit', defaultMessage: '缂栬緫' })
+                        : intl.formatMessage({ id: 'page.add', defaultMessage: '娣诲姞' })
+                }
+                width={640}
+                forceRender
+                destroyOnClose
+                open={props.open}
+                onCancel={handleCancel}
+                onOk={handleOk}
+            >
+                <ProForm
+                    form={form}
+                    submitter={false}
+                    onFinish={handleFinish}
+                    layout="horizontal"
+                    grid={true}
+                >
+                    <ProFormDigit
+                        name="id"
+                        disabled
+                        hidden={true}
+                    />
+                    <ProForm.Group>
+                        <ProFormText
+                            name="uuid"
+                            label="缂栧彿"
+                            colProps={{ md: 12, xl: 12 }}
+                        />
+                        <ProFormDigit
+                            name="wrkNo"
+                            label="浠诲姟鍙�"
+                            colProps={{ md: 12, xl: 12 }}
+                            fieldProps={{ precision: 0 }}
+                        />
+                    </ProForm.Group>
+                    <ProForm.Group>
+                        <ProFormText
+                            name="serialNo"
+                            label="搴忓垪鍙�"
+                            colProps={{ md: 12, xl: 12 }}
+                        />
+                        <ProFormText
+                            name="title"
+                            label="鎻忚堪"
+                            colProps={{ md: 12, xl: 12 }}
+                        />
+                    </ProForm.Group>
+                    <ProForm.Group>
+                        <ProFormDigit
+                            name="priority"
+                            label="浼樺厛绾�"
+                            colProps={{ md: 12, xl: 12 }}
+                            fieldProps={{ precision: 0 }}
+                        />
+                        <ProFormSelect
+                            name="sync"
+                            label="鍚屾"
+                            colProps={{ md: 12, xl: 12 }}
+                            rules={[{ required: true }]}
+                            options={[
+                                { label: '鏄�', value: 1 },
+                                { label: '鍚�', value: 0 },
+                            ]}
+                        />
+                    </ProForm.Group>
+                    <ProForm.Group>
+                        <ProFormSelect
+                            name="motionCtg"
+                            label="浠诲姟绫诲瀷"
+                            colProps={{ md: 12, xl: 12 }}
+                            fieldProps={{ precision: 0 }}
+                            rules={[{ required: true }]}
+                            showSearch
+                            debounceTime={300}
+                            request={async ({ keyWords }) => {
+                                const resp = await Http.doPostForm('api/motionCtg/query', { condition: keyWords });
+                                return resp.data;
+                            }}
+                        />
+                        <ProFormSelect
+                            name="motionSts"
+                            label="浠诲姟鐘舵��"
+                            colProps={{ md: 12, xl: 12 }}
+                            fieldProps={{ precision: 0 }}
+                            rules={[{ required: true }]}
+                            showSearch
+                            debounceTime={300}
+                            request={async ({ keyWords }) => {
+                                const resp = await Http.doPostForm('api/motionSts/query', { condition: keyWords });
+                                return resp.data;
+                            }}
+                        />
+                    </ProForm.Group>
+                    <ProForm.Group>
+                        <ProFormSelect
+                            name="deviceType"
+                            label="璁惧绫诲瀷"
+                            colProps={{ md: 12, xl: 12 }}
+                            fieldProps={{ precision: 0 }}
+                            showSearch
+                            debounceTime={300}
+                            request={async ({ keyWords }) => {
+                                const resp = await Http.doPostForm('api/deviceType/query', { condition: keyWords });
+                                return resp.data;
+                            }}
+                        />
+                        <ProFormText
+                            name="device"
+                            label="璁惧"
+                            colProps={{ md: 12, xl: 12 }}
+                        />
+                    </ProForm.Group>
+                    <ProForm.Group>
+                        <ProFormText
+                            name="origin"
+                            label="鏉ユ簮"
+                            colProps={{ md: 12, xl: 12 }}
+                        />
+                        <ProFormDigit
+                            name="oriDrt"
+                            label="鏉ユ簮鏂瑰悜"
+                            colProps={{ md: 12, xl: 12 }}
+                            fieldProps={{ precision: 0 }}
+                        />
+                    </ProForm.Group>
+                    <ProForm.Group>
+                        <ProFormText
+                            name="target"
+                            label="鐩爣"
+                            colProps={{ md: 12, xl: 12 }}
+                        />
+                        <ProFormDigit
+                            name="tarDrt"
+                            label="鐩爣鏂瑰悜"
+                            colProps={{ md: 12, xl: 12 }}
+                            fieldProps={{ precision: 0 }}
+                        />
+                    </ProForm.Group>
+                    <ProForm.Group>
+                        <ProFormText
+                            name="dockNo"
+                            label="瀵规帴璁惧"
+                            colProps={{ md: 12, xl: 12 }}
+                        />
+                        <ProFormDateTimePicker
+                            name="ioTime"
+                            label="宸ヤ綔鏃堕棿"
+                            colProps={{ md: 12, xl: 12 }}
+                            transform={(value) => moment(value).toISOString()}
+                        />
+                    </ProForm.Group>
+                    <ProForm.Group>
+                        <ProFormDateTimePicker
+                            name="startTime"
+                            label="寮�濮嬫椂闂�"
+                            colProps={{ md: 12, xl: 12 }}
+                            transform={(value) => moment(value).toISOString()}
+                        />
+                        <ProFormDateTimePicker
+                            name="endTime"
+                            label="缁撴潫鏃堕棿"
+                            colProps={{ md: 12, xl: 12 }}
+                            transform={(value) => moment(value).toISOString()}
+                        />
+                    </ProForm.Group>
+                    <ProForm.Group>
+                        <ProFormDateTimePicker
+                            name="errTime"
+                            label="寮傚父鏃堕棿"
+                            colProps={{ md: 12, xl: 12 }}
+                            transform={(value) => moment(value).toISOString()}
+                        />
+                        <ProFormDigit
+                            name="errCode"
+                            label="寮傚父浠g爜"
+                            colProps={{ md: 12, xl: 12 }}
+                            fieldProps={{ precision: 0 }}
+                        />
+                    </ProForm.Group>
+                    <ProForm.Group>
+                        <ProFormText
+                            name="errDesc"
+                            label="寮傚父鎻忚堪"
+                            colProps={{ md: 12, xl: 12 }}
+                        />
+                        <ProFormText
+                            name="temp"
+                            label="棰勭暀"
+                            colProps={{ md: 12, xl: 12 }}
+                        />
+                    </ProForm.Group>
+                    <ProForm.Group>
+                        <ProFormSelect
+                            name="status"
+                            label="鐘舵��"
+                            colProps={{ md: 12, xl: 12 }}
+                            options={[
+                                { label: '姝e父', value: 1 },
+                                { label: '绂佺敤', value: 0 },
+                            ]}
+                        />
+                        <ProFormSelect
+                            name="createBy"
+                            label="娣诲姞浜哄憳"
+                            colProps={{ md: 12, xl: 12 }}
+                            fieldProps={{ precision: 0 }}
+                            showSearch
+                            debounceTime={300}
+                            request={async ({ keyWords }) => {
+                                const resp = await Http.doPostForm('api/user/query', { condition: keyWords });
+                                return resp.data;
+                            }}
+                        />
+                    </ProForm.Group>
+                    <ProForm.Group>
+                        <ProFormDateTimePicker
+                            name="createTime"
+                            label="娣诲姞鏃堕棿"
+                            colProps={{ md: 12, xl: 12 }}
+                            transform={(value) => moment(value).toISOString()}
+                        />
+                        <ProFormSelect
+                            name="updateBy"
+                            label="淇敼浜哄憳"
+                            colProps={{ md: 12, xl: 12 }}
+                            fieldProps={{ precision: 0 }}
+                            showSearch
+                            debounceTime={300}
+                            request={async ({ keyWords }) => {
+                                const resp = await Http.doPostForm('api/user/query', { condition: keyWords });
+                                return resp.data;
+                            }}
+                        />
+                    </ProForm.Group>
+                    <ProForm.Group>
+                        <ProFormDateTimePicker
+                            name="updateTime"
+                            label="淇敼鏃堕棿"
+                            colProps={{ md: 12, xl: 12 }}
+                            transform={(value) => moment(value).toISOString()}
+                        />
+                        <ProFormText
+                            name="memo"
+                            label="澶囨敞"
+                            colProps={{ md: 12, xl: 12 }}
+                        />
+                    </ProForm.Group>
+
+                </ProForm>
+            </Modal>
+        </>
+    )
+}
+
+export default Edit;
diff --git a/zy-asrs-flow/src/pages/device/motion/index.jsx b/zy-asrs-flow/src/pages/device/motion/index.jsx
new file mode 100644
index 0000000..6d8e1ce
--- /dev/null
+++ b/zy-asrs-flow/src/pages/device/motion/index.jsx
@@ -0,0 +1,682 @@
+
+import React, { useState, useRef, useEffect } from 'react';
+import { Button, message, Modal, Tag  } from 'antd';
+import {
+    FooterToolbar,
+    PageContainer,
+    ProTable,
+    LightFilter,
+} from '@ant-design/pro-components';
+import { FormattedMessage, useIntl } from '@umijs/max';
+import { PlusOutlined, ExportOutlined } from '@ant-design/icons';
+import Http from '@/utils/http';
+import Edit from './components/edit'
+import { TextFilter, SelectFilter, DatetimeRangeFilter, LinkFilter } from '@/components/TableSearch'
+import { statusMap } from '@/utils/enum-util'
+import { repairBug } from '@/utils/common-util';
+
+const TABLE_KEY = 'pro-table-motion';
+
+const handleSave = async (val, intl) => {
+    const hide = message.loading(intl.formatMessage({ id: 'page.adding', defaultMessage: '姝e湪娣诲姞' }));
+    try {
+        const resp = await Http.doPost('api/motion/save', val);
+        if (resp.code === 200) {
+            message.success(intl.formatMessage({ id: 'page.add.success', defaultMessage: '娣诲姞鎴愬姛' }));
+            return true;
+        } else {
+            message.error(resp.msg);
+            return false;
+        }
+    } catch (error) {
+        message.error(intl.formatMessage({ id: 'page.add.fail', defaultMessage: '娣诲姞澶辫触璇烽噸璇曪紒' }));
+        return false;
+    } finally {
+        hide();
+    }
+};
+
+const handleUpdate = async (val, intl) => {
+    const hide = message.loading(intl.formatMessage({ id: 'page.updating', defaultMessage: '姝e湪鏇存柊' }));
+    try {
+        const resp = await Http.doPost('api/motion/update', val);
+        if (resp.code === 200) {
+            message.success(intl.formatMessage({ id: 'page.update.success', defaultMessage: '鏇存柊鎴愬姛' }));
+            return true;
+        } else {
+            message.error(resp.msg);
+            return false;
+        }
+    } catch (error) {
+        message.error(intl.formatMessage({ id: 'page.update.fail', defaultMessage: '鏇存柊澶辫触璇烽噸璇曪紒' }));
+        return false;
+    } finally {
+        hide();
+    }
+};
+
+const handleRemove = async (rows, intl) => {
+    if (!rows) return true;
+    const hide = message.loading(intl.formatMessage({ id: 'page.deleting', defaultMessage: '姝e湪鍒犻櫎' }));
+    try {
+        const resp = await Http.doPost('api/motion/remove/' + rows.map((row) => row.id).join(','));
+        if (resp.code === 200) {
+            message.success(intl.formatMessage({ id: 'page.delete.success', defaultMessage: '鍒犻櫎鎴愬姛' }));
+            return true;
+        } else {
+            message.error(resp.msg);
+            return false;
+        }
+    } catch (error) {
+        message.error(intl.formatMessage({ id: 'page.delete.fail', defaultMessage: '鍒犻櫎澶辫触锛岃閲嶈瘯锛�' }));
+        return false;
+    } finally {
+        hide();
+    }
+};
+
+const handleExport = async (intl) => {
+    const hide = message.loading(intl.formatMessage({ id: 'page.exporting', defaultMessage: '姝e湪瀵煎嚭' }));
+    try {
+        const resp = await Http.doPostBlob('api/motion/export');
+        const blob = new Blob([resp], { type: 'application/vnd.ms-excel' });
+        window.location.href = window.URL.createObjectURL(blob);
+        message.success(intl.formatMessage({ id: 'page.export.success', defaultMessage: '瀵煎嚭鎴愬姛' }));
+        return true;
+    } catch (error) {
+        message.error(intl.formatMessage({ id: 'page.export.fail', defaultMessage: '瀵煎嚭澶辫触锛岃閲嶈瘯' }));
+        return false;
+    } finally {
+        hide();
+    }
+};
+
+
+const Main = () => {
+    const intl = useIntl();
+    const formTableRef = useRef();
+    const actionRef = useRef();
+    const [selectedRows, setSelectedRows] = useState([]);
+    const [modalVisible, setModalVisible] = useState(false);
+    const [currentRow, setCurrentRow] = useState();
+    const [searchParam, setSearchParam] = useState({});
+
+    useEffect(() => {
+
+    }, []);
+
+    const columns = [
+        {
+            title: intl.formatMessage({
+                id: 'page.table.no',
+                defaultMessage: 'No'
+            }),
+            dataIndex: 'index',
+            valueType: 'indexBorder',
+            width: 48,
+        },
+        {
+            title: '缂栧彿',
+            dataIndex: 'uuid',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            filterDropdown: (props) => <TextFilter
+                name='uuid'
+                {...props}
+                actionRef={actionRef}
+                setSearchParam={setSearchParam}
+            />,
+        },
+        {
+            title: '浠诲姟鍙�',
+            dataIndex: 'wrkNo',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            filterDropdown: (props) => <TextFilter
+                name='wrkNo'
+                {...props}
+                actionRef={actionRef}
+                setSearchParam={setSearchParam}
+            />,
+        },
+        {
+            title: '搴忓垪鍙�',
+            dataIndex: 'serialNo',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            copyable: true,
+            filterDropdown: (props) => <TextFilter
+                name='serialNo'
+                {...props}
+                actionRef={actionRef}
+                setSearchParam={setSearchParam}
+            />,
+        },
+        {
+            title: '鎻忚堪',
+            dataIndex: 'title',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            filterDropdown: (props) => <TextFilter
+                name='title'
+                {...props}
+                actionRef={actionRef}
+                setSearchParam={setSearchParam}
+            />,
+        },
+        {
+            title: '浼樺厛绾�',
+            dataIndex: 'priority',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            filterDropdown: (props) => <TextFilter
+                name='priority'
+                {...props}
+                actionRef={actionRef}
+                setSearchParam={setSearchParam}
+            />,
+        },
+        {
+            title: '鍚屾',
+            dataIndex: 'sync$',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            filterDropdown: (props) => <SelectFilter
+                name='sync'
+                {...props}
+                actionRef={actionRef}
+                setSearchParam={setSearchParam}
+                data={[
+                    { label: '鏄�', value: 1 },
+                    { label: '鍚�', value: 0 },
+                ]}
+            />,
+        },
+        {
+            title: '浠诲姟绫诲瀷',
+            dataIndex: 'motionCtg$',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            filterDropdown: (props) => <LinkFilter
+                name='motionCtg'
+                major='motionCtg'
+                {...props}
+                actionRef={actionRef}
+                setSearchParam={setSearchParam}
+            />,
+        },
+        {
+            title: '浠诲姟鐘舵��',
+            dataIndex: 'motionSts$',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            filterDropdown: (props) => <LinkFilter
+                name='motionSts'
+                major='motionSts'
+                {...props}
+                actionRef={actionRef}
+                setSearchParam={setSearchParam}
+            />,
+        },
+        {
+            title: '璁惧绫诲瀷',
+            dataIndex: 'deviceType$',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            filterDropdown: (props) => <LinkFilter
+                name='deviceType'
+                major='deviceType'
+                {...props}
+                actionRef={actionRef}
+                setSearchParam={setSearchParam}
+            />,
+        },
+        {
+            title: '璁惧',
+            dataIndex: 'device',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            filterDropdown: (props) => <TextFilter
+                name='device'
+                {...props}
+                actionRef={actionRef}
+                setSearchParam={setSearchParam}
+            />,
+        },
+        {
+            title: '鏉ユ簮',
+            dataIndex: 'origin',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            filterDropdown: (props) => <TextFilter
+                name='origin'
+                {...props}
+                actionRef={actionRef}
+                setSearchParam={setSearchParam}
+            />,
+        },
+        {
+            title: '鏉ユ簮鏂瑰悜',
+            dataIndex: 'oriDrt',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            filterDropdown: (props) => <TextFilter
+                name='oriDrt'
+                {...props}
+                actionRef={actionRef}
+                setSearchParam={setSearchParam}
+            />,
+        },
+        {
+            title: '鐩爣',
+            dataIndex: 'target',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            filterDropdown: (props) => <TextFilter
+                name='target'
+                {...props}
+                actionRef={actionRef}
+                setSearchParam={setSearchParam}
+            />,
+        },
+        {
+            title: '鐩爣鏂瑰悜',
+            dataIndex: 'tarDrt',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            filterDropdown: (props) => <TextFilter
+                name='tarDrt'
+                {...props}
+                actionRef={actionRef}
+                setSearchParam={setSearchParam}
+            />,
+        },
+        {
+            title: '瀵规帴璁惧',
+            dataIndex: 'dockNo',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            filterDropdown: (props) => <TextFilter
+                name='dockNo'
+                {...props}
+                actionRef={actionRef}
+                setSearchParam={setSearchParam}
+            />,
+        },
+        {
+            title: '宸ヤ綔鏃堕棿',
+            dataIndex: 'ioTime$',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            filterDropdown: (props) => <DatetimeRangeFilter
+                name='ioTime'
+                {...props}
+                actionRef={actionRef}
+                setSearchParam={setSearchParam}
+            />,
+        },
+        {
+            title: '寮�濮嬫椂闂�',
+            dataIndex: 'startTime$',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            filterDropdown: (props) => <DatetimeRangeFilter
+                name='startTime'
+                {...props}
+                actionRef={actionRef}
+                setSearchParam={setSearchParam}
+            />,
+        },
+        {
+            title: '缁撴潫鏃堕棿',
+            dataIndex: 'endTime$',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            filterDropdown: (props) => <DatetimeRangeFilter
+                name='endTime'
+                {...props}
+                actionRef={actionRef}
+                setSearchParam={setSearchParam}
+            />,
+        },
+        {
+            title: '寮傚父鏃堕棿',
+            dataIndex: 'errTime$',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            filterDropdown: (props) => <DatetimeRangeFilter
+                name='errTime'
+                {...props}
+                actionRef={actionRef}
+                setSearchParam={setSearchParam}
+            />,
+        },
+        {
+            title: '寮傚父浠g爜',
+            dataIndex: 'errCode',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            filterDropdown: (props) => <TextFilter
+                name='errCode'
+                {...props}
+                actionRef={actionRef}
+                setSearchParam={setSearchParam}
+            />,
+        },
+        {
+            title: '寮傚父鎻忚堪',
+            dataIndex: 'errDesc',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            filterDropdown: (props) => <TextFilter
+                name='errDesc'
+                {...props}
+                actionRef={actionRef}
+                setSearchParam={setSearchParam}
+            />,
+        },
+        {
+            title: '棰勭暀',
+            dataIndex: 'temp',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            filterDropdown: (props) => <TextFilter
+                name='temp'
+                {...props}
+                actionRef={actionRef}
+                setSearchParam={setSearchParam}
+            />,
+        },
+        {
+            title: '鐘舵��',
+            dataIndex: 'status$',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            filterDropdown: (props) => <SelectFilter
+                name='status'
+                {...props}
+                actionRef={actionRef}
+                setSearchParam={setSearchParam}
+                data={[
+                    { label: '姝e父', value: 1 },
+                    { label: '绂佺敤', value: 0 },
+                ]}
+            />,
+        },
+        {
+            title: '娣诲姞浜哄憳',
+            dataIndex: 'createBy$',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            filterDropdown: (props) => <LinkFilter
+                name='createBy'
+                major='user'
+                {...props}
+                actionRef={actionRef}
+                setSearchParam={setSearchParam}
+            />,
+        },
+        {
+            title: '娣诲姞鏃堕棿',
+            dataIndex: 'createTime$',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            filterDropdown: (props) => <DatetimeRangeFilter
+                name='createTime'
+                {...props}
+                actionRef={actionRef}
+                setSearchParam={setSearchParam}
+            />,
+        },
+        {
+            title: '淇敼浜哄憳',
+            dataIndex: 'updateBy$',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            filterDropdown: (props) => <LinkFilter
+                name='updateBy'
+                major='user'
+                {...props}
+                actionRef={actionRef}
+                setSearchParam={setSearchParam}
+            />,
+        },
+        {
+            title: '淇敼鏃堕棿',
+            dataIndex: 'updateTime$',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            filterDropdown: (props) => <DatetimeRangeFilter
+                name='updateTime'
+                {...props}
+                actionRef={actionRef}
+                setSearchParam={setSearchParam}
+            />,
+        },
+        {
+            title: '澶囨敞',
+            dataIndex: 'memo',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            filterDropdown: (props) => <TextFilter
+                name='memo'
+                {...props}
+                actionRef={actionRef}
+                setSearchParam={setSearchParam}
+            />,
+        },
+
+        {
+            title: '鎿嶄綔',
+            dataIndex: 'option',
+            width: 140,
+            valueType: 'option',
+            render: (_, record) => [
+                <Button
+                    type="link"
+                    key="edit"
+                    onClick={() => {
+                        setModalVisible(true);
+                        setCurrentRow(record);
+                    }}
+                >
+                    <FormattedMessage id='page.edit' defaultMessage='缂栬緫' />
+                </Button>,
+                <Button
+                    type="link"
+                    danger
+                    key="batchRemove"
+                    onClick={async () => {
+                        Modal.confirm({
+                            title: intl.formatMessage({ id: 'page.delete', defaultMessage: '鍒犻櫎' }),
+                            content: intl.formatMessage({ id: 'page.delete.confirm', defaultMessage: '纭畾鍒犻櫎璇ラ」鍚楋紵' }),
+                            onOk: async () => {
+                                const success = await handleRemove([record], intl);
+                                if (success) {
+                                    if (actionRef.current) {
+                                        actionRef.current.reload();
+                                    }
+                                }
+                            },
+                        });
+                    }}
+                >
+                    <FormattedMessage id='page.delete' defaultMessage='鍒犻櫎' />
+                </Button>,
+            ],
+        },
+    ];
+
+    return (
+        <PageContainer
+            header={{
+                breadcrumb: {},
+            }}
+        >
+            <div style={{ width: '100%', float: 'right' }}>
+                <ProTable
+                    key="motion"
+                    rowKey="id"
+                    actionRef={actionRef}
+                    formRef={formTableRef}
+                    columns={columns}
+                    cardBordered
+                    scroll={{ x: 1300 }}
+                    dateFormatter="string"
+                    pagination={{ pageSize: 16 }}
+                    search={false}
+                    toolbar={{
+                        search: {
+                            onSearch: (value) => {
+                                setSearchParam(prevState => ({
+                                    ...prevState,
+                                    condition: value
+                                }));
+                                actionRef.current?.reload();
+                            },
+                        },
+                        filter: (
+                            <LightFilter
+                                onValuesChange={(val) => {
+                                }}
+                            >
+                            </LightFilter>
+                        ),
+                        actions: [
+                            <Button
+                                type="primary"
+                                key="save"
+                                onClick={async () => {
+                                    setModalVisible(true)
+                                }}
+                            >
+                                <PlusOutlined />
+                                <FormattedMessage id='page.add' defaultMessage='娣诲姞' />
+                            </Button>,
+                            <Button
+                                key="export"
+                                onClick={async () => {
+                                    handleExport(intl);
+                                }}
+                            >
+                                <ExportOutlined />
+                                <FormattedMessage id='page.export' defaultMessage='瀵煎嚭' />
+                            </Button>,
+                        ],
+                    }}
+                    request={(params, sorter, filter) =>
+                        Http.doPostPromise('/api/motion/page', { ...params, ...searchParam }, (res) => {
+                            return {
+                                data: res.data.records,
+                                total: res.data.total,
+                                success: true,
+                            }
+                        })
+                    }
+                    rowSelection={{
+                        onChange: (ids, rows) => {
+                            setSelectedRows(rows);
+                        }
+                    }}
+                    columnsState={{
+                        persistenceKey: TABLE_KEY,
+                        persistenceType: 'localStorage',
+                        defaultValue: {
+                            // memo: { show: repairBug(TABLE_KEY, 'memo', false) },
+                            option: { fixed: 'right', disable: true },
+                        },
+                        onChange(value) {
+                        },
+                    }}
+                />
+            </div>
+
+            {selectedRows?.length > 0 && (
+                <FooterToolbar
+                    extra={
+                        <div>
+                            <a style={{ fontWeight: 600 }}>{selectedRows.length}</a>
+                            <FormattedMessage id='page.selected' defaultMessage=' 椤瑰凡閫夋嫨' />
+                        </div>
+                    }
+                >
+                    <Button
+                        key="remove"
+                        danger
+                        onClick={async () => {
+                            Modal.confirm({
+                                title: intl.formatMessage({ id: 'page.delete', defaultMessage: '鍒犻櫎' }),
+                                content: intl.formatMessage({ id: 'page.delete.confirm', defaultMessage: '纭畾鍒犻櫎璇ラ」鍚楋紵' }),
+                                onOk: async () => {
+                                    const success = await handleRemove(selectedRows, intl);
+                                    if (success) {
+                                        setSelectedRows([]);
+                                        actionRef.current?.reloadAndRest?.();
+                                    }
+                                },
+                            });
+                        }}
+                    >
+                        <FormattedMessage id='page.delete.batch' defaultMessage='鎵归噺鍒犻櫎' />
+                    </Button>
+                </FooterToolbar>
+            )}
+
+            <Edit
+                open={modalVisible}
+                values={currentRow || {}}
+                onCancel={
+                    () => {
+                        setModalVisible(false);
+                        setCurrentRow(undefined);
+                    }
+                }
+                onSubmit={async (values) => {
+                    let ok = false;
+                    if (values.id) {
+                        ok = await handleUpdate({ ...values }, intl)
+                    } else {
+                        ok = await handleSave({ ...values }, intl)
+                    }
+                    if (ok) {
+                        setModalVisible(false);
+                        setCurrentRow(undefined);
+                        if (actionRef.current) {
+                            actionRef.current.reload();
+                        }
+                    }
+                }}
+            />
+        </PageContainer>
+    );
+};
+
+export default Main;
diff --git a/zy-asrs-flow/src/pages/device/motionCtg/components/edit.jsx b/zy-asrs-flow/src/pages/device/motionCtg/components/edit.jsx
new file mode 100644
index 0000000..f0f0292
--- /dev/null
+++ b/zy-asrs-flow/src/pages/device/motionCtg/components/edit.jsx
@@ -0,0 +1,160 @@
+import React, { useState, useRef, useEffect } from 'react';
+import {
+    ProForm,
+    ProFormDigit,
+    ProFormText,
+    ProFormSelect,
+    ProFormDateTimePicker
+} from '@ant-design/pro-components';
+import { Form, Modal } from 'antd';
+import { FormattedMessage, useIntl } from '@umijs/max';
+import moment from 'moment';
+import Http from '@/utils/http';
+
+const Edit = (props) => {
+    const intl = useIntl();
+    const [form] = Form.useForm();
+    const { } = props;
+
+    useEffect(() => {
+        form.resetFields();
+        form.setFieldsValue({
+            ...props.values
+        })
+    }, [form, props])
+
+    const handleCancel = () => {
+        props.onCancel();
+    };
+
+    const handleOk = () => {
+        form.submit();
+    }
+
+    const handleFinish = async (values) => {
+        props.onSubmit({ ...values });
+    }
+
+    return (
+        <>
+            <Modal
+                title={
+                    Object.keys(props.values).length > 0
+                        ? intl.formatMessage({ id: 'page.edit', defaultMessage: '缂栬緫' })
+                        : intl.formatMessage({ id: 'page.add', defaultMessage: '娣诲姞' })
+                }
+                width={640}
+                forceRender
+                destroyOnClose
+                open={props.open}
+                onCancel={handleCancel}
+                onOk={handleOk}
+            >
+                <ProForm
+                    form={form}
+                    submitter={false}
+                    onFinish={handleFinish}
+                    layout="horizontal"
+                    grid={true}
+                >
+                    <ProFormDigit
+                        name="id"
+                        disabled
+                        hidden={true}
+                    />
+                    <ProForm.Group>
+                        <ProFormSelect
+                            name="deviceCtg"
+                            label="璁惧绫诲瀷"
+                            colProps={{ md: 12, xl: 12 }}
+                            fieldProps={{ precision: 0 }}
+                            showSearch
+                            debounceTime={300}
+                            request={async ({ keyWords }) => {
+                                const resp = await Http.doPostForm('api/deviceCtg/query', { condition: keyWords });
+                                return resp.data;
+                            }}
+                        />
+                        <ProFormText
+                            name="uuid"
+                            label="缂栧彿"
+                            colProps={{ md: 12, xl: 12 }}
+                        />
+                    </ProForm.Group>
+                    <ProForm.Group>
+                        <ProFormText
+                            name="name"
+                            label="鍚嶇О"
+                            colProps={{ md: 12, xl: 12 }}
+                            rules={[{ required: true }]}
+                        />
+                        <ProFormText
+                            name="flag"
+                            label="鏍囪瘑"
+                            colProps={{ md: 12, xl: 12 }}
+                        />
+                    </ProForm.Group>
+                    <ProForm.Group>
+                        <ProFormSelect
+                            name="status"
+                            label="鐘舵��"
+                            colProps={{ md: 12, xl: 12 }}
+                            options={[
+                                { label: '姝e父', value: 1 },
+                                { label: '绂佺敤', value: 0 },
+                            ]}
+                        />
+                        <ProFormSelect
+                            name="createBy"
+                            label="娣诲姞浜哄憳"
+                            colProps={{ md: 12, xl: 12 }}
+                            fieldProps={{ precision: 0 }}
+                            showSearch
+                            debounceTime={300}
+                            request={async ({ keyWords }) => {
+                                const resp = await Http.doPostForm('api/user/query', { condition: keyWords });
+                                return resp.data;
+                            }}
+                        />
+                    </ProForm.Group>
+                    <ProForm.Group>
+                        <ProFormDateTimePicker
+                            name="createTime"
+                            label="娣诲姞鏃堕棿"
+                            colProps={{ md: 12, xl: 12 }}
+                            transform={(value) => moment(value).toISOString()}
+                        />
+                        <ProFormSelect
+                            name="updateBy"
+                            label="淇敼浜哄憳"
+                            colProps={{ md: 12, xl: 12 }}
+                            fieldProps={{ precision: 0 }}
+                            showSearch
+                            debounceTime={300}
+                            request={async ({ keyWords }) => {
+                                const resp = await Http.doPostForm('api/user/query', { condition: keyWords });
+                                return resp.data;
+                            }}
+                        />
+                    </ProForm.Group>
+                    <ProForm.Group>
+                        <ProFormDateTimePicker
+                            name="updateTime"
+                            label="淇敼鏃堕棿"
+                            colProps={{ md: 12, xl: 12 }}
+                            transform={(value) => moment(value).toISOString()}
+                        />
+                        <ProFormText
+                            name="memo"
+                            label="澶囨敞"
+                            colProps={{ md: 12, xl: 12 }}
+                        />
+                    </ProForm.Group>
+
+                </ProForm>
+            </Modal>
+        </>
+    )
+}
+
+export default Edit;
diff --git a/zy-asrs-flow/src/pages/device/motionCtg/index.jsx b/zy-asrs-flow/src/pages/device/motionCtg/index.jsx
new file mode 100644
index 0000000..07ae760
--- /dev/null
+++ b/zy-asrs-flow/src/pages/device/motionCtg/index.jsx
@@ -0,0 +1,442 @@
+
+import React, { useState, useRef, useEffect } from 'react';
+import { Button, message, Modal, Tag  } from 'antd';
+import {
+    FooterToolbar,
+    PageContainer,
+    ProTable,
+    LightFilter,
+} from '@ant-design/pro-components';
+import { FormattedMessage, useIntl } from '@umijs/max';
+import { PlusOutlined, ExportOutlined } from '@ant-design/icons';
+import Http from '@/utils/http';
+import Edit from './components/edit'
+import { TextFilter, SelectFilter, DatetimeRangeFilter, LinkFilter } from '@/components/TableSearch'
+import { statusMap } from '@/utils/enum-util'
+import { repairBug } from '@/utils/common-util';
+
+const TABLE_KEY = 'pro-table-motionCtg';
+
+const handleSave = async (val, intl) => {
+    const hide = message.loading(intl.formatMessage({ id: 'page.adding', defaultMessage: '姝e湪娣诲姞' }));
+    try {
+        const resp = await Http.doPost('api/motionCtg/save', val);
+        if (resp.code === 200) {
+            message.success(intl.formatMessage({ id: 'page.add.success', defaultMessage: '娣诲姞鎴愬姛' }));
+            return true;
+        } else {
+            message.error(resp.msg);
+            return false;
+        }
+    } catch (error) {
+        message.error(intl.formatMessage({ id: 'page.add.fail', defaultMessage: '娣诲姞澶辫触璇烽噸璇曪紒' }));
+        return false;
+    } finally {
+        hide();
+    }
+};
+
+const handleUpdate = async (val, intl) => {
+    const hide = message.loading(intl.formatMessage({ id: 'page.updating', defaultMessage: '姝e湪鏇存柊' }));
+    try {
+        const resp = await Http.doPost('api/motionCtg/update', val);
+        if (resp.code === 200) {
+            message.success(intl.formatMessage({ id: 'page.update.success', defaultMessage: '鏇存柊鎴愬姛' }));
+            return true;
+        } else {
+            message.error(resp.msg);
+            return false;
+        }
+    } catch (error) {
+        message.error(intl.formatMessage({ id: 'page.update.fail', defaultMessage: '鏇存柊澶辫触璇烽噸璇曪紒' }));
+        return false;
+    } finally {
+        hide();
+    }
+};
+
+const handleRemove = async (rows, intl) => {
+    if (!rows) return true;
+    const hide = message.loading(intl.formatMessage({ id: 'page.deleting', defaultMessage: '姝e湪鍒犻櫎' }));
+    try {
+        const resp = await Http.doPost('api/motionCtg/remove/' + rows.map((row) => row.id).join(','));
+        if (resp.code === 200) {
+            message.success(intl.formatMessage({ id: 'page.delete.success', defaultMessage: '鍒犻櫎鎴愬姛' }));
+            return true;
+        } else {
+            message.error(resp.msg);
+            return false;
+        }
+    } catch (error) {
+        message.error(intl.formatMessage({ id: 'page.delete.fail', defaultMessage: '鍒犻櫎澶辫触锛岃閲嶈瘯锛�' }));
+        return false;
+    } finally {
+        hide();
+    }
+};
+
+const handleExport = async (intl) => {
+    const hide = message.loading(intl.formatMessage({ id: 'page.exporting', defaultMessage: '姝e湪瀵煎嚭' }));
+    try {
+        const resp = await Http.doPostBlob('api/motionCtg/export');
+        const blob = new Blob([resp], { type: 'application/vnd.ms-excel' });
+        window.location.href = window.URL.createObjectURL(blob);
+        message.success(intl.formatMessage({ id: 'page.export.success', defaultMessage: '瀵煎嚭鎴愬姛' }));
+        return true;
+    } catch (error) {
+        message.error(intl.formatMessage({ id: 'page.export.fail', defaultMessage: '瀵煎嚭澶辫触锛岃閲嶈瘯' }));
+        return false;
+    } finally {
+        hide();
+    }
+};
+
+
+const Main = () => {
+    const intl = useIntl();
+    const formTableRef = useRef();
+    const actionRef = useRef();
+    const [selectedRows, setSelectedRows] = useState([]);
+    const [modalVisible, setModalVisible] = useState(false);
+    const [currentRow, setCurrentRow] = useState();
+    const [searchParam, setSearchParam] = useState({});
+
+    useEffect(() => {
+
+    }, []);
+
+    const columns = [
+        {
+            title: intl.formatMessage({
+                id: 'page.table.no',
+                defaultMessage: 'No'
+            }),
+            dataIndex: 'index',
+            valueType: 'indexBorder',
+            width: 48,
+        },
+        {
+            title: '璁惧绫诲瀷',
+            dataIndex: 'deviceCtg$',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            filterDropdown: (props) => <LinkFilter
+                name='deviceCtg'
+                major='deviceCtg'
+                {...props}
+                actionRef={actionRef}
+                setSearchParam={setSearchParam}
+            />,
+        },
+        {
+            title: '缂栧彿',
+            dataIndex: 'uuid',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            filterDropdown: (props) => <TextFilter
+                name='uuid'
+                {...props}
+                actionRef={actionRef}
+                setSearchParam={setSearchParam}
+            />,
+        },
+        {
+            title: '鍚嶇О',
+            dataIndex: 'name',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            copyable: true,
+            filterDropdown: (props) => <TextFilter
+                name='name'
+                {...props}
+                actionRef={actionRef}
+                setSearchParam={setSearchParam}
+            />,
+        },
+        {
+            title: '鏍囪瘑',
+            dataIndex: 'flag',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            filterDropdown: (props) => <TextFilter
+                name='flag'
+                {...props}
+                actionRef={actionRef}
+                setSearchParam={setSearchParam}
+            />,
+        },
+        {
+            title: '鐘舵��',
+            dataIndex: 'status$',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            filterDropdown: (props) => <SelectFilter
+                name='status'
+                {...props}
+                actionRef={actionRef}
+                setSearchParam={setSearchParam}
+                data={[
+                    { label: '姝e父', value: 1 },
+                    { label: '绂佺敤', value: 0 },
+                ]}
+            />,
+        },
+        {
+            title: '娣诲姞浜哄憳',
+            dataIndex: 'createBy$',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            filterDropdown: (props) => <LinkFilter
+                name='createBy'
+                major='user'
+                {...props}
+                actionRef={actionRef}
+                setSearchParam={setSearchParam}
+            />,
+        },
+        {
+            title: '娣诲姞鏃堕棿',
+            dataIndex: 'createTime$',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            filterDropdown: (props) => <DatetimeRangeFilter
+                name='createTime'
+                {...props}
+                actionRef={actionRef}
+                setSearchParam={setSearchParam}
+            />,
+        },
+        {
+            title: '淇敼浜哄憳',
+            dataIndex: 'updateBy$',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            filterDropdown: (props) => <LinkFilter
+                name='updateBy'
+                major='user'
+                {...props}
+                actionRef={actionRef}
+                setSearchParam={setSearchParam}
+            />,
+        },
+        {
+            title: '淇敼鏃堕棿',
+            dataIndex: 'updateTime$',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            filterDropdown: (props) => <DatetimeRangeFilter
+                name='updateTime'
+                {...props}
+                actionRef={actionRef}
+                setSearchParam={setSearchParam}
+            />,
+        },
+        {
+            title: '澶囨敞',
+            dataIndex: 'memo',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            filterDropdown: (props) => <TextFilter
+                name='memo'
+                {...props}
+                actionRef={actionRef}
+                setSearchParam={setSearchParam}
+            />,
+        },
+
+        {
+            title: '鎿嶄綔',
+            dataIndex: 'option',
+            width: 140,
+            valueType: 'option',
+            render: (_, record) => [
+                <Button
+                    type="link"
+                    key="edit"
+                    onClick={() => {
+                        setModalVisible(true);
+                        setCurrentRow(record);
+                    }}
+                >
+                    <FormattedMessage id='page.edit' defaultMessage='缂栬緫' />
+                </Button>,
+                <Button
+                    type="link"
+                    danger
+                    key="batchRemove"
+                    onClick={async () => {
+                        Modal.confirm({
+                            title: intl.formatMessage({ id: 'page.delete', defaultMessage: '鍒犻櫎' }),
+                            content: intl.formatMessage({ id: 'page.delete.confirm', defaultMessage: '纭畾鍒犻櫎璇ラ」鍚楋紵' }),
+                            onOk: async () => {
+                                const success = await handleRemove([record], intl);
+                                if (success) {
+                                    if (actionRef.current) {
+                                        actionRef.current.reload();
+                                    }
+                                }
+                            },
+                        });
+                    }}
+                >
+                    <FormattedMessage id='page.delete' defaultMessage='鍒犻櫎' />
+                </Button>,
+            ],
+        },
+    ];
+
+    return (
+        <PageContainer
+            header={{
+                breadcrumb: {},
+            }}
+        >
+            <div style={{ width: '100%', float: 'right' }}>
+                <ProTable
+                    key="motionCtg"
+                    rowKey="id"
+                    actionRef={actionRef}
+                    formRef={formTableRef}
+                    columns={columns}
+                    cardBordered
+                    scroll={{ x: 1300 }}
+                    dateFormatter="string"
+                    pagination={{ pageSize: 16 }}
+                    search={false}
+                    toolbar={{
+                        search: {
+                            onSearch: (value) => {
+                                setSearchParam(prevState => ({
+                                    ...prevState,
+                                    condition: value
+                                }));
+                                actionRef.current?.reload();
+                            },
+                        },
+                        filter: (
+                            <LightFilter
+                                onValuesChange={(val) => {
+                                }}
+                            >
+                            </LightFilter>
+                        ),
+                        actions: [
+                            <Button
+                                type="primary"
+                                key="save"
+                                onClick={async () => {
+                                    setModalVisible(true)
+                                }}
+                            >
+                                <PlusOutlined />
+                                <FormattedMessage id='page.add' defaultMessage='娣诲姞' />
+                            </Button>,
+                            <Button
+                                key="export"
+                                onClick={async () => {
+                                    handleExport(intl);
+                                }}
+                            >
+                                <ExportOutlined />
+                                <FormattedMessage id='page.export' defaultMessage='瀵煎嚭' />
+                            </Button>,
+                        ],
+                    }}
+                    request={(params, sorter, filter) =>
+                        Http.doPostPromise('/api/motionCtg/page', { ...params, ...searchParam }, (res) => {
+                            return {
+                                data: res.data.records,
+                                total: res.data.total,
+                                success: true,
+                            }
+                        })
+                    }
+                    rowSelection={{
+                        onChange: (ids, rows) => {
+                            setSelectedRows(rows);
+                        }
+                    }}
+                    columnsState={{
+                        persistenceKey: TABLE_KEY,
+                        persistenceType: 'localStorage',
+                        defaultValue: {
+                            // memo: { show: repairBug(TABLE_KEY, 'memo', false) },
+                            option: { fixed: 'right', disable: true },
+                        },
+                        onChange(value) {
+                        },
+                    }}
+                />
+            </div>
+
+            {selectedRows?.length > 0 && (
+                <FooterToolbar
+                    extra={
+                        <div>
+                            <a style={{ fontWeight: 600 }}>{selectedRows.length}</a>
+                            <FormattedMessage id='page.selected' defaultMessage=' 椤瑰凡閫夋嫨' />
+                        </div>
+                    }
+                >
+                    <Button
+                        key="remove"
+                        danger
+                        onClick={async () => {
+                            Modal.confirm({
+                                title: intl.formatMessage({ id: 'page.delete', defaultMessage: '鍒犻櫎' }),
+                                content: intl.formatMessage({ id: 'page.delete.confirm', defaultMessage: '纭畾鍒犻櫎璇ラ」鍚楋紵' }),
+                                onOk: async () => {
+                                    const success = await handleRemove(selectedRows, intl);
+                                    if (success) {
+                                        setSelectedRows([]);
+                                        actionRef.current?.reloadAndRest?.();
+                                    }
+                                },
+                            });
+                        }}
+                    >
+                        <FormattedMessage id='page.delete.batch' defaultMessage='鎵归噺鍒犻櫎' />
+                    </Button>
+                </FooterToolbar>
+            )}
+
+            <Edit
+                open={modalVisible}
+                values={currentRow || {}}
+                onCancel={
+                    () => {
+                        setModalVisible(false);
+                        setCurrentRow(undefined);
+                    }
+                }
+                onSubmit={async (values) => {
+                    let ok = false;
+                    if (values.id) {
+                        ok = await handleUpdate({ ...values }, intl)
+                    } else {
+                        ok = await handleSave({ ...values }, intl)
+                    }
+                    if (ok) {
+                        setModalVisible(false);
+                        setCurrentRow(undefined);
+                        if (actionRef.current) {
+                            actionRef.current.reload();
+                        }
+                    }
+                }}
+            />
+        </PageContainer>
+    );
+};
+
+export default Main;
diff --git a/zy-asrs-flow/src/pages/device/motionSts/components/edit.jsx b/zy-asrs-flow/src/pages/device/motionSts/components/edit.jsx
new file mode 100644
index 0000000..8dfc2ae
--- /dev/null
+++ b/zy-asrs-flow/src/pages/device/motionSts/components/edit.jsx
@@ -0,0 +1,148 @@
+import React, { useState, useRef, useEffect } from 'react';
+import {
+    ProForm,
+    ProFormDigit,
+    ProFormText,
+    ProFormSelect,
+    ProFormDateTimePicker
+} from '@ant-design/pro-components';
+import { Form, Modal } from 'antd';
+import { FormattedMessage, useIntl } from '@umijs/max';
+import moment from 'moment';
+import Http from '@/utils/http';
+
+const Edit = (props) => {
+    const intl = useIntl();
+    const [form] = Form.useForm();
+    const { } = props;
+
+    useEffect(() => {
+        form.resetFields();
+        form.setFieldsValue({
+            ...props.values
+        })
+    }, [form, props])
+
+    const handleCancel = () => {
+        props.onCancel();
+    };
+
+    const handleOk = () => {
+        form.submit();
+    }
+
+    const handleFinish = async (values) => {
+        props.onSubmit({ ...values });
+    }
+
+    return (
+        <>
+            <Modal
+                title={
+                    Object.keys(props.values).length > 0
+                        ? intl.formatMessage({ id: 'page.edit', defaultMessage: '缂栬緫' })
+                        : intl.formatMessage({ id: 'page.add', defaultMessage: '娣诲姞' })
+                }
+                width={640}
+                forceRender
+                destroyOnClose
+                open={props.open}
+                onCancel={handleCancel}
+                onOk={handleOk}
+            >
+                <ProForm
+                    form={form}
+                    submitter={false}
+                    onFinish={handleFinish}
+                    layout="horizontal"
+                    grid={true}
+                >
+                    <ProFormDigit
+                        name="id"
+                        disabled
+                        hidden={true}
+                    />
+                    <ProForm.Group>
+                        <ProFormText
+                            name="uuid"
+                            label="缂栧彿"
+                            colProps={{ md: 12, xl: 12 }}
+                        />
+                        <ProFormText
+                            name="name"
+                            label="鍚嶇О"
+                            colProps={{ md: 12, xl: 12 }}
+                            rules={[{ required: true }]}
+                        />
+                    </ProForm.Group>
+                    <ProForm.Group>
+                        <ProFormText
+                            name="flag"
+                            label="鏍囪瘑"
+                            colProps={{ md: 12, xl: 12 }}
+                        />
+                        <ProFormSelect
+                            name="status"
+                            label="鐘舵��"
+                            colProps={{ md: 12, xl: 12 }}
+                            options={[
+                                { label: '姝e父', value: 1 },
+                                { label: '绂佺敤', value: 0 },
+                            ]}
+                        />
+                    </ProForm.Group>
+                    <ProForm.Group>
+                        <ProFormSelect
+                            name="createBy"
+                            label="娣诲姞浜哄憳"
+                            colProps={{ md: 12, xl: 12 }}
+                            fieldProps={{ precision: 0 }}
+                            showSearch
+                            debounceTime={300}
+                            request={async ({ keyWords }) => {
+                                const resp = await Http.doPostForm('api/user/query', { condition: keyWords });
+                                return resp.data;
+                            }}
+                        />
+                        <ProFormDateTimePicker
+                            name="createTime"
+                            label="娣诲姞鏃堕棿"
+                            colProps={{ md: 12, xl: 12 }}
+                            transform={(value) => moment(value).toISOString()}
+                        />
+                    </ProForm.Group>
+                    <ProForm.Group>
+                        <ProFormSelect
+                            name="updateBy"
+                            label="淇敼浜哄憳"
+                            colProps={{ md: 12, xl: 12 }}
+                            fieldProps={{ precision: 0 }}
+                            showSearch
+                            debounceTime={300}
+                            request={async ({ keyWords }) => {
+                                const resp = await Http.doPostForm('api/user/query', { condition: keyWords });
+                                return resp.data;
+                            }}
+                        />
+                        <ProFormDateTimePicker
+                            name="updateTime"
+                            label="淇敼鏃堕棿"
+                            colProps={{ md: 12, xl: 12 }}
+                            transform={(value) => moment(value).toISOString()}
+                        />
+                    </ProForm.Group>
+                    <ProForm.Group>
+                        <ProFormText
+                            name="memo"
+                            label="澶囨敞"
+                            colProps={{ md: 12, xl: 12 }}
+                        />
+                    </ProForm.Group>
+
+                </ProForm>
+            </Modal>
+        </>
+    )
+}
+
+export default Edit;
diff --git a/zy-asrs-flow/src/pages/device/motionSts/index.jsx b/zy-asrs-flow/src/pages/device/motionSts/index.jsx
new file mode 100644
index 0000000..ff83e28
--- /dev/null
+++ b/zy-asrs-flow/src/pages/device/motionSts/index.jsx
@@ -0,0 +1,428 @@
+
+import React, { useState, useRef, useEffect } from 'react';
+import { Button, message, Modal, Tag  } from 'antd';
+import {
+    FooterToolbar,
+    PageContainer,
+    ProTable,
+    LightFilter,
+} from '@ant-design/pro-components';
+import { FormattedMessage, useIntl } from '@umijs/max';
+import { PlusOutlined, ExportOutlined } from '@ant-design/icons';
+import Http from '@/utils/http';
+import Edit from './components/edit'
+import { TextFilter, SelectFilter, DatetimeRangeFilter, LinkFilter } from '@/components/TableSearch'
+import { statusMap } from '@/utils/enum-util'
+import { repairBug } from '@/utils/common-util';
+
+const TABLE_KEY = 'pro-table-motionSts';
+
+const handleSave = async (val, intl) => {
+    const hide = message.loading(intl.formatMessage({ id: 'page.adding', defaultMessage: '姝e湪娣诲姞' }));
+    try {
+        const resp = await Http.doPost('api/motionSts/save', val);
+        if (resp.code === 200) {
+            message.success(intl.formatMessage({ id: 'page.add.success', defaultMessage: '娣诲姞鎴愬姛' }));
+            return true;
+        } else {
+            message.error(resp.msg);
+            return false;
+        }
+    } catch (error) {
+        message.error(intl.formatMessage({ id: 'page.add.fail', defaultMessage: '娣诲姞澶辫触璇烽噸璇曪紒' }));
+        return false;
+    } finally {
+        hide();
+    }
+};
+
+const handleUpdate = async (val, intl) => {
+    const hide = message.loading(intl.formatMessage({ id: 'page.updating', defaultMessage: '姝e湪鏇存柊' }));
+    try {
+        const resp = await Http.doPost('api/motionSts/update', val);
+        if (resp.code === 200) {
+            message.success(intl.formatMessage({ id: 'page.update.success', defaultMessage: '鏇存柊鎴愬姛' }));
+            return true;
+        } else {
+            message.error(resp.msg);
+            return false;
+        }
+    } catch (error) {
+        message.error(intl.formatMessage({ id: 'page.update.fail', defaultMessage: '鏇存柊澶辫触璇烽噸璇曪紒' }));
+        return false;
+    } finally {
+        hide();
+    }
+};
+
+const handleRemove = async (rows, intl) => {
+    if (!rows) return true;
+    const hide = message.loading(intl.formatMessage({ id: 'page.deleting', defaultMessage: '姝e湪鍒犻櫎' }));
+    try {
+        const resp = await Http.doPost('api/motionSts/remove/' + rows.map((row) => row.id).join(','));
+        if (resp.code === 200) {
+            message.success(intl.formatMessage({ id: 'page.delete.success', defaultMessage: '鍒犻櫎鎴愬姛' }));
+            return true;
+        } else {
+            message.error(resp.msg);
+            return false;
+        }
+    } catch (error) {
+        message.error(intl.formatMessage({ id: 'page.delete.fail', defaultMessage: '鍒犻櫎澶辫触锛岃閲嶈瘯锛�' }));
+        return false;
+    } finally {
+        hide();
+    }
+};
+
+const handleExport = async (intl) => {
+    const hide = message.loading(intl.formatMessage({ id: 'page.exporting', defaultMessage: '姝e湪瀵煎嚭' }));
+    try {
+        const resp = await Http.doPostBlob('api/motionSts/export');
+        const blob = new Blob([resp], { type: 'application/vnd.ms-excel' });
+        window.location.href = window.URL.createObjectURL(blob);
+        message.success(intl.formatMessage({ id: 'page.export.success', defaultMessage: '瀵煎嚭鎴愬姛' }));
+        return true;
+    } catch (error) {
+        message.error(intl.formatMessage({ id: 'page.export.fail', defaultMessage: '瀵煎嚭澶辫触锛岃閲嶈瘯' }));
+        return false;
+    } finally {
+        hide();
+    }
+};
+
+
+const Main = () => {
+    const intl = useIntl();
+    const formTableRef = useRef();
+    const actionRef = useRef();
+    const [selectedRows, setSelectedRows] = useState([]);
+    const [modalVisible, setModalVisible] = useState(false);
+    const [currentRow, setCurrentRow] = useState();
+    const [searchParam, setSearchParam] = useState({});
+
+    useEffect(() => {
+
+    }, []);
+
+    const columns = [
+        {
+            title: intl.formatMessage({
+                id: 'page.table.no',
+                defaultMessage: 'No'
+            }),
+            dataIndex: 'index',
+            valueType: 'indexBorder',
+            width: 48,
+        },
+        {
+            title: '缂栧彿',
+            dataIndex: 'uuid',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            filterDropdown: (props) => <TextFilter
+                name='uuid'
+                {...props}
+                actionRef={actionRef}
+                setSearchParam={setSearchParam}
+            />,
+        },
+        {
+            title: '鍚嶇О',
+            dataIndex: 'name',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            copyable: true,
+            filterDropdown: (props) => <TextFilter
+                name='name'
+                {...props}
+                actionRef={actionRef}
+                setSearchParam={setSearchParam}
+            />,
+        },
+        {
+            title: '鏍囪瘑',
+            dataIndex: 'flag',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            filterDropdown: (props) => <TextFilter
+                name='flag'
+                {...props}
+                actionRef={actionRef}
+                setSearchParam={setSearchParam}
+            />,
+        },
+        {
+            title: '鐘舵��',
+            dataIndex: 'status$',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            filterDropdown: (props) => <SelectFilter
+                name='status'
+                {...props}
+                actionRef={actionRef}
+                setSearchParam={setSearchParam}
+                data={[
+                    { label: '姝e父', value: 1 },
+                    { label: '绂佺敤', value: 0 },
+                ]}
+            />,
+        },
+        {
+            title: '娣诲姞浜哄憳',
+            dataIndex: 'createBy$',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            filterDropdown: (props) => <LinkFilter
+                name='createBy'
+                major='user'
+                {...props}
+                actionRef={actionRef}
+                setSearchParam={setSearchParam}
+            />,
+        },
+        {
+            title: '娣诲姞鏃堕棿',
+            dataIndex: 'createTime$',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            filterDropdown: (props) => <DatetimeRangeFilter
+                name='createTime'
+                {...props}
+                actionRef={actionRef}
+                setSearchParam={setSearchParam}
+            />,
+        },
+        {
+            title: '淇敼浜哄憳',
+            dataIndex: 'updateBy$',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            filterDropdown: (props) => <LinkFilter
+                name='updateBy'
+                major='user'
+                {...props}
+                actionRef={actionRef}
+                setSearchParam={setSearchParam}
+            />,
+        },
+        {
+            title: '淇敼鏃堕棿',
+            dataIndex: 'updateTime$',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            filterDropdown: (props) => <DatetimeRangeFilter
+                name='updateTime'
+                {...props}
+                actionRef={actionRef}
+                setSearchParam={setSearchParam}
+            />,
+        },
+        {
+            title: '澶囨敞',
+            dataIndex: 'memo',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            filterDropdown: (props) => <TextFilter
+                name='memo'
+                {...props}
+                actionRef={actionRef}
+                setSearchParam={setSearchParam}
+            />,
+        },
+
+        {
+            title: '鎿嶄綔',
+            dataIndex: 'option',
+            width: 140,
+            valueType: 'option',
+            render: (_, record) => [
+                <Button
+                    type="link"
+                    key="edit"
+                    onClick={() => {
+                        setModalVisible(true);
+                        setCurrentRow(record);
+                    }}
+                >
+                    <FormattedMessage id='page.edit' defaultMessage='缂栬緫' />
+                </Button>,
+                <Button
+                    type="link"
+                    danger
+                    key="batchRemove"
+                    onClick={async () => {
+                        Modal.confirm({
+                            title: intl.formatMessage({ id: 'page.delete', defaultMessage: '鍒犻櫎' }),
+                            content: intl.formatMessage({ id: 'page.delete.confirm', defaultMessage: '纭畾鍒犻櫎璇ラ」鍚楋紵' }),
+                            onOk: async () => {
+                                const success = await handleRemove([record], intl);
+                                if (success) {
+                                    if (actionRef.current) {
+                                        actionRef.current.reload();
+                                    }
+                                }
+                            },
+                        });
+                    }}
+                >
+                    <FormattedMessage id='page.delete' defaultMessage='鍒犻櫎' />
+                </Button>,
+            ],
+        },
+    ];
+
+    return (
+        <PageContainer
+            header={{
+                breadcrumb: {},
+            }}
+        >
+            <div style={{ width: '100%', float: 'right' }}>
+                <ProTable
+                    key="motionSts"
+                    rowKey="id"
+                    actionRef={actionRef}
+                    formRef={formTableRef}
+                    columns={columns}
+                    cardBordered
+                    scroll={{ x: 1300 }}
+                    dateFormatter="string"
+                    pagination={{ pageSize: 16 }}
+                    search={false}
+                    toolbar={{
+                        search: {
+                            onSearch: (value) => {
+                                setSearchParam(prevState => ({
+                                    ...prevState,
+                                    condition: value
+                                }));
+                                actionRef.current?.reload();
+                            },
+                        },
+                        filter: (
+                            <LightFilter
+                                onValuesChange={(val) => {
+                                }}
+                            >
+                            </LightFilter>
+                        ),
+                        actions: [
+                            <Button
+                                type="primary"
+                                key="save"
+                                onClick={async () => {
+                                    setModalVisible(true)
+                                }}
+                            >
+                                <PlusOutlined />
+                                <FormattedMessage id='page.add' defaultMessage='娣诲姞' />
+                            </Button>,
+                            <Button
+                                key="export"
+                                onClick={async () => {
+                                    handleExport(intl);
+                                }}
+                            >
+                                <ExportOutlined />
+                                <FormattedMessage id='page.export' defaultMessage='瀵煎嚭' />
+                            </Button>,
+                        ],
+                    }}
+                    request={(params, sorter, filter) =>
+                        Http.doPostPromise('/api/motionSts/page', { ...params, ...searchParam }, (res) => {
+                            return {
+                                data: res.data.records,
+                                total: res.data.total,
+                                success: true,
+                            }
+                        })
+                    }
+                    rowSelection={{
+                        onChange: (ids, rows) => {
+                            setSelectedRows(rows);
+                        }
+                    }}
+                    columnsState={{
+                        persistenceKey: TABLE_KEY,
+                        persistenceType: 'localStorage',
+                        defaultValue: {
+                            // memo: { show: repairBug(TABLE_KEY, 'memo', false) },
+                            option: { fixed: 'right', disable: true },
+                        },
+                        onChange(value) {
+                        },
+                    }}
+                />
+            </div>
+
+            {selectedRows?.length > 0 && (
+                <FooterToolbar
+                    extra={
+                        <div>
+                            <a style={{ fontWeight: 600 }}>{selectedRows.length}</a>
+                            <FormattedMessage id='page.selected' defaultMessage=' 椤瑰凡閫夋嫨' />
+                        </div>
+                    }
+                >
+                    <Button
+                        key="remove"
+                        danger
+                        onClick={async () => {
+                            Modal.confirm({
+                                title: intl.formatMessage({ id: 'page.delete', defaultMessage: '鍒犻櫎' }),
+                                content: intl.formatMessage({ id: 'page.delete.confirm', defaultMessage: '纭畾鍒犻櫎璇ラ」鍚楋紵' }),
+                                onOk: async () => {
+                                    const success = await handleRemove(selectedRows, intl);
+                                    if (success) {
+                                        setSelectedRows([]);
+                                        actionRef.current?.reloadAndRest?.();
+                                    }
+                                },
+                            });
+                        }}
+                    >
+                        <FormattedMessage id='page.delete.batch' defaultMessage='鎵归噺鍒犻櫎' />
+                    </Button>
+                </FooterToolbar>
+            )}
+
+            <Edit
+                open={modalVisible}
+                values={currentRow || {}}
+                onCancel={
+                    () => {
+                        setModalVisible(false);
+                        setCurrentRow(undefined);
+                    }
+                }
+                onSubmit={async (values) => {
+                    let ok = false;
+                    if (values.id) {
+                        ok = await handleUpdate({ ...values }, intl)
+                    } else {
+                        ok = await handleSave({ ...values }, intl)
+                    }
+                    if (ok) {
+                        setModalVisible(false);
+                        setCurrentRow(undefined);
+                        if (actionRef.current) {
+                            actionRef.current.reload();
+                        }
+                    }
+                }}
+            />
+        </PageContainer>
+    );
+};
+
+export default Main;
diff --git a/zy-asrs-wcs/src/main/java/basShuttle.sql b/zy-asrs-wcs/src/main/java/basShuttle.sql
new file mode 100644
index 0000000..9d3252a
--- /dev/null
+++ b/zy-asrs-wcs/src/main/java/basShuttle.sql
@@ -0,0 +1,9 @@
+-- save basShuttle record
+-- mysql
+insert into `sys_menu` ( `name`, `parent_id`, `route`, `component`, `type`, `sort`, `host_id`, `status`) values ( '鍥涘悜杞﹁澶囧垪琛ㄧ鐞�', '0', '/core/basShuttle', '/core/basShuttle', '0' , '0', '1' , '1');
+
+insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `host_id`, `status`) values ( '鏌ヨ鍥涘悜杞﹁澶囧垪琛�', '', '1', 'core:basShuttle:list', '0', '1', '1');
+insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `host_id`, `status`) values ( '娣诲姞鍥涘悜杞﹁澶囧垪琛�', '', '1', 'core:basShuttle:save', '1', '1', '1');
+insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `host_id`, `status`) values ( '淇敼鍥涘悜杞﹁澶囧垪琛�', '', '1', 'core:basShuttle:update', '2', '1', '1');
+insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `host_id`, `status`) values ( '鍒犻櫎鍥涘悜杞﹁澶囧垪琛�', '', '1', 'core:basShuttle:remove', '3', '1', '1');
+
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/controller/BasShuttleController.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/controller/BasShuttleController.java
new file mode 100644
index 0000000..21b798f
--- /dev/null
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/controller/BasShuttleController.java
@@ -0,0 +1,102 @@
+package com.zy.asrs.wcs.core.controller;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.zy.asrs.framework.common.Cools;
+import com.zy.asrs.framework.common.R;
+import com.zy.asrs.wcs.common.annotation.OperationLog;
+import com.zy.asrs.wcs.common.domain.BaseParam;
+import com.zy.asrs.wcs.common.domain.KeyValVo;
+import com.zy.asrs.wcs.common.domain.PageParam;
+import com.zy.asrs.wcs.core.entity.BasShuttle;
+import com.zy.asrs.wcs.core.service.BasShuttleService;
+import com.zy.asrs.wcs.system.controller.BaseController;
+import com.zy.asrs.wcs.utils.ExcelUtil;
+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.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+@RestController
+@RequestMapping("/api")
+public class BasShuttleController extends BaseController {
+
+    @Autowired
+    private BasShuttleService basShuttleService;
+
+    @PreAuthorize("hasAuthority('core:basShuttle:list')")
+    @PostMapping("/basShuttle/page")
+    public R page(@RequestBody Map<String, Object> map) {
+        BaseParam baseParam = buildParam(map, BaseParam.class);
+        PageParam<BasShuttle, BaseParam> pageParam = new PageParam<>(baseParam, BasShuttle.class);
+        return R.ok().add(basShuttleService.page(pageParam, pageParam.buildWrapper(true)));
+    }
+
+    @PreAuthorize("hasAuthority('core:basShuttle:list')")
+    @PostMapping("/basShuttle/list")
+    public R list(@RequestBody Map<String, Object> map) {
+        return R.ok().add(basShuttleService.list());
+    }
+
+    @PreAuthorize("hasAuthority('core:basShuttle:list')")
+    @GetMapping("/basShuttle/{id}")
+    public R get(@PathVariable("id") Long id) {
+        return R.ok().add(basShuttleService.getById(id));
+    }
+
+    @PreAuthorize("hasAuthority('core:basShuttle:save')")
+    @OperationLog("娣诲姞鍥涘悜杞﹁澶囧垪琛�")
+    @PostMapping("/basShuttle/save")
+    public R save(@RequestBody BasShuttle basShuttle) {
+        if (!basShuttleService.save(basShuttle)) {
+            return R.error("娣诲姞澶辫触");
+        }
+        return R.ok("娣诲姞鎴愬姛");
+    }
+
+    @PreAuthorize("hasAuthority('core:basShuttle:update')")
+    @OperationLog("淇敼鍥涘悜杞﹁澶囧垪琛�")
+    @PostMapping("/basShuttle/update")
+    public R update(@RequestBody BasShuttle basShuttle) {
+        if (!basShuttleService.updateById(basShuttle)) {
+            return R.error("淇敼澶辫触");
+        }
+        return R.ok("淇敼鎴愬姛");
+    }
+
+    @PreAuthorize("hasAuthority('core:basShuttle:remove')")
+    @OperationLog("鍒犻櫎鍥涘悜杞﹁澶囧垪琛�")
+    @PostMapping("/basShuttle/remove/{ids}")
+    public R remove(@PathVariable Long[] ids) {
+        if (!basShuttleService.removeByIds(Arrays.asList(ids))) {
+            return R.error("鍒犻櫎澶辫触");
+        }
+        return R.ok("鍒犻櫎鎴愬姛");
+    }
+
+    @PreAuthorize("hasAuthority('core:basShuttle:list')")
+    @PostMapping("/basShuttle/query")
+    public R query(@RequestParam(required = false) String condition) {
+        List<KeyValVo> vos = new ArrayList<>();
+        LambdaQueryWrapper<BasShuttle> wrapper = new LambdaQueryWrapper<>();
+        if (!Cools.isEmpty(condition)) {
+            wrapper.like(BasShuttle::getShuttleNo, condition);
+        }
+        basShuttleService.page(new Page<>(1, 30), wrapper).getRecords().forEach(
+                item -> vos.add(new KeyValVo(item.getShuttleNo(), item.getShuttleNo()))
+        );
+        return R.ok().add(vos);
+    }
+
+    @PreAuthorize("hasAuthority('core:basShuttle:list')")
+    @PostMapping("/basShuttle/export")
+    public void export(@RequestBody Map<String, Object> map, HttpServletResponse response) throws Exception {
+        ExcelUtil.build(ExcelUtil.create(basShuttleService.list(), BasShuttle.class), response);
+    }
+
+}
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/entity/BasShuttle.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/entity/BasShuttle.java
new file mode 100644
index 0000000..7d84ce8
--- /dev/null
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/entity/BasShuttle.java
@@ -0,0 +1,230 @@
+package com.zy.asrs.wcs.core.entity;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import com.zy.asrs.wcs.system.entity.Host;
+import com.zy.asrs.wcs.system.entity.User;
+import org.springframework.format.annotation.DateTimeFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import com.baomidou.mybatisplus.annotation.TableLogic;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import com.zy.asrs.framework.common.Cools;
+import com.zy.asrs.framework.common.SpringUtils;
+import com.zy.asrs.wcs.system.service.UserService;
+import com.zy.asrs.wcs.system.service.HostService;
+
+import java.io.Serializable;
+import java.util.Date;
+
+@Data
+@TableName("wcs_bas_shuttle")
+public class BasShuttle implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 鍥涘悜绌挎杞﹀彿
+     */
+    @ApiModelProperty(value= "鍥涘悜绌挎杞﹀彿")
+    @TableId(value = "shuttle_no", type = IdType.AUTO)
+    private Integer shuttleNo;
+
+    /**
+     * 鐘舵�� 1: 姝e父  0: 绂佺敤  
+     */
+    @ApiModelProperty(value= "鐘舵�� 1: 姝e父  0: 绂佺敤  ")
+    private Integer status;
+
+    /**
+     * 褰撳墠灏忚溅鐘舵��
+     */
+    @ApiModelProperty(value= "褰撳墠灏忚溅鐘舵��")
+    private Integer shuttleStatus;
+
+    /**
+     * 浠诲姟鍙�
+     */
+    @ApiModelProperty(value= "浠诲姟鍙�")
+    private Integer wrkNo;
+
+    /**
+     * 鏆傚瓨搴撲綅
+     */
+    @ApiModelProperty(value= "鏆傚瓨搴撲綅")
+    private String idleLoc;
+
+    /**
+     * 鑷姩鍏呯數
+     */
+    @ApiModelProperty(value= "鑷姩鍏呯數")
+    private Integer autoCharge;
+
+    /**
+     * 鐢甸噺绾�
+     */
+    @ApiModelProperty(value= "鐢甸噺绾�")
+    private Integer chargeLine;
+
+    /**
+     * 娣诲姞浜哄憳
+     */
+    @ApiModelProperty(value= "娣诲姞浜哄憳")
+    private Long createBy;
+
+    /**
+     * 娣诲姞鏃堕棿
+     */
+    @ApiModelProperty(value= "娣诲姞鏃堕棿")
+    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
+    private Date createTime;
+
+    /**
+     * 淇敼浜哄憳
+     */
+    @ApiModelProperty(value= "淇敼浜哄憳")
+    private Long updateBy;
+
+    /**
+     * 淇敼鏃堕棿
+     */
+    @ApiModelProperty(value= "淇敼鏃堕棿")
+    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
+    private Date updateTime;
+
+    /**
+     * 澶囨敞
+     */
+    @ApiModelProperty(value= "澶囨敞")
+    private String memo;
+
+    /**
+     * 灏忚溅杩愯閫熷害
+     */
+    @ApiModelProperty(value= "灏忚溅杩愯閫熷害")
+    private Integer runSpeed;
+
+    /**
+     * 鏄惁鍒犻櫎 1: 鏄�  0: 鍚�  
+     */
+    @ApiModelProperty(value= "鏄惁鍒犻櫎 1: 鏄�  0: 鍚�  ")
+    @TableLogic
+    private Integer deleted;
+
+    /**
+     * 鎵�灞炴満鏋�
+     */
+    @ApiModelProperty(value= "鎵�灞炴満鏋�")
+    private Long hostId;
+
+    public BasShuttle() {}
+
+    public BasShuttle(Integer status,Integer shuttleStatus,Integer wrkNo,String idleLoc,Integer autoCharge,Integer chargeLine,Long createBy,Date createTime,Long updateBy,Date updateTime,String memo,Integer runSpeed,Integer deleted,Long hostId) {
+        this.status = status;
+        this.shuttleStatus = shuttleStatus;
+        this.wrkNo = wrkNo;
+        this.idleLoc = idleLoc;
+        this.autoCharge = autoCharge;
+        this.chargeLine = chargeLine;
+        this.createBy = createBy;
+        this.createTime = createTime;
+        this.updateBy = updateBy;
+        this.updateTime = updateTime;
+        this.memo = memo;
+        this.runSpeed = runSpeed;
+        this.deleted = deleted;
+        this.hostId = hostId;
+    }
+
+//    BasShuttle basShuttle = new BasShuttle(
+//            null,    // 鐘舵��
+//            null,    // 褰撳墠灏忚溅鐘舵��
+//            null,    // 浠诲姟鍙�
+//            null,    // 鏆傚瓨搴撲綅
+//            null,    // 鑷姩鍏呯數
+//            null,    // 鐢甸噺绾�
+//            null,    // 娣诲姞浜哄憳
+//            null,    // 娣诲姞鏃堕棿
+//            null,    // 淇敼浜哄憳
+//            null,    // 淇敼鏃堕棿
+//            null,    // 澶囨敞
+//            null,    // 灏忚溅杩愯閫熷害
+//            null,    // 鏄惁鍒犻櫎
+//            null    // 鎵�灞炴満鏋�
+//    );
+
+    public String getStatus$(){
+        if (null == this.status){ return null; }
+        switch (this.status){
+            case 1:
+                return "姝e父";
+            case 0:
+                return "绂佺敤";
+            default:
+                return String.valueOf(this.status);
+        }
+    }
+
+    public String getCreateBy$(){
+        UserService service = SpringUtils.getBean(UserService.class);
+        User user = service.getById(this.createBy);
+        if (!Cools.isEmpty(user)){
+            return String.valueOf(user.getNickname());
+        }
+        return null;
+    }
+
+    public String getCreateTime$(){
+        if (Cools.isEmpty(this.createTime)){
+            return "";
+        }
+        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.createTime);
+    }
+
+    public String getUpdateBy$(){
+        UserService service = SpringUtils.getBean(UserService.class);
+        User user = service.getById(this.updateBy);
+        if (!Cools.isEmpty(user)){
+            return String.valueOf(user.getNickname());
+        }
+        return null;
+    }
+
+    public String getUpdateTime$(){
+        if (Cools.isEmpty(this.updateTime)){
+            return "";
+        }
+        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.updateTime);
+    }
+
+    public String getDeleted$(){
+        if (null == this.deleted){ return null; }
+        switch (this.deleted){
+            case 1:
+                return "鏄�";
+            case 0:
+                return "鍚�";
+            default:
+                return String.valueOf(this.deleted);
+        }
+    }
+
+    public String getHostId$(){
+        HostService service = SpringUtils.getBean(HostService.class);
+        Host host = service.getById(this.hostId);
+        if (!Cools.isEmpty(host)){
+            return String.valueOf(host.getName());
+        }
+        return null;
+    }
+
+
+}
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/mapper/BasShuttleMapper.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/mapper/BasShuttleMapper.java
new file mode 100644
index 0000000..c54c789
--- /dev/null
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/mapper/BasShuttleMapper.java
@@ -0,0 +1,12 @@
+package com.zy.asrs.wcs.core.mapper;
+
+import com.zy.asrs.wcs.core.entity.BasShuttle;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+import org.springframework.stereotype.Repository;
+
+@Mapper
+@Repository
+public interface BasShuttleMapper extends BaseMapper<BasShuttle> {
+
+}
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/service/BasShuttleService.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/service/BasShuttleService.java
new file mode 100644
index 0000000..a44aff8
--- /dev/null
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/service/BasShuttleService.java
@@ -0,0 +1,8 @@
+package com.zy.asrs.wcs.core.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.zy.asrs.wcs.core.entity.BasShuttle;
+
+public interface BasShuttleService extends IService<BasShuttle> {
+
+}
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/service/impl/BasShuttleServiceImpl.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/service/impl/BasShuttleServiceImpl.java
new file mode 100644
index 0000000..b9ca124
--- /dev/null
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/service/impl/BasShuttleServiceImpl.java
@@ -0,0 +1,12 @@
+package com.zy.asrs.wcs.core.service.impl;
+
+import com.zy.asrs.wcs.core.mapper.BasShuttleMapper;
+import com.zy.asrs.wcs.core.entity.BasShuttle;
+import com.zy.asrs.wcs.core.service.BasShuttleService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+@Service("basShuttleService")
+public class BasShuttleServiceImpl extends ServiceImpl<BasShuttleMapper, BasShuttle> implements BasShuttleService {
+
+}
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/utils/NavigateMapUtils.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/utils/NavigateMapUtils.java
index 396260b..00a447e 100644
--- a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/utils/NavigateMapUtils.java
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/utils/NavigateMapUtils.java
@@ -1,93 +1,93 @@
-//package com.zy.asrs.wcs.core.utils;
-//
-//import com.alibaba.fastjson.JSON;
-//import com.zy.asrs.common.wms.entity.BasMap;
-//import com.zy.asrs.framework.common.SpringUtils;
-//import com.zy.asrs.wcs.core.model.MapNode;
-//import com.zy.asrs.wcs.core.model.NavigateNode;
-//import com.zy.asrs.wcs.core.model.enums.NavigationMapType;
-//import com.zy.asrs.wcs.rcs.constant.DeviceRedisConstant;
-//import org.springframework.stereotype.Component;
-//
-//import java.util.ArrayList;
-//import java.util.Date;
-//import java.util.List;
-//
-//@Component
-//public class NavigateMapUtils {
-//
-//    /**
-//     * 鍐欏叆璺緞鑺傜偣鏁版嵁鍒皉edis鍦板浘涓�
-//     * lock涓簍rue 绂佺敤搴撲綅锛宭ock涓篺alse鎭㈠搴撲綅
-//     */
-//    public synchronized boolean writeNavigateNodeToRedisMap(Integer lev, Integer shuttleNo, List<NavigateNode> nodes, boolean lock) {
-//        RedisUtil redisUtil = SpringUtils.getBean(RedisUtil.class);
-//        try {
-//            if (nodes.isEmpty()) {
-//                return true;
-//            }
-//
-//            NavigateMapData navigateMapData = new NavigateMapData(lev);
-//
-//            Object o = redisUtil.get(DeviceRedisConstant.MAP + lev);
-//            if (o == null) {
-//                return false;
-//            }
-//
-//            //鑾峰彇灏忚溅鑺傜偣
-//            List<int[]> shuttlePoints = Utils.getShuttlePoints(shuttleNo, lev);
-//
-//            BasMap basMap = JSON.parseObject(o.toString(), BasMap.class);
-//            ArrayList arrayList = JSON.parseObject(basMap.getData(), ArrayList.class);
-//            //甯﹀皬杞﹀湴鍥�
-//            List<List<MapNode>> listsHasShuttle = navigateMapData.filterMap(NavigationMapType.NONE.id, arrayList, lev, null, shuttlePoints);//鑾峰彇甯﹀皬杞﹀湴鍥炬暟鎹�
-//            List<List<MapNode>> lists = navigateMapData.filterMap(NavigationMapType.NONE.id, arrayList, lev, null, null);//鑾峰彇鍏ㄩ儴鍦板浘鏁版嵁
-//
-//            //妫�娴嬭矾寰勬槸鍚﹁閿佸畾
-//            if (lock) {
-//                for (NavigateNode node : nodes) {
-//                    List<MapNode> listX = listsHasShuttle.get(node.getX());
-//                    MapNode mapNode = listX.get(node.getY());
-//                    if (mapNode.getValue() == -999) {
-//                        return false;//璺緞琚攣瀹氳繃锛岀姝㈠啀娆¢攣瀹�
-//                    }
-//                    if (mapNode.getValue() == 66) {
-//                        return false;//璺緞瀛樺湪灏忚溅锛岀姝㈤攣瀹�
-//                    }
-//                }
-//            }
-//
-//            //灏濊瘯閿佸畾/瑙i攣璺緞
-//            NavigateMapData mapData = new NavigateMapData(nodes.get(0).getZ());
-//            List<List<MapNode>> realMap = mapData.getJsonData(-1, null, null);//鑾峰彇瀹屾暣鍦板浘(鍖呮嫭鍏ュ簱鍑哄簱)
-//            for (NavigateNode node : nodes) {
-//                if (node.getZ() != lev) {
-//                    continue;
-//                }
-//
-//                List<MapNode> listX = lists.get(node.getX());
-//                MapNode mapNode = listX.get(node.getY());
-//                if (lock) {
-//                    mapNode.setValue(-999);//绂佺敤搴撲綅
-//                } else {
-//                    //鑾峰彇鍘熷鑺傜偣鏁版嵁
-//                    List<MapNode> rows = realMap.get(node.getX());
-//                    MapNode col = rows.get(node.getY());
-//                    mapNode.setValue(col.getValue());//鎭㈠搴撲綅
-//                }
-//
-//                listX.set(node.getY(), mapNode);
-//                lists.set(node.getX(), listX);
-//            }
-//            basMap.setData(JSON.toJSONString(lists));
-//            basMap.setUpdateTime(new Date());
-//            //灏嗘暟鎹簱鍦板浘鏁版嵁瀛樺叆redis
-//            redisUtil.set(DeviceRedisConstant.MAP + lev, JSON.toJSONString(basMap));
-//            return true;
-//        } catch (Exception e) {
-//            e.printStackTrace();
-//        }
-//        return false;
-//    }
-//
-//}
+package com.zy.asrs.wcs.core.utils;
+
+import com.alibaba.fastjson.JSON;
+import com.zy.asrs.common.wms.entity.BasMap;
+import com.zy.asrs.framework.common.SpringUtils;
+import com.zy.asrs.wcs.core.model.MapNode;
+import com.zy.asrs.wcs.core.model.NavigateNode;
+import com.zy.asrs.wcs.core.model.enums.NavigationMapType;
+import com.zy.asrs.wcs.rcs.constant.DeviceRedisConstant;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+@Component
+public class NavigateMapUtils {
+
+    /**
+     * 鍐欏叆璺緞鑺傜偣鏁版嵁鍒皉edis鍦板浘涓�
+     * lock涓簍rue 绂佺敤搴撲綅锛宭ock涓篺alse鎭㈠搴撲綅
+     */
+    public synchronized boolean writeNavigateNodeToRedisMap(Integer lev, Integer shuttleNo, List<NavigateNode> nodes, boolean lock) {
+        RedisUtil redisUtil = SpringUtils.getBean(RedisUtil.class);
+        try {
+            if (nodes.isEmpty()) {
+                return true;
+            }
+
+            NavigateMapData navigateMapData = new NavigateMapData(lev);
+
+            Object o = redisUtil.get(DeviceRedisConstant.MAP + lev);
+            if (o == null) {
+                return false;
+            }
+
+            //鑾峰彇灏忚溅鑺傜偣
+            List<int[]> shuttlePoints = Utils.getShuttlePoints(shuttleNo, lev);
+
+            BasMap basMap = JSON.parseObject(o.toString(), BasMap.class);
+            ArrayList arrayList = JSON.parseObject(basMap.getData(), ArrayList.class);
+            //甯﹀皬杞﹀湴鍥�
+            List<List<MapNode>> listsHasShuttle = navigateMapData.filterMap(NavigationMapType.NONE.id, arrayList, lev, null, shuttlePoints);//鑾峰彇甯﹀皬杞﹀湴鍥炬暟鎹�
+            List<List<MapNode>> lists = navigateMapData.filterMap(NavigationMapType.NONE.id, arrayList, lev, null, null);//鑾峰彇鍏ㄩ儴鍦板浘鏁版嵁
+
+            //妫�娴嬭矾寰勬槸鍚﹁閿佸畾
+            if (lock) {
+                for (NavigateNode node : nodes) {
+                    List<MapNode> listX = listsHasShuttle.get(node.getX());
+                    MapNode mapNode = listX.get(node.getY());
+                    if (mapNode.getValue() == -999) {
+                        return false;//璺緞琚攣瀹氳繃锛岀姝㈠啀娆¢攣瀹�
+                    }
+                    if (mapNode.getValue() == 66) {
+                        return false;//璺緞瀛樺湪灏忚溅锛岀姝㈤攣瀹�
+                    }
+                }
+            }
+
+            //灏濊瘯閿佸畾/瑙i攣璺緞
+            NavigateMapData mapData = new NavigateMapData(nodes.get(0).getZ());
+            List<List<MapNode>> realMap = mapData.getJsonData(-1, null, null);//鑾峰彇瀹屾暣鍦板浘(鍖呮嫭鍏ュ簱鍑哄簱)
+            for (NavigateNode node : nodes) {
+                if (node.getZ() != lev) {
+                    continue;
+                }
+
+                List<MapNode> listX = lists.get(node.getX());
+                MapNode mapNode = listX.get(node.getY());
+                if (lock) {
+                    mapNode.setValue(-999);//绂佺敤搴撲綅
+                } else {
+                    //鑾峰彇鍘熷鑺傜偣鏁版嵁
+                    List<MapNode> rows = realMap.get(node.getX());
+                    MapNode col = rows.get(node.getY());
+                    mapNode.setValue(col.getValue());//鎭㈠搴撲綅
+                }
+
+                listX.set(node.getY(), mapNode);
+                lists.set(node.getX(), listX);
+            }
+            basMap.setData(JSON.toJSONString(lists));
+            basMap.setUpdateTime(new Date());
+            //灏嗘暟鎹簱鍦板浘鏁版嵁瀛樺叆redis
+            redisUtil.set(DeviceRedisConstant.MAP + lev, JSON.toJSONString(basMap));
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return false;
+    }
+
+}
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/utils/Utils.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/utils/Utils.java
new file mode 100644
index 0000000..81dae25
--- /dev/null
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/utils/Utils.java
@@ -0,0 +1,41 @@
+package com.zy.asrs.wcs.core.utils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Utils {
+
+    //鑾峰彇闄ょ櫧鍚嶅崟澶栫殑鎸囧畾妤煎眰鍏ㄩ儴绌挎杞y鍧愭爣鐐�
+    public static List<int[]> getShuttlePoints(Integer whiteShuttle, Integer lev) {
+//        SlaveProperties slaveProperties = SpringUtils.getBean(SlaveProperties.class);
+        ArrayList<int[]> list = new ArrayList<>();
+//        for (ShuttleSlave slave : slaveProperties.getShuttle()) {
+//            if (slave.getId().intValue() == whiteShuttle) {
+//                continue;//璺宠繃鐧藉悕鍗�
+//            }
+//
+//            //鑾峰彇绌挎杞︽墍鍦ㄨ妭鐐逛綅缃�
+//            ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, slave.getId());
+//            if (shuttleThread == null) {
+//                continue;
+//            }
+//            ShuttleProtocol shuttleProtocol = shuttleThread.getShuttleProtocol();
+//            if (shuttleProtocol == null) {
+//                continue;
+//            }
+//
+//            if (shuttleProtocol.getCurrentLocNo() == null) {
+//                continue;
+//            }
+//
+//            if (lev != Utils.getLev(shuttleProtocol.getCurrentLocNo())) {
+//                continue;//妤煎眰涓嶅悓
+//            }
+//
+//            int[] xyPosition = NavigatePositionConvert.positionToXY(shuttleProtocol.getCurrentLocNo());//閫氳繃搴撲綅鍙疯幏鍙杧y鍧愭爣
+//            list.add(xyPosition);
+//        }
+        return list;
+    }
+
+}
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/controller/DeviceController.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/controller/DeviceController.java
index b77ded9..03ed55f 100644
--- a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/controller/DeviceController.java
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/controller/DeviceController.java
@@ -1,4 +1,4 @@
-package com.zy.asrs.wcs.system.controller;
+package com.zy.asrs.wcs.rcs.controller;
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -11,6 +11,7 @@
 import com.zy.asrs.wcs.common.domain.PageParam;
 import com.zy.asrs.wcs.rcs.entity.Device;
 import com.zy.asrs.wcs.rcs.service.DeviceService;
+import com.zy.asrs.wcs.system.controller.BaseController;
 import com.zy.asrs.wcs.utils.ExcelUtil;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/controller/DevicePlcController.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/controller/DevicePlcController.java
index dd9e247..3b5d75d 100644
--- a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/controller/DevicePlcController.java
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/controller/DevicePlcController.java
@@ -1,4 +1,4 @@
-package com.zy.asrs.wcs.system.controller;
+package com.zy.asrs.wcs.rcs.controller;
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -10,6 +10,7 @@
 import com.zy.asrs.wcs.common.domain.PageParam;
 import com.zy.asrs.wcs.rcs.entity.DevicePlc;
 import com.zy.asrs.wcs.rcs.service.DevicePlcService;
+import com.zy.asrs.wcs.system.controller.BaseController;
 import com.zy.asrs.wcs.utils.ExcelUtil;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/controller/DeviceTypeController.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/controller/DeviceTypeController.java
index 18ef7c7..cffae7d 100644
--- a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/controller/DeviceTypeController.java
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/controller/DeviceTypeController.java
@@ -1,4 +1,4 @@
-package com.zy.asrs.wcs.system.controller;
+package com.zy.asrs.wcs.rcs.controller;
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -10,6 +10,7 @@
 import com.zy.asrs.wcs.common.domain.PageParam;
 import com.zy.asrs.wcs.rcs.entity.DeviceType;
 import com.zy.asrs.wcs.rcs.service.DeviceTypeService;
+import com.zy.asrs.wcs.system.controller.BaseController;
 import com.zy.asrs.wcs.utils.ExcelUtil;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/controller/MotionController.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/controller/MotionController.java
new file mode 100644
index 0000000..7e4227c
--- /dev/null
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/controller/MotionController.java
@@ -0,0 +1,102 @@
+package com.zy.asrs.wcs.rcs.controller;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.zy.asrs.framework.common.Cools;
+import com.zy.asrs.framework.common.R;
+import com.zy.asrs.wcs.common.annotation.OperationLog;
+import com.zy.asrs.wcs.common.domain.BaseParam;
+import com.zy.asrs.wcs.common.domain.KeyValVo;
+import com.zy.asrs.wcs.common.domain.PageParam;
+import com.zy.asrs.wcs.rcs.entity.Motion;
+import com.zy.asrs.wcs.rcs.service.MotionService;
+import com.zy.asrs.wcs.system.controller.BaseController;
+import com.zy.asrs.wcs.utils.ExcelUtil;
+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.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+@RestController
+@RequestMapping("/api")
+public class MotionController extends BaseController {
+
+    @Autowired
+    private MotionService motionService;
+
+    @PreAuthorize("hasAuthority('rcs:motion:list')")
+    @PostMapping("/motion/page")
+    public R page(@RequestBody Map<String, Object> map) {
+        BaseParam baseParam = buildParam(map, BaseParam.class);
+        PageParam<Motion, BaseParam> pageParam = new PageParam<>(baseParam, Motion.class);
+        return R.ok().add(motionService.page(pageParam, pageParam.buildWrapper(true)));
+    }
+
+    @PreAuthorize("hasAuthority('rcs:motion:list')")
+    @PostMapping("/motion/list")
+    public R list(@RequestBody Map<String, Object> map) {
+        return R.ok().add(motionService.list());
+    }
+
+    @PreAuthorize("hasAuthority('rcs:motion:list')")
+    @GetMapping("/motion/{id}")
+    public R get(@PathVariable("id") Long id) {
+        return R.ok().add(motionService.getById(id));
+    }
+
+    @PreAuthorize("hasAuthority('rcs:motion:save')")
+    @OperationLog("娣诲姞Motion鍒楄〃")
+    @PostMapping("/motion/save")
+    public R save(@RequestBody Motion motion) {
+        if (!motionService.save(motion)) {
+            return R.error("娣诲姞澶辫触");
+        }
+        return R.ok("娣诲姞鎴愬姛");
+    }
+
+    @PreAuthorize("hasAuthority('rcs:motion:update')")
+    @OperationLog("淇敼Motion鍒楄〃")
+    @PostMapping("/motion/update")
+    public R update(@RequestBody Motion motion) {
+        if (!motionService.updateById(motion)) {
+            return R.error("淇敼澶辫触");
+        }
+        return R.ok("淇敼鎴愬姛");
+    }
+
+    @PreAuthorize("hasAuthority('rcs:motion:remove')")
+    @OperationLog("鍒犻櫎Motion鍒楄〃")
+    @PostMapping("/motion/remove/{ids}")
+    public R remove(@PathVariable Long[] ids) {
+        if (!motionService.removeByIds(Arrays.asList(ids))) {
+            return R.error("鍒犻櫎澶辫触");
+        }
+        return R.ok("鍒犻櫎鎴愬姛");
+    }
+
+    @PreAuthorize("hasAuthority('rcs:motion:list')")
+    @PostMapping("/motion/query")
+    public R query(@RequestParam(required = false) String condition) {
+        List<KeyValVo> vos = new ArrayList<>();
+        LambdaQueryWrapper<Motion> wrapper = new LambdaQueryWrapper<>();
+        if (!Cools.isEmpty(condition)) {
+            wrapper.like(Motion::getSerialNo, condition);
+        }
+        motionService.page(new Page<>(1, 30), wrapper).getRecords().forEach(
+                item -> vos.add(new KeyValVo(item.getId(), item.getSerialNo()))
+        );
+        return R.ok().add(vos);
+    }
+
+    @PreAuthorize("hasAuthority('rcs:motion:list')")
+    @PostMapping("/motion/export")
+    public void export(@RequestBody Map<String, Object> map, HttpServletResponse response) throws Exception {
+        ExcelUtil.build(ExcelUtil.create(motionService.list(), Motion.class), response);
+    }
+
+}
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/controller/MotionCtgController.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/controller/MotionCtgController.java
index afd4cdf..eb1761a 100644
--- a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/controller/MotionCtgController.java
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/controller/MotionCtgController.java
@@ -1,4 +1,4 @@
-package com.zy.asrs.wcs.system.controller;
+package com.zy.asrs.wcs.rcs.controller;
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -10,6 +10,7 @@
 import com.zy.asrs.wcs.common.domain.PageParam;
 import com.zy.asrs.wcs.rcs.entity.MotionCtg;
 import com.zy.asrs.wcs.rcs.service.MotionCtgService;
+import com.zy.asrs.wcs.system.controller.BaseController;
 import com.zy.asrs.wcs.utils.ExcelUtil;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/controller/MotionStsController.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/controller/MotionStsController.java
index 28d1711..1c4cce3 100644
--- a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/controller/MotionStsController.java
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/controller/MotionStsController.java
@@ -1,4 +1,4 @@
-package com.zy.asrs.wcs.system.controller;
+package com.zy.asrs.wcs.rcs.controller;
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -10,6 +10,7 @@
 import com.zy.asrs.wcs.common.domain.PageParam;
 import com.zy.asrs.wcs.rcs.entity.MotionSts;
 import com.zy.asrs.wcs.rcs.service.MotionStsService;
+import com.zy.asrs.wcs.system.controller.BaseController;
 import com.zy.asrs.wcs.utils.ExcelUtil;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/controller/ShuttleDeviceStatusController.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/controller/ShuttleDeviceStatusController.java
index 5d8329a..cc0b3dc 100644
--- a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/controller/ShuttleDeviceStatusController.java
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/controller/ShuttleDeviceStatusController.java
@@ -1,4 +1,4 @@
-package com.zy.asrs.wcs.system.controller;
+package com.zy.asrs.wcs.rcs.controller;
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -10,6 +10,7 @@
 import com.zy.asrs.wcs.common.domain.PageParam;
 import com.zy.asrs.wcs.rcs.entity.ShuttleDeviceStatus;
 import com.zy.asrs.wcs.rcs.service.ShuttleDeviceStatusService;
+import com.zy.asrs.wcs.system.controller.BaseController;
 import com.zy.asrs.wcs.utils.ExcelUtil;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/entity/Motion.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/entity/Motion.java
new file mode 100644
index 0000000..1b895ad
--- /dev/null
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/entity/Motion.java
@@ -0,0 +1,440 @@
+package com.zy.asrs.wcs.rcs.entity;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import com.zy.asrs.wcs.rcs.service.DeviceTypeService;
+import com.zy.asrs.wcs.rcs.service.MotionCtgService;
+import com.zy.asrs.wcs.rcs.service.MotionStsService;
+import com.zy.asrs.wcs.system.entity.Host;
+import com.zy.asrs.wcs.system.entity.User;
+import org.springframework.format.annotation.DateTimeFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import com.baomidou.mybatisplus.annotation.TableLogic;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import com.zy.asrs.framework.common.Cools;
+import com.zy.asrs.framework.common.SpringUtils;
+import com.zy.asrs.wcs.system.service.UserService;
+import com.zy.asrs.wcs.system.service.HostService;
+
+import java.io.Serializable;
+import java.util.Date;
+
+@Data
+@TableName("rcs_motion")
+public class Motion implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * ID
+     */
+    @ApiModelProperty(value= "ID")
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+
+    /**
+     * 缂栧彿
+     */
+    @ApiModelProperty(value= "缂栧彿")
+    private String uuid;
+
+    /**
+     * 浠诲姟鍙�
+     */
+    @ApiModelProperty(value= "浠诲姟鍙�")
+    private Integer wrkNo;
+
+    /**
+     * 搴忓垪鍙�
+     */
+    @ApiModelProperty(value= "搴忓垪鍙�")
+    private String serialNo;
+
+    /**
+     * 鎻忚堪
+     */
+    @ApiModelProperty(value= "鎻忚堪")
+    private String title;
+
+    /**
+     * 浼樺厛绾�
+     */
+    @ApiModelProperty(value= "浼樺厛绾�")
+    private Integer priority;
+
+    /**
+     * 鍚屾 1: 鏄�  0: 鍚�  
+     */
+    @ApiModelProperty(value= "鍚屾 1: 鏄�  0: 鍚�  ")
+    private Integer sync;
+
+    /**
+     * 浠诲姟绫诲瀷
+     */
+    @ApiModelProperty(value= "浠诲姟绫诲瀷")
+    private Long motionCtg;
+
+    /**
+     * 浠诲姟鐘舵��
+     */
+    @ApiModelProperty(value= "浠诲姟鐘舵��")
+    private Long motionSts;
+
+    /**
+     * 璁惧绫诲瀷
+     */
+    @ApiModelProperty(value= "璁惧绫诲瀷")
+    private Long deviceType;
+
+    /**
+     * 璁惧
+     */
+    @ApiModelProperty(value= "璁惧")
+    private String device;
+
+    /**
+     * 鏉ユ簮
+     */
+    @ApiModelProperty(value= "鏉ユ簮")
+    private String origin;
+
+    /**
+     * 鏉ユ簮鏂瑰悜
+     */
+    @ApiModelProperty(value= "鏉ユ簮鏂瑰悜")
+    private Integer oriDrt;
+
+    /**
+     * 鐩爣
+     */
+    @ApiModelProperty(value= "鐩爣")
+    private String target;
+
+    /**
+     * 鐩爣鏂瑰悜
+     */
+    @ApiModelProperty(value= "鐩爣鏂瑰悜")
+    private Integer tarDrt;
+
+    /**
+     * 瀵规帴璁惧
+     */
+    @ApiModelProperty(value= "瀵规帴璁惧")
+    private String dockNo;
+
+    /**
+     * 宸ヤ綔鏃堕棿
+     */
+    @ApiModelProperty(value= "宸ヤ綔鏃堕棿")
+    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
+    private Date ioTime;
+
+    /**
+     * 寮�濮嬫椂闂�
+     */
+    @ApiModelProperty(value= "寮�濮嬫椂闂�")
+    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
+    private Date startTime;
+
+    /**
+     * 缁撴潫鏃堕棿
+     */
+    @ApiModelProperty(value= "缁撴潫鏃堕棿")
+    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
+    private Date endTime;
+
+    /**
+     * 寮傚父鏃堕棿
+     */
+    @ApiModelProperty(value= "寮傚父鏃堕棿")
+    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
+    private Date errTime;
+
+    /**
+     * 寮傚父浠g爜
+     */
+    @ApiModelProperty(value= "寮傚父浠g爜")
+    private Long errCode;
+
+    /**
+     * 寮傚父鎻忚堪
+     */
+    @ApiModelProperty(value= "寮傚父鎻忚堪")
+    private String errDesc;
+
+    /**
+     * 棰勭暀
+     */
+    @ApiModelProperty(value= "棰勭暀")
+    private String temp;
+
+    /**
+     * 鐘舵�� 1: 姝e父  0: 绂佺敤  
+     */
+    @ApiModelProperty(value= "鐘舵�� 1: 姝e父  0: 绂佺敤  ")
+    private Integer status;
+
+    /**
+     * 娣诲姞浜哄憳
+     */
+    @ApiModelProperty(value= "娣诲姞浜哄憳")
+    private Long createBy;
+
+    /**
+     * 娣诲姞鏃堕棿
+     */
+    @ApiModelProperty(value= "娣诲姞鏃堕棿")
+    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
+    private Date createTime;
+
+    /**
+     * 淇敼浜哄憳
+     */
+    @ApiModelProperty(value= "淇敼浜哄憳")
+    private Long updateBy;
+
+    /**
+     * 淇敼鏃堕棿
+     */
+    @ApiModelProperty(value= "淇敼鏃堕棿")
+    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
+    private Date updateTime;
+
+    /**
+     * 澶囨敞
+     */
+    @ApiModelProperty(value= "澶囨敞")
+    private String memo;
+
+    /**
+     * 鏄惁鍒犻櫎 1: 鏄�  0: 鍚�  
+     */
+    @ApiModelProperty(value= "鏄惁鍒犻櫎 1: 鏄�  0: 鍚�  ")
+    @TableLogic
+    private Integer deleted;
+
+    /**
+     * 鎵�灞炴満鏋�
+     */
+    @ApiModelProperty(value= "鎵�灞炴満鏋�")
+    private Long hostId;
+
+    public Motion() {}
+
+    public Motion(String uuid,Integer wrkNo,String serialNo,String title,Integer priority,Integer sync,Long motionCtg,Long motionSts,Long deviceType,String device,String origin,Integer oriDrt,String target,Integer tarDrt,String dockNo,Date ioTime,Date startTime,Date endTime,Date errTime,Long errCode,String errDesc,String temp,Integer status,Long createBy,Date createTime,Long updateBy,Date updateTime,String memo,Integer deleted,Long hostId) {
+        this.uuid = uuid;
+        this.wrkNo = wrkNo;
+        this.serialNo = serialNo;
+        this.title = title;
+        this.priority = priority;
+        this.sync = sync;
+        this.motionCtg = motionCtg;
+        this.motionSts = motionSts;
+        this.deviceType = deviceType;
+        this.device = device;
+        this.origin = origin;
+        this.oriDrt = oriDrt;
+        this.target = target;
+        this.tarDrt = tarDrt;
+        this.dockNo = dockNo;
+        this.ioTime = ioTime;
+        this.startTime = startTime;
+        this.endTime = endTime;
+        this.errTime = errTime;
+        this.errCode = errCode;
+        this.errDesc = errDesc;
+        this.temp = temp;
+        this.status = status;
+        this.createBy = createBy;
+        this.createTime = createTime;
+        this.updateBy = updateBy;
+        this.updateTime = updateTime;
+        this.memo = memo;
+        this.deleted = deleted;
+        this.hostId = hostId;
+    }
+
+//    Motion motion = new Motion(
+//            null,    // 缂栧彿
+//            null,    // 浠诲姟鍙�
+//            null,    // 搴忓垪鍙�
+//            null,    // 鎻忚堪
+//            null,    // 浼樺厛绾�
+//            null,    // 鍚屾[闈炵┖]
+//            null,    // 浠诲姟绫诲瀷[闈炵┖]
+//            null,    // 浠诲姟鐘舵�乕闈炵┖]
+//            null,    // 璁惧绫诲瀷
+//            null,    // 璁惧
+//            null,    // 鏉ユ簮
+//            null,    // 鏉ユ簮鏂瑰悜
+//            null,    // 鐩爣
+//            null,    // 鐩爣鏂瑰悜
+//            null,    // 瀵规帴璁惧
+//            null,    // 宸ヤ綔鏃堕棿
+//            null,    // 寮�濮嬫椂闂�
+//            null,    // 缁撴潫鏃堕棿
+//            null,    // 寮傚父鏃堕棿
+//            null,    // 寮傚父浠g爜
+//            null,    // 寮傚父鎻忚堪
+//            null,    // 棰勭暀
+//            null,    // 鐘舵��
+//            null,    // 娣诲姞浜哄憳
+//            null,    // 娣诲姞鏃堕棿
+//            null,    // 淇敼浜哄憳
+//            null,    // 淇敼鏃堕棿
+//            null,    // 澶囨敞
+//            null,    // 鏄惁鍒犻櫎
+//            null    // 鎵�灞炴満鏋�
+//    );
+
+    public String getSync$(){
+        if (null == this.sync){ return null; }
+        switch (this.sync){
+            case 1:
+                return "鏄�";
+            case 0:
+                return "鍚�";
+            default:
+                return String.valueOf(this.sync);
+        }
+    }
+
+    public String getMotionCtg$(){
+        MotionCtgService service = SpringUtils.getBean(MotionCtgService.class);
+        MotionCtg motionCtg = service.getById(this.motionCtg);
+        if (!Cools.isEmpty(motionCtg)){
+            return String.valueOf(motionCtg.getName());
+        }
+        return null;
+    }
+
+    public String getMotionSts$(){
+        MotionStsService service = SpringUtils.getBean(MotionStsService.class);
+        MotionSts motionSts = service.getById(this.motionSts);
+        if (!Cools.isEmpty(motionSts)){
+            return String.valueOf(motionSts.getName());
+        }
+        return null;
+    }
+
+    public String getDeviceType$(){
+        DeviceTypeService service = SpringUtils.getBean(DeviceTypeService.class);
+        DeviceType deviceType = service.getById(this.deviceType);
+        if (!Cools.isEmpty(deviceType)){
+            return String.valueOf(deviceType.getName());
+        }
+        return null;
+    }
+
+    public String getIoTime$(){
+        if (Cools.isEmpty(this.ioTime)){
+            return "";
+        }
+        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.ioTime);
+    }
+
+    public String getStartTime$(){
+        if (Cools.isEmpty(this.startTime)){
+            return "";
+        }
+        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.startTime);
+    }
+
+    public String getEndTime$(){
+        if (Cools.isEmpty(this.endTime)){
+            return "";
+        }
+        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.endTime);
+    }
+
+    public String getErrTime$(){
+        if (Cools.isEmpty(this.errTime)){
+            return "";
+        }
+        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.errTime);
+    }
+
+    public String getStatus$(){
+        if (null == this.status){ return null; }
+        switch (this.status){
+            case 1:
+                return "姝e父";
+            case 0:
+                return "绂佺敤";
+            default:
+                return String.valueOf(this.status);
+        }
+    }
+
+    public String getCreateBy$(){
+        UserService service = SpringUtils.getBean(UserService.class);
+        User user = service.getById(this.createBy);
+        if (!Cools.isEmpty(user)){
+            return String.valueOf(user.getNickname());
+        }
+        return null;
+    }
+
+    public String getCreateTime$(){
+        if (Cools.isEmpty(this.createTime)){
+            return "";
+        }
+        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.createTime);
+    }
+
+    public String getUpdateBy$(){
+        UserService service = SpringUtils.getBean(UserService.class);
+        User user = service.getById(this.updateBy);
+        if (!Cools.isEmpty(user)){
+            return String.valueOf(user.getNickname());
+        }
+        return null;
+    }
+
+    public String getUpdateTime$(){
+        if (Cools.isEmpty(this.updateTime)){
+            return "";
+        }
+        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.updateTime);
+    }
+
+    public String getDeleted$(){
+        if (null == this.deleted){ return null; }
+        switch (this.deleted){
+            case 1:
+                return "鏄�";
+            case 0:
+                return "鍚�";
+            default:
+                return String.valueOf(this.deleted);
+        }
+    }
+
+    public String getHostId$(){
+        HostService service = SpringUtils.getBean(HostService.class);
+        Host host = service.getById(this.hostId);
+        if (!Cools.isEmpty(host)){
+            return String.valueOf(host.getName());
+        }
+        return null;
+    }
+
+
+}
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/mapper/MotionMapper.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/mapper/MotionMapper.java
new file mode 100644
index 0000000..45d4aac
--- /dev/null
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/mapper/MotionMapper.java
@@ -0,0 +1,12 @@
+package com.zy.asrs.wcs.rcs.mapper;
+
+import com.zy.asrs.wcs.rcs.entity.Motion;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+import org.springframework.stereotype.Repository;
+
+@Mapper
+@Repository
+public interface MotionMapper extends BaseMapper<Motion> {
+
+}
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/service/MotionService.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/service/MotionService.java
new file mode 100644
index 0000000..5b20073
--- /dev/null
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/service/MotionService.java
@@ -0,0 +1,8 @@
+package com.zy.asrs.wcs.rcs.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.zy.asrs.wcs.rcs.entity.Motion;
+
+public interface MotionService extends IService<Motion> {
+
+}
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/service/impl/MotionServiceImpl.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/service/impl/MotionServiceImpl.java
new file mode 100644
index 0000000..3180bb0
--- /dev/null
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/service/impl/MotionServiceImpl.java
@@ -0,0 +1,12 @@
+package com.zy.asrs.wcs.rcs.service.impl;
+
+import com.zy.asrs.wcs.rcs.mapper.MotionMapper;
+import com.zy.asrs.wcs.rcs.entity.Motion;
+import com.zy.asrs.wcs.rcs.service.MotionService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+@Service("motionService")
+public class MotionServiceImpl extends ServiceImpl<MotionMapper, Motion> implements MotionService {
+
+}
diff --git a/zy-asrs-wcs/src/main/java/motionCtg.sql b/zy-asrs-wcs/src/main/java/motionCtg.sql
deleted file mode 100644
index 2911274..0000000
--- a/zy-asrs-wcs/src/main/java/motionCtg.sql
+++ /dev/null
@@ -1,9 +0,0 @@
--- save motionCtg record
--- mysql
-insert into `sys_menu` ( `name`, `parent_id`, `route`, `component`, `type`, `sort`, `host_id`, `status`) values ( 'Motion鏍囪绠$悊', '0', '/rcs/motionCtg', '/rcs/motionCtg', '0' , '0', '1' , '1');
-
-insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `host_id`, `status`) values ( '鏌ヨMotion鏍囪', '', '1', 'rcs:motionCtg:list', '0', '1', '1');
-insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `host_id`, `status`) values ( '娣诲姞Motion鏍囪', '', '1', 'rcs:motionCtg:save', '1', '1', '1');
-insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `host_id`, `status`) values ( '淇敼Motion鏍囪', '', '1', 'rcs:motionCtg:update', '2', '1', '1');
-insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `host_id`, `status`) values ( '鍒犻櫎Motion鏍囪', '', '1', 'rcs:motionCtg:remove', '3', '1', '1');
-
diff --git a/zy-asrs-wcs/src/main/java/motionSts.sql b/zy-asrs-wcs/src/main/java/motionSts.sql
deleted file mode 100644
index bbaf6f5..0000000
--- a/zy-asrs-wcs/src/main/java/motionSts.sql
+++ /dev/null
@@ -1,9 +0,0 @@
--- save motionSts record
--- mysql
-insert into `sys_menu` ( `name`, `parent_id`, `route`, `component`, `type`, `sort`, `host_id`, `status`) values ( 'Motion鐘舵�佺鐞�', '0', '/rcs/motionSts', '/rcs/motionSts', '0' , '0', '1' , '1');
-
-insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `host_id`, `status`) values ( '鏌ヨMotion鐘舵��', '', '1', 'rcs:motionSts:list', '0', '1', '1');
-insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `host_id`, `status`) values ( '娣诲姞Motion鐘舵��', '', '1', 'rcs:motionSts:save', '1', '1', '1');
-insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `host_id`, `status`) values ( '淇敼Motion鐘舵��', '', '1', 'rcs:motionSts:update', '2', '1', '1');
-insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `host_id`, `status`) values ( '鍒犻櫎Motion鐘舵��', '', '1', 'rcs:motionSts:remove', '3', '1', '1');
-
diff --git a/zy-asrs-wcs/src/main/resources/mapper/core/BasShuttleMapper.xml b/zy-asrs-wcs/src/main/resources/mapper/core/BasShuttleMapper.xml
new file mode 100644
index 0000000..e46e153
--- /dev/null
+++ b/zy-asrs-wcs/src/main/resources/mapper/core/BasShuttleMapper.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.zy.asrs.wcs.core.mapper.BasShuttleMapper">
+
+</mapper>
diff --git a/zy-asrs-wcs/src/main/resources/mapper/rcs/MotionMapper.xml b/zy-asrs-wcs/src/main/resources/mapper/rcs/MotionMapper.xml
new file mode 100644
index 0000000..15a23bb
--- /dev/null
+++ b/zy-asrs-wcs/src/main/resources/mapper/rcs/MotionMapper.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.zy.asrs.wcs.rcs.mapper.MotionMapper">
+
+</mapper>

--
Gitblit v1.9.1