From e49208f2514ccf950164a2d6d590d85f7cecb46a Mon Sep 17 00:00:00 2001
From: Junjie <540245094@qq.com>
Date: 星期五, 07 六月 2024 16:26:28 +0800
Subject: [PATCH] #

---
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/service/BasLedService.java                  |    8 
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/service/impl/MainServiceImpl.java           |  352 +++-
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/model/protocol/StaProtocol.java              |   12 
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/service/BasConveyorStaService.java          |    8 
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/thread/impl/NormalLedThread.java             |   96 +
 zy-asrs-flow/src/pages/device/basConveyor/index.jsx                                        |  477 ++++++
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/service/impl/BasLedServiceImpl.java         |   12 
 zy-asrs-wcs/src/main/resources/mapper/core/BasConveyorMapper.xml                           |    5 
 zy-asrs-wcs/src/main/resources/mapper/core/BasLedMapper.xml                                |    5 
 zy-asrs-flow/src/pages/device/basConveyorSta/index.jsx                                     |  570 +++++++
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/entity/BasConveyorSta.java                  |  323 ++++
 zy-asrs-flow/src/pages/device/shuttle/index.jsx                                            |   20 
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/entity/BasLed.java                          |  212 ++
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/controller/BasShuttleController.java        |   28 
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/service/impl/BasConveyorServiceImpl.java    |   12 
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/controller/BasConveyorController.java       |  101 +
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/mapper/BasConveyorStaMapper.java            |   12 
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/thread/LedThread.java                        |   21 
 zy-asrs-flow/src/pages/device/basLed/index.jsx                                             |  426 +++++
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/entity/BasConveyor.java                     |  234 +++
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/utils/CodeBuilder.java                           |    8 
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/service/BasConveyorService.java             |    8 
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/service/impl/BasConveyorStaServiceImpl.java |   12 
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/thread/DevpThread.java                       |    4 
 zy-asrs-flow/src/pages/system/dict/index.jsx                                               |    1 
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/controller/BasConveyorStaController.java    |  101 +
 zy-asrs-flow/src/pages/device/basConveyorSta/components/edit.jsx                           |  228 +++
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/domain/dto/MatDto.java                      |   76 +
 zy-asrs-flow/src/pages/map/drawer/shuttle/handle.jsx                                       |   19 
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/domain/dto/StaDto.java                      |   18 
 zy-asrs-wcs/src/main/resources/mapper/core/BasConveyorStaMapper.xml                        |    5 
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/mapper/BasLedMapper.java                    |   12 
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/model/enums/SlaveType.java                   |    2 
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/MainProcess.java                            |   10 
 zy-asrs-flow/src/pages/device/basLed/components/edit.jsx                                   |  160 ++
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/controller/BasLedController.java            |  101 +
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/cache/MessageQueue.java                      |   42 
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/model/enums/DeviceCtgType.java              |    1 
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/model/MessageTask.java                       |    6 
 zy-asrs-flow/src/pages/device/basConveyor/components/edit.jsx                              |  176 ++
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/action/ShuttleAction.java                   |  304 +++
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/thread/impl/SiemensDevpThread.java           |   33 
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/model/command/LedCommand.java                |   36 
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/mapper/BasConveyorMapper.java               |   12 
 44 files changed, 4,096 insertions(+), 213 deletions(-)

diff --git a/zy-asrs-flow/src/pages/device/basConveyor/components/edit.jsx b/zy-asrs-flow/src/pages/device/basConveyor/components/edit.jsx
new file mode 100644
index 0000000..f25d65d
--- /dev/null
+++ b/zy-asrs-flow/src/pages/device/basConveyor/components/edit.jsx
@@ -0,0 +1,176 @@
+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="deviceId"
+                            label="璁惧id"
+                            colProps={{ md: 12, xl: 12 }}
+                            fieldProps={{ precision: 0 }}
+                            showSearch
+                            debounceTime={300}
+                            request={async ({ keyWords }) => {
+                                const resp = await Http.doPostForm('api/device/query', { condition: keyWords });
+                                return resp.data;
+                            }}
+                        />
+                        <ProFormDigit
+                            name="conveyorNo"
+                            label="杈撻�佺嚎鍙�"
+                            colProps={{ md: 12, xl: 12 }}
+                            fieldProps={{ precision: 0 }}
+                            rules={[{ required: true }]}
+                        />
+                    </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;
+                            }}
+                        />
+                        <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()}
+                        />
+                        <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 }}
+                        />
+                        <ProFormText
+                            name="inSta"
+                            label="鍏ュ簱绔欑偣鍒楄〃"
+                            colProps={{ md: 12, xl: 12 }}
+                        />
+                    </ProForm.Group>
+                    <ProForm.Group>
+                        <ProFormText
+                            name="emptyInSta"
+                            label="绌烘澘鍏ュ簱绔欑偣鍒楄〃"
+                            colProps={{ md: 12, xl: 12 }}
+                        />
+                        <ProFormText
+                            name="pickInSta"
+                            label="鎷f枡鍏ュ簱绔欑偣鍒楄〃"
+                            colProps={{ md: 12, xl: 12 }}
+                        />
+                    </ProForm.Group>
+                    <ProForm.Group>
+                        <ProFormText
+                            name="outSta"
+                            label="鍑哄簱绔欑偣鍒楄〃"
+                            colProps={{ md: 12, xl: 12 }}
+                        />
+                        <ProFormText
+                            name="emptyOutSta"
+                            label="绌烘澘鍑哄簱绔欑偣鍒楄〃"
+                            colProps={{ md: 12, xl: 12 }}
+                        />
+                    </ProForm.Group>
+                    <ProForm.Group>
+                        <ProFormText
+                            name="pickOutSta"
+                            label="鎷f枡鍑哄簱绔欑偣鍒楄〃"
+                            colProps={{ md: 12, xl: 12 }}
+                        />
+                    </ProForm.Group>
+
+                </ProForm>
+            </Modal>
+        </>
+    )
+}
+
+export default Edit;
diff --git a/zy-asrs-flow/src/pages/device/basConveyor/index.jsx b/zy-asrs-flow/src/pages/device/basConveyor/index.jsx
new file mode 100644
index 0000000..88aeaad
--- /dev/null
+++ b/zy-asrs-flow/src/pages/device/basConveyor/index.jsx
@@ -0,0 +1,477 @@
+
+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-basConveyor';
+
+const handleSave = async (val, intl) => {
+    const hide = message.loading(intl.formatMessage({ id: 'page.adding', defaultMessage: '姝e湪娣诲姞' }));
+    try {
+        const resp = await Http.doPost('api/basConveyor/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/basConveyor/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/basConveyor/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/basConveyor/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: '璁惧id',
+            dataIndex: 'deviceId$',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            filterDropdown: (props) => <LinkFilter
+                name='deviceId'
+                major='device'
+                {...props}
+                actionRef={actionRef}
+                setSearchParam={setSearchParam}
+            />,
+        },
+        {
+            title: '杈撻�佺嚎鍙�',
+            dataIndex: 'conveyorNo',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            copyable: true,
+            filterDropdown: (props) => <TextFilter
+                name='conveyorNo'
+                {...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: '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: '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: 'inSta',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            filterDropdown: (props) => <TextFilter
+                name='inSta'
+                {...props}
+                actionRef={actionRef}
+                setSearchParam={setSearchParam}
+            />,
+        },
+        {
+            title: '绌烘澘鍏ュ簱绔欑偣鍒楄〃',
+            dataIndex: 'emptyInSta',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            filterDropdown: (props) => <TextFilter
+                name='emptyInSta'
+                {...props}
+                actionRef={actionRef}
+                setSearchParam={setSearchParam}
+            />,
+        },
+        {
+            title: '鎷f枡鍏ュ簱绔欑偣鍒楄〃',
+            dataIndex: 'pickInSta',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            filterDropdown: (props) => <TextFilter
+                name='pickInSta'
+                {...props}
+                actionRef={actionRef}
+                setSearchParam={setSearchParam}
+            />,
+        },
+        {
+            title: '鍑哄簱绔欑偣鍒楄〃',
+            dataIndex: 'outSta',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            filterDropdown: (props) => <TextFilter
+                name='outSta'
+                {...props}
+                actionRef={actionRef}
+                setSearchParam={setSearchParam}
+            />,
+        },
+        {
+            title: '绌烘澘鍑哄簱绔欑偣鍒楄〃',
+            dataIndex: 'emptyOutSta',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            filterDropdown: (props) => <TextFilter
+                name='emptyOutSta'
+                {...props}
+                actionRef={actionRef}
+                setSearchParam={setSearchParam}
+            />,
+        },
+        {
+            title: '鎷f枡鍑哄簱绔欑偣鍒楄〃',
+            dataIndex: 'pickOutSta',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            filterDropdown: (props) => <TextFilter
+                name='pickOutSta'
+                {...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="basConveyor"
+                    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/basConveyor/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/basConveyorSta/components/edit.jsx b/zy-asrs-flow/src/pages/device/basConveyorSta/components/edit.jsx
new file mode 100644
index 0000000..fa957d6
--- /dev/null
+++ b/zy-asrs-flow/src/pages/device/basConveyorSta/components/edit.jsx
@@ -0,0 +1,228 @@
+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="conveyorId"
+                            label="杈撻�佺嚎id"
+                            colProps={{ md: 12, xl: 12 }}
+                            fieldProps={{ precision: 0 }}
+                            showSearch
+                            debounceTime={300}
+                            request={async ({ keyWords }) => {
+                                const resp = await Http.doPostForm('api/basConveyor/query', { condition: keyWords });
+                                return resp.data;
+                            }}
+                        />
+                        <ProFormDigit
+                            name="conveyorNo"
+                            label="杈撻�佺嚎鍙�"
+                            colProps={{ md: 12, xl: 12 }}
+                            fieldProps={{ precision: 0 }}
+                            rules={[{ required: true }]}
+                        />
+                    </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;
+                            }}
+                        />
+                        <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()}
+                        />
+                        <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 }}
+                        />
+                        <ProFormDigit
+                            name="siteNo"
+                            label="杈撻�佺珯鍙�"
+                            colProps={{ md: 12, xl: 12 }}
+                            fieldProps={{ precision: 0 }}
+                        />
+                    </ProForm.Group>
+                    <ProForm.Group>
+                        <ProFormText
+                            name="inEnable"
+                            label="鍙叆(checkBox)"
+                            colProps={{ md: 12, xl: 12 }}
+                        />
+                        <ProFormText
+                            name="outEnable"
+                            label="鍙嚭(checkBox)"
+                            colProps={{ md: 12, xl: 12 }}
+                        />
+                    </ProForm.Group>
+                    <ProForm.Group>
+                        <ProFormText
+                            name="autoing"
+                            label="鑷姩(checkBox)"
+                            colProps={{ md: 12, xl: 12 }}
+                        />
+                        <ProFormText
+                            name="loading"
+                            label="鏈夌墿(checkBox)"
+                            colProps={{ md: 12, xl: 12 }}
+                        />
+                    </ProForm.Group>
+                    <ProForm.Group>
+                        <ProFormText
+                            name="canining"
+                            label="鑳藉叆(checkBox)"
+                            colProps={{ md: 12, xl: 12 }}
+                        />
+                        <ProFormText
+                            name="canouting"
+                            label="鑳藉嚭(checkBox)"
+                            colProps={{ md: 12, xl: 12 }}
+                        />
+                    </ProForm.Group>
+                    <ProForm.Group>
+                        <ProFormSelect
+                            name="locType1"
+                            label="楂樹綆绫诲瀷"
+                            colProps={{ md: 12, xl: 12 }}
+                            options={[
+                                { label: '鏈煡', value: 0 },
+                                { label: '浣庡簱浣�', value: 1 },
+                                { label: '楂樺簱浣�', value: 2 },
+                            ]}
+                        />
+                        <ProFormSelect
+                            name="locType2"
+                            label="瀹界獎绫诲瀷"
+                            colProps={{ md: 12, xl: 12 }}
+                            options={[
+                                { label: '鏈煡', value: 0 },
+                                { label: '绐勫簱浣�', value: 1 },
+                                { label: '瀹藉簱浣�', value: 2 },
+                            ]}
+                        />
+                    </ProForm.Group>
+                    <ProForm.Group>
+                        <ProFormSelect
+                            name="locType3"
+                            label="杞婚噸绫诲瀷"
+                            colProps={{ md: 12, xl: 12 }}
+                            options={[
+                                { label: '鏈煡', value: 0 },
+                                { label: '杞诲簱浣�', value: 1 },
+                                { label: '閲嶅簱浣�', value: 2 },
+                            ]}
+                        />
+                        <ProFormText
+                            name="locNo"
+                            label="搴撲綅鍙�"
+                            colProps={{ md: 12, xl: 12 }}
+                        />
+                    </ProForm.Group>
+                    <ProForm.Group>
+                        <ProFormText
+                            name="qrCodeValue"
+                            label="鍥涘悜绌挎杞︽墍璇嗗埆鐨勪簩缁寸爜"
+                            colProps={{ md: 12, xl: 12 }}
+                        />
+                    </ProForm.Group>
+
+                </ProForm>
+            </Modal>
+        </>
+    )
+}
+
+export default Edit;
diff --git a/zy-asrs-flow/src/pages/device/basConveyorSta/index.jsx b/zy-asrs-flow/src/pages/device/basConveyorSta/index.jsx
new file mode 100644
index 0000000..1deb1b9
--- /dev/null
+++ b/zy-asrs-flow/src/pages/device/basConveyorSta/index.jsx
@@ -0,0 +1,570 @@
+
+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-basConveyorSta';
+
+const handleSave = async (val, intl) => {
+    const hide = message.loading(intl.formatMessage({ id: 'page.adding', defaultMessage: '姝e湪娣诲姞' }));
+    try {
+        const resp = await Http.doPost('api/basConveyorSta/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/basConveyorSta/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/basConveyorSta/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/basConveyorSta/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: '杈撻�佺嚎id',
+            dataIndex: 'conveyorId$',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            filterDropdown: (props) => <LinkFilter
+                name='conveyorId'
+                major='basConveyor'
+                {...props}
+                actionRef={actionRef}
+                setSearchParam={setSearchParam}
+            />,
+        },
+        {
+            title: '杈撻�佺嚎鍙�',
+            dataIndex: 'conveyorNo',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            copyable: true,
+            filterDropdown: (props) => <TextFilter
+                name='conveyorNo'
+                {...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: '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: '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: 'siteNo',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            filterDropdown: (props) => <TextFilter
+                name='siteNo'
+                {...props}
+                actionRef={actionRef}
+                setSearchParam={setSearchParam}
+            />,
+        },
+        {
+            title: '鍙叆(checkBox)',
+            dataIndex: 'inEnable',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            filterDropdown: (props) => <TextFilter
+                name='inEnable'
+                {...props}
+                actionRef={actionRef}
+                setSearchParam={setSearchParam}
+            />,
+        },
+        {
+            title: '鍙嚭(checkBox)',
+            dataIndex: 'outEnable',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            filterDropdown: (props) => <TextFilter
+                name='outEnable'
+                {...props}
+                actionRef={actionRef}
+                setSearchParam={setSearchParam}
+            />,
+        },
+        {
+            title: '鑷姩(checkBox)',
+            dataIndex: 'autoing',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            filterDropdown: (props) => <TextFilter
+                name='autoing'
+                {...props}
+                actionRef={actionRef}
+                setSearchParam={setSearchParam}
+            />,
+        },
+        {
+            title: '鏈夌墿(checkBox)',
+            dataIndex: 'loading',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            filterDropdown: (props) => <TextFilter
+                name='loading'
+                {...props}
+                actionRef={actionRef}
+                setSearchParam={setSearchParam}
+            />,
+        },
+        {
+            title: '鑳藉叆(checkBox)',
+            dataIndex: 'canining',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            filterDropdown: (props) => <TextFilter
+                name='canining'
+                {...props}
+                actionRef={actionRef}
+                setSearchParam={setSearchParam}
+            />,
+        },
+        {
+            title: '鑳藉嚭(checkBox)',
+            dataIndex: 'canouting',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            filterDropdown: (props) => <TextFilter
+                name='canouting'
+                {...props}
+                actionRef={actionRef}
+                setSearchParam={setSearchParam}
+            />,
+        },
+        {
+            title: '楂樹綆绫诲瀷',
+            dataIndex: 'locType1$',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            filterDropdown: (props) => <SelectFilter
+                name='locType1'
+                {...props}
+                actionRef={actionRef}
+                setSearchParam={setSearchParam}
+                data={[
+                    { label: '鏈煡', value: 0 },
+                    { label: '浣庡簱浣�', value: 1 },
+                    { label: '楂樺簱浣�', value: 2 },
+                ]}
+            />,
+        },
+        {
+            title: '瀹界獎绫诲瀷',
+            dataIndex: 'locType2$',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            filterDropdown: (props) => <SelectFilter
+                name='locType2'
+                {...props}
+                actionRef={actionRef}
+                setSearchParam={setSearchParam}
+                data={[
+                    { label: '鏈煡', value: 0 },
+                    { label: '绐勫簱浣�', value: 1 },
+                    { label: '瀹藉簱浣�', value: 2 },
+                ]}
+            />,
+        },
+        {
+            title: '杞婚噸绫诲瀷',
+            dataIndex: 'locType3$',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            filterDropdown: (props) => <SelectFilter
+                name='locType3'
+                {...props}
+                actionRef={actionRef}
+                setSearchParam={setSearchParam}
+                data={[
+                    { label: '鏈煡', value: 0 },
+                    { label: '杞诲簱浣�', value: 1 },
+                    { label: '閲嶅簱浣�', value: 2 },
+                ]}
+            />,
+        },
+        {
+            title: '搴撲綅鍙�',
+            dataIndex: 'locNo',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            filterDropdown: (props) => <TextFilter
+                name='locNo'
+                {...props}
+                actionRef={actionRef}
+                setSearchParam={setSearchParam}
+            />,
+        },
+        {
+            title: '鍥涘悜绌挎杞︽墍璇嗗埆鐨勪簩缁寸爜',
+            dataIndex: 'qrCodeValue',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            filterDropdown: (props) => <TextFilter
+                name='qrCodeValue'
+                {...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="basConveyorSta"
+                    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/basConveyorSta/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/basLed/components/edit.jsx b/zy-asrs-flow/src/pages/device/basLed/components/edit.jsx
new file mode 100644
index 0000000..019c993
--- /dev/null
+++ b/zy-asrs-flow/src/pages/device/basLed/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="deviceId"
+                            label="璁惧id"
+                            colProps={{ md: 12, xl: 12 }}
+                            fieldProps={{ precision: 0 }}
+                            showSearch
+                            debounceTime={300}
+                            request={async ({ keyWords }) => {
+                                const resp = await Http.doPostForm('api/device/query', { condition: keyWords });
+                                return resp.data;
+                            }}
+                        />
+                        <ProFormDigit
+                            name="ledNo"
+                            label="LED鏄剧ず灞忓彿"
+                            colProps={{ md: 12, xl: 12 }}
+                            fieldProps={{ precision: 0 }}
+                            rules={[{ required: true }]}
+                        />
+                    </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;
+                            }}
+                        />
+                        <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()}
+                        />
+                        <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 }}
+                        />
+                        <ProFormText
+                            name="sta"
+                            label="鏄剧ず灞忕珯鐐瑰彿"
+                            colProps={{ md: 12, xl: 12 }}
+                            fieldProps={{ precision: 0 }}
+                        />
+                    </ProForm.Group>
+                    <ProForm.Group>
+                        <ProFormSelect
+                            name="conveyorId"
+                            label="杈撻�佺嚎id"
+                            colProps={{ md: 12, xl: 12 }}
+                            fieldProps={{ precision: 0 }}
+                            showSearch
+                            debounceTime={300}
+                            request={async ({ keyWords }) => {
+                                const resp = await Http.doPostForm('api/basConveyor/query', { condition: keyWords });
+                                return resp.data;
+                            }}
+                        />
+                    </ProForm.Group>
+
+                </ProForm>
+            </Modal>
+        </>
+    )
+}
+
+export default Edit;
diff --git a/zy-asrs-flow/src/pages/device/basLed/index.jsx b/zy-asrs-flow/src/pages/device/basLed/index.jsx
new file mode 100644
index 0000000..2cf9c9a
--- /dev/null
+++ b/zy-asrs-flow/src/pages/device/basLed/index.jsx
@@ -0,0 +1,426 @@
+
+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-basLed';
+
+const handleSave = async (val, intl) => {
+    const hide = message.loading(intl.formatMessage({ id: 'page.adding', defaultMessage: '姝e湪娣诲姞' }));
+    try {
+        const resp = await Http.doPost('api/basLed/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/basLed/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/basLed/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/basLed/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: '璁惧id',
+            dataIndex: 'deviceId$',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            filterDropdown: (props) => <LinkFilter
+                name='deviceId'
+                major='device'
+                {...props}
+                actionRef={actionRef}
+                setSearchParam={setSearchParam}
+            />,
+        },
+        {
+            title: 'LED鏄剧ず灞忓彿',
+            dataIndex: 'ledNo',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            copyable: true,
+            filterDropdown: (props) => <TextFilter
+                name='ledNo'
+                {...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: '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: '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: 'sta',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            filterDropdown: (props) => <TextFilter
+                name='sta'
+                {...props}
+                actionRef={actionRef}
+                setSearchParam={setSearchParam}
+            />,
+        },
+        {
+            title: '杈撻�佺嚎id',
+            dataIndex: 'conveyorId$',
+            valueType: 'text',
+            hidden: false,
+            width: 140,
+            filterDropdown: (props) => <LinkFilter
+                name='conveyorId'
+                major='basConveyor'
+                {...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="basLed"
+                    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/basLed/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/shuttle/index.jsx b/zy-asrs-flow/src/pages/device/shuttle/index.jsx
index 43eff9c..1aebf64 100644
--- a/zy-asrs-flow/src/pages/device/shuttle/index.jsx
+++ b/zy-asrs-flow/src/pages/device/shuttle/index.jsx
@@ -163,6 +163,25 @@
         }
     }
 
+    const shuttleMoveLocClose = async () => {
+        try {
+            const resp = await Http.doPost('api/basShuttle/moveLocClose', {
+                shuttleNo: currentData.shuttleNo,
+            });
+            if (resp.code === 200) {
+                message.success("璇锋眰鎴愬姛");
+                return true;
+            } else {
+                message.warning(resp.msg);
+                return false;
+            }
+        } catch (error) {
+            message.warning("璇锋眰澶辫触");
+            return false;
+        }
+    }
+
+
     const xStartChange = (e) => {
         setXStart(e.target.value)
     }
@@ -325,6 +344,7 @@
                                     />
                                 </div>
                                 <Button onClick={() => shuttleMoveLoc()}>璺戝簱</Button>
+                                <Button onClick={() => shuttleMoveLocClose()}>璺戝簱鍏抽棴</Button>
                             </div>
                         </Card>
                     </div>
diff --git a/zy-asrs-flow/src/pages/map/drawer/shuttle/handle.jsx b/zy-asrs-flow/src/pages/map/drawer/shuttle/handle.jsx
index 8ec4f2c..40d5946 100644
--- a/zy-asrs-flow/src/pages/map/drawer/shuttle/handle.jsx
+++ b/zy-asrs-flow/src/pages/map/drawer/shuttle/handle.jsx
@@ -97,6 +97,24 @@
         }
     }
 
+    const shuttleMoveLocClose = async () => {
+        try {
+            const resp = await Http.doPost('api/basShuttle/moveLocClose', {
+                shuttleNo: currentData.shuttleNo,
+            });
+            if (resp.code === 200) {
+                message.success("璇锋眰鎴愬姛");
+                return true;
+            } else {
+                message.warning(resp.msg);
+                return false;
+            }
+        } catch (error) {
+            message.warning("璇锋眰澶辫触");
+            return false;
+        }
+    }
+
     return (
         <>
             <Drawer
@@ -166,6 +184,7 @@
                                 />
                             </div>
                             <Button onClick={() => shuttleMoveLoc()}>璺戝簱</Button>
+                            <Button onClick={() => shuttleMoveLocClose()}>璺戝簱鍏抽棴</Button>
                         </div>
                     </Card>
                 </div>
diff --git a/zy-asrs-flow/src/pages/system/dict/index.jsx b/zy-asrs-flow/src/pages/system/dict/index.jsx
index 3cd28c8..56cbfd7 100644
--- a/zy-asrs-flow/src/pages/system/dict/index.jsx
+++ b/zy-asrs-flow/src/pages/system/dict/index.jsx
@@ -181,6 +181,7 @@
             valueType: 'text',
             hidden: false,
             width: 140,
+            ellipsis: true,
             filterDropdown: (props) => <TextFilter
                 name='value'
                 {...props}
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/MainProcess.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/MainProcess.java
index ccbc866..0bccc02 100644
--- a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/MainProcess.java
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/MainProcess.java
@@ -42,7 +42,7 @@
                     }
 
                     // 鍏ュ簱  ===>> 鍏ュ簱绔欏埌鍫嗗灈鏈虹珯锛屾牴鎹潯鐮佹壂鎻忕敓鎴愬叆搴撳伐浣滄。
-//                    mainService.generateInboundWrk(); // 缁勬墭
+                    mainService.generateInboundWrk(); // 缁勬墭
 
                     // 闂撮殧
                     Thread.sleep(500);
@@ -59,10 +59,10 @@
 //                    mainService.recErr();
 //                    // 鍏ュ簱  ===>> 绌烘爤鏉垮垵濮嬪寲鍏ュ簱,鍙夎溅鍏ュ簱绔欐斁璐�
 //                    mainService.storeEmptyPlt();
-//                    // 鍑哄簱  ===>> 宸ヤ綔妗d俊鎭啓鍏ed鏄剧ず鍣�
-//                    mainService.ledExecute();
-//                    // 鍏朵粬  ===>> LED鏄剧ず鍣ㄥ浣嶏紝鏄剧ず榛樿淇℃伅
-//                    mainService.ledReset();
+                    // 鍑哄簱  ===>> 宸ヤ綔妗d俊鎭啓鍏ed鏄剧ず鍣�
+                    mainService.ledExecute();
+                    // 鍏朵粬  ===>> LED鏄剧ず鍣ㄥ浣嶏紝鏄剧ず榛樿淇℃伅
+                    mainService.ledReset();
                     // 绌挎杞� ===>> 灏忚溅鐢甸噺妫�娴嬪厖鐢�
                     mainService.loopShuttleCharge();
                     // 绌挎杞� ===>> 灏忚溅鐢甸噺婊$數鍚庡洖寰呮満浣�
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/action/ShuttleAction.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/action/ShuttleAction.java
index 12beefa..1be358f 100644
--- a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/action/ShuttleAction.java
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/action/ShuttleAction.java
@@ -19,10 +19,7 @@
 import com.zy.asrs.wcs.core.model.enums.ShuttleTaskModeType;
 import com.zy.asrs.wcs.core.service.BasShuttleService;
 import com.zy.asrs.wcs.core.service.LocService;
-import com.zy.asrs.wcs.core.utils.NavigateMapUtils;
-import com.zy.asrs.wcs.core.utils.RedisUtil;
-import com.zy.asrs.wcs.core.utils.ShuttleDispatcher;
-import com.zy.asrs.wcs.core.utils.Utils;
+import com.zy.asrs.wcs.core.utils.*;
 import com.zy.asrs.wcs.rcs.News;
 import com.zy.asrs.wcs.rcs.cache.SlaveConnection;
 import com.zy.asrs.wcs.rcs.constant.DeviceRedisConstant;
@@ -31,6 +28,8 @@
 import com.zy.asrs.wcs.rcs.model.enums.SlaveType;
 import com.zy.asrs.wcs.rcs.model.protocol.ShuttleProtocol;
 import com.zy.asrs.wcs.rcs.thread.ShuttleThread;
+import com.zy.asrs.wcs.system.entity.Dict;
+import com.zy.asrs.wcs.system.service.DictService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
@@ -53,6 +52,10 @@
     private ShuttleDispatcher shuttleDispatcher;
     @Autowired
     private ObjectMapper objectMapper;
+    @Autowired
+    private DictService dictService;
+    @Autowired
+    private ConveyorDispatcher conveyorDispatcher;
 
     public synchronized boolean assignWork(Device device, ShuttleAssignCommand assignCommand) {
         ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, device.getId().intValue());
@@ -277,77 +280,240 @@
         }
 
         int lev = Utils.getLev(shuttleProtocol.getCurrentLocNo());//灏忚溅褰撳墠妤煎眰
-        if (shuttleProtocol.getYCurrent() > shuttleProtocol.getYTarget()) {
-            //璺戝簱缁撴潫
-            shuttleProtocol.setMoveLoc(false);
-            shuttleProtocol.setMoveType(0);
-            shuttleProtocol.setXStart(0);
-            shuttleProtocol.setXTarget(0);
-            shuttleProtocol.setXCurrent(0);
-            shuttleProtocol.setYStart(0);
-            shuttleProtocol.setYTarget(0);
-            shuttleProtocol.setYCurrent(0);
-            return;
-        }
 
         if (shuttleProtocol.getMoveType() == 0) {//璺戣建閬�
-            Integer xCurrent = shuttleProtocol.getXCurrent();
-            if (xCurrent > shuttleProtocol.getXTarget()) {//褰揦鍊煎ぇ浜嶺鐩爣鍊硷紝杩涜褰掗浂涓擸鏂瑰悜+1
-                shuttleProtocol.setXCurrent(shuttleProtocol.getXStart());
-                shuttleProtocol.setYCurrent(shuttleProtocol.getYCurrent() + 1);
+            //鏍规嵁鍦板浘鏂瑰悜鍐冲畾璺憍鎴杫
+            Dict dict = dictService.getOne(new LambdaQueryWrapper<Dict>()
+                    .eq(Dict::getFlag, "direction_map")
+                    .eq(Dict::getStatus, 1));
+            if (dict == null) {
+                //璺戝簱缁撴潫
+                shuttleProtocol.setMoveLoc(false);
+                shuttleProtocol.setMoveType(0);
+                shuttleProtocol.setXStart(0);
+                shuttleProtocol.setXTarget(0);
+                shuttleProtocol.setXCurrent(0);
+                shuttleProtocol.setYStart(0);
+                shuttleProtocol.setYTarget(0);
+                shuttleProtocol.setYCurrent(0);
                 return;
             }
+            String direction = dict.getValue();
 
-            Integer yCurrent = shuttleProtocol.getYCurrent();
-            String locNo = Utils.getLocNo(xCurrent, yCurrent, lev);
-            Loc target = locService.getOne(new LambdaQueryWrapper<Loc>()
-                    .eq(Loc::getLocNo, locNo)
-                    .eq(Loc::getHostId, device.getHostId()));
-            if (target == null) {
-                shuttleProtocol.setXCurrent(shuttleProtocol.getXCurrent() + 1);
-                return;
-            }
-
-//            if (!target.getLocSts().equals("O")) {
-//                shuttleProtocol.setXCurrent(shuttleProtocol.getXCurrent() + 1);
-//                return;
-//            }
-
-            //璋冨害鍘荤洰鏍囦綅缃�
-            if (shuttleProtocol.getCurrentLocNo().equals(target.getLocNo())) {
-                shuttleProtocol.setXCurrent(shuttleProtocol.getXCurrent() + 1);//灏忚溅鍜岀洰鏍囦綅缃竴鑷达紝璺宠繃
-            } else {
-                shuttleDispatcher.generateMoveTask(device, target.getLocNo());
-                shuttleProtocol.setXCurrent(shuttleProtocol.getXCurrent() + 1);
-            }
-        } else if (shuttleProtocol.getMoveType() == 1) {//璺戝簱浣�
-            ArrayList<String> locs = new ArrayList<>();
-            for (int i = shuttleProtocol.getXCurrent(); i <= shuttleProtocol.getXTarget(); i++) {
-                String locNo = Utils.getLocNo(i, shuttleProtocol.getYCurrent(), lev);
-                locs.add(locNo);
-            }
-
-            List<Loc> locList = locService.list(new LambdaQueryWrapper<Loc>()
-                    .in(Loc::getLocNo, locs));
-            if (locList.isEmpty()) {
-                //绌哄簱浣�
-                shuttleProtocol.setYCurrent(shuttleProtocol.getYCurrent() + 1);
-                return;
-            }
-
-            Loc start = locList.get(0);
-            Loc target = locList.get(locList.size() - 1);
-            //鍒ゆ柇灏忚溅鏄惁鍦ㄨ捣鐐逛綅缃�
-            if (!shuttleProtocol.getCurrentLocNo().equals(start.getLocNo())) {//涓嶅湪璧风偣浣嶇疆锛岃皟搴﹀幓璧风偣浣嶇疆
-                shuttleDispatcher.generateMoveTask(device, start.getLocNo());
-            }else {
-                //鍦ㄨ捣鐐逛綅缃紝璋冨害鍘荤洰鏍囦綅缃�
-                if (shuttleProtocol.getCurrentLocNo().equals(target.getLocNo())) {
-                    shuttleProtocol.setYCurrent(shuttleProtocol.getYCurrent() + 1);//灏忚溅鍜岀洰鏍囦綅缃竴鑷达紝璺宠繃
-                }else {
-                    shuttleDispatcher.generateMoveTask(device, start.getLocNo());
-                    shuttleProtocol.setYCurrent(shuttleProtocol.getYCurrent() + 1);
+            if (direction.equals("y")) {//璺憍杞存柟鍚戯紝璺戝畬x杞村啀鍒囨崲y杞�
+                ArrayList<String> locs = new ArrayList<>();
+                for (int i = shuttleProtocol.getXCurrent(); i <= shuttleProtocol.getXTarget(); i++) {
+                    String locNo = Utils.getLocNo(i, shuttleProtocol.getYCurrent(), lev);
+                    locs.add(locNo);
                 }
+
+                List<Loc> locList = locService.list(new LambdaQueryWrapper<Loc>()
+                        .eq(Loc::getLocSts, LocStsType.O.val())
+                        .in(Loc::getLocNo, locs));
+                if (locList.isEmpty()) {
+                    //绌哄簱浣�
+                    shuttleProtocol.setYCurrent(shuttleProtocol.getYCurrent() + 1);
+                    return;
+                }
+
+                Loc start = locList.get(0);
+                Loc target = locList.get(locList.size() - 1);
+                //鍒ゆ柇灏忚溅鏄惁鍦ㄨ捣鐐逛綅缃�
+                if (!shuttleProtocol.getCurrentLocNo().equals(start.getLocNo())) {//涓嶅湪璧风偣浣嶇疆锛岃皟搴﹀幓璧风偣浣嶇疆
+                    shuttleDispatcher.generateMoveTask(device, start.getLocNo());
+                }else {
+                    //鍦ㄨ捣鐐逛綅缃紝璋冨害鍘荤洰鏍囦綅缃�
+                    shuttleDispatcher.generateMoveTask(device, target.getLocNo());
+                    shuttleProtocol.setYCurrent(shuttleProtocol.getYCurrent() + 1);//鍒囨崲y杞�
+
+                    if(shuttleProtocol.getYCurrent() > shuttleProtocol.getYTarget()) {
+                        //y杞翠篃璺戝畬浜嗭紝缁撴潫璺戝簱
+                        shuttleProtocol.setMoveLoc(false);
+                        shuttleProtocol.setMoveType(0);
+                        shuttleProtocol.setXStart(0);
+                        shuttleProtocol.setXTarget(0);
+                        shuttleProtocol.setXCurrent(0);
+                        shuttleProtocol.setYStart(0);
+                        shuttleProtocol.setYTarget(0);
+                        shuttleProtocol.setYCurrent(0);
+                        return;
+                    }
+                }
+            }else {//璺憏杞存柟鍚戯紝璺戝畬y杞村啀鍒囨崲x杞�
+                ArrayList<String> locs = new ArrayList<>();
+                for (int i = shuttleProtocol.getYCurrent(); i <= shuttleProtocol.getYTarget(); i++) {
+                    String locNo = Utils.getLocNo(shuttleProtocol.getXCurrent(), i, lev);
+                    locs.add(locNo);
+                }
+
+                List<Loc> locList = locService.list(new LambdaQueryWrapper<Loc>()
+                        .eq(Loc::getLocSts, LocStsType.O.val())
+                        .in(Loc::getLocNo, locs));
+                if (locList.isEmpty()) {
+                    //绌哄簱浣�
+                    shuttleProtocol.setXCurrent(shuttleProtocol.getXCurrent() + 1);
+                    return;
+                }
+
+                Loc start = locList.get(0);
+                Loc target = locList.get(locList.size() - 1);
+                //鍒ゆ柇灏忚溅鏄惁鍦ㄨ捣鐐逛綅缃�
+                if (!shuttleProtocol.getCurrentLocNo().equals(start.getLocNo())) {//涓嶅湪璧风偣浣嶇疆锛岃皟搴﹀幓璧风偣浣嶇疆
+                    shuttleDispatcher.generateMoveTask(device, start.getLocNo());
+                }else {
+                    //鍦ㄨ捣鐐逛綅缃紝璋冨害鍘荤洰鏍囦綅缃�
+                    shuttleDispatcher.generateMoveTask(device, target.getLocNo());
+                    shuttleProtocol.setXCurrent(shuttleProtocol.getXCurrent() + 1);//鍒囨崲x杞�
+
+                    if(shuttleProtocol.getXCurrent() > shuttleProtocol.getXTarget()) {
+                        //y杞翠篃璺戝畬浜嗭紝缁撴潫璺戝簱
+                        shuttleProtocol.setMoveLoc(false);
+                        shuttleProtocol.setMoveType(0);
+                        shuttleProtocol.setXStart(0);
+                        shuttleProtocol.setXTarget(0);
+                        shuttleProtocol.setXCurrent(0);
+                        shuttleProtocol.setYStart(0);
+                        shuttleProtocol.setYTarget(0);
+                        shuttleProtocol.setYCurrent(0);
+                        return;
+                    }
+                }
+            }
+
+        } else if (shuttleProtocol.getMoveType() == 1) {//璺戝簱浣�
+            //鏍规嵁鍦板浘鏂瑰悜鍐冲畾璺憍鎴杫
+            Dict dict = dictService.getOne(new LambdaQueryWrapper<Dict>()
+                    .eq(Dict::getFlag, "direction_map")
+                    .eq(Dict::getStatus, 1));
+            if (dict == null) {
+                //璺戝簱缁撴潫
+                shuttleProtocol.setMoveLoc(false);
+                shuttleProtocol.setMoveType(0);
+                shuttleProtocol.setXStart(0);
+                shuttleProtocol.setXTarget(0);
+                shuttleProtocol.setXCurrent(0);
+                shuttleProtocol.setYStart(0);
+                shuttleProtocol.setYTarget(0);
+                shuttleProtocol.setYCurrent(0);
+                return;
+            }
+            String direction = dict.getValue();
+
+            if (direction.equals("y")) {//璺憍杞存柟鍚戯紝璺戝畬x杞村啀鍒囨崲y杞�
+                Integer xCurrent = shuttleProtocol.getXCurrent();
+
+                //鑾峰彇寰呰窇搴撲綅鍙�
+                String locNo = Utils.getLocNo(xCurrent, shuttleProtocol.getYCurrent(), lev);
+                Loc target = locService.getOne(new LambdaQueryWrapper<Loc>()
+                        .eq(Loc::getLocNo, locNo)
+                        .eq(Loc::getLocSts, LocStsType.O.val())
+                        .eq(Loc::getHostId, device.getHostId()));
+                if (target == null || shuttleProtocol.getCurrentLocNo().equals(locNo)) {//搴撲綅涓嶅瓨鍦ㄦ垨灏忚溅宸插湪褰撳墠浣嶇疆
+                    shuttleProtocol.setXCurrent(xCurrent + 1);
+                    if (shuttleProtocol.getXCurrent() > shuttleProtocol.getXTarget()) {
+                        //x杞磋窇瀹岋紝鍒囨崲y杞�
+                        shuttleProtocol.setXCurrent(shuttleProtocol.getXStart());
+                        shuttleProtocol.setYCurrent(shuttleProtocol.getYCurrent() + 1);
+
+                        if(shuttleProtocol.getYCurrent() > shuttleProtocol.getYTarget()) {
+                            //y杞翠篃璺戝畬浜嗭紝缁撴潫璺戝簱
+                            shuttleProtocol.setMoveLoc(false);
+                            shuttleProtocol.setMoveType(0);
+                            shuttleProtocol.setXStart(0);
+                            shuttleProtocol.setXTarget(0);
+                            shuttleProtocol.setXCurrent(0);
+                            shuttleProtocol.setYStart(0);
+                            shuttleProtocol.setYTarget(0);
+                            shuttleProtocol.setYCurrent(0);
+                            return;
+                        }
+                    }
+                    return;
+                }
+
+                //璋冨害鍘诲簱浣�
+                Task task = shuttleDispatcher.generateMoveTask(device, locNo);
+                if (task == null) {
+                    return;//璋冨害澶辫触
+                }
+
+                shuttleProtocol.setXCurrent(xCurrent + 1);
+                if (shuttleProtocol.getXCurrent() > shuttleProtocol.getXTarget()) {
+                    //x杞磋窇瀹岋紝鍒囨崲y杞�
+                    shuttleProtocol.setXCurrent(shuttleProtocol.getXStart());
+                    shuttleProtocol.setYCurrent(shuttleProtocol.getYCurrent() + 1);
+
+                    if(shuttleProtocol.getYCurrent() > shuttleProtocol.getYTarget()) {
+                        //y杞翠篃璺戝畬浜嗭紝缁撴潫璺戝簱
+                        shuttleProtocol.setMoveLoc(false);
+                        shuttleProtocol.setMoveType(0);
+                        shuttleProtocol.setXStart(0);
+                        shuttleProtocol.setXTarget(0);
+                        shuttleProtocol.setXCurrent(0);
+                        shuttleProtocol.setYStart(0);
+                        shuttleProtocol.setYTarget(0);
+                        shuttleProtocol.setYCurrent(0);
+                        return;
+                    }
+                }
+
+            }else {//璺憏杞存柟鍚戯紝璺戝畬y杞村啀鍒囨崲x杞�
+                Integer yCurrent = shuttleProtocol.getYCurrent();
+
+                //鑾峰彇寰呰窇搴撲綅鍙�
+                String locNo = Utils.getLocNo(shuttleProtocol.getXCurrent(), yCurrent, lev);
+                Loc target = locService.getOne(new LambdaQueryWrapper<Loc>()
+                        .eq(Loc::getLocNo, locNo)
+                        .eq(Loc::getLocSts, LocStsType.O.val())
+                        .eq(Loc::getHostId, device.getHostId()));
+                if (target == null || shuttleProtocol.getCurrentLocNo().equals(locNo)) {//搴撲綅涓嶅瓨鍦ㄦ垨灏忚溅宸插湪褰撳墠浣嶇疆
+                    shuttleProtocol.setYCurrent(yCurrent + 1);
+                    if (shuttleProtocol.getYCurrent() > shuttleProtocol.getYTarget()) {
+                        //y杞磋窇瀹岋紝鍒囨崲x杞�
+                        shuttleProtocol.setYCurrent(shuttleProtocol.getYStart());
+                        shuttleProtocol.setXCurrent(shuttleProtocol.getXCurrent() + 1);
+
+                        if(shuttleProtocol.getXCurrent() > shuttleProtocol.getXTarget()) {
+                            //x杞翠篃璺戝畬浜嗭紝缁撴潫璺戝簱
+                            shuttleProtocol.setMoveLoc(false);
+                            shuttleProtocol.setMoveType(0);
+                            shuttleProtocol.setXStart(0);
+                            shuttleProtocol.setXTarget(0);
+                            shuttleProtocol.setXCurrent(0);
+                            shuttleProtocol.setYStart(0);
+                            shuttleProtocol.setYTarget(0);
+                            shuttleProtocol.setYCurrent(0);
+                            return;
+                        }
+                    }
+                }
+
+                //璋冨害鍘诲簱浣�
+                Task task = shuttleDispatcher.generateMoveTask(device, locNo);
+                if (task == null) {
+                    return;//璋冨害澶辫触
+                }
+
+                shuttleProtocol.setYCurrent(yCurrent + 1);
+                if (shuttleProtocol.getYCurrent() > shuttleProtocol.getYTarget()) {
+                    //y杞磋窇瀹岋紝鍒囨崲x杞�
+                    shuttleProtocol.setYCurrent(shuttleProtocol.getYStart());
+                    shuttleProtocol.setXCurrent(shuttleProtocol.getXCurrent() + 1);
+
+                    if(shuttleProtocol.getXCurrent() > shuttleProtocol.getXTarget()) {
+                        //x杞翠篃璺戝畬浜嗭紝缁撴潫璺戝簱
+                        shuttleProtocol.setMoveLoc(false);
+                        shuttleProtocol.setMoveType(0);
+                        shuttleProtocol.setXStart(0);
+                        shuttleProtocol.setXTarget(0);
+                        shuttleProtocol.setXCurrent(0);
+                        shuttleProtocol.setYStart(0);
+                        shuttleProtocol.setYTarget(0);
+                        shuttleProtocol.setYCurrent(0);
+                        return;
+                    }
+                }
+
             }
         } else if (shuttleProtocol.getMoveType() == 2) {//姣嶈建閬撳惊鐜窇
             Integer xCurrent = shuttleProtocol.getXCurrent();
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/controller/BasConveyorController.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/controller/BasConveyorController.java
new file mode 100644
index 0000000..4ae9ba0
--- /dev/null
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/controller/BasConveyorController.java
@@ -0,0 +1,101 @@
+package com.zy.asrs.wcs.system.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.BasConveyor;
+import com.zy.asrs.wcs.core.service.BasConveyorService;
+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 BasConveyorController extends BaseController {
+
+    @Autowired
+    private BasConveyorService basConveyorService;
+
+    @PreAuthorize("hasAuthority('core:basConveyor:list')")
+    @PostMapping("/basConveyor/page")
+    public R page(@RequestBody Map<String, Object> map) {
+        BaseParam baseParam = buildParam(map, BaseParam.class);
+        PageParam<BasConveyor, BaseParam> pageParam = new PageParam<>(baseParam, BasConveyor.class);
+        return R.ok().add(basConveyorService.page(pageParam, pageParam.buildWrapper(true)));
+    }
+
+    @PreAuthorize("hasAuthority('core:basConveyor:list')")
+    @PostMapping("/basConveyor/list")
+    public R list(@RequestBody Map<String, Object> map) {
+        return R.ok().add(basConveyorService.list());
+    }
+
+    @PreAuthorize("hasAuthority('core:basConveyor:list')")
+    @GetMapping("/basConveyor/{id}")
+    public R get(@PathVariable("id") Long id) {
+        return R.ok().add(basConveyorService.getById(id));
+    }
+
+    @PreAuthorize("hasAuthority('core:basConveyor:save')")
+    @OperationLog("娣诲姞杈撻�佺嚎閰嶇疆")
+    @PostMapping("/basConveyor/save")
+    public R save(@RequestBody BasConveyor basConveyor) {
+        if (!basConveyorService.save(basConveyor)) {
+            return R.error("娣诲姞澶辫触");
+        }
+        return R.ok("娣诲姞鎴愬姛");
+    }
+
+    @PreAuthorize("hasAuthority('core:basConveyor:update')")
+    @OperationLog("淇敼杈撻�佺嚎閰嶇疆")
+    @PostMapping("/basConveyor/update")
+    public R update(@RequestBody BasConveyor basConveyor) {
+        if (!basConveyorService.updateById(basConveyor)) {
+            return R.error("淇敼澶辫触");
+        }
+        return R.ok("淇敼鎴愬姛");
+    }
+
+    @PreAuthorize("hasAuthority('core:basConveyor:remove')")
+    @OperationLog("鍒犻櫎杈撻�佺嚎閰嶇疆")
+    @PostMapping("/basConveyor/remove/{ids}")
+    public R remove(@PathVariable Long[] ids) {
+        if (!basConveyorService.removeByIds(Arrays.asList(ids))) {
+            return R.error("鍒犻櫎澶辫触");
+        }
+        return R.ok("鍒犻櫎鎴愬姛");
+    }
+
+    @PreAuthorize("hasAuthority('core:basConveyor:list')")
+    @PostMapping("/basConveyor/query")
+    public R query(@RequestParam(required = false) String condition) {
+        List<KeyValVo> vos = new ArrayList<>();
+        LambdaQueryWrapper<BasConveyor> wrapper = new LambdaQueryWrapper<>();
+        if (!Cools.isEmpty(condition)) {
+            wrapper.like(BasConveyor::getConveyorNo, condition);
+        }
+        basConveyorService.page(new Page<>(1, 30), wrapper).getRecords().forEach(
+                item -> vos.add(new KeyValVo(item.getDeviceId(), item.getConveyorNo() + "杈撻�佺嚎[id:" + item.getDeviceId() + "]"))
+        );
+        return R.ok().add(vos);
+    }
+
+    @PreAuthorize("hasAuthority('core:basConveyor:list')")
+    @PostMapping("/basConveyor/export")
+    public void export(@RequestBody Map<String, Object> map, HttpServletResponse response) throws Exception {
+        ExcelUtil.build(ExcelUtil.create(basConveyorService.list(), BasConveyor.class), response);
+    }
+
+}
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/controller/BasConveyorStaController.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/controller/BasConveyorStaController.java
new file mode 100644
index 0000000..18c2af1
--- /dev/null
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/controller/BasConveyorStaController.java
@@ -0,0 +1,101 @@
+package com.zy.asrs.wcs.system.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.BasConveyorSta;
+import com.zy.asrs.wcs.core.service.BasConveyorStaService;
+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 BasConveyorStaController extends BaseController {
+
+    @Autowired
+    private BasConveyorStaService basConveyorStaService;
+
+    @PreAuthorize("hasAuthority('core:basConveyorSta:list')")
+    @PostMapping("/basConveyorSta/page")
+    public R page(@RequestBody Map<String, Object> map) {
+        BaseParam baseParam = buildParam(map, BaseParam.class);
+        PageParam<BasConveyorSta, BaseParam> pageParam = new PageParam<>(baseParam, BasConveyorSta.class);
+        return R.ok().add(basConveyorStaService.page(pageParam, pageParam.buildWrapper(true)));
+    }
+
+    @PreAuthorize("hasAuthority('core:basConveyorSta:list')")
+    @PostMapping("/basConveyorSta/list")
+    public R list(@RequestBody Map<String, Object> map) {
+        return R.ok().add(basConveyorStaService.list());
+    }
+
+    @PreAuthorize("hasAuthority('core:basConveyorSta:list')")
+    @GetMapping("/basConveyorSta/{id}")
+    public R get(@PathVariable("id") Long id) {
+        return R.ok().add(basConveyorStaService.getById(id));
+    }
+
+    @PreAuthorize("hasAuthority('core:basConveyorSta:save')")
+    @OperationLog("娣诲姞杈撻�佺珯鐐归厤缃�")
+    @PostMapping("/basConveyorSta/save")
+    public R save(@RequestBody BasConveyorSta basConveyorSta) {
+        if (!basConveyorStaService.save(basConveyorSta)) {
+            return R.error("娣诲姞澶辫触");
+        }
+        return R.ok("娣诲姞鎴愬姛");
+    }
+
+    @PreAuthorize("hasAuthority('core:basConveyorSta:update')")
+    @OperationLog("淇敼杈撻�佺珯鐐归厤缃�")
+    @PostMapping("/basConveyorSta/update")
+    public R update(@RequestBody BasConveyorSta basConveyorSta) {
+        if (!basConveyorStaService.updateById(basConveyorSta)) {
+            return R.error("淇敼澶辫触");
+        }
+        return R.ok("淇敼鎴愬姛");
+    }
+
+    @PreAuthorize("hasAuthority('core:basConveyorSta:remove')")
+    @OperationLog("鍒犻櫎杈撻�佺珯鐐归厤缃�")
+    @PostMapping("/basConveyorSta/remove/{ids}")
+    public R remove(@PathVariable Long[] ids) {
+        if (!basConveyorStaService.removeByIds(Arrays.asList(ids))) {
+            return R.error("鍒犻櫎澶辫触");
+        }
+        return R.ok("鍒犻櫎鎴愬姛");
+    }
+
+    @PreAuthorize("hasAuthority('core:basConveyorSta:list')")
+    @PostMapping("/basConveyorSta/query")
+    public R query(@RequestParam(required = false) String condition) {
+        List<KeyValVo> vos = new ArrayList<>();
+        LambdaQueryWrapper<BasConveyorSta> wrapper = new LambdaQueryWrapper<>();
+        if (!Cools.isEmpty(condition)) {
+            wrapper.like(BasConveyorSta::getConveyorNo, condition);
+        }
+        basConveyorStaService.page(new Page<>(1, 30), wrapper).getRecords().forEach(
+                item -> vos.add(new KeyValVo(item.getId(), item.getConveyorNo()))
+        );
+        return R.ok().add(vos);
+    }
+
+    @PreAuthorize("hasAuthority('core:basConveyorSta:list')")
+    @PostMapping("/basConveyorSta/export")
+    public void export(@RequestBody Map<String, Object> map, HttpServletResponse response) throws Exception {
+        ExcelUtil.build(ExcelUtil.create(basConveyorStaService.list(), BasConveyorSta.class), response);
+    }
+
+}
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/controller/BasLedController.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/controller/BasLedController.java
new file mode 100644
index 0000000..4b64823
--- /dev/null
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/controller/BasLedController.java
@@ -0,0 +1,101 @@
+package com.zy.asrs.wcs.system.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.BasLed;
+import com.zy.asrs.wcs.core.service.BasLedService;
+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 BasLedController extends BaseController {
+
+    @Autowired
+    private BasLedService basLedService;
+
+    @PreAuthorize("hasAuthority('core:basLed:list')")
+    @PostMapping("/basLed/page")
+    public R page(@RequestBody Map<String, Object> map) {
+        BaseParam baseParam = buildParam(map, BaseParam.class);
+        PageParam<BasLed, BaseParam> pageParam = new PageParam<>(baseParam, BasLed.class);
+        return R.ok().add(basLedService.page(pageParam, pageParam.buildWrapper(true)));
+    }
+
+    @PreAuthorize("hasAuthority('core:basLed:list')")
+    @PostMapping("/basLed/list")
+    public R list(@RequestBody Map<String, Object> map) {
+        return R.ok().add(basLedService.list());
+    }
+
+    @PreAuthorize("hasAuthority('core:basLed:list')")
+    @GetMapping("/basLed/{id}")
+    public R get(@PathVariable("id") Long id) {
+        return R.ok().add(basLedService.getById(id));
+    }
+
+    @PreAuthorize("hasAuthority('core:basLed:save')")
+    @OperationLog("娣诲姞LED鏄剧ず灞忛厤缃�")
+    @PostMapping("/basLed/save")
+    public R save(@RequestBody BasLed basLed) {
+        if (!basLedService.save(basLed)) {
+            return R.error("娣诲姞澶辫触");
+        }
+        return R.ok("娣诲姞鎴愬姛");
+    }
+
+    @PreAuthorize("hasAuthority('core:basLed:update')")
+    @OperationLog("淇敼LED鏄剧ず灞忛厤缃�")
+    @PostMapping("/basLed/update")
+    public R update(@RequestBody BasLed basLed) {
+        if (!basLedService.updateById(basLed)) {
+            return R.error("淇敼澶辫触");
+        }
+        return R.ok("淇敼鎴愬姛");
+    }
+
+    @PreAuthorize("hasAuthority('core:basLed:remove')")
+    @OperationLog("鍒犻櫎LED鏄剧ず灞忛厤缃�")
+    @PostMapping("/basLed/remove/{ids}")
+    public R remove(@PathVariable Long[] ids) {
+        if (!basLedService.removeByIds(Arrays.asList(ids))) {
+            return R.error("鍒犻櫎澶辫触");
+        }
+        return R.ok("鍒犻櫎鎴愬姛");
+    }
+
+    @PreAuthorize("hasAuthority('core:basLed:list')")
+    @PostMapping("/basLed/query")
+    public R query(@RequestParam(required = false) String condition) {
+        List<KeyValVo> vos = new ArrayList<>();
+        LambdaQueryWrapper<BasLed> wrapper = new LambdaQueryWrapper<>();
+        if (!Cools.isEmpty(condition)) {
+            wrapper.like(BasLed::getLedNo, condition);
+        }
+        basLedService.page(new Page<>(1, 30), wrapper).getRecords().forEach(
+                item -> vos.add(new KeyValVo(item.getId(), item.getLedNo()))
+        );
+        return R.ok().add(vos);
+    }
+
+    @PreAuthorize("hasAuthority('core:basLed:list')")
+    @PostMapping("/basLed/export")
+    public void export(@RequestBody Map<String, Object> map, HttpServletResponse response) throws Exception {
+        ExcelUtil.build(ExcelUtil.create(basLedService.list(), BasLed.class), response);
+    }
+
+}
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
index 39d86d7..d248998 100644
--- 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
@@ -222,7 +222,6 @@
     //璺戝簱绯荤粺
     @PreAuthorize("hasAuthority('core:basShuttle:operator')")
     @PostMapping("/basShuttle/moveLoc")
-    @Transactional
     public synchronized R shuttleMoveLoc(@RequestBody ShuttleMoveLocParam param) {
         Device device = deviceService.getOne(new LambdaQueryWrapper<Device>()
                 .eq(Device::getDeviceType, DeviceCtgType.SHUTTLE.val())
@@ -251,4 +250,31 @@
         return R.ok();
     }
 
+    //璺戝簱绯荤粺鍏抽棴
+    @PreAuthorize("hasAuthority('core:basShuttle:operator')")
+    @PostMapping("/basShuttle/moveLocClose")
+    public synchronized R shuttleMoveLocClose(@RequestBody ShuttleMoveLocParam param) {
+        Device device = deviceService.getOne(new LambdaQueryWrapper<Device>()
+                .eq(Device::getDeviceType, DeviceCtgType.SHUTTLE.val())
+                .eq(Device::getStatus, 1)
+                .eq(Device::getHostId, getHostId())
+                .eq(Device::getDeviceNo, param.getShuttleNo()));
+        if (device == null) {
+            return R.error();
+        }
+
+        ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, device.getId().intValue());
+        if (shuttleThread == null) {
+            return R.error();
+        }
+
+        ShuttleProtocol shuttleProtocol = shuttleThread.getStatus();
+        if (shuttleProtocol == null) {
+            return R.error();
+        }
+
+        shuttleThread.enableMoveLoc(null, false);
+        return R.ok();
+    }
+
 }
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/domain/dto/MatDto.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/domain/dto/MatDto.java
new file mode 100644
index 0000000..7674020
--- /dev/null
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/domain/dto/MatDto.java
@@ -0,0 +1,76 @@
+package com.zy.asrs.wcs.core.domain.dto;
+
+import lombok.Data;
+
+/**
+ * Created by vincent on 2020/8/6
+ */
+@Data
+public class MatDto {
+
+    // 鐗╂枡缂栧彿
+    private String matNo;
+
+    // 鐗╂枡鍚嶇О
+    private String maknx;
+
+    // 搴撲綅瑙勬牸
+    private String specs;
+
+    // 鐗╂枡鏁伴噺
+    private Double count;
+
+    // 搴撲綅鏁伴噺
+    private Double total;
+
+    // 鐗╂枡鍚嶇О
+    private String model;
+
+    // 绠辩爜
+    private String containerCode;
+
+    // 鏉$爜
+    private String batch;
+
+    // 璁㈠崟缂栧彿
+    private String orderNo;
+
+    public MatDto() {
+    }
+
+    public MatDto(String matNo, String maknx, Double count) {
+        this.matNo = matNo;
+        this.maknx = maknx;
+        this.count = count;
+    }
+    public MatDto(String matNo, String maknx, Double count, String specs) {
+        this.specs = specs;
+        this.matNo = matNo;
+        this.maknx = maknx;
+        this.count = count;
+    }
+    public MatDto(String matNo, String maknx, Double count, Double total, String specs) {
+        this.specs = specs;
+        this.matNo = matNo;
+        this.maknx = maknx;
+        this.count = count;
+        this.total = total;
+    }
+    public MatDto(String matNo, String maknx, Double count, Double total, String specs, String containerCode) {
+        this.containerCode = containerCode;
+        this.specs = specs;
+        this.matNo = matNo;
+        this.maknx = maknx;
+        this.count = count;
+        this.total = total;
+    }
+    public MatDto(String matNo, String maknx, Double count, Double total, String specs, String containerCode, String orderNo) {
+        this.containerCode = containerCode;
+        this.specs = specs;
+        this.matNo = matNo;
+        this.maknx = maknx;
+        this.count = count;
+        this.total = total;
+        this.orderNo = orderNo;
+    }
+}
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/domain/dto/StaDto.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/domain/dto/StaDto.java
new file mode 100644
index 0000000..e4e2b82
--- /dev/null
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/domain/dto/StaDto.java
@@ -0,0 +1,18 @@
+package com.zy.asrs.wcs.core.domain.dto;
+
+import lombok.Data;
+
+@Data
+public class StaDto {
+
+    private Integer staNo;
+
+    private Integer barcode;
+
+    private Integer backSta;
+
+    private Integer led;
+
+    private Integer liftNo;
+
+}
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/entity/BasConveyor.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/entity/BasConveyor.java
new file mode 100644
index 0000000..a24e153
--- /dev/null
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/entity/BasConveyor.java
@@ -0,0 +1,234 @@
+package com.zy.asrs.wcs.core.entity;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import com.zy.asrs.wcs.rcs.entity.Device;
+import com.zy.asrs.wcs.rcs.service.DeviceService;
+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_conveyor")
+public class BasConveyor implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value= "")
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+
+    /**
+     * 璁惧id
+     */
+    @ApiModelProperty(value= "璁惧id")
+    private Long deviceId;
+
+    /**
+     * 杈撻�佺嚎鍙�
+     */
+    @ApiModelProperty(value= "杈撻�佺嚎鍙�")
+    private Integer conveyorNo;
+
+    /**
+     * 淇敼浜哄憳
+     */
+    @ApiModelProperty(value= "淇敼浜哄憳")
+    private Long updateBy;
+
+    /**
+     * 鍒涘缓浜哄憳
+     */
+    @ApiModelProperty(value= "鍒涘缓浜哄憳")
+    private Long createBy;
+
+    /**
+     * 鍒涘缓鏃堕棿
+     */
+    @ApiModelProperty(value= "鍒涘缓鏃堕棿")
+    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
+    private Date createTime;
+
+    /**
+     * 淇敼鏃堕棿
+     */
+    @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;
+
+    /**
+     * 鍏ュ簱绔欑偣鍒楄〃
+     */
+    @ApiModelProperty(value= "鍏ュ簱绔欑偣鍒楄〃")
+    private String inSta;
+
+    /**
+     * 绌烘澘鍏ュ簱绔欑偣鍒楄〃
+     */
+    @ApiModelProperty(value= "绌烘澘鍏ュ簱绔欑偣鍒楄〃")
+    private String emptyInSta;
+
+    /**
+     * 鎷f枡鍏ュ簱绔欑偣鍒楄〃
+     */
+    @ApiModelProperty(value= "鎷f枡鍏ュ簱绔欑偣鍒楄〃")
+    private String pickInSta;
+
+    /**
+     * 鍑哄簱绔欑偣鍒楄〃
+     */
+    @ApiModelProperty(value= "鍑哄簱绔欑偣鍒楄〃")
+    private String outSta;
+
+    /**
+     * 绌烘澘鍑哄簱绔欑偣鍒楄〃
+     */
+    @ApiModelProperty(value= "绌烘澘鍑哄簱绔欑偣鍒楄〃")
+    private String emptyOutSta;
+
+    /**
+     * 鎷f枡鍑哄簱绔欑偣鍒楄〃
+     */
+    @ApiModelProperty(value= "鎷f枡鍑哄簱绔欑偣鍒楄〃")
+    private String pickOutSta;
+
+    public BasConveyor() {}
+
+    public BasConveyor(Long deviceId,Integer conveyorNo,Long updateBy,Long createBy,Date createTime,Date updateTime,String memo,Integer deleted,Long hostId,String inSta,String emptyInSta,String pickInSta,String outSta,String emptyOutSta,String pickOutSta) {
+        this.deviceId = deviceId;
+        this.conveyorNo = conveyorNo;
+        this.updateBy = updateBy;
+        this.createBy = createBy;
+        this.createTime = createTime;
+        this.updateTime = updateTime;
+        this.memo = memo;
+        this.deleted = deleted;
+        this.hostId = hostId;
+        this.inSta = inSta;
+        this.emptyInSta = emptyInSta;
+        this.pickInSta = pickInSta;
+        this.outSta = outSta;
+        this.emptyOutSta = emptyOutSta;
+        this.pickOutSta = pickOutSta;
+    }
+
+//    BasConveyor basConveyor = new BasConveyor(
+//            null,    // 璁惧id
+//            null,    // 杈撻�佺嚎鍙穂闈炵┖]
+//            null,    // 淇敼浜哄憳
+//            null,    // 鍒涘缓浜哄憳
+//            null,    // 鍒涘缓鏃堕棿
+//            null,    // 淇敼鏃堕棿
+//            null,    // 澶囨敞
+//            null,    // 鏄惁鍒犻櫎
+//            null,    // 鎵�灞炴満鏋�
+//            null,    // 鍏ュ簱绔欑偣鍒楄〃
+//            null,    // 绌烘澘鍏ュ簱绔欑偣鍒楄〃
+//            null,    // 鎷f枡鍏ュ簱绔欑偣鍒楄〃
+//            null,    // 鍑哄簱绔欑偣鍒楄〃
+//            null,    // 绌烘澘鍑哄簱绔欑偣鍒楄〃
+//            null    // 鎷f枡鍑哄簱绔欑偣鍒楄〃
+//    );
+
+    public String getDeviceId$(){
+        DeviceService service = SpringUtils.getBean(DeviceService.class);
+        Device device = service.getById(this.deviceId);
+        if (!Cools.isEmpty(device)){
+            return String.valueOf(device.getDeviceNo());
+        }
+        return null;
+    }
+
+    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 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 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/entity/BasConveyorSta.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/entity/BasConveyorSta.java
new file mode 100644
index 0000000..a89c054
--- /dev/null
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/entity/BasConveyorSta.java
@@ -0,0 +1,323 @@
+package com.zy.asrs.wcs.core.entity;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import com.zy.asrs.wcs.core.service.BasConveyorService;
+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_conveyor_sta")
+public class BasConveyorSta implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value= "")
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+
+    /**
+     * 杈撻�佺嚎id
+     */
+    @ApiModelProperty(value= "杈撻�佺嚎id")
+    private Long conveyorId;
+
+    /**
+     * 杈撻�佺嚎鍙�
+     */
+    @ApiModelProperty(value= "杈撻�佺嚎鍙�")
+    private Integer conveyorNo;
+
+    /**
+     * 淇敼浜哄憳
+     */
+    @ApiModelProperty(value= "淇敼浜哄憳")
+    private Long updateBy;
+
+    /**
+     * 鍒涘缓浜哄憳
+     */
+    @ApiModelProperty(value= "鍒涘缓浜哄憳")
+    private Long createBy;
+
+    /**
+     * 鍒涘缓鏃堕棿
+     */
+    @ApiModelProperty(value= "鍒涘缓鏃堕棿")
+    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
+    private Date createTime;
+
+    /**
+     * 淇敼鏃堕棿
+     */
+    @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;
+
+    /**
+     * 杈撻�佺珯鍙�
+     */
+    @ApiModelProperty(value= "杈撻�佺珯鍙�")
+    private Integer siteNo;
+
+    /**
+     * 鍙叆(checkBox)
+     */
+    @ApiModelProperty(value= "鍙叆(checkBox)")
+    private String inEnable;
+
+    /**
+     * 鍙嚭(checkBox)
+     */
+    @ApiModelProperty(value= "鍙嚭(checkBox)")
+    private String outEnable;
+
+    /**
+     * 鑷姩(checkBox)
+     */
+    @ApiModelProperty(value= "鑷姩(checkBox)")
+    private String autoing;
+
+    /**
+     * 鏈夌墿(checkBox)
+     */
+    @ApiModelProperty(value= "鏈夌墿(checkBox)")
+    private String loading;
+
+    /**
+     * 鑳藉叆(checkBox)
+     */
+    @ApiModelProperty(value= "鑳藉叆(checkBox)")
+    private String canining;
+
+    /**
+     * 鑳藉嚭(checkBox)
+     */
+    @ApiModelProperty(value= "鑳藉嚭(checkBox)")
+    private String canouting;
+
+    /**
+     * 楂樹綆绫诲瀷 0: 鏈煡  1: 浣庡簱浣�  2: 楂樺簱浣�  
+     */
+    @ApiModelProperty(value= "楂樹綆绫诲瀷 0: 鏈煡  1: 浣庡簱浣�  2: 楂樺簱浣�  ")
+    private Integer locType1;
+
+    /**
+     * 瀹界獎绫诲瀷 0: 鏈煡  1: 绐勫簱浣�  2: 瀹藉簱浣�  
+     */
+    @ApiModelProperty(value= "瀹界獎绫诲瀷 0: 鏈煡  1: 绐勫簱浣�  2: 瀹藉簱浣�  ")
+    private Integer locType2;
+
+    /**
+     * 杞婚噸绫诲瀷 0: 鏈煡  1: 杞诲簱浣�  2: 閲嶅簱浣�  
+     */
+    @ApiModelProperty(value= "杞婚噸绫诲瀷 0: 鏈煡  1: 杞诲簱浣�  2: 閲嶅簱浣�  ")
+    private Integer locType3;
+
+    /**
+     * 搴撲綅鍙�
+     */
+    @ApiModelProperty(value= "搴撲綅鍙�")
+    private String locNo;
+
+    /**
+     * 鍥涘悜绌挎杞︽墍璇嗗埆鐨勪簩缁寸爜
+     */
+    @ApiModelProperty(value= "鍥涘悜绌挎杞︽墍璇嗗埆鐨勪簩缁寸爜")
+    private String qrCodeValue;
+
+    public BasConveyorSta() {}
+
+    public BasConveyorSta(Long conveyorId,Integer conveyorNo,Long updateBy,Long createBy,Date createTime,Date updateTime,String memo,Integer deleted,Long hostId,Integer siteNo,String inEnable,String outEnable,String autoing,String loading,String canining,String canouting,Integer locType1,Integer locType2,Integer locType3,String locNo,String qrCodeValue) {
+        this.conveyorId = conveyorId;
+        this.conveyorNo = conveyorNo;
+        this.updateBy = updateBy;
+        this.createBy = createBy;
+        this.createTime = createTime;
+        this.updateTime = updateTime;
+        this.memo = memo;
+        this.deleted = deleted;
+        this.hostId = hostId;
+        this.siteNo = siteNo;
+        this.inEnable = inEnable;
+        this.outEnable = outEnable;
+        this.autoing = autoing;
+        this.loading = loading;
+        this.canining = canining;
+        this.canouting = canouting;
+        this.locType1 = locType1;
+        this.locType2 = locType2;
+        this.locType3 = locType3;
+        this.locNo = locNo;
+        this.qrCodeValue = qrCodeValue;
+    }
+
+//    BasConveyorSta basConveyorSta = new BasConveyorSta(
+//            null,    // 杈撻�佺嚎id
+//            null,    // 杈撻�佺嚎鍙穂闈炵┖]
+//            null,    // 淇敼浜哄憳
+//            null,    // 鍒涘缓浜哄憳
+//            null,    // 鍒涘缓鏃堕棿
+//            null,    // 淇敼鏃堕棿
+//            null,    // 澶囨敞
+//            null,    // 鏄惁鍒犻櫎
+//            null,    // 鎵�灞炴満鏋�
+//            null,    // 杈撻�佺珯鍙�
+//            null,    // 鍙叆(checkBox)
+//            null,    // 鍙嚭(checkBox)
+//            null,    // 鑷姩(checkBox)
+//            null,    // 鏈夌墿(checkBox)
+//            null,    // 鑳藉叆(checkBox)
+//            null,    // 鑳藉嚭(checkBox)
+//            null,    // 楂樹綆绫诲瀷
+//            null,    // 瀹界獎绫诲瀷
+//            null,    // 杞婚噸绫诲瀷
+//            null,    // 搴撲綅鍙�
+//            null    // 鍥涘悜绌挎杞︽墍璇嗗埆鐨勪簩缁寸爜
+//    );
+
+    public String getConveyorId$(){
+        BasConveyorService service = SpringUtils.getBean(BasConveyorService.class);
+        BasConveyor basConveyor = service.getById(this.conveyorId);
+        if (!Cools.isEmpty(basConveyor)){
+            return String.valueOf(basConveyor.getConveyorNo());
+        }
+        return null;
+    }
+
+    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 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 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;
+    }
+
+    public String getLocType1$(){
+        if (null == this.locType1){ return null; }
+        switch (this.locType1){
+            case 0:
+                return "鏈煡";
+            case 1:
+                return "浣庡簱浣�";
+            case 2:
+                return "楂樺簱浣�";
+            default:
+                return String.valueOf(this.locType1);
+        }
+    }
+
+    public String getLocType2$(){
+        if (null == this.locType2){ return null; }
+        switch (this.locType2){
+            case 0:
+                return "鏈煡";
+            case 1:
+                return "绐勫簱浣�";
+            case 2:
+                return "瀹藉簱浣�";
+            default:
+                return String.valueOf(this.locType2);
+        }
+    }
+
+    public String getLocType3$(){
+        if (null == this.locType3){ return null; }
+        switch (this.locType3){
+            case 0:
+                return "鏈煡";
+            case 1:
+                return "杞诲簱浣�";
+            case 2:
+                return "閲嶅簱浣�";
+            default:
+                return String.valueOf(this.locType3);
+        }
+    }
+
+
+}
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/entity/BasLed.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/entity/BasLed.java
new file mode 100644
index 0000000..4a15f4f
--- /dev/null
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/entity/BasLed.java
@@ -0,0 +1,212 @@
+package com.zy.asrs.wcs.core.entity;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import com.zy.asrs.wcs.core.service.BasConveyorService;
+import com.zy.asrs.wcs.rcs.entity.Device;
+import com.zy.asrs.wcs.rcs.service.DeviceService;
+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_led")
+public class BasLed implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value= "")
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+
+    /**
+     * 璁惧id
+     */
+    @ApiModelProperty(value= "璁惧id")
+    private Long deviceId;
+
+    /**
+     * LED鏄剧ず灞忓彿
+     */
+    @ApiModelProperty(value= "LED鏄剧ず灞忓彿")
+    private Integer ledNo;
+
+    /**
+     * 淇敼浜哄憳
+     */
+    @ApiModelProperty(value= "淇敼浜哄憳")
+    private Long updateBy;
+
+    /**
+     * 鍒涘缓浜哄憳
+     */
+    @ApiModelProperty(value= "鍒涘缓浜哄憳")
+    private Long createBy;
+
+    /**
+     * 鍒涘缓鏃堕棿
+     */
+    @ApiModelProperty(value= "鍒涘缓鏃堕棿")
+    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
+    private Date createTime;
+
+    /**
+     * 淇敼鏃堕棿
+     */
+    @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;
+
+    /**
+     * 鏄剧ず灞忕珯鐐瑰彿
+     */
+    @ApiModelProperty(value= "鏄剧ず灞忕珯鐐瑰彿")
+    private String sta;
+
+    /**
+     * 杈撻�佺嚎id
+     */
+    @ApiModelProperty(value= "杈撻�佺嚎id")
+    private Long conveyorId;
+
+    public BasLed() {}
+
+    public BasLed(Long deviceId,Integer ledNo,Long updateBy,Long createBy,Date createTime,Date updateTime,String memo,Integer deleted,Long hostId,String sta,Long conveyorId) {
+        this.deviceId = deviceId;
+        this.ledNo = ledNo;
+        this.updateBy = updateBy;
+        this.createBy = createBy;
+        this.createTime = createTime;
+        this.updateTime = updateTime;
+        this.memo = memo;
+        this.deleted = deleted;
+        this.hostId = hostId;
+        this.sta = sta;
+        this.conveyorId = conveyorId;
+    }
+
+//    BasLed basLed = new BasLed(
+//            null,    // 璁惧id
+//            null,    // LED鏄剧ず灞忓彿[闈炵┖]
+//            null,    // 淇敼浜哄憳
+//            null,    // 鍒涘缓浜哄憳
+//            null,    // 鍒涘缓鏃堕棿
+//            null,    // 淇敼鏃堕棿
+//            null,    // 澶囨敞
+//            null,    // 鏄惁鍒犻櫎
+//            null,    // 鎵�灞炴満鏋�
+//            null,    // 鏄剧ず灞忕珯鐐瑰彿
+//            null    // 杈撻�佺嚎id
+//    );
+
+    public String getDeviceId$(){
+        DeviceService service = SpringUtils.getBean(DeviceService.class);
+        Device device = service.getById(this.deviceId);
+        if (!Cools.isEmpty(device)){
+            return String.valueOf(device.getDeviceNo());
+        }
+        return null;
+    }
+
+    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 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 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;
+    }
+
+    public String getConveyorId$(){
+        BasConveyorService service = SpringUtils.getBean(BasConveyorService.class);
+        BasConveyor basConveyor = service.getById(this.conveyorId);
+        if (!Cools.isEmpty(basConveyor)){
+            return String.valueOf(basConveyor.getConveyorNo());
+        }
+        return null;
+    }
+
+
+}
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/mapper/BasConveyorMapper.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/mapper/BasConveyorMapper.java
new file mode 100644
index 0000000..11561c9
--- /dev/null
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/mapper/BasConveyorMapper.java
@@ -0,0 +1,12 @@
+package com.zy.asrs.wcs.core.mapper;
+
+import com.zy.asrs.wcs.core.entity.BasConveyor;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+import org.springframework.stereotype.Repository;
+
+@Mapper
+@Repository
+public interface BasConveyorMapper extends BaseMapper<BasConveyor> {
+
+}
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/mapper/BasConveyorStaMapper.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/mapper/BasConveyorStaMapper.java
new file mode 100644
index 0000000..8d2fb1d
--- /dev/null
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/mapper/BasConveyorStaMapper.java
@@ -0,0 +1,12 @@
+package com.zy.asrs.wcs.core.mapper;
+
+import com.zy.asrs.wcs.core.entity.BasConveyorSta;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+import org.springframework.stereotype.Repository;
+
+@Mapper
+@Repository
+public interface BasConveyorStaMapper extends BaseMapper<BasConveyorSta> {
+
+}
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/mapper/BasLedMapper.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/mapper/BasLedMapper.java
new file mode 100644
index 0000000..78acb06
--- /dev/null
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/mapper/BasLedMapper.java
@@ -0,0 +1,12 @@
+package com.zy.asrs.wcs.core.mapper;
+
+import com.zy.asrs.wcs.core.entity.BasLed;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+import org.springframework.stereotype.Repository;
+
+@Mapper
+@Repository
+public interface BasLedMapper extends BaseMapper<BasLed> {
+
+}
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/model/enums/DeviceCtgType.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/model/enums/DeviceCtgType.java
index 5abf648..05252e6 100644
--- a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/model/enums/DeviceCtgType.java
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/model/enums/DeviceCtgType.java
@@ -12,6 +12,7 @@
     LIFT,
     SHUTTLE,
     AGV,
+    LED,
     ;
 
     DeviceCtgType() {
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/service/BasConveyorService.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/service/BasConveyorService.java
new file mode 100644
index 0000000..8c255cf
--- /dev/null
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/service/BasConveyorService.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.BasConveyor;
+
+public interface BasConveyorService extends IService<BasConveyor> {
+
+}
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/service/BasConveyorStaService.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/service/BasConveyorStaService.java
new file mode 100644
index 0000000..cae77ab
--- /dev/null
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/service/BasConveyorStaService.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.BasConveyorSta;
+
+public interface BasConveyorStaService extends IService<BasConveyorSta> {
+
+}
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/service/BasLedService.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/service/BasLedService.java
new file mode 100644
index 0000000..1c74fcc
--- /dev/null
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/service/BasLedService.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.BasLed;
+
+public interface BasLedService extends IService<BasLed> {
+
+}
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/service/impl/BasConveyorServiceImpl.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/service/impl/BasConveyorServiceImpl.java
new file mode 100644
index 0000000..c95b20c
--- /dev/null
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/service/impl/BasConveyorServiceImpl.java
@@ -0,0 +1,12 @@
+package com.zy.asrs.wcs.core.service.impl;
+
+import com.zy.asrs.wcs.core.mapper.BasConveyorMapper;
+import com.zy.asrs.wcs.core.entity.BasConveyor;
+import com.zy.asrs.wcs.core.service.BasConveyorService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+@Service("basConveyorService")
+public class BasConveyorServiceImpl extends ServiceImpl<BasConveyorMapper, BasConveyor> implements BasConveyorService {
+
+}
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/service/impl/BasConveyorStaServiceImpl.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/service/impl/BasConveyorStaServiceImpl.java
new file mode 100644
index 0000000..c021b3e
--- /dev/null
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/service/impl/BasConveyorStaServiceImpl.java
@@ -0,0 +1,12 @@
+package com.zy.asrs.wcs.core.service.impl;
+
+import com.zy.asrs.wcs.core.mapper.BasConveyorStaMapper;
+import com.zy.asrs.wcs.core.entity.BasConveyorSta;
+import com.zy.asrs.wcs.core.service.BasConveyorStaService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+@Service("basConveyorStaService")
+public class BasConveyorStaServiceImpl extends ServiceImpl<BasConveyorStaMapper, BasConveyorSta> implements BasConveyorStaService {
+
+}
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/service/impl/BasLedServiceImpl.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/service/impl/BasLedServiceImpl.java
new file mode 100644
index 0000000..b8176fa
--- /dev/null
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/service/impl/BasLedServiceImpl.java
@@ -0,0 +1,12 @@
+package com.zy.asrs.wcs.core.service.impl;
+
+import com.zy.asrs.wcs.core.mapper.BasLedMapper;
+import com.zy.asrs.wcs.core.entity.BasLed;
+import com.zy.asrs.wcs.core.service.BasLedService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+@Service("basLedService")
+public class BasLedServiceImpl extends ServiceImpl<BasLedMapper, BasLed> implements BasLedService {
+
+}
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/service/impl/MainServiceImpl.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/service/impl/MainServiceImpl.java
index ad71444..db25c37 100644
--- a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/service/impl/MainServiceImpl.java
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/service/impl/MainServiceImpl.java
@@ -4,8 +4,12 @@
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.zy.asrs.common.domain.dto.StartupDto;
+import com.zy.asrs.common.domain.param.SearchLocParam;
+import com.zy.asrs.common.utils.HttpHandler;
 import com.zy.asrs.framework.common.Cools;
 import com.zy.asrs.framework.common.SnowflakeIdWorker;
+import com.zy.asrs.wcs.core.domain.dto.MatDto;
 import com.zy.asrs.wcs.core.domain.dto.RedisMapDto;
 import com.zy.asrs.wcs.core.domain.dto.StaDto;
 import com.zy.asrs.wcs.core.entity.*;
@@ -22,6 +26,7 @@
 import com.zy.asrs.wcs.rcs.cache.SlaveConnection;
 import com.zy.asrs.wcs.rcs.constant.DeviceRedisConstant;
 import com.zy.asrs.wcs.rcs.entity.Device;
+import com.zy.asrs.wcs.rcs.model.command.LedCommand;
 import com.zy.asrs.wcs.rcs.model.enums.ShuttleProtocolStatusType;
 import com.zy.asrs.wcs.rcs.model.enums.SlaveType;
 import com.zy.asrs.wcs.rcs.model.protocol.ShuttleProtocol;
@@ -29,6 +34,7 @@
 import com.zy.asrs.wcs.rcs.service.DeviceService;
 import com.zy.asrs.wcs.rcs.thread.BarcodeThread;
 import com.zy.asrs.wcs.rcs.thread.DevpThread;
+import com.zy.asrs.wcs.rcs.thread.LedThread;
 import com.zy.asrs.wcs.rcs.thread.ShuttleThread;
 import com.zy.asrs.wcs.system.entity.Dict;
 import com.zy.asrs.wcs.system.service.DictService;
@@ -36,7 +42,7 @@
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
-
+import org.springframework.transaction.interceptor.TransactionAspectSupport;
 import java.util.*;
 
 /**
@@ -72,6 +78,8 @@
     private RedisUtil redisUtil;
     @Autowired
     private BasConveyorService basConveyorService;
+    @Autowired
+    private BasLedService basLedService;
 
     /**
      * 缁勬墭
@@ -88,7 +96,7 @@
                 // 閬嶅巻鍏ュ簱鍙�
                 for (StaDto inSta : JSON.parseArray(basConveyor.getInSta(), StaDto.class)) {
                     // 鑾峰彇鍏ュ簱绔欎俊鎭�
-                    DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, devp.getId().intValue());
+                    DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Conveyor, devp.getId().intValue());
                     StaProtocol staProtocol = devpThread.getStation().get(inSta.getStaNo());
                     if (staProtocol == null) {
                         continue;
@@ -129,11 +137,11 @@
                     }
                     // 閫�鍥�
                     if (back) {
-//                        // led 寮傚父鏄剧ず
-//                        LedThread ledThread = (LedThread) SlaveConnection.get(SlaveType.Led, inSta.getLed());
-//                        if (ledThread != null) {
-//                            MessageQueue.offer(SlaveType.Led, inSta.getLed(), new Task(3, errMsg));
-//                        }
+                        // led 寮傚父鏄剧ず
+                        LedThread ledThread = (LedThread) SlaveConnection.get(SlaveType.Led, inSta.getLed());
+                        if (ledThread != null) {
+                            ledThread.error(errMsg);
+                        }
                         continue;
                     }
 
@@ -150,115 +158,93 @@
                         }
                         String barcode = barcodeThread.getBarcode();
                         if (!Cools.isEmpty(barcode)) {
-//                        News.info("{}鍙锋潯鐮佹壂鎻忓櫒妫�娴嬫潯鐮佷俊鎭細{}", inSta.getBarcode(), barcode);
+                            News.info("{}鍙锋潯鐮佹壂鎻忓櫒妫�娴嬫潯鐮佷俊鎭細{}", inSta.getBarcode(), barcode);
                             if ("NG".endsWith(barcode) || "NoRead".equals(barcode) || "empty".equals(barcode) || "00000000".equals(barcode)) {
-//                            staProtocol.setWorkNo((short) 32002);
-//                            staProtocol.setStaNo(inSta.getBackSta().shortValue());
-//                            devpThread.setPakMk(staProtocol.getSiteId(), false);
-//                            MessageQueue.offer(SlaveType.Devp, devp.getId(), new Task(2, staProtocol));
+                                staProtocol.setWorkNo((short) 32002);
+                                staProtocol.setStaNo(inSta.getBackSta().shortValue());
+                                devpThread.setPakMk(staProtocol.getSiteId(), false);
+                                devpThread.writeWorkSta(staProtocol.getSiteId(), (short) 32002, inSta.getBackSta().shortValue());
 
-//                                // led 寮傚父鏄剧ず
-//                                LedThread ledThread = (LedThread) SlaveConnection.get(SlaveType.Led, inSta.getLed());
-//                                if (ledThread != null) {
-//                                    String errorMsg = "鎵爜澶辫触锛岃閲嶈瘯";
-//                                    MessageQueue.offer(SlaveType.Led, inSta.getLed(), new Task(3, errorMsg));
-//                                }
+                                // led 寮傚父鏄剧ず
+                                LedThread ledThread = (LedThread) SlaveConnection.get(SlaveType.Led, inSta.getLed());
+                                if (ledThread != null) {
+                                    String errorMsg = "鎵爜澶辫触锛岃閲嶈瘯";
+                                    ledThread.error(errorMsg);
+                                }
                                 continue;
                             }
-                        } else {
-//                        staProtocol.setWorkNo((short) 32002);
-//                        staProtocol.setStaNo(inSta.getBackSta().shortValue());
-//                        devpThread.setPakMk(staProtocol.getSiteId(), false);
-//                        MessageQueue.offer(SlaveType.Devp, devp.getId(), new Task(2, staProtocol));
+                        }
 
-//                        // led 寮傚父鏄剧ず
-//                        LedThread ledThread = (LedThread) SlaveConnection.get(SlaveType.Led, inSta.getLed());
-//                        if (ledThread != null) {
-//                            String errorMsg = "鎵爜澶辫触锛岃閲嶈瘯";
-//                            MessageQueue.offer(SlaveType.Led, inSta.getLed(), new Task(3, errorMsg));
-//                        }
+                        //鑾峰彇鍏ュ簱浠诲姟绫诲瀷
+                        TaskCtg taskCtg = taskCtgService.getOne(new LambdaQueryWrapper<TaskCtg>()
+                                .eq(TaskCtg::getFlag, "IN")
+                                .eq(TaskCtg::getStatus, 1));
+
+                        // 鍒ゆ柇閲嶅宸ヤ綔妗�
+                        Task task1 = taskService.getOne(new LambdaQueryWrapper<Task>()
+                                .eq(Task::getOriginSite, inSta.getStaNo())
+                                .eq(Task::getTaskCtg, taskCtg.getId())
+                                .in(Task::getTaskSts, 1, 2, 3)
+                                .eq(Task::getZpallet, barcode));
+                        if (task1 != null) {
+                            News.error("宸ヤ綔妗e凡瀛樺湪,宸ヤ綔鍙�={}", task1.getTaskNo());
                             continue;
                         }
 
-//                        // 杩囨护鐩樼偣/鎷f枡/骞舵澘浠诲姟
-//                        WrkMast wrkMast1 = wrkMastMapper.selectPickStepByBarcode(barcode);
-//                        if (null != wrkMast1) {
-//                            continue;
-//                        }
-//
-//                        // 鍒ゆ柇閲嶅宸ヤ綔妗�
-//                        WrkMast wrkMast2 = wrkMastMapper.selectPakInStep1(inSta.getStaNo(), barcode);
-//                        if (wrkMast2 != null) {
-//                            News.error("宸ヤ綔妗d腑宸插瓨鍦ㄨ绔欑姸鎬佷负锛� 2.璁惧涓婅蛋 锛夌殑鏁版嵁,宸ヤ綔鍙�={}", wrkMast2.getWrkNo());
-//                            continue;
-//                        }
-//
-//                        try {
-//                            LocTypeDto locTypeDto = new LocTypeDto(staProtocol);
-//                            SearchLocParam param = new SearchLocParam();
-//                            param.setBarcode(barcode);
-//                            param.setIoType(1);
-//                            param.setSourceStaNo(inSta.getStaNo());
-//                            param.setLocType1(locTypeDto.getLocType1());
-//                            String response = new HttpHandler.Builder()
-//                                    .setUri(wmsUrl)
-//                                    .setPath("/rpc/pakin/loc/v2")
-//                                    .setJson(JSON.toJSONString(param))
-//                                    .build()
-//                                    .doPost();
-//                            JSONObject jsonObject = JSON.parseObject(response);
-//                            LedThread ledThread = (LedThread) SlaveConnection.get(SlaveType.Led, inSta.getLed());
-//                            Integer code = jsonObject.getInteger("code");
-//                            if (code.equals(200)) {
-//                                StartupDto dto = jsonObject.getObject("data", StartupDto.class);
-////                            staProtocol.setWorkNo(dto.getWorkNo().shortValue());
-////                            staProtocol.setStaNo(dto.getStaNo().shortValue());
-////                            devpThread.setPakMk(staProtocol.getSiteId(), false);
-////
-////                            boolean result = MessageQueue.offer(SlaveType.Devp, devp.getId(), new Task(2, staProtocol));
-////                            if (!result) {
-////                                throw new CoolException("鏇存柊plc绔欑偣淇℃伅澶辫触");
-////                            }
-//
-//                                // 鍒ゆ柇閲嶅宸ヤ綔妗�
-//                                WrkMast wrkMast = wrkMastMapper.selectPakInStep11(inSta.getStaNo());
-//                                if (wrkMast == null) {
-//                                    continue;
-//                                }
-//
-//                                // 鏇存柊宸ヤ綔涓绘。
-//                                wrkMast.setWrkSts(2L); // 宸ヤ綔鐘舵�侊細2.璁惧涓婅蛋
-//                                wrkMast.setModiTime(new Date());
-//                                if (wrkMastMapper.updateById(wrkMast) == 0) {
-//                                    News.error("鏇存柊宸ヤ綔妗eけ璐ワ紒锛侊紒 [宸ヤ綔鍙凤細{}]", wrkMast.getWrkNo());
-//                                }
-//
-//                            } else if (code == 500) {
-//                                if (ledThread != null) {
-//                                    String errorMsg = jsonObject.getString("msg");
-//                                    if (!Cools.isEmpty(errorMsg)) {
-//                                        MessageQueue.offer(SlaveType.Led, inSta.getLed(), new Task(3, errorMsg));
-//                                        ledThread.setLedMk(false);
-//                                    }
-//                                }
-//                                News.error("璇锋眰鎺ュ彛澶辫触锛侊紒锛乽rl锛歿}锛況equest锛歿}锛況esponse锛歿}", wmsUrl + "/rpc/pakin/loc/v2", JSON.toJSONString(param), response);
-//                            } else if (code == 700) {
-////                            staProtocol.setWorkNo((short) 32002);
-////                            staProtocol.setRollback102(1);//102绔欏洖閫�淇″彿
-////                            devpThread.setPakMk(staProtocol.getSiteId(), false);
-////                            MessageQueue.offer(SlaveType.Devp, devp.getId(), new Task(5, staProtocol));
-//
-//                                // led 寮傚父鏄剧ず
-//                                if (ledThread != null) {
-//                                    String errorMsg = barcode + "鎵樼洏璇嗗埆寮傚父锛岃鍏堣繘琛岀粍鎵橈紒";
-//                                    MessageQueue.offer(SlaveType.Led, inSta.getLed(), new Task(3, errorMsg));
-//                                    ledThread.setLedMk(false);
-//                                }
-//                            }
-//                        } catch (Exception e) {
-//                            e.printStackTrace();
-//                            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
-//                        }
+                        try {
+                            //鑾峰彇WMS鍦板潃
+                            Dict dict = dictService.getOne(new LambdaQueryWrapper<Dict>().eq(Dict::getFlag, "WMS_URL").eq(Dict::getStatus, 1));
+                            if (dict == null) {
+                                News.error("WMS鍦板潃鏈厤缃�");
+                                continue;
+                            }
+                            String wmsUrl = dict.getValue();
+
+                            SearchLocParam param = new SearchLocParam();
+                            param.setBarcode(barcode);
+                            param.setIoType(1);
+                            param.setSourceStaNo(inSta.getStaNo());
+                            param.setLocType1(staProtocol.getLocType1().shortValue());
+                            String response = new HttpHandler.Builder()
+                                    .setUri(wmsUrl)
+                                    .setPath("/rpc/pakin/loc/v2")
+                                    .setJson(JSON.toJSONString(param))
+                                    .build()
+                                    .doPost();
+                            JSONObject jsonObject = JSON.parseObject(response);
+                            LedThread ledThread = (LedThread) SlaveConnection.get(SlaveType.Led, inSta.getLed());
+                            Integer code = jsonObject.getInteger("code");
+                            if (code.equals(200)) {
+                                StartupDto dto = jsonObject.getObject("data", StartupDto.class);
+                                devpThread.writeWorkSta(staProtocol.getSiteId(), dto.getWorkNo().shortValue(), dto.getStaNo().shortValue());
+                                devpThread.setPakMk(staProtocol.getSiteId(), false);
+
+                            } else if (code == 500) {
+                                if (ledThread != null) {
+                                    String errorMsg = jsonObject.getString("msg");
+                                    if (!Cools.isEmpty(errorMsg)) {
+                                        ledThread.error(errorMsg);
+                                        ledThread.setLedMk(false);
+                                    }
+                                }
+                                News.error("璇锋眰鎺ュ彛澶辫触锛侊紒锛乽rl锛歿}锛況equest锛歿}锛況esponse锛歿}", wmsUrl + "/rpc/pakin/loc/v2", JSON.toJSONString(param), response);
+                            } else if (code == 700) {
+//                            staProtocol.setWorkNo((short) 32002);
+//                            staProtocol.setRollback102(1);//102绔欏洖閫�淇″彿
+//                            devpThread.setPakMk(staProtocol.getSiteId(), false);
+//                            MessageQueue.offer(SlaveType.Devp, devp.getId(), new Task(5, staProtocol));
+
+                                // led 寮傚父鏄剧ず
+                                if (ledThread != null) {
+                                    String errorMsg = barcode + "鎵樼洏璇嗗埆寮傚父锛岃鍏堣繘琛岀粍鎵橈紒";
+                                    ledThread.error(errorMsg);
+                                    ledThread.setLedMk(false);
+                                }
+                            }
+                        } catch (Exception e) {
+                            e.printStackTrace();
+                            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
+                        }
                     }
                 }
             }
@@ -444,7 +430,7 @@
         }
 
         for (Task task : tasks) {
-            DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, 1);
+            DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Conveyor, 1);
             StaProtocol staProtocol = devpThread.getStation().get(Integer.parseInt(task.getOriginSite()));//婧愮珯
             StaProtocol staProtocol1 = devpThread.getStation().get(Integer.parseInt(task.getDestSite()));//鐩爣绔�
             if (staProtocol == null || staProtocol1 == null) {
@@ -736,4 +722,152 @@
         }
     }
 
+    /**
+     * 鍑哄簱  ===>> 宸ヤ綔妗d俊鎭啓鍏ed鏄剧ず鍣�
+     */
+    public void ledExecute() {
+        // 閬嶅巻LED
+        List<Device> list = deviceService.list(new LambdaQueryWrapper<Device>()
+                .eq(Device::getDeviceType, DeviceCtgType.LED.val())
+                .eq(Device::getStatus, 1));
+        for (Device ledDevice : list) {
+            //鑾峰彇led鏁版嵁
+            BasLed led = basLedService.getOne(new LambdaQueryWrapper<BasLed>()
+                    .eq(BasLed::getDeviceId, ledDevice.getId()));
+            List<Integer> staArr = JSON.parseArray(led.getSta(), Integer.class);
+
+            // 鑾峰彇杈撻�佺嚎plc绾跨▼
+            DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Conveyor, led.getConveyorId().intValue());
+            // 鍛戒护闆嗗悎
+            List<LedCommand> commands = new ArrayList<>();
+            // 宸ヤ綔妗i泦鍚�
+            List<Task> tasks = new ArrayList<>();
+            for (Integer staNo : staArr) {
+                // 鑾峰彇鍙夎溅绔欑偣
+                StaProtocol staProtocol = devpThread.getStation().get(staNo);
+                if (null == staProtocol || null == staProtocol.getWorkNo() || 0 == staProtocol.getWorkNo() || !staProtocol.isLoading()) {
+                    continue;
+                } else {
+                    staProtocol = staProtocol.clone();
+                }
+                // 鑾峰彇宸ヤ綔妗f暟鎹�
+                Task task = taskService.getOne(new LambdaQueryWrapper<Task>().eq(Task::getTaskNo, staProtocol.getWorkNo()));
+                if (null == task) {
+                    continue;
+                }
+
+                tasks.add(task);
+                // 缁勮鍛戒护
+                LedCommand ledCommand = new LedCommand();
+                ledCommand.setWorkNo(task.getTaskNo());
+                ledCommand.setIoType(task.getTaskCtg().intValue());
+                ledCommand.setTitle(task.getTaskCtg$());
+                ledCommand.setSourceLocNo(task.getOriginLoc());
+                ledCommand.setLocNo(task.getDestLoc());
+                ledCommand.setStaNo(Integer.parseInt(task.getDestSite()));
+
+                try {
+                    //鑾峰彇WMS鍦板潃
+                    Dict dict = dictService.getOne(new LambdaQueryWrapper<Dict>().eq(Dict::getFlag, "WMS_URL").eq(Dict::getStatus, 1));
+                    if (dict != null) {
+                        String wmsUrl = dict.getValue();
+
+                        HashMap<String, Object> param = new HashMap<>();
+                        param.put("taskNo", task.getTaskNo());
+                        String response = new HttpHandler.Builder()
+                                .setUri(wmsUrl)
+                                .setPath("/queryTask")
+                                .setJson(JSON.toJSONString(param))
+                                .build()
+                                .doPost();
+                        JSONObject jsonObject = JSON.parseObject(response);
+                        Integer code = jsonObject.getInteger("code");
+                        if (code.equals(200)) {
+                            List<MatDto> matDtos = JSON.parseArray(jsonObject.getString("data"), MatDto.class);
+                            ledCommand.setMatDtos(matDtos);
+                        }
+                    }
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+
+                commands.add(ledCommand);
+            }
+            // 鑾峰彇LED绾跨▼
+            LedThread ledThread = (LedThread) SlaveConnection.get(SlaveType.Led, ledDevice.getId().intValue());
+            // 鍛戒护涓嬪彂 -------------------------------------------------------------------------------
+            if (!commands.isEmpty()) {
+                ledThread.write(commands);
+                ledThread.setLedMk(false);
+            }
+        }
+    }
+
+    /**
+     * 鍏朵粬  ===>> LED鏄剧ず鍣ㄥ浣嶏紝鏄剧ず榛樿淇℃伅
+     */
+    public void ledReset() {
+        // 鏍规嵁杈撻�佺嚎plc閬嶅巻
+        List<Device> list = deviceService.list(new LambdaQueryWrapper<Device>()
+                .eq(Device::getDeviceType, DeviceCtgType.LED.val())
+                .eq(Device::getStatus, 1));
+        for (Device ledDevice : list) {
+            //鑾峰彇led鏁版嵁
+            BasLed led = basLedService.getOne(new LambdaQueryWrapper<BasLed>()
+                    .eq(BasLed::getDeviceId, ledDevice.getId()));
+            List<Integer> staArr = JSON.parseArray(led.getSta(), Integer.class);
+
+            // 鑾峰彇杈撻�佺嚎plc绾跨▼
+            DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Conveyor, led.getConveyorId().intValue());
+            // 鍛戒护闆嗗悎
+            boolean reset = true;
+            for (Integer staNo : staArr) {
+                // 鑾峰彇鍙夎溅绔欑偣
+                StaProtocol staProtocol = devpThread.getStation().get(staNo);
+                if (staProtocol == null) {
+                    continue;
+                }
+                if (staProtocol.getWorkNo() != 0 && staProtocol.isLoading()) {
+                    reset = false;
+                    break;
+                }
+            }
+            // 鑾峰彇led绾跨▼
+            LedThread ledThread = (LedThread) SlaveConnection.get(SlaveType.Led, ledDevice.getId().intValue());
+            // led鏄剧ず榛樿鍐呭
+            if (reset && !ledThread.isLedMk()) {
+                ledThread.errorReset();
+                ledThread.setLedMk(true);
+            }
+        }
+
+        for (Device ledDevice : list) {
+            //鑾峰彇led鏁版嵁
+            BasLed led = basLedService.getOne(new LambdaQueryWrapper<BasLed>()
+                    .eq(BasLed::getDeviceId, ledDevice.getId()));
+            List<Integer> staArr = JSON.parseArray(led.getSta(), Integer.class);
+
+            // 鑾峰彇杈撻�佺嚎plc绾跨▼
+            DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Conveyor, led.getConveyorId().intValue());
+            // 鍛戒护闆嗗悎
+            boolean reset = true;
+            for (Integer staNo : staArr) {
+                // 鑾峰彇鍙夎溅绔欑偣
+                StaProtocol staProtocol = devpThread.getStation().get(staNo);
+                if (staProtocol == null) { continue; }
+                if (staProtocol.getWorkNo() != 0) {
+                    reset = false;
+                    break;
+                }
+            }
+            // 鑾峰彇led绾跨▼
+            LedThread ledThread = (LedThread) SlaveConnection.get(SlaveType.Led, ledDevice.getId().intValue());
+            // led鏄剧ず榛樿鍐呭
+            if (reset && !ledThread.isLedMk()) {
+                ledThread.reset();
+                ledThread.setLedMk(true);
+            }
+        }
+    }
+
 }
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/cache/MessageQueue.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/cache/MessageQueue.java
index e6361a6..9c84886 100644
--- a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/cache/MessageQueue.java
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/cache/MessageQueue.java
@@ -1,6 +1,6 @@
 package com.zy.asrs.wcs.rcs.cache;
 
-import com.zy.asrs.wcs.rcs.model.Task;
+import com.zy.asrs.wcs.rcs.model.MessageTask;
 import com.zy.asrs.wcs.rcs.model.enums.SlaveType;
 
 import java.util.Map;
@@ -15,27 +15,27 @@
 public class MessageQueue {
 
     // 杈撻�佺嚎mq浜ゆ崲鏈�
-    private static final Map<Integer, ConcurrentLinkedQueue<Task>> DEVP_EXCHANGE = new ConcurrentHashMap<>();
+    private static final Map<Integer, ConcurrentLinkedQueue<MessageTask>> CONVEYOR_EXCHANGE = new ConcurrentHashMap<>();
     // 鏉$爜鎵弿浠猰q浜ゆ崲鏈�
-    private static final Map<Integer, ConcurrentLinkedQueue<Task>> BARCODE_EXCHANGE = new ConcurrentHashMap<>();
+    private static final Map<Integer, ConcurrentLinkedQueue<MessageTask>> BARCODE_EXCHANGE = new ConcurrentHashMap<>();
     // Led鐏� mq浜ゆ崲鏈�
-    private static final Map<Integer, LinkedBlockingQueue<Task>> LED_EXCHANGE = new ConcurrentHashMap<>();
+    private static final Map<Integer, LinkedBlockingQueue<MessageTask>> LED_EXCHANGE = new ConcurrentHashMap<>();
     // 纾呯Оmq浜ゆ崲鏈�
-    private static final Map<Integer, ConcurrentLinkedQueue<Task>> SCALE_EXCHANGE = new ConcurrentHashMap<>();
+    private static final Map<Integer, ConcurrentLinkedQueue<MessageTask>> SCALE_EXCHANGE = new ConcurrentHashMap<>();
     // 鍙拌溅mq浜ゆ崲鏈�
-    private static final Map<Integer, ConcurrentLinkedQueue<Task>> CAR_EXCHANGE = new ConcurrentHashMap<>();
+    private static final Map<Integer, ConcurrentLinkedQueue<MessageTask>> CAR_EXCHANGE = new ConcurrentHashMap<>();
     //鍥涘悜绌挎杞q浜ゆ崲鏈�
-    private static final Map<Integer, ConcurrentLinkedQueue<Task>> SHUTTLE_EXCHANGE = new ConcurrentHashMap<>();
+    private static final Map<Integer, ConcurrentLinkedQueue<MessageTask>> SHUTTLE_EXCHANGE = new ConcurrentHashMap<>();
     //鎻愬崌鏈簃q浜ゆ崲鏈�
-    private static final Map<Integer, ConcurrentLinkedQueue<Task>> LIFT_EXCHANGE = new ConcurrentHashMap<>();
+    private static final Map<Integer, ConcurrentLinkedQueue<MessageTask>> LIFT_EXCHANGE = new ConcurrentHashMap<>();
 
     /**
      * mq 浜ゆ崲鏈哄垵濮嬪寲
      */
     public static void init(SlaveType type, Integer id) {
         switch (type) {
-            case Devp:
-                DEVP_EXCHANGE.put(id, new ConcurrentLinkedQueue<>());
+            case Conveyor:
+                CONVEYOR_EXCHANGE.put(id, new ConcurrentLinkedQueue<>());
                 break;
             case Barcode:
                 BARCODE_EXCHANGE.put(id, new ConcurrentLinkedQueue<>());
@@ -61,10 +61,10 @@
      * 娣诲姞鍏冪礌
      * 濡傛灉鍙戠幇闃熷垪宸叉弧鏃犳硶娣诲姞鐨勮瘽锛屼細鐩存帴杩斿洖false銆�
      */
-    public static boolean offer(SlaveType type, Integer id, Task task) {
+    public static boolean offer(SlaveType type, Integer id, MessageTask task) {
         switch (type) {
-            case Devp:
-                return DEVP_EXCHANGE.get(id).offer(task);
+            case Conveyor:
+                return CONVEYOR_EXCHANGE.get(id).offer(task);
             case Barcode:
                 return BARCODE_EXCHANGE.get(id).offer(task);
             case Led:
@@ -84,10 +84,10 @@
      * 绉婚櫎鍏冪礌
      * 鑻ラ槦鍒椾负绌猴紝杩斿洖null銆�
      */
-    public static Task poll(SlaveType type, Integer id) {
+    public static MessageTask poll(SlaveType type, Integer id) {
         switch (type) {
-            case Devp:
-                return DEVP_EXCHANGE.get(id).poll();
+            case Conveyor:
+                return CONVEYOR_EXCHANGE.get(id).poll();
             case Barcode:
                 return BARCODE_EXCHANGE.get(id).poll();
             case Led:
@@ -106,10 +106,10 @@
     /**
      * 鍙栧嚭鍏冪礌锛屽苟涓嶅垹闄�.
      */
-    public static Task peek(SlaveType type, Integer id) {
+    public static MessageTask peek(SlaveType type, Integer id) {
         switch (type) {
-            case Devp:
-                return DEVP_EXCHANGE.get(id).peek();
+            case Conveyor:
+                return CONVEYOR_EXCHANGE.get(id).peek();
             case Barcode:
                 return BARCODE_EXCHANGE.get(id).peek();
             case Led:
@@ -127,8 +127,8 @@
 
     public static void clear(SlaveType type, Integer id){
         switch (type) {
-            case Devp:
-                DEVP_EXCHANGE.get(id).clear();
+            case Conveyor:
+                CONVEYOR_EXCHANGE.get(id).clear();
                 break;
             case Barcode:
                 BARCODE_EXCHANGE.get(id).clear();
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/model/Task.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/model/MessageTask.java
similarity index 68%
rename from zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/model/Task.java
rename to zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/model/MessageTask.java
index 911f686..0abfa03 100644
--- a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/model/Task.java
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/model/MessageTask.java
@@ -6,16 +6,16 @@
  * Created by vincent on 2020/8/5
  */
 @Data
-public class Task {
+public class MessageTask {
 
     private Integer step;
 
     private Object data;
 
-    public Task() {
+    public MessageTask() {
     }
 
-    public Task(Integer step, Object data) {
+    public MessageTask(Integer step, Object data) {
         this.step = step;
         this.data = data;
     }
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/model/command/LedCommand.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/model/command/LedCommand.java
new file mode 100644
index 0000000..ea7a838
--- /dev/null
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/model/command/LedCommand.java
@@ -0,0 +1,36 @@
+package com.zy.asrs.wcs.rcs.model.command;
+
+import com.zy.asrs.wcs.core.domain.dto.MatDto;
+import lombok.Data;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * led鍛戒护鎶ユ枃
+ * Created by vincent on 2020/8/11
+ */
+@Data
+public class LedCommand extends Object {
+
+    private String title;
+
+    private String workNo;
+
+    private Integer staNo;
+
+    private Integer sourceStaNo;
+
+    private String locNo;
+
+    private String sourceLocNo;
+
+    private List<MatDto> matDtos = new ArrayList<>();
+
+    private boolean emptyMk = false;
+
+    private Integer ioType;
+
+    private String barcode;
+
+}
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/model/enums/SlaveType.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/model/enums/SlaveType.java
index 5b117f0..043313c 100644
--- a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/model/enums/SlaveType.java
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/model/enums/SlaveType.java
@@ -3,13 +3,13 @@
 public enum SlaveType {
 
     Crn,
-    Devp,
     Barcode,
     Led,
     Scale,
     Ste,
     Shuttle,
     Lift,
+    Conveyor,
     ;
 
     public static SlaveType findInstance(String s){
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/model/protocol/StaProtocol.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/model/protocol/StaProtocol.java
index da95667..0c0a429 100644
--- a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/model/protocol/StaProtocol.java
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/model/protocol/StaProtocol.java
@@ -94,4 +94,16 @@
         return station;
     }
 
+    public Integer getLocType1() {
+        if (!this.high && !this.low) {
+            return 0;//鏈煡
+        }
+
+        if (this.low) {
+            return 1;//浣�
+        }else {
+            return 2;//楂�
+        }
+    }
+
 }
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/thread/DevpThread.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/thread/DevpThread.java
index b3bddd0..defcbc6 100644
--- a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/thread/DevpThread.java
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/thread/DevpThread.java
@@ -12,4 +12,8 @@
 
     boolean writeStaNo(int siteId,short staNo);//鍐欏叆鐩爣绔�
 
+    boolean writeWorkSta(int siteId, short workNo, short staNo);//鍐欏叆宸ヤ綔鍙峰拰鐩爣绔�
+
+    void setPakMk(Integer siteId, boolean pakMk);
+
 }
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/thread/LedThread.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/thread/LedThread.java
new file mode 100644
index 0000000..080b6ad
--- /dev/null
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/thread/LedThread.java
@@ -0,0 +1,21 @@
+package com.zy.asrs.wcs.rcs.thread;
+
+import com.zy.asrs.wcs.rcs.model.command.LedCommand;
+
+import java.util.List;
+
+public interface LedThread extends ThreadHandler{
+
+    void write(List<LedCommand> commands);
+
+    void reset();
+
+    void error(String error);
+
+    void errorReset();
+
+    void setLedMk(boolean mk);
+
+    boolean isLedMk();
+
+}
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/thread/impl/NormalLedThread.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/thread/impl/NormalLedThread.java
new file mode 100644
index 0000000..56cf09d
--- /dev/null
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/thread/impl/NormalLedThread.java
@@ -0,0 +1,96 @@
+package com.zy.asrs.wcs.rcs.thread.impl;
+
+import com.zy.asrs.wcs.core.domain.dto.MatDto;
+import com.zy.asrs.wcs.core.utils.RedisUtil;
+import com.zy.asrs.wcs.rcs.entity.Device;
+import com.zy.asrs.wcs.rcs.model.command.LedCommand;
+import com.zy.asrs.wcs.rcs.thread.LedThread;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+@Slf4j
+@SuppressWarnings("all")
+public class NormalLedThread implements LedThread, Runnable {
+
+    private Device device;
+    private RedisUtil redisUtil;
+    private Set<Integer> workNos = new HashSet<>();
+    private boolean ledMk = false;
+    private boolean resetStatus = false;    // 澶嶄綅鐘舵��
+
+    // 鏄剧ず鍣�
+    private StringBuffer stringBuffer = new StringBuffer();
+    private List<LedCommand> commandList;
+
+    private StringBuffer errorMsg = new StringBuffer();
+
+    public NormalLedThread(Device device, RedisUtil redisUtil) {
+        this.device = device;
+        this.redisUtil = redisUtil;
+    }
+
+    @Override
+    public void run() {
+    }
+
+    public void write(List<LedCommand> list) {
+        commandList = list;
+
+        StringBuilder sb = new StringBuilder();
+        for (LedCommand command : list) {
+            sb.append(command.getTitle()).append("锛�").append(command.getWorkNo()).append(")").append("\n");
+            sb.append("婧愬簱浣嶏細").append(command.getSourceLocNo()).append("\n");
+            sb.append("鐩爣绔欙細").append(command.getStaNo()).append("\n");
+            if (!command.isEmptyMk()) {
+                for (MatDto matDto : command.getMatDtos()) {
+                    sb.append("鐗╂枡缂栫爜锛�").append(matDto.getMatNo()).append("\n");
+                    sb.append("鍚嶇О锛�").append(matDto.getMaknx()).append("\n");
+                    sb.append("鏁伴噺锛�").append(matDto.getCount()).append("\n");
+                    sb.append("瑙勬牸锛�").append(matDto.getSpecs()).append("\n");
+                }
+            }
+            sb.append("\n");
+        }
+        stringBuffer.delete(0, stringBuffer.length());
+        stringBuffer.append(sb.toString());
+
+        errorReset();
+    }
+
+    public void reset() {
+        commandList = null;
+        stringBuffer.delete(0, stringBuffer.length());
+        errorMsg.delete(0, errorMsg.length());
+    }
+
+    public void error(String msg) {
+        errorMsg.delete(0, errorMsg.length());
+        errorMsg.append(msg);
+    }
+
+    public void errorReset() {
+        this.errorMsg.delete(0, errorMsg.length());
+    }
+
+    @Override
+    public boolean connect() {
+        return true;
+    }
+
+    @Override
+    public void close() {
+    }
+
+    @Override
+    public void setLedMk(boolean mk) {
+        this.ledMk = mk;
+    }
+
+    @Override
+    public boolean isLedMk() {
+        return this.ledMk;
+    }
+}
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/thread/impl/SiemensDevpThread.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/thread/impl/SiemensDevpThread.java
index f28644c..6e8f537 100644
--- a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/thread/impl/SiemensDevpThread.java
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/thread/impl/SiemensDevpThread.java
@@ -230,6 +230,28 @@
     }
 
     @Override
+    public boolean writeWorkSta(int siteId, short staNo, short workNo) {
+        int index = findStaNosIndex(siteId);
+
+        OperateResult write1 = siemensS7Net.Write("DB100." + index*6, workNo);    // 宸ヤ綔鍙�
+        OperateResult write2 = siemensS7Net.Write("DB100." + (index*6+4), staNo);    // 鐩爣绔�
+
+        if (!(write1.IsSuccess && write2.IsSuccess)) {
+            StaProtocol staProtocol = station.get(siteId);
+            if (staProtocol.getWorkNo() == 0 && staProtocol.getStaNo() ==0) {
+                staProtocol.setPakMk(true);
+            }
+            OutputQueue.DEVP.offer(MessageFormat.format("銆恵0}銆戝啓鍏ヨ緭閫佺嚎绔欑偣鏁版嵁澶辫触銆傝緭閫佺嚎plc缂栧彿={1}锛岀珯鐐规暟鎹�={2}", device.getId(), JSON.toJSON(staProtocol)));
+            log.error("鍐欏叆杈撻�佺嚎绔欑偣鏁版嵁澶辫触銆傝緭閫佺嚎plc缂栧彿={}锛岀珯鐐规暟鎹�={}", device.getId(), JSON.toJSON(staProtocol));
+        } else {
+            OutputQueue.DEVP.offer(MessageFormat.format("銆恵0}銆� 杈撻�佺嚎鍛戒护涓嬪彂 [id:{1}] >>>>> {2}", DateUtils.convert(new Date()), device.getId(), JSON.toJSON(staNo)));
+            log.info("杈撻�佺嚎鍛戒护涓嬪彂 [id:{}] >>>>> 鍛戒护涓嬪彂锛� {}",  device.getId(), JSON.toJSON(staNo));
+            return true;
+        }
+        return false;
+    }
+
+    @Override
     public Map<Integer, StaProtocol> getStation() {
         return this.station;
     }
@@ -247,4 +269,15 @@
         }
         return index;
     }
+
+    /**
+     * 璁剧疆鍏ュ簱鏍囪
+     */
+    @Override
+    public void setPakMk(Integer siteId, boolean pakMk) {
+        StaProtocol staProtocol = station.get(siteId);
+        if (null != staProtocol) {
+            staProtocol.setPakMk(pakMk);
+        }
+    }
 }
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/utils/CodeBuilder.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/utils/CodeBuilder.java
index 73b2398..a1e99f0 100644
--- a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/utils/CodeBuilder.java
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/utils/CodeBuilder.java
@@ -15,15 +15,15 @@
         generator.frontendPrefixPath = "zy-asrs-flow/";
 
         generator.sqlOsType = SqlOsType.MYSQL;
-        generator.url="192.168.4.15:3306/asrs";
+        generator.url="127.0.0.1:3306/asrs";
         generator.username="root";
-        generator.password="xltys1995";
+        generator.password="root";
 //        generator.url="47.97.1.152:51433;databasename=jkasrs";
 //        generator.username="sa";
 //        generator.password="Zoneyung@zy56$";
 
-        generator.table="wcs_task_log";
-        generator.tableName="浠诲姟鍘嗗彶璁板綍";
+        generator.table="wcs_bas_led";
+        generator.tableName="LED鏄剧ず灞忛厤缃�";
         generator.packagePath="com.zy.asrs.wcs.core";
 
         generator.build();
diff --git a/zy-asrs-wcs/src/main/resources/mapper/core/BasConveyorMapper.xml b/zy-asrs-wcs/src/main/resources/mapper/core/BasConveyorMapper.xml
new file mode 100644
index 0000000..be513cb
--- /dev/null
+++ b/zy-asrs-wcs/src/main/resources/mapper/core/BasConveyorMapper.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.BasConveyorMapper">
+
+</mapper>
diff --git a/zy-asrs-wcs/src/main/resources/mapper/core/BasConveyorStaMapper.xml b/zy-asrs-wcs/src/main/resources/mapper/core/BasConveyorStaMapper.xml
new file mode 100644
index 0000000..f40d300
--- /dev/null
+++ b/zy-asrs-wcs/src/main/resources/mapper/core/BasConveyorStaMapper.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.BasConveyorStaMapper">
+
+</mapper>
diff --git a/zy-asrs-wcs/src/main/resources/mapper/core/BasLedMapper.xml b/zy-asrs-wcs/src/main/resources/mapper/core/BasLedMapper.xml
new file mode 100644
index 0000000..eb5eaf8
--- /dev/null
+++ b/zy-asrs-wcs/src/main/resources/mapper/core/BasLedMapper.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.BasLedMapper">
+
+</mapper>

--
Gitblit v1.9.1