From 48278d6051b6e58d648178964585d35ae000ec91 Mon Sep 17 00:00:00 2001
From: Junjie <540245094@qq.com>
Date: 星期五, 30 八月 2024 15:36:56 +0800
Subject: [PATCH] #

---
 zy-asrs-wms/src/main/resources/sql/menu/operationPort.sql                                 |    9 
 zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/service/OperationPortService.java          |    8 
 zy-asrs-wms/src/main/resources/application.yml                                            |    2 
 zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/service/LocService.java                    |    4 
 zy-asrs-wms/src/main/java/com/zy/asrs/wms/utils/CodeBuilder.java                          |    4 
 zy-asrs-wms/src/main/resources/mapper/asrs/OperationPortMapper.xml                        |    5 
 zy-asrs-admin/src/components/locDetl/selectLocDetl/index.vue                              |  259 ++++++
 zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/entity/OperationPort.java                  |  195 ++++
 zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/controller/LocDetlController.java          |   41 
 zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/entity/TaskDetlFieldLog.java               |    2 
 zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/timer/TaskLogTimer.java                    |   22 
 zy-asrs-admin/src/views/loc/locDetl/edit.vue                                              |   32 
 zy-asrs-admin/src/views/task/task/index.vue                                               |   33 
 zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/service/WorkService.java                   |    9 
 zy-asrs-admin/src/views/base/operationPort/index.vue                                      |  216 +++++
 zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/entity/TaskDetlLog.java                    |    2 
 zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/service/impl/OperationPortServiceImpl.java |   12 
 zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/entity/dto/OutDetlDto.java                 |   23 
 zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/controller/OperationPortController.java    |  102 ++
 zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/mapper/LocMapper.java                      |    4 
 zy-asrs-admin/src/components/loc/map/index.vue                                            |    2 
 zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/entity/dto/OutLocDto.java                  |   18 
 zy-asrs-admin/src/views/base/operationPort/edit.vue                                       |  175 ++++
 zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/entity/TaskDetl.java                       |   21 
 zy-asrs-wms/src/main/java/com/zy/asrs/wms/utils/LocUtils.java                             |   20 
 zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/controller/TaskController.java             |   13 
 zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/entity/TaskLog.java                        |    2 
 zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/service/impl/LocServiceImpl.java           |    9 
 /dev/null                                                                                 |   18 
 zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/entity/enums/LocTypeHeightType.java        |    9 
 zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/controller/OutController.java              |   57 -
 zy-asrs-wms/src/main/resources/mapper/asrs/LocMapper.xml                                  |    5 
 zy-asrs-admin/src/views/out/manual/index.vue                                              |  311 +++++++
 zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/entity/param/OutParam.java                 |   22 
 zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/mapper/OperationPortMapper.java            |   12 
 zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/service/impl/WorkServiceImpl.java          |  174 +++
 zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/manage/OutManage.java                      |  184 +--
 zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/timer/TaskTimer.java                       |  313 +++++--
 zy-asrs-wms/src/main/java/com/zy/asrs/wms/utils/OutUtils.java                             |   96 ++
 39 files changed, 2,075 insertions(+), 370 deletions(-)

diff --git a/zy-asrs-admin/src/components/loc/map/index.vue b/zy-asrs-admin/src/components/loc/map/index.vue
index 3a1cc8b..cb39c13 100644
--- a/zy-asrs-admin/src/components/loc/map/index.vue
+++ b/zy-asrs-admin/src/components/loc/map/index.vue
@@ -323,7 +323,7 @@
         </div>
 
         <!--杈撳嚭鎿嶄綔鍜孎PS-->
-        <div style="position: absolute;bottom: 0px;left: 0px;user-select: none;">
+        <div style="position: absolute;bottom: 20px;left: 20px;user-select: none;">
             <a-button type="dashed" @click="containerAppViewCenter">
                 <CompressOutlined />
             </a-button>
diff --git a/zy-asrs-admin/src/components/locDetl/selectLocDetl/index.vue b/zy-asrs-admin/src/components/locDetl/selectLocDetl/index.vue
new file mode 100644
index 0000000..fb6a698
--- /dev/null
+++ b/zy-asrs-admin/src/components/locDetl/selectLocDetl/index.vue
@@ -0,0 +1,259 @@
+<script setup>
+import { getCurrentInstance, ref, watch, reactive } from 'vue';
+import { useRouter } from "vue-router";
+import { get, post, postForm } from '@/utils/request.js'
+import { message, Modal } from 'ant-design-vue';
+import { logout } from '@/config.js';
+import { formatMessage } from '@/utils/localeUtils.js';
+import useTableSearch from '@/utils/tableUtils.jsx';
+const context = getCurrentInstance()?.appContext.config.globalProperties;
+
+const router = useRouter();
+
+const emit = defineEmits(['handleOk'])
+
+const TABLE_KEY = 'table-mat';
+let currentPage = 1;
+let pageSize = 10;
+let tableData = ref([]);
+let selectedData = ref([]);
+const open = ref(false);
+const reload = ref(false);
+const searchInput = ref("")
+
+const showWidth = ref("60%")
+
+const {
+    getColumnSearchProps,
+} = useTableSearch();
+
+const state = reactive({
+    selectedRowKeys: [],
+    loading: false,
+    columns: [],
+});
+const onSelectChange = (selectedRowKeys) => {
+    // console.log('selectedRowKeys changed: ', selectedRowKeys);
+    state.selectedRowKeys = selectedRowKeys;
+    selectedData.value = selectedRowKeys;
+};
+
+getColumns();
+getPage();
+
+state.columns = [
+    {
+        title: formatMessage('db.man_loc_detl.loc_no', '搴撲綅鍙�'),
+        dataIndex: 'locNo',
+        width: 140,
+        ellipsis: true,
+        ...getColumnSearchProps('locNo'),
+    },
+    {
+        title: formatMessage('db.man_loc_detl.mat_id', '鍟嗗搧'),
+        dataIndex: 'matId$',
+        width: 140,
+        ellipsis: true,
+        ...getColumnSearchProps('matId$'),
+    },
+    {
+        title: formatMessage('db.man_loc_detl.matnr', '鍟嗗搧缂栧彿'),
+        dataIndex: 'matnr',
+        width: 140,
+        ellipsis: true,
+        ...getColumnSearchProps('matnr'),
+    },
+    {
+        title: formatMessage('db.man_loc_detl.order_no', '璁㈠崟鍙�'),
+        dataIndex: 'orderNo',
+        width: 140,
+        ellipsis: true,
+        ...getColumnSearchProps('orderNo'),
+    },
+    {
+        title: formatMessage('db.man_loc_detl.batch', '鎵瑰彿'),
+        dataIndex: 'batch',
+        width: 140,
+        ellipsis: true,
+        ...getColumnSearchProps('batch'),
+    },
+    {
+        title: formatMessage('db.man_loc_detl.anfme', '鏁伴噺'),
+        dataIndex: 'anfme',
+        width: 140,
+        ellipsis: true,
+        ...getColumnSearchProps('anfme'),
+    },
+    {
+        title: formatMessage('db.man_loc_detl.status', '鐘舵��'),
+        dataIndex: 'status$',
+        width: 140,
+        ellipsis: true,
+        ...getColumnSearchProps('status$'),
+    },
+    // {
+    //   title: formatMessage('db.man_loc_detl.create_time', '娣诲姞鏃堕棿'),
+    //   dataIndex: 'createTime$',
+    //   width: 140,
+    //   ellipsis: true,
+    //   ...getColumnSearchProps('createTime$'),
+    // },
+    // {
+    //   title: formatMessage('db.man_loc_detl.create_by', '娣诲姞浜哄憳'),
+    //   dataIndex: 'createBy$',
+    //   width: 140,
+    //   ellipsis: true,
+    //   ...getColumnSearchProps('createBy$'),
+    // },
+    {
+        title: formatMessage('db.man_loc_detl.update_time', '淇敼鏃堕棿'),
+        dataIndex: 'updateTime$',
+        width: 140,
+        ellipsis: true,
+        ...getColumnSearchProps('updateTime$'),
+    },
+    {
+        title: formatMessage('db.man_loc_detl.update_by', '淇敼浜哄憳'),
+        dataIndex: 'updateBy$',
+        width: 140,
+        ellipsis: true,
+        ...getColumnSearchProps('updateBy$'),
+    },
+    {
+        title: formatMessage('db.man_loc_detl.memo', '澶囨敞'),
+        dataIndex: 'memo',
+        width: 140,
+        ellipsis: true,
+        ...getColumnSearchProps('memo'),
+    },
+];
+
+//鍔犺浇鎵╁睍瀛楁
+async function getColumns() {
+    let fieldResp = await post('/api/matField/list', {
+        fieldType: 1
+    })
+    let fieldResult = fieldResp.data;
+    let tmp = state.columns;
+    if (fieldResult.code == 200) {
+        let data = fieldResult.data;
+
+        data.forEach((item) => {
+            tmp.push({
+                title: formatMessage(item.language, item.describe),
+                name: item.name,
+                dataIndex: item.name,
+                key: item.name,
+                width: 140,
+                editable: true,
+            })
+        })
+
+        // tmp.push({
+        //     title: formatMessage('common.operation', '鎿嶄綔'),
+        //     name: 'oper',
+        //     dataIndex: 'oper',
+        //     key: 'oper',
+        //     width: 140,
+        // })
+
+        state.columns = tmp;
+    } else if (result.code === 401) {
+        message.error(result.msg);
+        logout()
+    } else {
+        message.error(result.msg);
+    }
+}
+
+function getPage() {
+    post('/api/locDetl/outPage', {
+        current: currentPage,
+        pageSize: pageSize,
+        condition: searchInput.value
+    }).then((resp) => {
+        let result = resp.data;
+        if (result.code == 200) {
+            let data = result.data;
+            tableData.value = data.records;
+        } else if (result.code === 401) {
+            message.error(result.msg);
+            logout()
+        } else {
+            message.error(result.msg);
+        }
+    })
+}
+
+const handleOk = () => {
+    open.value = false;
+    let tmpKeys = selectedData.value;
+
+    post('/api/locDetl/listByIds', tmpKeys).then(resp => {
+        let result = resp.data;
+        if (result.code == 200) {
+            let tmp = result.data;
+            tmp.forEach((item) => {
+                item.workQty = item.anfme;
+            })
+            emit('handleOk', tmp)
+        } else {
+            message.error(result.msg);
+        }
+    })
+
+    state.selectedRowKeys = []
+    selectedData.value = []
+}
+
+const handleCancel = () => {
+    open.value = false;
+}
+
+const onSearch = () => {
+    getPage()
+}
+
+const reloadPage = () => {
+    currentPage = 1;
+    searchInput.value = "";
+    getPage()
+}
+
+watch(reload,(newVal,oldVal) => {
+    if(reload.value) {
+        reloadPage()
+    }
+})
+
+defineExpose({
+    tableData,
+    open,
+    showWidth,
+    reload
+})
+
+</script>
+
+<script>
+export default {
+    name: 'selectLocDetlComponent'
+}
+</script>
+
+<template>
+    <div>
+        <a-modal v-model:open="open" :width="showWidth" @ok="handleOk" @cancel="handleCancel">
+            <div class="table-header">
+                <a-input-search v-model:value="searchInput" :placeholder="formatMessage('page.input', '璇疯緭鍏�')"
+                    style="width: 200px;" @search="onSearch" />
+            </div>
+            <a-table :row-selection="{ selectedRowKeys: state.selectedRowKeys, onChange: onSelectChange }"
+                :data-source="tableData" :defaultExpandAllRows="false" :key="TABLE_KEY" rowKey="id" :scroll="{ y: 768 }"
+                :columns="state.columns">
+            </a-table>
+        </a-modal>
+    </div>
+</template>
+
+<style></style>
diff --git a/zy-asrs-admin/src/views/base/operationPort/edit.vue b/zy-asrs-admin/src/views/base/operationPort/edit.vue
new file mode 100644
index 0000000..f9d7f13
--- /dev/null
+++ b/zy-asrs-admin/src/views/base/operationPort/edit.vue
@@ -0,0 +1,175 @@
+<script setup>
+import { ref, nextTick } from 'vue';
+import { get, post, postBlob, postForm } from '@/utils/request.js'
+import { formatMessage } from '@/utils/localeUtils.js';
+import { message } from 'ant-design-vue';
+
+const formTable = ref(null);
+const submitButton = ref(null);
+const isSave = ref(true);
+const open = ref(false);
+const initFormData = {}
+let formData = ref(initFormData);
+
+const emit = defineEmits(['tableReload'])
+
+const handleOk = (e) => {
+    nextTick(() => {
+        setTimeout(() => {
+            submitButton.value.$el.click();
+        }, 100);
+    });
+};
+
+const onFinish = values => {
+    // console.log('Success:', values);
+    open.value = false;
+    post(isSave.value ? '/api/operationPort/save' : '/api/operationPort/update', formData.value).then((resp) => {
+        let result = resp.data;
+        if (result.code === 200) {
+            message.success(isSave.value ? formatMessage('page.add.success', '鏂板鎴愬姛') : formatMessage('page.update.success', '鏇存柊鎴愬姛'));
+        } else {
+            message.error(result.msg);
+        }
+        emit('tableReload', 'reload')
+        nextTick(() => {
+            formTable.value.resetFields()
+        })
+    })
+};
+const onFinishFailed = errorInfo => {
+    console.log('Failed:', errorInfo);
+};
+
+const userQueryList = ref(null); 
+userQuery();
+function userQuery() { 
+    postForm('/api/user/query', {}).then(resp => { 
+        let result = resp.data;
+        userQueryList.value = result.data;
+    })
+}
+
+
+defineExpose({
+    open,
+    formData,
+    initFormData,
+    isSave,
+})
+
+</script>
+
+<script>
+export default {
+    name: '浣滀笟鍙g鐞�-edit'
+}
+</script>
+
+<template>
+    <div>
+        <a-modal v-model:open="open"
+            :title="isSave ? formatMessage('page.add', '娣诲姞') : formatMessage('page.edit', '缂栬緫')" @ok="handleOk"
+            style="width: 600px;">
+            <a-form :model="formData" ref="formTable" name="formTable" :label-col="{ span: 8 }" :wrapper-col="{ span: 16 }"
+                style="display: flex;justify-content: space-between;flex-wrap: wrap;" autocomplete="off"
+                @finish="onFinish" @finishFailed="onFinishFailed">
+                    <a-form-item 
+                      :label="formatMessage('db.man_operation_port.flag', '浣滀笟鍙�') " 
+                      name="flag" 
+                      style="width: 250px;" 
+                            >
+                    <a-input 
+                        v-model:value="formData.flag" 
+                     /> 
+                        </a-form-item>
+                    <a-form-item 
+                      :label="formatMessage('db.man_operation_port.status', '鐘舵��') " 
+                      name="status" 
+                      style="width: 250px;" 
+                            >
+                    <a-select 
+                        v-model:value="formData.status" 
+                        :options="[
+                                { label: '姝e父', value: 1 },
+                                { label: '绂佺敤', value: 0 },
+                            ]"
+                        >
+                    </a-select>
+                        </a-form-item>
+                    <a-form-item 
+                      :label="formatMessage('db.man_operation_port.create_time', '娣诲姞鏃堕棿') " 
+                      name="createTime" 
+                      style="width: 250px;" 
+                            >
+                    <a-date-picker 
+                        v-model:value="formData.createTime" 
+                        show-time 
+                        format="YYYY-MM-DD HH:mm:ss" 
+                        value-format="YYYY-MM-DD HH:mm:ss" 
+                     /> 
+                        </a-form-item>
+                    <a-form-item 
+                      :label="formatMessage('db.man_operation_port.create_by', '娣诲姞浜哄憳') " 
+                      name="createBy" 
+                      style="width: 250px;" 
+                            >
+                    <a-select 
+                        v-model:value="formData.createBy" 
+                        :placeholder="formatMessage('common.select', '璇烽�夋嫨')" 
+                        style="width: 100%" 
+                        show-search 
+                        :options="userQueryList" 
+                        optionFilterProp="label" 
+                        optionLabelProp="label" 
+                     > 
+                    </a-select>
+                        </a-form-item>
+                    <a-form-item 
+                      :label="formatMessage('db.man_operation_port.update_time', '淇敼鏃堕棿') " 
+                      name="updateTime" 
+                      style="width: 250px;" 
+                            >
+                    <a-date-picker 
+                        v-model:value="formData.updateTime" 
+                        show-time 
+                        format="YYYY-MM-DD HH:mm:ss" 
+                        value-format="YYYY-MM-DD HH:mm:ss" 
+                     /> 
+                        </a-form-item>
+                    <a-form-item 
+                      :label="formatMessage('db.man_operation_port.update_by', '淇敼浜哄憳') " 
+                      name="updateBy" 
+                      style="width: 250px;" 
+                            >
+                    <a-select 
+                        v-model:value="formData.updateBy" 
+                        :placeholder="formatMessage('common.select', '璇烽�夋嫨')" 
+                        style="width: 100%" 
+                        show-search 
+                        :options="userQueryList" 
+                        optionFilterProp="label" 
+                        optionLabelProp="label" 
+                     > 
+                    </a-select>
+                        </a-form-item>
+                    <a-form-item 
+                      :label="formatMessage('db.man_operation_port.memo', '澶囨敞') " 
+                      name="memo" 
+                      style="width: 250px;" 
+                            >
+                    <a-input 
+                        v-model:value="formData.memo" 
+                     /> 
+                        </a-form-item>
+
+                <a-form-item>
+                    <a-button type="primary" html-type="submit" ref="submitButton"
+                        style="visibility: hidden;">Submit</a-button>
+                </a-form-item>
+            </a-form>
+        </a-modal>
+    </div>
+</template>
+
+<style></style>
diff --git a/zy-asrs-admin/src/views/base/operationPort/index.vue b/zy-asrs-admin/src/views/base/operationPort/index.vue
new file mode 100644
index 0000000..28d8df2
--- /dev/null
+++ b/zy-asrs-admin/src/views/base/operationPort/index.vue
@@ -0,0 +1,216 @@
+<script setup>
+import { getCurrentInstance, ref, computed, reactive } from 'vue';
+import { useRouter } from "vue-router";
+import { get, post, postBlob } from '@/utils/request.js'
+import { message, Modal } from 'ant-design-vue';
+import { logout } from '@/config.js';
+import EditView from './edit.vue'
+import { formatMessage } from '@/utils/localeUtils.js';
+import useTableSearch from '@/utils/tableUtils.jsx';
+const context = getCurrentInstance()?.appContext.config.globalProperties;
+
+const router = useRouter();
+
+const TABLE_KEY = 'table-operationPort';
+let currentPage = 1;
+let pageSize = 10;
+const searchInput = ref("")
+const editChild = ref(null)
+
+let tableData = ref([]);
+getPage();
+
+const {
+  getColumnSearchProps,
+  handleResizeColumn,
+} = useTableSearch();
+
+const columns = [
+        {
+            title: formatMessage('db.man_operation_port.flag', '浣滀笟鍙�'),
+            dataIndex: 'flag',
+            width: 140,
+            ellipsis: true,
+            ...getColumnSearchProps('flag'),
+        },
+        {
+            title: formatMessage('db.man_operation_port.status', '鐘舵��'),
+            dataIndex: 'status$',
+            width: 140,
+            ellipsis: true,
+            ...getColumnSearchProps('status$'),
+        },
+        {
+            title: formatMessage('db.man_operation_port.create_time', '娣诲姞鏃堕棿'),
+            dataIndex: 'createTime$',
+            width: 140,
+            ellipsis: true,
+            ...getColumnSearchProps('createTime$'),
+        },
+        {
+            title: formatMessage('db.man_operation_port.create_by', '娣诲姞浜哄憳'),
+            dataIndex: 'createBy$',
+            width: 140,
+            ellipsis: true,
+            ...getColumnSearchProps('createBy$'),
+        },
+        {
+            title: formatMessage('db.man_operation_port.update_time', '淇敼鏃堕棿'),
+            dataIndex: 'updateTime$',
+            width: 140,
+            ellipsis: true,
+            ...getColumnSearchProps('updateTime$'),
+        },
+        {
+            title: formatMessage('db.man_operation_port.update_by', '淇敼浜哄憳'),
+            dataIndex: 'updateBy$',
+            width: 140,
+            ellipsis: true,
+            ...getColumnSearchProps('updateBy$'),
+        },
+        {
+            title: formatMessage('db.man_operation_port.memo', '澶囨敞'),
+            dataIndex: 'memo',
+            width: 140,
+            ellipsis: true,
+            ...getColumnSearchProps('memo'),
+        },
+
+  {
+    title: formatMessage('common.operation', '鎿嶄綔'),
+    name: 'oper',
+    dataIndex: 'oper',
+    key: 'oper',
+    width: 140,
+    fixed: 'right',
+  },
+];
+
+const state = reactive({
+  selectedRowKeys: [],
+  loading: false,
+});
+const hasSelected = computed(() => state.selectedRowKeys.length > 0);
+const start = () => {
+  state.loading = true;
+  // ajax request after empty completing
+  setTimeout(() => {
+    state.loading = false;
+    state.selectedRowKeys = [];
+  }, 1000);
+};
+const onSelectChange = selectedRowKeys => {
+  // console.log('selectedRowKeys changed: ', selectedRowKeys);
+  state.selectedRowKeys = selectedRowKeys;
+};
+
+function getPage() {
+  post('/api/operationPort/page', {
+    current: currentPage,
+    pageSize: pageSize,
+    condition: searchInput.value
+  }).then((resp) => {
+    let result = resp.data;
+    if (result.code == 200) {
+      let data = result.data;
+      tableData.value = data;
+    } else if (result.code === 401) {
+      message.error(result.msg);
+      logout()
+    } else {
+      message.error(result.msg);
+    }
+  })
+}
+
+const handleEdit = (item) => {
+  editChild.value.open = true;
+  editChild.value.formData = item == null ? editChild.value.initFormData : JSON.parse(JSON.stringify(item));
+  editChild.value.isSave = item == null;
+}
+
+const handleDel = (rows) => {
+  Modal.confirm({
+    title: formatMessage('page.delete', '鍒犻櫎'),
+    content: formatMessage('page.delete.confirm', '纭畾鍒犻櫎璇ラ」鍚楋紵'),
+    maskClosable: true,
+    onOk: async () => {
+      const hide = message.loading(formatMessage('common.loading', '璇锋眰涓�'));
+      try {
+        post('/api/operationPort/remove/' + rows.map((row) => row.id).join(','), {}).then(resp => {
+          let result = resp.data;
+          if (result.code === 200) {
+            message.success(result.msg);
+          } else {
+            message.error(result.msg);
+          }
+          getPage()
+          hide()
+        })
+      } catch (error) {
+        message.error(formatMessage('common.fail', '璇锋眰澶辫触'));
+      }
+    },
+  });
+}
+
+const handleExport = async (intl) => {
+  postBlob('/api/operationPort/export', {}).then(result => {
+    const blob = new Blob([result.data], { type: 'application/vnd.ms-excel' });
+    window.location.href = window.URL.createObjectURL(blob);
+    return true;
+  })
+};
+
+const onSearch = () => {
+  // console.log('search');
+  getPage()
+}
+
+const onPageChange = (page, size) => {
+  currentPage = page;
+  pageSize = size;
+  getPage();
+}
+
+function handleTableReload(value) {
+  getPage()
+}
+
+</script>
+
+<script>
+export default {
+  name: '浣滀笟鍙g鐞�'
+}
+</script>
+
+<template>
+  <div>
+    <EditView ref="editChild" @tableReload="handleTableReload" />
+    <div class="table-header">
+      <a-input-search v-model:value="searchInput" :placeholder="formatMessage('page.input', '璇疯緭鍏�')"
+        style="width: 200px;" @search="onSearch" />
+      <div class="table-header-right">
+        <a-button @click="handleEdit(null)" type="primary">{{ formatMessage('page.add', '娣诲姞') }}</a-button>
+        <a-button @click="handleExport">{{ formatMessage('page.export', '瀵煎嚭') }}</a-button>
+      </div>
+    </div>
+    <a-table :row-selection="{ selectedRowKeys: state.selectedRowKeys, onChange: onSelectChange }"
+      :data-source="tableData.records" :defaultExpandAllRows="false" :key="TABLE_KEY" rowKey="id"
+      :pagination="{ total: tableData.total, onChange: onPageChange }"
+      :scroll="{ y: 768, scrollToFirstRowOnChange: true }" :columns="columns" @resizeColumn="handleResizeColumn">
+      <template #bodyCell="{ column, text, record }">
+        <template v-if="column.dataIndex === 'oper'">
+          <div style="display: flex;justify-content: space-evenly;">
+            <a-button type="link" primary @click="handleEdit(record)">{{ formatMessage('page.edit', '缂栬緫') }}</a-button>
+            <a-button type="link" danger @click="handleDel([record])">{{ formatMessage('page.delete', '鍒犻櫎')
+              }}</a-button>
+          </div>
+        </template>
+      </template>
+    </a-table>
+  </div>
+</template>
+
+<style></style>
diff --git a/zy-asrs-admin/src/views/loc/locDetl/edit.vue b/zy-asrs-admin/src/views/loc/locDetl/edit.vue
index 544d1c5..343aae5 100644
--- a/zy-asrs-admin/src/views/loc/locDetl/edit.vue
+++ b/zy-asrs-admin/src/views/loc/locDetl/edit.vue
@@ -70,19 +70,19 @@
 //鎵╁睍瀛楁
 getColumns()
 async function getColumns() {
-  let fieldResp = await post('/api/matField/list', {
-    fieldType: 1
-  })
-  let fieldResult = fieldResp.data;
-  if (fieldResult.code == 200) {
-    let data = fieldResult.data;
-    extendField.value = data;
-  } else if (result.code === 401) {
-    message.error(result.msg);
-    logout()
-  } else {
-    message.error(result.msg);
-  }
+    let fieldResp = await post('/api/matField/list', {
+        fieldType: 1
+    })
+    let fieldResult = fieldResp.data;
+    if (fieldResult.code == 200) {
+        let data = fieldResult.data;
+        extendField.value = data;
+    } else if (result.code === 401) {
+        message.error(result.msg);
+        logout()
+    } else {
+        message.error(result.msg);
+    }
 }
 
 defineExpose({
@@ -137,8 +137,7 @@
                 <a-form-item :label="formatMessage('db.man_loc_detl.anfme', '鏁伴噺')" name="anfme" style="width: 250px;">
                     <a-input v-model:value="formData.anfme" />
                 </a-form-item>
-                <a-form-item :label="formatMessage('db.man_loc_detl.status', '鐘舵��')" name="status"
-                    style="width: 250px;">
+                <a-form-item :label="formatMessage('db.man_loc_detl.status', '鐘舵��')" name="status" style="width: 250px;">
                     <a-select v-model:value="formData.status" :options="[
                         { label: '姝e父', value: 1 },
                         { label: '绂佺敤', value: 0 },
@@ -173,7 +172,8 @@
                     <a-input v-model:value="formData.memo" />
                 </a-form-item>
 
-                <a-form-item v-for="(item, index) in extendField" :key="index" :label="formatMessage(item.language, item.describe)" :name="item.name" style="width: 250px;">
+                <a-form-item v-for="(item, index) in extendField" :key="index"
+                    :label="formatMessage(item.language, item.describe)" :name="item.name" style="width: 250px;">
                     <a-input v-model:value="formData[item.name]" />
                 </a-form-item>
 
diff --git a/zy-asrs-admin/src/views/out/manual/index.vue b/zy-asrs-admin/src/views/out/manual/index.vue
new file mode 100644
index 0000000..ddd5d7b
--- /dev/null
+++ b/zy-asrs-admin/src/views/out/manual/index.vue
@@ -0,0 +1,311 @@
+<script setup>
+import { ref, reactive } from 'vue';
+import { useRouter } from "vue-router";
+import { get, post, postForm } from '@/utils/request.js'
+import { message, Modal } from 'ant-design-vue';
+import { logout } from '@/config.js';
+import { formatMessage } from '@/utils/localeUtils.js';
+import useTableSearch from '@/utils/tableUtils.jsx';
+import SelectLocDetlView from '@/components/locDetl/selectLocDetl/index.vue'
+
+const router = useRouter();
+
+const TABLE_KEY = 'table-locDetl';
+const selectLocDetlChild = ref(null)
+const selectLocDetlViewShow = ref(false)
+
+let tableData = ref([]);
+getColumns();
+
+const {
+    getColumnSearchProps,
+    handleResizeColumn,
+} = useTableSearch();
+
+const state = reactive({
+    selectedRowKeys: [],
+    loading: false,
+    columns: [],
+});
+const onSelectChange = selectedRowKeys => {
+    // console.log('selectedRowKeys changed: ', selectedRowKeys);
+    state.selectedRowKeys = selectedRowKeys;
+};
+
+state.columns = [
+    {
+        title: formatMessage('db.man_loc_detl.anfme', '鍑哄簱鏁伴噺'),
+        dataIndex: 'workQty',
+        width: 140,
+        ellipsis: true,
+        editable: true,
+    },
+    {
+        title: formatMessage('db.man_loc_detl.anfme', '搴撳瓨鏁伴噺'),
+        dataIndex: 'anfme',
+        width: 140,
+        ellipsis: true,
+    },
+    {
+        title: formatMessage('db.man_loc_detl.loc_id', '搴撲綅'),
+        dataIndex: 'locId$',
+        width: 140,
+        ellipsis: true,
+        ...getColumnSearchProps('locId$'),
+    },
+    {
+        title: formatMessage('db.man_loc_detl.loc_no', '搴撲綅鍙�'),
+        dataIndex: 'locNo',
+        width: 140,
+        ellipsis: true,
+        ...getColumnSearchProps('locNo'),
+    },
+    {
+        title: formatMessage('db.man_loc_detl.mat_id', '鍟嗗搧'),
+        dataIndex: 'matId$',
+        width: 140,
+        ellipsis: true,
+        ...getColumnSearchProps('matId$'),
+    },
+    {
+        title: formatMessage('db.man_loc_detl.matnr', '鍟嗗搧缂栧彿'),
+        dataIndex: 'matnr',
+        width: 140,
+        ellipsis: true,
+        ...getColumnSearchProps('matnr'),
+    },
+    {
+        title: formatMessage('db.man_loc_detl.order_no', '璁㈠崟鍙�'),
+        dataIndex: 'orderNo',
+        width: 140,
+        ellipsis: true,
+        ...getColumnSearchProps('orderNo'),
+    },
+    {
+        title: formatMessage('db.man_loc_detl.batch', '鎵瑰彿'),
+        dataIndex: 'batch',
+        width: 140,
+        ellipsis: true,
+        ...getColumnSearchProps('batch'),
+    },
+    {
+        title: formatMessage('db.man_loc_detl.anfme', '鏁伴噺'),
+        dataIndex: 'anfme',
+        width: 140,
+        ellipsis: true,
+        ...getColumnSearchProps('anfme'),
+    },
+    {
+        title: formatMessage('db.man_loc_detl.status', '鐘舵��'),
+        dataIndex: 'status$',
+        width: 140,
+        ellipsis: true,
+        ...getColumnSearchProps('status$'),
+    },
+    // {
+    //   title: formatMessage('db.man_loc_detl.create_time', '娣诲姞鏃堕棿'),
+    //   dataIndex: 'createTime$',
+    //   width: 140,
+    //   ellipsis: true,
+    //   ...getColumnSearchProps('createTime$'),
+    // },
+    // {
+    //   title: formatMessage('db.man_loc_detl.create_by', '娣诲姞浜哄憳'),
+    //   dataIndex: 'createBy$',
+    //   width: 140,
+    //   ellipsis: true,
+    //   ...getColumnSearchProps('createBy$'),
+    // },
+    {
+        title: formatMessage('db.man_loc_detl.update_time', '淇敼鏃堕棿'),
+        dataIndex: 'updateTime$',
+        width: 140,
+        ellipsis: true,
+        ...getColumnSearchProps('updateTime$'),
+    },
+    {
+        title: formatMessage('db.man_loc_detl.update_by', '淇敼浜哄憳'),
+        dataIndex: 'updateBy$',
+        width: 140,
+        ellipsis: true,
+        ...getColumnSearchProps('updateBy$'),
+    },
+    {
+        title: formatMessage('db.man_loc_detl.memo', '澶囨敞'),
+        dataIndex: 'memo',
+        width: 140,
+        ellipsis: true,
+        ...getColumnSearchProps('memo'),
+    },
+];
+
+//鍔犺浇鎵╁睍瀛楁
+async function getColumns() {
+    let fieldResp = await post('/api/matField/list', {
+        unique: 1,
+        fieldType: 1
+    })
+    let fieldResult = fieldResp.data;
+    let tmp = state.columns;
+    if (fieldResult.code == 200) {
+        let data = fieldResult.data;
+
+        data.forEach((item) => {
+            tmp.push({
+                title: formatMessage(item.language, item.describe),
+                name: item.name,
+                dataIndex: item.name,
+                key: item.name,
+                width: 140,
+            })
+        })
+
+        tmp.push({
+            title: formatMessage('common.operation', '鎿嶄綔'),
+            name: 'oper',
+            dataIndex: 'oper',
+            key: 'oper',
+            width: 140,
+            fixed: 'right',
+        })
+
+        state.columns = tmp;
+    } else if (result.code === 401) {
+        message.error(result.msg);
+        logout()
+    } else {
+        message.error(result.msg);
+    }
+}
+
+const openSelect = () => {
+    selectLocDetlChild.value.open = true;
+}
+
+const handleSelectLocDetlOk = (result) => {
+    let tmp = [];
+
+    if (tableData.value != undefined) {
+        tmp = [...tableData.value]
+    }
+
+    for (let i = 0; i < result.length; i++) {
+        let item = result[i]
+        let flag = false;
+        for (let j = 0; j < tmp.length; j++) {
+            let tmpItem = tmp[j]
+            if (item.id == tmpItem.id) {
+                flag = true;
+                break
+            }
+        }
+
+        if (flag) {
+            continue
+        }
+
+        tmp.push(item)
+    }
+
+    tableData.value = tmp;
+}
+
+const handleDel = (record) => {
+    let data = tableData.value;
+    let tmp = []
+
+    for (let i = 0; i < data.length; i++) {
+        let item = data[i]
+        if (item.id == record.id) {
+            continue
+        }
+        tmp.push(item)
+    }
+    tableData.value = tmp
+}
+
+const operationPort = ref(null);
+const operationPortQueryList = ref(null);
+operationPortQuery();
+function operationPortQuery() {
+    postForm('/api/operationPort/query', {}).then(resp => {
+        let result = resp.data;
+        operationPortQueryList.value = result.data;
+    })
+}
+
+const startOut = () => {
+    let detls = []
+    tableData.value.forEach((item) => {
+        let tmp = {
+            detlId: item.id,
+            anfme: item.workQty
+        }
+        detls.push(tmp)
+    })
+
+    let param = {
+        operationPort: operationPort.value,
+        detls: detls
+    }
+
+    post('/api/out/start', param).then(resp => {
+        let result = resp.data;
+        if(result.code == 200) {
+            message.success(formatMessage('page.out.success', '鍑哄簱鎴愬姛'));
+            operationPort.value = null;
+            tableData.value = [];
+            selectLocDetlChild.value.reload = true;    
+        }else {
+            message.error(result.msg);
+        }
+    })
+}
+
+</script>
+
+<script>
+export default {
+    name: '鎵嬪姩鍑哄簱'
+}
+</script>
+
+<template>
+    <div>
+        <div class="table-header">
+            <div>
+                <a-button type="primary" @click="openSelect">鎻愬彇搴撳瓨</a-button>
+
+                <a-select v-model:value="operationPort" :placeholder="formatMessage('common.select', '璇烽�夋嫨')"
+                    style="width: 120px;margin-left: 30px;" :options="operationPortQueryList" optionFilterProp="label"
+                    optionLabelProp="label">
+                </a-select>
+
+                <a-button type="primary" style="margin-left: 5px;" @click="startOut">鍚姩鍑哄簱</a-button>
+            </div>
+        </div>
+        <a-table :row-selection="{ selectedRowKeys: state.selectedRowKeys, onChange: onSelectChange }"
+            :data-source="tableData" :defaultExpandAllRows="false" :key="TABLE_KEY" rowKey="id"
+            :scroll="{ y: 768, scrollToFirstRowOnChange: true }" :columns="state.columns"
+            @resizeColumn="handleResizeColumn">
+            <template #bodyCell="{ column, text, record }">
+                <template v-if="column.dataIndex === 'oper'">
+                    <div style="display: flex;justify-content: space-evenly;">
+                        <a-button type="link" danger @click="handleDel(record)">{{ formatMessage('page.delete', '鍒犻櫎')
+                            }}</a-button>
+                    </div>
+                </template>
+
+                <template v-if="column.dataIndex === 'workQty'">
+                    <div>
+                        <a-input-number v-model:value="record[column.dataIndex]" :min="1" :max="record.anfme" />
+                    </div>
+                </template>
+            </template>
+        </a-table>
+
+        <SelectLocDetlView ref="selectLocDetlChild" @handle-ok="handleSelectLocDetlOk" />
+    </div>
+</template>
+
+<style></style>
diff --git a/zy-asrs-admin/src/views/task/task/index.vue b/zy-asrs-admin/src/views/task/task/index.vue
index 1ebbd22..734511d 100644
--- a/zy-asrs-admin/src/views/task/task/index.vue
+++ b/zy-asrs-admin/src/views/task/task/index.vue
@@ -139,7 +139,7 @@
     dataIndex: 'oper',
     key: 'oper',
     fixed: 'right',
-    width: 240,
+    width: 300,
   },
 ];
 
@@ -289,6 +289,31 @@
   });
 }
 
+const handlePick = (record) => {
+  Modal.confirm({
+    title: formatMessage('page.pick', '鎷f枡'),
+    content: formatMessage('page.pick.confirm', '纭畾鎷f枡璇ラ」鍚楋紵'),
+    maskClosable: true,
+    onOk: async () => {
+      const hide = message.loading(formatMessage('common.loading', '璇锋眰涓�'));
+      try {
+        post('/api/task/pick', record).then(resp => {
+          let result = resp.data;
+          if (result.code === 200) {
+            message.success(result.msg);
+          } else {
+            message.error(result.msg);
+          }
+          getPage()
+          hide()
+        })
+      } catch (error) {
+        message.error(formatMessage('common.fail', '璇锋眰澶辫触'));
+      }
+    },
+  });
+}
+
 </script>
 
 <script>
@@ -317,7 +342,11 @@
           <div style="display: flex;justify-content: space-evenly;">
             <a-button type="link" primary @click="showDetl(record)">{{ formatMessage('page.task.orderDetl', '浠诲姟鏄庣粏')
               }}</a-button>
-            <a-button type="link" primary @click="handleComplete(record)">{{ formatMessage('page.complete', '瀹屾垚') }}</a-button>
+            <a-button v-if="record.taskType == 103" type="link" primary @click="handlePick(record)">{{
+              formatMessage('page.pick', '鎷f枡')
+            }}</a-button>
+            <a-button type="link" primary @click="handleComplete(record)">{{ formatMessage('page.complete', '瀹屾垚')
+              }}</a-button>
             <a-button type="link" danger @click="handleCancel(record)">{{ formatMessage('page.cancel', '鍙栨秷')
               }}</a-button>
           </div>
diff --git a/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/controller/LocDetlController.java b/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/controller/LocDetlController.java
index c196ef8..3549007 100644
--- a/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/controller/LocDetlController.java
+++ b/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/controller/LocDetlController.java
@@ -3,10 +3,12 @@
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.parser.Feature;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.zy.asrs.framework.common.Cools;
 import com.zy.asrs.framework.common.R;
 import com.zy.asrs.wms.asrs.entity.*;
+import com.zy.asrs.wms.asrs.entity.enums.LocStsType;
 import com.zy.asrs.wms.asrs.mapper.LocDetlMapper;
 import com.zy.asrs.wms.asrs.service.LocDetlFieldService;
 import com.zy.asrs.wms.asrs.service.LocService;
@@ -38,27 +40,28 @@
     @Autowired
     private LocDetlFieldService locDetlFieldService;
 
-
-
     @PreAuthorize("hasAuthority('asrs:locDetl:list')")
     @PostMapping("/locDetl/page")
     public R page(@RequestBody Map<String, Object> map) {
-//        BaseParam baseParam = buildParam(map, BaseParam.class);
-//        PageParam<LocDetl, BaseParam> pageParam = new PageParam<>(baseParam, LocDetl.class);
-//
-//        PageParam<LocDetl, BaseParam> page = locDetlService.page(pageParam, pageParam.buildWrapper(true));
-//        JSONObject data = JSON.parseObject(JSON.toJSONString(page));
-//
-//        List<LocDetl> records = page.getRecords();
-//        data.put("records", records);
-//        for (LocDetl locDetl : records) {
-//            List<LocDetlField> list = locDetlFieldService.list(new LambdaQueryWrapper<LocDetlField>().eq(LocDetlField::getDetlId, locDetl.getId()));
-//            locDetl.syncField(list);
-//        }
-
         BaseParam baseParam = buildParam(map, BaseParam.class);
         PageParam<ViewLocDetl, BaseParam> pageParam = new PageParam<>(baseParam, ViewLocDetl.class);
         PageParam<ViewLocDetl, BaseParam> data = locDetlService.getPage(pageParam, pageParam.buildWrapper(true));
+        return R.ok().add(data);
+    }
+
+    @PreAuthorize("hasAuthority('asrs:locDetl:list')")
+    @PostMapping("/locDetl/outPage")
+    public R outPage(@RequestBody Map<String, Object> map) {
+        BaseParam baseParam = buildParam(map, BaseParam.class);
+        PageParam<ViewLocDetl, BaseParam> pageParam = new PageParam<>(baseParam, ViewLocDetl.class);
+
+        QueryWrapper<ViewLocDetl> queryWrapper = pageParam.buildWrapper(true);
+        List<Long> locIds = locService.listBySts(LocStsType.F.val());
+        if (locIds.isEmpty()) {
+            locIds.add(-1L);
+        }
+        queryWrapper.in("loc_id", locIds);
+        PageParam<ViewLocDetl, BaseParam> data = locDetlService.getPage(pageParam, queryWrapper);
         return R.ok().add(data);
     }
 
@@ -70,6 +73,14 @@
     }
 
     @PreAuthorize("hasAuthority('asrs:locDetl:list')")
+    @PostMapping("/locDetl/listByIds")
+    public R listByIds(@RequestBody List<Long> ids) {
+        List<LocDetl> list = locDetlService.listByIds(ids);
+        List<LocDetl> locDetls = locDetlService.parseLocDetl(list);
+        return R.ok().add(locDetls);
+    }
+
+    @PreAuthorize("hasAuthority('asrs:locDetl:list')")
     @GetMapping("/locDetl/locId/{locId}")
     public R list(@PathVariable("locId") Long locId) {
         List<LocDetl> list = locDetlService.list(new LambdaQueryWrapper<LocDetl>().eq(LocDetl::getLocId, locId));
diff --git a/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/controller/OperationPortController.java b/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/controller/OperationPortController.java
new file mode 100644
index 0000000..167a9cf
--- /dev/null
+++ b/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/controller/OperationPortController.java
@@ -0,0 +1,102 @@
+package com.zy.asrs.wms.asrs.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.wms.common.annotation.OperationLog;
+import com.zy.asrs.wms.common.domain.BaseParam;
+import com.zy.asrs.wms.common.domain.KeyValVo;
+import com.zy.asrs.wms.common.domain.PageParam;
+import com.zy.asrs.wms.asrs.entity.OperationPort;
+import com.zy.asrs.wms.asrs.service.OperationPortService;
+import com.zy.asrs.wms.system.controller.BaseController;
+import com.zy.asrs.wms.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 OperationPortController extends BaseController {
+
+    @Autowired
+    private OperationPortService operationPortService;
+
+    @PreAuthorize("hasAuthority('asrs:operationPort:list')")
+    @PostMapping("/operationPort/page")
+    public R page(@RequestBody Map<String, Object> map) {
+        BaseParam baseParam = buildParam(map, BaseParam.class);
+        PageParam<OperationPort, BaseParam> pageParam = new PageParam<>(baseParam, OperationPort.class);
+        return R.ok().add(operationPortService.page(pageParam, pageParam.buildWrapper(true)));
+    }
+
+    @PreAuthorize("hasAuthority('asrs:operationPort:list')")
+    @PostMapping("/operationPort/list")
+    public R list(@RequestBody Map<String, Object> map) {
+        return R.ok().add(operationPortService.list());
+    }
+
+    @PreAuthorize("hasAuthority('asrs:operationPort:list')")
+    @GetMapping("/operationPort/{id}")
+    public R get(@PathVariable("id") Long id) {
+        return R.ok().add(operationPortService.getById(id));
+    }
+
+    @PreAuthorize("hasAuthority('asrs:operationPort:save')")
+    @OperationLog("娣诲姞浣滀笟鍙g鐞�")
+    @PostMapping("/operationPort/save")
+    public R save(@RequestBody OperationPort operationPort) {
+        if (!operationPortService.save(operationPort)) {
+            return R.error("娣诲姞澶辫触");
+        }
+        return R.ok("娣诲姞鎴愬姛");
+    }
+
+    @PreAuthorize("hasAuthority('asrs:operationPort:update')")
+    @OperationLog("淇敼浣滀笟鍙g鐞�")
+    @PostMapping("/operationPort/update")
+    public R update(@RequestBody OperationPort operationPort) {
+        if (!operationPortService.updateById(operationPort)) {
+            return R.error("淇敼澶辫触");
+        }
+        return R.ok("淇敼鎴愬姛");
+    }
+
+    @PreAuthorize("hasAuthority('asrs:operationPort:remove')")
+    @OperationLog("鍒犻櫎浣滀笟鍙g鐞�")
+    @PostMapping("/operationPort/remove/{ids}")
+    public R remove(@PathVariable Long[] ids) {
+        if (!operationPortService.removeByIds(Arrays.asList(ids))) {
+            return R.error("鍒犻櫎澶辫触");
+        }
+        return R.ok("鍒犻櫎鎴愬姛");
+    }
+
+    @PreAuthorize("hasAuthority('asrs:operationPort:list')")
+    @PostMapping("/operationPort/query")
+    public R query(@RequestParam(required = false) String condition) {
+        List<KeyValVo> vos = new ArrayList<>();
+        LambdaQueryWrapper<OperationPort> wrapper = new LambdaQueryWrapper<>();
+        if (!Cools.isEmpty(condition)) {
+            wrapper.like(OperationPort::getId, condition);
+        }
+        operationPortService.page(new Page<>(1, 30), wrapper).getRecords().forEach(
+                item -> vos.add(new KeyValVo(item.getFlag(), item.getFlag()))
+        );
+        return R.ok().add(vos);
+    }
+
+    @PreAuthorize("hasAuthority('asrs:operationPort:list')")
+    @PostMapping("/operationPort/export")
+    public void export(@RequestBody Map<String, Object> map, HttpServletResponse response) throws Exception {
+        ExcelUtil.build(ExcelUtil.create(operationPortService.list(), OperationPort.class), response);
+    }
+
+}
diff --git a/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/controller/OutController.java b/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/controller/OutController.java
index 26fbee4..d3d6558 100644
--- a/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/controller/OutController.java
+++ b/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/controller/OutController.java
@@ -1,9 +1,7 @@
 package com.zy.asrs.wms.asrs.controller;
 
 import com.zy.asrs.framework.common.R;
-import com.zy.asrs.wms.asrs.controller.req.IdReq;
-import com.zy.asrs.wms.asrs.controller.req.OutReq;
-import com.zy.asrs.wms.asrs.entity.LocDetl;
+import com.zy.asrs.wms.asrs.entity.param.OutParam;
 import com.zy.asrs.wms.asrs.manage.OutManage;
 import com.zy.asrs.wms.system.controller.BaseController;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -12,15 +10,7 @@
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
-import java.util.List;
-import java.util.Map;
 
-/**
- * 杩欓噷澶勭悊鎵�鏈夌殑鍑哄簱娴佺▼鐨勬帴鍙�
- * 鍑哄簱閫昏緫涓昏鍦ㄦ煡璇㈠尮閰嶇殑搴撳瓨淇℃伅锛�
- * 1. 鑾峰彇搴撳瓨锛屾牴鎹潯浠讹紙鐏垫椿閰嶇疆锛夋煡璇㈠簱瀛橈紝杩斿洖缁欏墠绔緵鐢ㄦ埛閫夋嫨锛堣繑鍥炴椂锛屾瘡鏉″簱瀛樿褰曡鎼哄甫loc_detl琛ㄧ殑涓婚敭id锛岃繖鏍风珛鍗冲嚭搴擄紝鍙浼犻�抣oc_detl琛╥d+鏁伴噺锛屽氨鍙互鏄庣‘鍑哄簱鍑哄摢浜涙暟鎹簡锛屼笉闇�瑕佷簩娆″尮閰嶏級
- * 2. 鍑哄簱锛堝彧闇�瑕佷竴涓帴鍙o紙鍗�/out/start鎺ュ彛锛夛紝鍙搴撲綅璇︽儏鐨刬d鍜屽嚭搴撴暟閲忎互鍙婂嚭搴撳埌鍝釜绔欑偣锛夛紙浠ュ強娑夊強鍒扮Щ搴擄級
- */
 @RestController
 @RequestMapping("/api")
 public class OutController extends BaseController {
@@ -28,53 +18,12 @@
     @Autowired
     private OutManage outManage;
 
-
-    /**
-     * 鑾峰彇搴撳瓨
-     *
-     * @param map
-     * @return
-     */
-    @PostMapping("/out/getStock")
-    public R getStock(@RequestBody Map<String, Object> map) {
-        List<LocDetl> suitableMat = outManage.listSuitableMat(map);
-        return R.ok(suitableMat);
-    }
-
-    /**
-     * 鑾峰彇搴撳瓨
-     *
-     * @param order
-     * @return
-     */
-    @PostMapping("/out/getStockByOrder")
-    public R getStockByOrder(@RequestBody IdReq order) {
-        List<LocDetl> suitableMat = outManage.listSuitableMatByOrder(order.getId());
-        return R.ok(suitableMat);
-    }
-
-    /**
-     * 鑾峰彇搴撳瓨
-     *
-     * @param wave
-     * @return
-     */
-    @PostMapping("/out/getStockByWave")
-    public R getStockByWave(@RequestBody IdReq wave) {
-        List<LocDetl> suitableMat = outManage.listSuitableMatByWave(wave.getId());
-        return R.ok(suitableMat);
-    }
-
     /**
      * 鍑哄簱
-     * 鍑哄簱鍙渶瑕佷竴涓帴鍙o紝鍙鍑哄埌鍝釜绔欑偣锛屽簱浣嶅嚭澶氬皯鏁伴噺锛屽嵆OutReq瀵硅薄
-     *
-     * @param outReq 鍑哄簱鍒楄〃
-     * @return
      */
     @PostMapping("/out/start")
-    public R start(@RequestBody OutReq outReq) {
-        outManage.out(outReq);
+    public R start(@RequestBody OutParam param) {
+        outManage.out(param);
         return R.ok();
     }
 }
diff --git a/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/controller/TaskController.java b/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/controller/TaskController.java
index d4c90b1..48cab40 100644
--- a/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/controller/TaskController.java
+++ b/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/controller/TaskController.java
@@ -134,4 +134,17 @@
         }
     }
 
+    @PreAuthorize("hasAuthority('asrs:task:update')")
+    @OperationLog("鎷f枡浠诲姟")
+    @PostMapping("/task/pick")
+    public R pick(@RequestBody Task task) {
+        try {
+            boolean result = workService.pickTask(task.getId());
+            return R.ok("鎷f枡鎴愬姛");
+        } catch (Exception e) {
+            e.printStackTrace();
+            return R.error(e.getMessage());
+        }
+    }
+
 }
diff --git a/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/controller/req/IdReq.java b/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/controller/req/IdReq.java
deleted file mode 100644
index db76f88..0000000
--- a/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/controller/req/IdReq.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package com.zy.asrs.wms.asrs.controller.req;
-
-import lombok.Data;
-
-import java.io.Serializable;
-import java.util.List;
-
-@Data
-public class IdReq implements Serializable {
-    /**
-     * 涓婚敭id
-     */
-    private Long id;
-
-
-
-}
diff --git a/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/controller/req/OutReq.java b/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/controller/req/OutReq.java
deleted file mode 100644
index 1457d6d..0000000
--- a/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/controller/req/OutReq.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package com.zy.asrs.wms.asrs.controller.req;
-
-import lombok.Data;
-
-import java.io.Serializable;
-import java.util.List;
-
-@Data
-public class OutReq implements Serializable {
-    /**
-     * 搴撲綅鏄庣粏
-     */
-    private List<Detl> detls;
-    /**
-     * 鐩爣绔欑偣
-     */
-    private String targetSite;
-
-    @Data
-    public static class Detl {
-        /**
-         * 搴撳瓨鏄庣粏ID
-         */
-        private Long locDetlId;
-        /**
-         * 鏁伴噺
-         */
-        private Double anfme;
-    }
-
-
-}
diff --git a/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/entity/OperationPort.java b/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/entity/OperationPort.java
new file mode 100644
index 0000000..a883097
--- /dev/null
+++ b/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/entity/OperationPort.java
@@ -0,0 +1,195 @@
+package com.zy.asrs.wms.asrs.entity;
+
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import com.zy.asrs.wms.system.entity.Host;
+import com.zy.asrs.wms.system.entity.User;
+import org.springframework.format.annotation.DateTimeFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+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.wms.system.service.UserService;
+import com.zy.asrs.wms.system.service.HostService;
+import com.zy.asrs.common.utils.Synchro;
+
+import java.io.Serializable;
+import java.util.Date;
+
+@Data
+@TableName("man_operation_port")
+public class OperationPort implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * ID
+     */
+    @ApiModelProperty(value= "ID")
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+
+    /**
+     * 浣滀笟鍙�
+     */
+    @ApiModelProperty(value= "浣滀笟鍙�")
+    private String flag;
+
+    /**
+     * 鎵�灞炴満鏋�
+     */
+    @ApiModelProperty(value= "鎵�灞炴満鏋�")
+    private Long hostId;
+
+    /**
+     * 鐘舵�� 1: 姝e父  0: 绂佺敤  
+     */
+    @ApiModelProperty(value= "鐘舵�� 1: 姝e父  0: 绂佺敤  ")
+    private Integer status;
+
+    /**
+     * 鏄惁鍒犻櫎 1: 鏄�  0: 鍚�  
+     */
+    @ApiModelProperty(value= "鏄惁鍒犻櫎 1: 鏄�  0: 鍚�  ")
+    @TableLogic
+    private Integer deleted;
+
+    /**
+     * 娣诲姞鏃堕棿
+     */
+    @ApiModelProperty(value= "娣诲姞鏃堕棿")
+    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
+    private Date createTime;
+
+    /**
+     * 娣诲姞浜哄憳
+     */
+    @ApiModelProperty(value= "娣诲姞浜哄憳")
+    private Long createBy;
+
+    /**
+     * 淇敼鏃堕棿
+     */
+    @ApiModelProperty(value= "淇敼鏃堕棿")
+    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
+    private Date updateTime;
+
+    /**
+     * 淇敼浜哄憳
+     */
+    @ApiModelProperty(value= "淇敼浜哄憳")
+    private Long updateBy;
+
+    /**
+     * 澶囨敞
+     */
+    @ApiModelProperty(value= "澶囨敞")
+    private String memo;
+
+    public OperationPort() {}
+
+    public OperationPort(String flag,Long hostId,Integer status,Integer deleted,Date createTime,Long createBy,Date updateTime,Long updateBy,String memo) {
+        this.flag = flag;
+        this.hostId = hostId;
+        this.status = status;
+        this.deleted = deleted;
+        this.createTime = createTime;
+        this.createBy = createBy;
+        this.updateTime = updateTime;
+        this.updateBy = updateBy;
+        this.memo = memo;
+    }
+
+//    OperationPort operationPort = new OperationPort(
+//            null,    // 浣滀笟鍙�
+//            null,    // 鎵�灞炴満鏋�
+//            null,    // 鐘舵��
+//            null,    // 鏄惁鍒犻櫎
+//            null,    // 娣诲姞鏃堕棿
+//            null,    // 娣诲姞浜哄憳
+//            null,    // 淇敼鏃堕棿
+//            null,    // 淇敼浜哄憳
+//            null    // 澶囨敞
+//    );
+
+    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 getStatus$(){
+        if (null == this.status){ return null; }
+        switch (this.status){
+            case 1:
+                return "姝e父";
+            case 0:
+                return "绂佺敤";
+            default:
+                return String.valueOf(this.status);
+        }
+    }
+
+    public String getDeleted$(){
+        if (null == this.deleted){ return null; }
+        switch (this.deleted){
+            case 1:
+                return "鏄�";
+            case 0:
+                return "鍚�";
+            default:
+                return String.valueOf(this.deleted);
+        }
+    }
+
+    public String getCreateTime$(){
+        if (Cools.isEmpty(this.createTime)){
+            return "";
+        }
+        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.createTime);
+    }
+
+    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 getUpdateTime$(){
+        if (Cools.isEmpty(this.updateTime)){
+            return "";
+        }
+        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.updateTime);
+    }
+
+    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 void sync(Object source) {
+        Synchro.Copy(source, this);
+    }
+}
diff --git a/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/entity/TaskDetl.java b/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/entity/TaskDetl.java
index 1b6f769..0f0bb1e 100644
--- a/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/entity/TaskDetl.java
+++ b/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/entity/TaskDetl.java
@@ -6,12 +6,11 @@
 import java.text.SimpleDateFormat;
 import java.util.*;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.fasterxml.jackson.annotation.JsonAnyGetter;
 import com.zy.asrs.common.utils.Synchro;
-import com.zy.asrs.wms.asrs.service.MatService;
-import com.zy.asrs.wms.asrs.service.OrderDetlService;
-import com.zy.asrs.wms.asrs.service.OrderService;
-import com.zy.asrs.wms.asrs.service.TaskService;
+import com.zy.asrs.wms.asrs.entity.param.FieldParam;
+import com.zy.asrs.wms.asrs.service.*;
 import com.zy.asrs.wms.system.entity.Host;
 import com.zy.asrs.wms.system.entity.User;
 import org.springframework.format.annotation.DateTimeFormat;
@@ -385,5 +384,19 @@
         dynamicFields.put(key, value);
     }
 
+    //鑾峰彇绱㈠紩瀛楁
+    public List<FieldParam> getUniqueField() {
+        MatFieldService service = SpringUtils.getBean(MatFieldService.class);
+
+        List<FieldParam> list = new ArrayList<>();
+        for (MatField matField : service.list(new LambdaQueryWrapper<MatField>().eq(MatField::getUnique, 1))) {
+            FieldParam param = new FieldParam();
+            param.setName(matField.getName());
+            param.setValue(dynamicFields.get(matField.getName()));
+            list.add(param);
+        }
+        return list;
+    }
+
 
 }
diff --git a/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/entity/TaskDetlFieldLog.java b/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/entity/TaskDetlFieldLog.java
index 12feea0..e83e174 100644
--- a/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/entity/TaskDetlFieldLog.java
+++ b/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/entity/TaskDetlFieldLog.java
@@ -41,7 +41,7 @@
      * ID
      */
     @ApiModelProperty(value= "ID")
-    @TableId(value = "id", type = IdType.INPUT)
+    @TableId(value = "id", type = IdType.AUTO)
     private Long id;
 
     /**
diff --git a/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/entity/TaskDetlLog.java b/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/entity/TaskDetlLog.java
index 71e1d66..ed638ca 100644
--- a/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/entity/TaskDetlLog.java
+++ b/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/entity/TaskDetlLog.java
@@ -43,7 +43,7 @@
      * ID
      */
     @ApiModelProperty(value= "ID")
-    @TableId(value = "id", type = IdType.INPUT)
+    @TableId(value = "id", type = IdType.AUTO)
     private Long id;
 
     /**
diff --git a/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/entity/TaskLog.java b/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/entity/TaskLog.java
index 0d7ed7c..1260cf4 100644
--- a/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/entity/TaskLog.java
+++ b/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/entity/TaskLog.java
@@ -38,7 +38,7 @@
      * ID
      */
     @ApiModelProperty(value= "ID")
-    @TableId(value = "id", type = IdType.INPUT)
+    @TableId(value = "id", type = IdType.AUTO)
     private Long id;
 
     /**
diff --git a/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/entity/dto/OutDetlDto.java b/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/entity/dto/OutDetlDto.java
new file mode 100644
index 0000000..7b7a10a
--- /dev/null
+++ b/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/entity/dto/OutDetlDto.java
@@ -0,0 +1,23 @@
+package com.zy.asrs.wms.asrs.entity.dto;
+
+import lombok.Data;
+
+@Data
+public class OutDetlDto {
+
+    /**
+     * 搴撳瓨鏄庣粏ID
+     */
+    private Long detlId;
+
+    /**
+     * 鏁伴噺
+     */
+    private Double anfme;
+
+    /**
+     * 搴撳瓨鏁伴噺
+     */
+    private Double stock;
+
+}
diff --git a/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/entity/dto/OutLocDto.java b/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/entity/dto/OutLocDto.java
new file mode 100644
index 0000000..03bc7e3
--- /dev/null
+++ b/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/entity/dto/OutLocDto.java
@@ -0,0 +1,18 @@
+package com.zy.asrs.wms.asrs.entity.dto;
+
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class OutLocDto {
+
+    private Long locId;
+
+    private List<OutDetlDto> detls;
+
+    private Boolean all;
+
+    private String operationPort;
+
+}
diff --git a/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/entity/enums/LocTypeHeightType.java b/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/entity/enums/LocTypeHeightType.java
index a93ffab..cad96d8 100644
--- a/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/entity/enums/LocTypeHeightType.java
+++ b/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/entity/enums/LocTypeHeightType.java
@@ -30,4 +30,13 @@
         return null;
     }
 
+    public static LocTypeHeightType get(String flag) {
+        for (LocTypeHeightType value : LocTypeHeightType.values()) {
+            if (value.flag.equals(flag)) {
+                return value;
+            }
+        }
+        return null;
+    }
+
 }
diff --git a/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/entity/param/OutParam.java b/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/entity/param/OutParam.java
new file mode 100644
index 0000000..7874c71
--- /dev/null
+++ b/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/entity/param/OutParam.java
@@ -0,0 +1,22 @@
+package com.zy.asrs.wms.asrs.entity.param;
+
+import com.zy.asrs.wms.asrs.entity.dto.OutDetlDto;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+@Data
+public class OutParam implements Serializable {
+
+    /**
+     * 搴撲綅鏄庣粏
+     */
+    private List<OutDetlDto> detls;
+
+    /**
+     * 浣滀笟鍙�
+     */
+    private String operationPort;
+
+}
diff --git a/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/entity/po/OutStrategyPO.java b/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/entity/po/OutStrategyPO.java
deleted file mode 100644
index 5eeaf82..0000000
--- a/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/entity/po/OutStrategyPO.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package com.zy.asrs.wms.asrs.entity.po;
-
-import lombok.Data;
-
-import java.io.Serializable;
-
-@Data
-public class OutStrategyPO implements Serializable {
-
-}
diff --git a/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/manage/OutManage.java b/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/manage/OutManage.java
index b84d50a..2ae0958 100644
--- a/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/manage/OutManage.java
+++ b/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/manage/OutManage.java
@@ -1,19 +1,23 @@
 package com.zy.asrs.wms.asrs.manage;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.zy.asrs.framework.exception.CoolException;
-import com.zy.asrs.wms.asrs.controller.req.OutReq;
+import com.zy.asrs.wms.asrs.entity.dto.OutDetlDto;
+import com.zy.asrs.wms.asrs.entity.dto.OutLocDto;
+import com.zy.asrs.wms.asrs.entity.enums.LocStsType;
+import com.zy.asrs.wms.asrs.entity.param.OutParam;
 import com.zy.asrs.wms.asrs.entity.*;
-import com.zy.asrs.wms.asrs.entity.param.FieldParam;
 import com.zy.asrs.wms.asrs.service.*;
+import com.zy.asrs.wms.utils.OutUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
-import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
 
 /**
  * 鍑哄簱绠$悊
@@ -25,124 +29,98 @@
 
     @Autowired
     private TaskService taskService;
-
-
     @Autowired
     private TaskDetlService taskDetlService;
-
+    @Autowired
+    private TaskDetlFieldService taskDetlFieldService;
     @Autowired
     private LocService locService;
-
-
     @Autowired
     private LocDetlService locDetlService;
-
-
+    @Autowired
+    private LocDetlFieldService locDetlFieldService;
     @Autowired
     private WorkService workService;
-
-
     @Autowired
     private OrderService orderService;
-
     @Autowired
     private OrderDetlService orderDetlService;
+    @Autowired
+    private OutUtils outUtils;
 
-
-    /**
-     * 鑾峰彇搴撳瓨
-     *
-     * @param map
-     */
-    public List<LocDetl> listSuitableMat(Map<String, Object> map) {
-        List<FieldParam> param = new ArrayList<>();
-        map.entrySet().stream().filter(entry -> entry.getValue() != null).forEach(entry -> {
-            FieldParam fieldParam = new FieldParam();
-            fieldParam.setName(entry.getKey());
-            fieldParam.setValue(entry.getValue());
-            param.add(fieldParam);
-        });
-        //TODO 杩欓噷鍔犱笂鍑哄簱瑙勫垯
-
-        List<LocDetl> stock = locDetlService.listSuitableMat(param, null);
-        return stock;
-    }
-
-    /**
-     * 鏍规嵁璁㈠崟id鑾峰彇搴撳瓨
-     *
-     * @param orderId 璁㈠崟ID
-     */
-    public List<LocDetl> listSuitableMatByOrder(Long orderId) {
-        Order order = orderService.getById(orderId);
-        List<OrderDetl> orderDetls = orderDetlService.getOrderDetlByOrderId(orderId);
-        //TODO 杩欓噷鍔犱笂鍑哄簱瑙勫垯
-        for (OrderDetl orderDetl : orderDetls) {
-
-        }
-        List<FieldParam> param = new ArrayList<>();
-
-
-        List<LocDetl> stock = locDetlService.listSuitableMat(param, null);
-        return stock;
-    }
-
-    /**
-     * 鏍规嵁璁㈠崟id鑾峰彇搴撳瓨
-     *
-     * @param waveId 璁㈠崟ID
-     */
-    public List<LocDetl> listSuitableMatByWave(Long waveId) {
-
-        List<FieldParam> param = new ArrayList<>();
-
-
-        List<LocDetl> stock = locDetlService.listSuitableMat(param, null);
-        return stock;
-    }
 
     /**
      * 鍑哄簱
-     *
-     * @param outReq
      */
-    public void out(OutReq outReq) {
-        Map<Long, List<OutReq.Detl>> map = outReq.getDetls().stream().collect(Collectors.groupingBy(OutReq.Detl::getLocDetlId));
-        map.forEach((k, v) -> {
-            Loc loc = locService.getById(k);
-            processTask(loc, v, outReq.getTargetSite());
-        });
+    @Transactional
+    public void out(OutParam outParam) {
+        if (outParam.getOperationPort() == null) {
+            throw new CoolException("浣滀笟鍙d笉瀛樺湪");
+        }
+
+        List<OutLocDto> list = outUtils.merge(outParam);
+        processTask(list);
     }
 
+    private void processTask(List<OutLocDto> list) {
+        for (OutLocDto locDto : list) {
+            long taskType = locDto.getAll() ? 101L : 103L;
 
-    private void processTask(Loc loc, List<OutReq.Detl> detls, String targetSite) {
-        // 淇濆瓨宸ヤ綔妗�
-        Task task = new Task();
-        task.setTaskNo(workService.generateTaskNo(1L));
-        // 浠诲姟鐘舵��
-        task.setTaskSts(101L);
-        // 浠诲姟绫诲瀷
-        task.setTaskType(101L);
-        // 浼樺厛绾�
-        task.setIoPri(1);
-        // 婧愬簱浣�
-        task.setOriginLoc(loc.getLocNo());
-        // 鐩爣绔欑偣
-        task.setTargetSite(targetSite);
-        // 鎵樼洏鐮�
-        task.setBarcode(loc.getBarcode());
-        boolean res = taskService.save(task);
-        if (!res) {
-            throw new CoolException("淇濆瓨宸ヤ綔妗eけ璐�");
-        }
-        // 宸ヤ綔妗f槑缁嗕繚瀛�
-        for (OutReq.Detl detl : detls) {
-            LocDetl locDetl = locDetlService.getById(detl.getLocDetlId());
-            TaskDetl taskDetl = new TaskDetl();
-            taskDetl.sync(locDetl);
-            taskDetl.setTaskId(task.getId());
-            if (!taskDetlService.save(taskDetl)) {
-                throw new CoolException("淇濆瓨宸ヤ綔妗f槑缁嗗け璐�");
+            Loc loc = locService.getById(locDto.getLocId());
+            if(loc == null) {
+                throw new CoolException("搴撲綅涓嶅瓨鍦�");
+            }
+
+            if (!loc.getLocStsId().equals(LocStsType.F.val())) {
+                throw new CoolException("搴撲綅鐘舵�佷笉鍦ㄥ簱");
+            }
+
+            Task task = new Task();
+            task.setTaskNo(workService.generateTaskNo(1L));
+            task.setTaskSts(101L);
+            task.setTaskType(taskType);
+            task.setIoPri(workService.generateIoPri(taskType));
+            task.setOriginLoc(loc.getLocNo());
+            task.setTargetSite(locDto.getOperationPort());
+            task.setBarcode(loc.getBarcode());
+            boolean res = taskService.save(task);
+            if (!res) {
+                throw new CoolException("淇濆瓨宸ヤ綔妗eけ璐�");
+            }
+            // 宸ヤ綔妗f槑缁嗕繚瀛�
+            for (OutDetlDto detl : locDto.getDetls()) {
+                LocDetl locDetl = locDetlService.getById(detl.getDetlId());
+                if(locDetl == null) {
+                    throw new CoolException("鏄庣粏涓嶅瓨鍦�");
+                }
+
+                TaskDetl taskDetl = new TaskDetl();
+                taskDetl.sync(locDetl);
+                taskDetl.setTaskId(task.getId());
+                taskDetl.setAnfme(detl.getAnfme());
+                taskDetl.setStock(detl.getStock());
+                if (!taskDetlService.save(taskDetl)) {
+                    throw new CoolException("淇濆瓨宸ヤ綔妗f槑缁嗗け璐�");
+                }
+
+                List<LocDetlField> locDetlFields = locDetlFieldService.list(new LambdaQueryWrapper<LocDetlField>().eq(LocDetlField::getDetlId, locDetl.getId()));
+                for (LocDetlField locDetlField : locDetlFields) {
+                    TaskDetlField taskDetlField = new TaskDetlField();
+                    taskDetlField.sync(locDetlField);
+                    taskDetlField.setDetlId(taskDetl.getId());
+                    boolean taskDetlFieldSave = taskDetlFieldService.save(taskDetlField);
+                    if(!taskDetlFieldSave){
+                        throw new CoolException("鏄庣粏鎵╁睍鐢熸垚澶辫触");
+                    }
+                }
+            }
+
+            //搴撲綅F => R
+            loc.setLocStsId(LocStsType.R.val());
+            loc.setUpdateTime(new Date());
+            boolean locUpdate = locService.updateById(loc);
+            if(!locUpdate){
+                throw new CoolException("搴撲綅鐘舵�佹洿鏂板け璐�");
             }
         }
     }
diff --git a/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/mapper/LocMapper.java b/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/mapper/LocMapper.java
index 3f6a0ad..1e07c08 100644
--- a/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/mapper/LocMapper.java
+++ b/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/mapper/LocMapper.java
@@ -5,8 +5,12 @@
 import org.apache.ibatis.annotations.Mapper;
 import org.springframework.stereotype.Repository;
 
+import java.util.List;
+
 @Mapper
 @Repository
 public interface LocMapper extends BaseMapper<Loc> {
 
+    List<Long> listBySts(Long sts);
+
 }
diff --git a/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/mapper/OperationPortMapper.java b/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/mapper/OperationPortMapper.java
new file mode 100644
index 0000000..5a3e6a4
--- /dev/null
+++ b/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/mapper/OperationPortMapper.java
@@ -0,0 +1,12 @@
+package com.zy.asrs.wms.asrs.mapper;
+
+import com.zy.asrs.wms.asrs.entity.OperationPort;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+import org.springframework.stereotype.Repository;
+
+@Mapper
+@Repository
+public interface OperationPortMapper extends BaseMapper<OperationPort> {
+
+}
diff --git a/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/service/LocService.java b/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/service/LocService.java
index 81093b8..6ff46e9 100644
--- a/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/service/LocService.java
+++ b/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/service/LocService.java
@@ -3,6 +3,10 @@
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.zy.asrs.wms.asrs.entity.Loc;
 
+import java.util.List;
+
 public interface LocService extends IService<Loc> {
 
+    List<Long> listBySts(Long sts);
+
 }
diff --git a/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/service/OperationPortService.java b/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/service/OperationPortService.java
new file mode 100644
index 0000000..dd80d15
--- /dev/null
+++ b/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/service/OperationPortService.java
@@ -0,0 +1,8 @@
+package com.zy.asrs.wms.asrs.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.zy.asrs.wms.asrs.entity.OperationPort;
+
+public interface OperationPortService extends IService<OperationPort> {
+
+}
diff --git a/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/service/WorkService.java b/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/service/WorkService.java
index 1d613f3..dbde948 100644
--- a/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/service/WorkService.java
+++ b/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/service/WorkService.java
@@ -1,7 +1,10 @@
 package com.zy.asrs.wms.asrs.service;
 
 import com.zy.asrs.wms.asrs.entity.Loc;
+import com.zy.asrs.wms.asrs.entity.param.FieldParam;
 import com.zy.asrs.wms.asrs.entity.param.GeneratePakInParam;
+
+import java.util.List;
 
 public interface WorkService {
 
@@ -17,6 +20,9 @@
     //鐢熸垚鍙敤搴撲綅鍙�
     Loc generateLoc(Long taskType, String barcode, Integer locTypeHeight);
 
+    //鐢熸垚鍙敤搴撲綅鍙�
+    Loc generateLoc(Long taskType, Long matId, String batch, List<FieldParam> uniqueFields, Integer locTypeHeight);
+
     //鐢熸垚鍏ュ簱浠诲姟(婊℃墭鐩�)
     boolean generatePakIn(GeneratePakInParam param);
 
@@ -29,4 +35,7 @@
     //鍙栨秷浠诲姟
     boolean cancelTask(Long taskId);
 
+    //鎷f枡浠诲姟
+    boolean pickTask(Long taskId);
+
 }
diff --git a/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/service/impl/LocServiceImpl.java b/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/service/impl/LocServiceImpl.java
index c70fd26..c02b5f5 100644
--- a/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/service/impl/LocServiceImpl.java
+++ b/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/service/impl/LocServiceImpl.java
@@ -7,9 +7,14 @@
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import org.springframework.stereotype.Service;
 
+import java.util.Collections;
+import java.util.List;
+
 @Service("locService")
 public class LocServiceImpl extends ServiceImpl<LocMapper, Loc> implements LocService {
 
-
-
+    @Override
+    public List<Long> listBySts(Long sts) {
+        return this.baseMapper.listBySts(sts);
+    }
 }
diff --git a/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/service/impl/OperationPortServiceImpl.java b/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/service/impl/OperationPortServiceImpl.java
new file mode 100644
index 0000000..682a054
--- /dev/null
+++ b/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/service/impl/OperationPortServiceImpl.java
@@ -0,0 +1,12 @@
+package com.zy.asrs.wms.asrs.service.impl;
+
+import com.zy.asrs.wms.asrs.mapper.OperationPortMapper;
+import com.zy.asrs.wms.asrs.entity.OperationPort;
+import com.zy.asrs.wms.asrs.service.OperationPortService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+@Service("operationPortService")
+public class OperationPortServiceImpl extends ServiceImpl<OperationPortMapper, OperationPort> implements OperationPortService {
+
+}
diff --git a/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/service/impl/WorkServiceImpl.java b/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/service/impl/WorkServiceImpl.java
index 1c1748b..141bcf3 100644
--- a/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/service/impl/WorkServiceImpl.java
+++ b/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/service/impl/WorkServiceImpl.java
@@ -4,6 +4,7 @@
 import com.zy.asrs.framework.exception.CoolException;
 import com.zy.asrs.wms.asrs.entity.*;
 import com.zy.asrs.wms.asrs.entity.enums.*;
+import com.zy.asrs.wms.asrs.entity.param.FieldParam;
 import com.zy.asrs.wms.asrs.entity.param.GeneratePakInParam;
 import com.zy.asrs.wms.asrs.service.*;
 import com.zy.asrs.wms.utils.LocUtils;
@@ -50,6 +51,12 @@
     private LanewayRuleService lanewayRuleService;
     @Autowired
     private CircleRuleService circleRuleService;
+    @Autowired
+    private LocTypeBindService locTypeBindService;
+    @Autowired
+    private LocTypeService locTypeService;
+    @Autowired
+    private MatService matService;
 
     @Override
     public String generateTaskNo(Long taskType) {
@@ -134,7 +141,7 @@
     }
 
     @Override
-    public Loc generateLoc(Long taskType, String barcode, Integer locTypeHeight) {
+    public synchronized Loc generateLoc(Long taskType, String barcode, Integer locTypeHeight) {
         List<WaitPakin> waitPakins = waitPakinService.list(new LambdaQueryWrapper<WaitPakin>().eq(WaitPakin::getBarcode, barcode));
         if (taskType != 10 && waitPakins.isEmpty()) {
             throw new CoolException("鎵樼洏鏈粍鎵�");
@@ -145,14 +152,26 @@
         if (detl == null) {
             throw new CoolException("璁㈠崟鏄庣粏涓嶅瓨鍦�");
         }
+        String batch = detl.getBatch();
+        List<FieldParam> uniqueFields = detl.getUniqueField();
 
         Mat mat = detl.getMat$();
         if (mat == null) {
             throw new CoolException("鍟嗗搧涓嶅瓨鍦�");
         }
 
+        return generateLoc(taskType, mat.getId(), batch, uniqueFields, locTypeHeight);
+    }
+
+    @Override
+    public synchronized Loc generateLoc(Long taskType, Long matId, String batch, List<FieldParam> uniqueFields, Integer locTypeHeight) {
+        Mat mat = matService.getById(matId);
+        if (mat == null) {
+            throw new CoolException("鍟嗗搧涓嶅瓨鍦�");
+        }
+
         List<ShelvesRule> shelvesRules = shelvesRuleService.list(new LambdaQueryWrapper<ShelvesRule>().eq(ShelvesRule::getStatus, 1).orderByDesc(ShelvesRule::getCreateTime));
-        if(shelvesRules.isEmpty()) {
+        if (shelvesRules.isEmpty()) {
             throw new CoolException("鏈厤缃笂鏋惰鍒�");
         }
         ShelvesRule shelvesRule = shelvesRules.get(0);
@@ -176,7 +195,7 @@
         }
 
         List<ShelvesRuleDetl> ruleDetls = shelvesRule.getRuleDetl$();
-        if(ruleDetls.isEmpty()) {
+        if (ruleDetls.isEmpty()) {
             throw new CoolException("鏈厤缃笂鏋惰鍒欐槑缁�");
         }
 
@@ -185,7 +204,7 @@
         for (ShelvesRuleDetl ruleDetl : ruleDetls) {
             if (ruleDetl.getDetlType().equals(ShelvesRuleDetlType.TASK_OR_LOC.id)) {
                 //浠庡簱瀛樻垨浠诲姟涓尮閰嶇浉閭诲簱浣�
-                defaultLoc = locUtils.getNeighborLoc(taskType, detl, locTypeHeight);
+                defaultLoc = locUtils.getNeighborLoc(taskType, mat.getId(), batch, uniqueFields, locTypeHeight);
                 if (defaultLoc != null) {
                     return defaultLoc;
                 }
@@ -193,11 +212,11 @@
 
             if (ruleDetl.getDetlType().equals(ShelvesRuleDetlType.SUGGEST.id)) {
                 //鑾峰彇鎺ㄨ崘搴撲綅
-                List<Loc> suggestLoc = locUtils.getSuggestLoc(taskType, mat.getId(), detl.getBatch(), locTypeHeight, laneRowList, currentLev);
+                List<Loc> suggestLoc = locUtils.getSuggestLoc(taskType, mat.getId(), batch, locTypeHeight, laneRowList, currentLev);
                 //鑾峰彇搴撲綅
                 if (!suggestLoc.isEmpty()) {
                     defaultLoc = locUtils.filterLoc(taskType, suggestLoc);
-                    if(defaultLoc != null) {
+                    if (defaultLoc != null) {
                         return defaultLoc;
                     }
                 }
@@ -209,7 +228,7 @@
                 //鑾峰彇搴撲綅
                 if (!globalLoc.isEmpty()) {
                     defaultLoc = locUtils.filterAllLoc(globalLoc);
-                    if(defaultLoc != null) {
+                    if (defaultLoc != null) {
                         return defaultLoc;
                     }
                 }
@@ -454,6 +473,20 @@
                 break;
         }
 
+        //鏁版嵁淇濆瓨鑷冲巻鍙叉。
+        TaskLog taskLog = new TaskLog();
+        taskLog.sync(task);
+        taskLog.setId(null);
+        if (!taskLogService.save(taskLog)) {
+            throw new CoolException("浠诲姟妗f杞巻鍙叉。妗堝け璐�");
+        }
+
+        //鍒犻櫎浠诲姟
+        boolean removeTask = taskService.removeById(taskId);
+        if(!removeTask){
+            throw new CoolException("鍥炴粴浠诲姟澶辫触");
+        }
+
         if (task.getTaskType() != 10) {
             List<TaskDetl> taskDetls = taskDetlService.getTaskDetlByTaskId(taskId);
             if (taskDetls.isEmpty()) {
@@ -462,17 +495,20 @@
 
             //鍥炴粴璁㈠崟
             for (TaskDetl taskDetl : taskDetls) {
-                OrderDetl orderDetl = orderDetlService.getById(taskDetl.getDetlId());
-                if(orderDetl == null){
-                    throw new CoolException("璁㈠崟鏄庣粏涓嶅瓨鍦�");
-                }
+                if (taskDetl.getDetlId() != null) {
+                    OrderDetl orderDetl = orderDetlService.getById(taskDetl.getDetlId());
+                    if(orderDetl == null){
+                        throw new CoolException("璁㈠崟鏄庣粏涓嶅瓨鍦�");
+                    }
 
-                //鍥炴粴宸ヤ綔鏁伴噺
-                orderDetl.setWorkQty(orderDetl.getWorkQty() - taskDetl.getAnfme());
-                orderDetl.setUpdateTime(new Date());
-                boolean orderDetlUpdate = orderDetlService.updateById(orderDetl);
-                if(!orderDetlUpdate){
-                    throw new CoolException("宸ヤ綔鏁伴噺鍥炴粴澶辫触");
+                    //鍥炴粴宸ヤ綔鏁伴噺
+                    orderDetl.setWorkQty(orderDetl.getWorkQty() - taskDetl.getAnfme());
+                    orderDetl.setUpdateTime(new Date());
+                    boolean orderDetlUpdate = orderDetlService.updateById(orderDetl);
+                    if(!orderDetlUpdate){
+                        throw new CoolException("宸ヤ綔鏁伴噺鍥炴粴澶辫触");
+                    }
+
                 }
 
                 //鍏ュ簱鍥炴粴缁勬墭閫氱煡妗�
@@ -490,11 +526,28 @@
                     }
                 }
 
+                //鏄庣粏鏁版嵁淇濆瓨鑷冲巻鍙叉。
+                TaskDetlLog taskDetlLog = new TaskDetlLog();
+                taskDetlLog.sync(taskDetl);
+                taskDetlLog.setId(null);
+                taskDetlLog.setTaskId(taskLog.getId());
+                if (!taskDetlLogService.save(taskDetlLog)) {
+                    throw new CoolException("鏄庣粏鏁版嵁杞巻鍙叉。妗堝け璐�");
+                }
+
+                //鍒犻櫎鏄庣粏
+                boolean removeDetl = taskDetlService.removeById(taskDetl.getId());
+                if(!removeDetl){
+                    throw new CoolException("鍥炴粴鏄庣粏澶辫触");
+                }
+
                 List<TaskDetlField> detlFields = taskDetlFieldService.list(new LambdaQueryWrapper<TaskDetlField>().eq(TaskDetlField::getDetlId, taskDetl.getId()));
                 for (TaskDetlField detlField : detlFields) {
                     //鏄庣粏鎵╁睍瀛楁鏁版嵁淇濆瓨鑷冲巻鍙叉。
                     TaskDetlFieldLog taskDetlFieldLog = new TaskDetlFieldLog();
                     taskDetlFieldLog.sync(detlField);
+                    taskDetlFieldLog.setId(null);
+                    taskDetlFieldLog.setDetlId(taskDetlLog.getId());
                     if (!taskDetlFieldLogService.save(taskDetlFieldLog)) {
                         throw new CoolException("鏄庣粏鎵╁睍瀛楁杞巻鍙叉。妗堝け璐�");
                     }
@@ -505,34 +558,75 @@
                         throw new CoolException("鍥炴粴鎵╁睍鏄庣粏澶辫触");
                     }
                 }
-
-
-                //鏄庣粏鏁版嵁淇濆瓨鑷冲巻鍙叉。
-                TaskDetlLog taskDetlLog = new TaskDetlLog();
-                taskDetlLog.sync(taskDetl);
-                if (!taskDetlLogService.save(taskDetlLog)) {
-                    throw new CoolException("鏄庣粏鏁版嵁杞巻鍙叉。妗堝け璐�");
-                }
-
-                //鍒犻櫎鏄庣粏
-                boolean removeDetl = taskDetlService.removeById(taskDetl.getId());
-                if(!removeDetl){
-                    throw new CoolException("鍥炴粴鏄庣粏澶辫触");
-                }
             }
         }
 
-        //鏁版嵁淇濆瓨鑷冲巻鍙叉。
-        TaskLog taskLog = new TaskLog();
-        taskLog.sync(task);
-        if (!taskLogService.save(taskLog)) {
-            throw new CoolException("浠诲姟妗f杞巻鍙叉。妗堝け璐�");
+        return true;
+    }
+
+    @Override
+    public boolean pickTask(Long taskId) {
+        Task task = taskService.getById(taskId);
+        if(task == null){
+            throw new CoolException("浠诲姟涓嶅瓨鍦�");
         }
 
-        //鍒犻櫎浠诲姟
-        boolean removeTask = taskService.removeById(taskId);
-        if(!removeTask){
-            throw new CoolException("鍥炴粴浠诲姟澶辫触");
+        if (task.getTaskType() != 103) {
+            throw new CoolException("浠诲姟绫诲瀷涓嶅彲鎷f枡");
+        }
+
+        if (task.getTaskSts() != 200) {
+            throw new CoolException("褰撳墠鐘舵�佷笉鍙嫞鏂�");
+        }
+
+        //鑾峰彇婧愬簱浣�
+        Loc originLoc = locService.getOne(new LambdaQueryWrapper<Loc>().eq(Loc::getLocNo, task.getOriginLoc()));
+        if(originLoc == null){
+            throw new CoolException("婧愬簱浣嶄笉瀛樺湪");
+        }
+
+        //鑾峰彇婧愬簱浣嶉珮搴�
+        LocTypeBind locTypeBind = locTypeBindService.getOne(new LambdaQueryWrapper<LocTypeBind>().eq(LocTypeBind::getLocId, originLoc.getId()));
+        if(locTypeBind == null){
+            throw new CoolException("搴撲綅绫诲瀷涓嶅瓨鍦�");
+        }
+        LocType locType = locTypeService.getById(locTypeBind.getTypeId());
+        if(locType == null){
+            throw new CoolException("搴撲綅绫诲瀷涓嶅瓨鍦�");
+        }
+        LocTypeHeightType locTypeHeightType = LocTypeHeightType.get(locType.getFlag());
+        if(locTypeHeightType == null){
+            throw new CoolException("楂樹綆搴撲綅绫诲瀷涓嶅瓨鍦�");
+        }
+
+        Long taskType = task.getTaskType() - 50;
+
+        List<TaskDetl> taskDetls = taskDetlService.list(new LambdaQueryWrapper<TaskDetl>().eq(TaskDetl::getTaskId, taskId).gt(TaskDetl::getAnfme, 0));
+        if (taskDetls.isEmpty()) {
+            throw new CoolException("浠诲姟鏄庣粏涓嶅瓨鍦�");
+        }
+        TaskDetl taskDetl = taskDetls.get(0);
+
+        //鐢熸垚搴撲綅
+        Loc loc = this.generateLoc(taskType, taskDetl.getMatId(), taskDetl.getBatch(), taskDetl.getUniqueField(), locTypeHeightType.id);
+        if(loc == null) {
+            throw new CoolException("娌℃湁绌哄簱浣�");
+        }
+
+        task.setTaskSts(1L);//1.鐢熸垚鍏ュ簱浠诲姟
+        task.setTaskType(taskType);
+        task.setTargetLoc(loc.getLocNo());
+        task.setUpdateTime(new Date());
+        if (!taskService.updateById(task)) {
+            throw new CoolException("鎷f枡澶辫触");
+        }
+
+        //搴撲綅O => S
+        loc.setLocStsId(LocStsType.S.val());
+        loc.setUpdateTime(new Date());
+        boolean locUpdate = locService.updateById(loc);
+        if(!locUpdate){
+            throw new CoolException("搴撲綅鐘舵�佹洿鏂板け璐�");
         }
 
         return true;
diff --git a/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/timer/TaskLogTimer.java b/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/timer/TaskLogTimer.java
index 8962a76..cde400b 100644
--- a/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/timer/TaskLogTimer.java
+++ b/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/timer/TaskLogTimer.java
@@ -53,6 +53,7 @@
                 //淇濆瓨浠诲姟鍘嗗彶妗�
                 TaskLog taskLog = new TaskLog();
                 taskLog.sync(task);
+                taskLog.setId(null);
                 if (!taskLogService.save(taskLog)) {
                     throw new CoolException("淇濆瓨浠诲姟鍘嗗彶妗eけ璐�");
                 }
@@ -70,6 +71,8 @@
                 for (TaskDetl taskDetl : taskDetls) {
                     TaskDetlLog taskDetlLog = new TaskDetlLog();
                     taskDetlLog.sync(taskDetl);
+                    taskDetlLog.setId(null);
+                    taskDetlLog.setTaskId(taskLog.getId());
                     if (!taskDetlLogService.save(taskDetlLog)) {
                         throw new CoolException("淇濆瓨浠诲姟鏄庣粏鍘嗗彶妗eけ璐�");
                     }
@@ -80,6 +83,8 @@
                         //鏄庣粏鎵╁睍瀛楁鏁版嵁淇濆瓨鑷冲巻鍙叉。
                         TaskDetlFieldLog taskDetlFieldLog = new TaskDetlFieldLog();
                         taskDetlFieldLog.sync(detlField);
+                        taskDetlFieldLog.setId(null);
+                        taskDetlFieldLog.setDetlId(taskDetlLog.getId());
                         if (!taskDetlFieldLogService.save(taskDetlFieldLog)) {
                             throw new CoolException("鏄庣粏鎵╁睍瀛楁杞巻鍙叉。妗堝け璐�");
                         }
@@ -100,6 +105,10 @@
 
                 //鏇存柊璁㈠崟淇℃伅
                 for (TaskDetl taskDetl : taskDetls) {
+                    if (taskDetl.getDetlId() == null) {
+                        continue;
+                    }
+
                     OrderDetl orderDetl = orderDetlService.getById(taskDetl.getDetlId());
                     if (orderDetl == null) {
                         throw new CoolException("璁㈠崟鏄庣粏涓嶅瓨鍦�");
@@ -146,7 +155,9 @@
         InterceptorIgnoreHelper.handle(IgnoreStrategy.builder().tenantLine(true).build());
         try {
             //鑾峰彇鍏ュ簱瀹屾垚浠诲姟
-            List<Task> list = taskService.list(new LambdaQueryWrapper<Task>().eq(Task::getTaskSts, 200));
+            List<Task> list = taskService.list(new LambdaQueryWrapper<Task>()
+                    .eq(Task::getTaskSts, 200)
+                    .in(Task::getTaskType, 101, 53, 57));
             if (list.isEmpty()) {
                 return;
             }
@@ -157,6 +168,7 @@
                 //淇濆瓨浠诲姟鍘嗗彶妗�
                 TaskLog taskLog = new TaskLog();
                 taskLog.sync(task);
+                taskLog.setId(null);
                 if (!taskLogService.save(taskLog)) {
                     throw new CoolException("淇濆瓨浠诲姟鍘嗗彶妗eけ璐�");
                 }
@@ -174,6 +186,8 @@
                 for (TaskDetl taskDetl : taskDetls) {
                     TaskDetlLog taskDetlLog = new TaskDetlLog();
                     taskDetlLog.sync(taskDetl);
+                    taskDetlLog.setId(null);
+                    taskDetlLog.setTaskId(taskLog.getId());
                     if (!taskDetlLogService.save(taskDetlLog)) {
                         throw new CoolException("淇濆瓨浠诲姟鏄庣粏鍘嗗彶妗eけ璐�");
                     }
@@ -184,6 +198,8 @@
                         //鏄庣粏鎵╁睍瀛楁鏁版嵁淇濆瓨鑷冲巻鍙叉。
                         TaskDetlFieldLog taskDetlFieldLog = new TaskDetlFieldLog();
                         taskDetlFieldLog.sync(detlField);
+                        taskDetlFieldLog.setId(null);
+                        taskDetlFieldLog.setDetlId(taskDetlLog.getId());
                         if (!taskDetlFieldLogService.save(taskDetlFieldLog)) {
                             throw new CoolException("鏄庣粏鎵╁睍瀛楁杞巻鍙叉。妗堝け璐�");
                         }
@@ -204,6 +220,10 @@
 
                 //鏇存柊璁㈠崟淇℃伅
                 for (TaskDetl taskDetl : taskDetls) {
+                    if (taskDetl.getDetlId() == null) {
+                        continue;
+                    }
+
                     OrderDetl orderDetl = orderDetlService.getById(taskDetl.getDetlId());
                     if (orderDetl == null) {
                         throw new CoolException("璁㈠崟鏄庣粏涓嶅瓨鍦�");
diff --git a/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/timer/TaskTimer.java b/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/timer/TaskTimer.java
index 4b78bed..10399de 100644
--- a/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/timer/TaskTimer.java
+++ b/zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/timer/TaskTimer.java
@@ -69,78 +69,15 @@
 
             for (Task task : list) {
                 //鍚屾鏁版嵁
-                Long hostId = task.getHostId();
                 switch (task.getTaskType().intValue()) {
                     case 1://鍏ュ簱
-                        Loc loc = locService.getOne(new LambdaQueryWrapper<Loc>().eq(Loc::getLocNo, task.getTargetLoc()).eq(Loc::getHostId, hostId));
-                        if (loc == null) {
-                            throw new CoolException("搴撲綅涓嶅瓨鍦�");
-                        }
-
-                        if (loc.getLocStsId() != LocStsType.S.val()) {
-                            throw new CoolException("搴撲綅鐘舵�佷笉澶勪簬S.鍏ュ簱棰勭害");
-                        }
-
-                        loc.setLocStsId(LocStsType.F.val());
-                        loc.setUpdateTime(new Date());
-                        loc.setBarcode(task.getBarcode());
-                        if (!locService.updateById(loc)) {
-                            throw new CoolException("搴撲綅鐘舵�佹洿鏂板け璐�");
-                        }
-
-
-                        List<TaskDetl> taskDetls = taskDetlService.getTaskDetlByTaskId(task.getId());
-                        if (taskDetls.isEmpty()) {
-                            throw new CoolException("浠诲姟鏄庣粏涓嶅瓨鍦�");
-                        }
-
-                        //娣诲姞搴撳瓨鏄庣粏
-                        for (TaskDetl taskDetl : taskDetls) {
-                            LocDetl locDetl = new LocDetl();
-                            locDetl.setLocId(loc.getId());
-                            locDetl.setLocNo(loc.getLocNo());
-                            locDetl.setMatId(taskDetl.getMatId());
-                            locDetl.setMatnr(taskDetl.getMat$().getMatnr());
-                            locDetl.setOrderNo(taskDetl.getOrderNo());
-                            locDetl.setBatch(taskDetl.getBatch());
-                            locDetl.setAnfme(taskDetl.getAnfme());
-                            locDetl.setHostId(hostId);
-                            if (!locDetlService.save(locDetl)) {
-                                throw new CoolException("鎻掑叆搴撳瓨鏄庣粏澶辫触");
-                            }
-
-                            //娣诲姞搴撳瓨鏄庣粏鎵╁睍瀛楁
-                            List<TaskDetlField> detlFields = taskDetlFieldService.list(new LambdaQueryWrapper<TaskDetlField>().eq(TaskDetlField::getDetlId, taskDetl.getId()).eq(TaskDetlField::getHostId, hostId));
-                            for (TaskDetlField detlField : detlFields) {
-                                LocDetlField locDetlField = new LocDetlField();
-                                locDetlField.setDetlId(locDetl.getId());
-                                locDetlField.setFieldId(detlField.getFieldId());
-                                locDetlField.setName(detlField.getName());
-                                locDetlField.setValue(detlField.getValue());
-                                locDetlField.setHostId(hostId);
-                                if (!locDetlFieldService.save(locDetlField)) {
-                                    throw new CoolException("鎻掑叆鏄庣粏鎵╁睍瀛楁澶辫触");
-                                }
-                            }
-                        }
-
-                        //缁勬墭閫氱煡妗h浆鍘嗗彶妗�
-                        List<WaitPakin> waitPakins = waitPakinService.list(new LambdaQueryWrapper<WaitPakin>().eq(WaitPakin::getBarcode, task.getBarcode()).eq(WaitPakin::getHostId, hostId));
-                        if (waitPakins.isEmpty()) {
-                            throw new CoolException("缁勬墭閫氱煡妗d笉瀛樺湪");
-                        }
-                        for (WaitPakin waitPakin : waitPakins) {
-                            WaitPakinLog waitPakinLog = new WaitPakinLog();
-                            waitPakinLog.sync(waitPakin);
-                            if (!waitPakinLogService.save(waitPakinLog)) {
-                                throw new CoolException("缁勬墭閫氱煡妗h浆鍘嗗彶妗eけ璐�");
-                            }
-
-                            //鍒犻櫎缁勬墭閫氱煡妗�
-                            waitPakinService.removeById(waitPakin.getId());
-                        }
-
+                        executeTask1(task);
                         break;
+                    case 53://鎷f枡鍐嶅叆搴�
+                        executeTask53(task);
+                        break;
+                    default:
+                        throw new CoolException("鏈煡浠诲姟绫诲瀷");
                 }
 
                 task.setTaskSts(100L);//100.搴撳瓨鏇存柊瀹屾垚
@@ -169,41 +106,15 @@
             }
             for (Task task : list) {
                 //鍚屾鏁版嵁
-                Long hostId = task.getHostId();
-                Loc loc = locService.getOne(new LambdaQueryWrapper<Loc>().eq(Loc::getLocNo, task.getOriginLoc()).eq(Loc::getHostId, hostId));
-                if (loc == null) {
-                    throw new CoolException("搴撲綅涓嶅瓨鍦�");
-                }
-                if (loc.getLocStsId() != LocStsType.R.val()) {
-                    throw new CoolException("搴撲綅鐘舵�佷笉澶勪簬R.鍑哄簱棰勭害");
-                }
-                List<TaskDetl> taskDetls = taskDetlService.getTaskDetlByTaskId(task.getId());
-                if (taskDetls.isEmpty()) {
-                    throw new CoolException("浠诲姟鏄庣粏涓嶅瓨鍦�");
-                }
                 switch (task.getTaskType().intValue()) {
-                    //鍑哄簱
-                    case 101:
-                        loc.setLocStsId(LocStsType.O.val());
-                        loc.setBarcode("");
-                        if (!locService.updateById(loc)) {
-                            throw new CoolException("搴撲綅鐘舵�佹洿鏂板け璐�");
-                        }
-                        List<LocDetl> detlList = locDetlService.list(new LambdaQueryWrapper<LocDetl>().eq(LocDetl::getLocNo, loc.getId()).eq(LocDetl::getHostId, hostId));
-                        //鍒犻櫎搴撳瓨鏄庣粏
-                        for (LocDetl locDetl : detlList) {
-                            if (!locDetlService.removeById(locDetl)) {
-                                throw new CoolException("鍒犻櫎搴撳瓨鏄庣粏澶辫触");
-                            }
-                            List<LocDetlField> detlFields = locDetlFieldService.list(new LambdaQueryWrapper<LocDetlField>().eq(LocDetlField::getDetlId, locDetl.getId()).eq(LocDetlField::getHostId, hostId));
-                            for (LocDetlField detlField : detlFields) {
-                                if (!locDetlFieldService.removeById(detlField)) {
-                                    throw new CoolException("鍒犻櫎鏄庣粏鎵╁睍瀛楁澶辫触");
-                                }
-                            }
-                        }
+                    case 101://鍑哄簱
+                        executeTask101(task);
                         break;
-
+                    case 103://鎷f枡
+                        executeTask103(task);
+                        break;
+                    default:
+                        throw new CoolException("鏈煡浠诲姟绫诲瀷");
                 }
 
                 task.setTaskSts(200L);//200.搴撳瓨鏇存柊瀹屾垚
@@ -220,4 +131,202 @@
         }
     }
 
+    //鍏ュ簱
+    private void executeTask1(Task task) {
+        Long hostId = task.getHostId();
+
+        Loc loc = locService.getOne(new LambdaQueryWrapper<Loc>().eq(Loc::getLocNo, task.getTargetLoc()).eq(Loc::getHostId, hostId));
+        if (loc == null) {
+            throw new CoolException("搴撲綅涓嶅瓨鍦�");
+        }
+
+        if (loc.getLocStsId() != LocStsType.S.val()) {
+            throw new CoolException("搴撲綅鐘舵�佷笉澶勪簬S.鍏ュ簱棰勭害");
+        }
+
+        loc.setLocStsId(LocStsType.F.val());
+        loc.setUpdateTime(new Date());
+        loc.setBarcode(task.getBarcode());
+        if (!locService.updateById(loc)) {
+            throw new CoolException("搴撲綅鐘舵�佹洿鏂板け璐�");
+        }
+
+        List<TaskDetl> taskDetls = taskDetlService.getTaskDetlByTaskId(task.getId());
+        if (taskDetls.isEmpty()) {
+            throw new CoolException("浠诲姟鏄庣粏涓嶅瓨鍦�");
+        }
+
+        //娣诲姞搴撳瓨鏄庣粏
+        for (TaskDetl taskDetl : taskDetls) {
+            LocDetl locDetl = new LocDetl();
+            locDetl.setLocId(loc.getId());
+            locDetl.setLocNo(loc.getLocNo());
+            locDetl.setMatId(taskDetl.getMatId());
+            locDetl.setMatnr(taskDetl.getMat$().getMatnr());
+            locDetl.setOrderNo(taskDetl.getOrderNo());
+            locDetl.setBatch(taskDetl.getBatch());
+            locDetl.setAnfme(taskDetl.getAnfme());
+            locDetl.setHostId(hostId);
+            if (!locDetlService.save(locDetl)) {
+                throw new CoolException("鎻掑叆搴撳瓨鏄庣粏澶辫触");
+            }
+
+            //娣诲姞搴撳瓨鏄庣粏鎵╁睍瀛楁
+            List<TaskDetlField> detlFields = taskDetlFieldService.list(new LambdaQueryWrapper<TaskDetlField>().eq(TaskDetlField::getDetlId, taskDetl.getId()).eq(TaskDetlField::getHostId, hostId));
+            for (TaskDetlField detlField : detlFields) {
+                LocDetlField locDetlField = new LocDetlField();
+                locDetlField.setDetlId(locDetl.getId());
+                locDetlField.setFieldId(detlField.getFieldId());
+                locDetlField.setName(detlField.getName());
+                locDetlField.setValue(detlField.getValue());
+                locDetlField.setHostId(hostId);
+                if (!locDetlFieldService.save(locDetlField)) {
+                    throw new CoolException("鎻掑叆鏄庣粏鎵╁睍瀛楁澶辫触");
+                }
+            }
+        }
+
+        //缁勬墭閫氱煡妗h浆鍘嗗彶妗�
+        List<WaitPakin> waitPakins = waitPakinService.list(new LambdaQueryWrapper<WaitPakin>().eq(WaitPakin::getBarcode, task.getBarcode()).eq(WaitPakin::getHostId, hostId));
+        if (waitPakins.isEmpty()) {
+            throw new CoolException("缁勬墭閫氱煡妗d笉瀛樺湪");
+        }
+        for (WaitPakin waitPakin : waitPakins) {
+            WaitPakinLog waitPakinLog = new WaitPakinLog();
+            waitPakinLog.sync(waitPakin);
+            if (!waitPakinLogService.save(waitPakinLog)) {
+                throw new CoolException("缁勬墭閫氱煡妗h浆鍘嗗彶妗eけ璐�");
+            }
+
+            //鍒犻櫎缁勬墭閫氱煡妗�
+            waitPakinService.removeById(waitPakin.getId());
+        }
+    }
+
+    //鎷f枡鍐嶅叆搴�
+    private void executeTask53(Task task) {
+        Long hostId = task.getHostId();
+
+        Loc loc = locService.getOne(new LambdaQueryWrapper<Loc>().eq(Loc::getLocNo, task.getTargetLoc()).eq(Loc::getHostId, hostId));
+        if (loc == null) {
+            throw new CoolException("搴撲綅涓嶅瓨鍦�");
+        }
+
+        if (loc.getLocStsId() != LocStsType.S.val()) {
+            throw new CoolException("搴撲綅鐘舵�佷笉澶勪簬S.鍏ュ簱棰勭害");
+        }
+
+        loc.setLocStsId(LocStsType.F.val());
+        loc.setUpdateTime(new Date());
+        loc.setBarcode(task.getBarcode());
+        if (!locService.updateById(loc)) {
+            throw new CoolException("搴撲綅鐘舵�佹洿鏂板け璐�");
+        }
+
+        List<TaskDetl> taskDetls = taskDetlService.getTaskDetlByTaskId(task.getId());
+        if (taskDetls.isEmpty()) {
+            throw new CoolException("浠诲姟鏄庣粏涓嶅瓨鍦�");
+        }
+
+        //娣诲姞搴撳瓨鏄庣粏
+        for (TaskDetl taskDetl : taskDetls) {
+            LocDetl locDetl = new LocDetl();
+            locDetl.setLocId(loc.getId());
+            locDetl.setLocNo(loc.getLocNo());
+            locDetl.setMatId(taskDetl.getMatId());
+            locDetl.setMatnr(taskDetl.getMat$().getMatnr());
+            locDetl.setOrderNo(taskDetl.getOrderNo());
+            locDetl.setBatch(taskDetl.getBatch());
+            locDetl.setAnfme(taskDetl.getStock() - taskDetl.getAnfme());
+            locDetl.setHostId(hostId);
+            if (!locDetlService.save(locDetl)) {
+                throw new CoolException("鎻掑叆搴撳瓨鏄庣粏澶辫触");
+            }
+
+            //娣诲姞搴撳瓨鏄庣粏鎵╁睍瀛楁
+            List<TaskDetlField> detlFields = taskDetlFieldService.list(new LambdaQueryWrapper<TaskDetlField>().eq(TaskDetlField::getDetlId, taskDetl.getId()).eq(TaskDetlField::getHostId, hostId));
+            for (TaskDetlField detlField : detlFields) {
+                LocDetlField locDetlField = new LocDetlField();
+                locDetlField.setDetlId(locDetl.getId());
+                locDetlField.setFieldId(detlField.getFieldId());
+                locDetlField.setName(detlField.getName());
+                locDetlField.setValue(detlField.getValue());
+                locDetlField.setHostId(hostId);
+                if (!locDetlFieldService.save(locDetlField)) {
+                    throw new CoolException("鎻掑叆鏄庣粏鎵╁睍瀛楁澶辫触");
+                }
+            }
+        }
+    }
+
+    //鍑哄簱
+    private void executeTask101(Task task) {
+        Long hostId = task.getHostId();
+        Loc loc = locService.getOne(new LambdaQueryWrapper<Loc>().eq(Loc::getLocNo, task.getOriginLoc()).eq(Loc::getHostId, hostId));
+        if (loc == null) {
+            throw new CoolException("搴撲綅涓嶅瓨鍦�");
+        }
+        if (loc.getLocStsId() != LocStsType.R.val()) {
+            throw new CoolException("搴撲綅鐘舵�佷笉澶勪簬R.鍑哄簱棰勭害");
+        }
+        List<TaskDetl> taskDetls = taskDetlService.getTaskDetlByTaskId(task.getId());
+        if (taskDetls.isEmpty()) {
+            throw new CoolException("浠诲姟鏄庣粏涓嶅瓨鍦�");
+        }
+
+        loc.setLocStsId(LocStsType.O.val());
+        loc.setBarcode("");
+        if (!locService.updateById(loc)) {
+            throw new CoolException("搴撲綅鐘舵�佹洿鏂板け璐�");
+        }
+        List<LocDetl> detlList = locDetlService.list(new LambdaQueryWrapper<LocDetl>().eq(LocDetl::getLocId, loc.getId()).eq(LocDetl::getHostId, hostId));
+        //鍒犻櫎搴撳瓨鏄庣粏
+        for (LocDetl locDetl : detlList) {
+            if (!locDetlService.removeById(locDetl)) {
+                throw new CoolException("鍒犻櫎搴撳瓨鏄庣粏澶辫触");
+            }
+            List<LocDetlField> detlFields = locDetlFieldService.list(new LambdaQueryWrapper<LocDetlField>().eq(LocDetlField::getDetlId, locDetl.getId()).eq(LocDetlField::getHostId, hostId));
+            for (LocDetlField detlField : detlFields) {
+                if (!locDetlFieldService.removeById(detlField)) {
+                    throw new CoolException("鍒犻櫎鏄庣粏鎵╁睍瀛楁澶辫触");
+                }
+            }
+        }
+    }
+
+    //鎷f枡鍑哄簱
+    private void executeTask103(Task task) {
+        Long hostId = task.getHostId();
+        Loc loc = locService.getOne(new LambdaQueryWrapper<Loc>().eq(Loc::getLocNo, task.getOriginLoc()).eq(Loc::getHostId, hostId));
+        if (loc == null) {
+            throw new CoolException("搴撲綅涓嶅瓨鍦�");
+        }
+        if (loc.getLocStsId() != LocStsType.R.val()) {
+            throw new CoolException("搴撲綅鐘舵�佷笉澶勪簬R.鍑哄簱棰勭害");
+        }
+        List<TaskDetl> taskDetls = taskDetlService.getTaskDetlByTaskId(task.getId());
+        if (taskDetls.isEmpty()) {
+            throw new CoolException("浠诲姟鏄庣粏涓嶅瓨鍦�");
+        }
+
+        loc.setLocStsId(LocStsType.O.val());
+        loc.setBarcode("");
+        if (!locService.updateById(loc)) {
+            throw new CoolException("搴撲綅鐘舵�佹洿鏂板け璐�");
+        }
+        List<LocDetl> detlList = locDetlService.list(new LambdaQueryWrapper<LocDetl>().eq(LocDetl::getLocId, loc.getId()).eq(LocDetl::getHostId, hostId));
+        //鍒犻櫎搴撳瓨鏄庣粏
+        for (LocDetl locDetl : detlList) {
+            if (!locDetlService.removeById(locDetl)) {
+                throw new CoolException("鍒犻櫎搴撳瓨鏄庣粏澶辫触");
+            }
+            List<LocDetlField> detlFields = locDetlFieldService.list(new LambdaQueryWrapper<LocDetlField>().eq(LocDetlField::getDetlId, locDetl.getId()).eq(LocDetlField::getHostId, hostId));
+            for (LocDetlField detlField : detlFields) {
+                if (!locDetlFieldService.removeById(detlField)) {
+                    throw new CoolException("鍒犻櫎鏄庣粏鎵╁睍瀛楁澶辫触");
+                }
+            }
+        }
+    }
+
 }
diff --git a/zy-asrs-wms/src/main/java/com/zy/asrs/wms/common/event/OrderBatchEvent.java b/zy-asrs-wms/src/main/java/com/zy/asrs/wms/common/event/OrderBatchEvent.java
deleted file mode 100644
index 33ff054..0000000
--- a/zy-asrs-wms/src/main/java/com/zy/asrs/wms/common/event/OrderBatchEvent.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package com.zy.asrs.wms.common.event;
-
-import org.springframework.context.ApplicationEvent;
-
-
-public class OrderBatchEvent extends ApplicationEvent {
-    private String orderId;
-
-    public OrderBatchEvent(Object source, String orderId) {
-        super(source);
-        this.orderId = orderId;
-    }
-
-    public String getOrderId() {
-        return orderId;
-    }
-}
diff --git a/zy-asrs-wms/src/main/java/com/zy/asrs/wms/common/event/OrderBatchListener.java b/zy-asrs-wms/src/main/java/com/zy/asrs/wms/common/event/OrderBatchListener.java
deleted file mode 100644
index 5d4b5e9..0000000
--- a/zy-asrs-wms/src/main/java/com/zy/asrs/wms/common/event/OrderBatchListener.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package com.zy.asrs.wms.common.event;
-
-import org.springframework.context.ApplicationListener;
-import org.springframework.stereotype.Component;
-
-//瀹炵幇ApplicationListener鎺ュ彛锛屽苟鎸囧畾鐩戝惉鐨勪簨浠剁被鍨�
-@Component
-public class OrderBatchListener implements ApplicationListener<OrderBatchEvent> {
-
-    @Override
-    public void onApplicationEvent(OrderBatchEvent event) {
-        //浣跨敤onApplicationEvent鏂规硶瀵规秷鎭繘琛屾帴鍙楀鐞�
-        String orderId = event.getOrderId();
-        System.out.println("DemoListener鑾峰彇鍒颁簡鐩戝惉娑堟伅:" + orderId);
-
-    }
-}
-
diff --git a/zy-asrs-wms/src/main/java/com/zy/asrs/wms/utils/CodeBuilder.java b/zy-asrs-wms/src/main/java/com/zy/asrs/wms/utils/CodeBuilder.java
index 951922e..0853feb 100644
--- a/zy-asrs-wms/src/main/java/com/zy/asrs/wms/utils/CodeBuilder.java
+++ b/zy-asrs-wms/src/main/java/com/zy/asrs/wms/utils/CodeBuilder.java
@@ -22,8 +22,8 @@
 //        generator.username="sa";
 //        generator.password="Zoneyung@zy56$";
 
-        generator.table="man_loc_map";
-        generator.tableName="搴撲綅鍦板浘";
+        generator.table="man_operation_port";
+        generator.tableName="浣滀笟鍙g鐞�";
         generator.rootPackagePath="com.zy.asrs.wms";
         generator.packagePath="com.zy.asrs.wms.asrs";
 
diff --git a/zy-asrs-wms/src/main/java/com/zy/asrs/wms/utils/LocUtils.java b/zy-asrs-wms/src/main/java/com/zy/asrs/wms/utils/LocUtils.java
index 3c9330c..210b416 100644
--- a/zy-asrs-wms/src/main/java/com/zy/asrs/wms/utils/LocUtils.java
+++ b/zy-asrs-wms/src/main/java/com/zy/asrs/wms/utils/LocUtils.java
@@ -7,6 +7,7 @@
 import com.zy.asrs.wms.asrs.entity.enums.LocStsType;
 import com.zy.asrs.wms.asrs.entity.enums.LocTypeHeightType;
 import com.zy.asrs.wms.asrs.entity.enums.ShelvesRuleType;
+import com.zy.asrs.wms.asrs.entity.param.FieldParam;
 import com.zy.asrs.wms.asrs.mapper.ViewLocDetlMapper;
 import com.zy.asrs.wms.asrs.mapper.ViewTaskDetlMapper;
 import com.zy.asrs.wms.asrs.service.*;
@@ -36,22 +37,29 @@
     private ViewLocDetlMapper viewLocDetlMapper;
     @Autowired
     private ViewTaskDetlMapper viewTaskDetlMapper;
+    @Autowired
+    private MatService matService;
 
     //浠庡簱瀛樻垨浠诲姟涓尮閰嶇浉閭诲簱浣�(婊℃墭鐩�)
-    public Loc getNeighborLoc(Long taskType, OrderDetl orderDetl, Integer locTypeHeight) {
+    public Loc getNeighborLoc(Long taskType, Long matId, String batch, List<FieldParam> uniqueFields, Integer locTypeHeight) {
         //婊℃墭鐩�
+        Mat mat = matService.getById(matId);
+        if (mat == null) {
+            return null;
+        }
+
         //浠庝换鍔′腑杩涜鍖归厤
         List<Loc> locs = new ArrayList<>();
-        List<Map<String, Object>> list = viewTaskDetlMapper.getList(orderDetl.getMat$().getMatnr(), orderDetl.getBatch(), orderDetl.getUniqueField());
+        List<Map<String, Object>> list = viewTaskDetlMapper.getList(mat.getMatnr(), batch, uniqueFields);
         for (Map<String, Object> map : list) {
             Task task = taskService.getById(map.get("taskId").toString());
-            if(task == null) {
+            if (task == null) {
                 continue;
             }
 
             String targetLoc = task.getTargetLoc();
             Loc one = locService.getOne(new LambdaQueryWrapper<Loc>().eq(Loc::getLocNo, targetLoc));
-            if(one == null) {
+            if (one == null) {
                 continue;
             }
             locs.add(one);
@@ -64,10 +72,10 @@
 
         //浠庡簱瀛樹腑杩涜鍖归厤
         List<Loc> locs2 = new ArrayList<>();
-        List<Map<String, Object>> list2 = viewLocDetlMapper.getList(orderDetl.getMat$().getMatnr(), orderDetl.getBatch(), orderDetl.getUniqueField());
+        List<Map<String, Object>> list2 = viewLocDetlMapper.getList(mat.getMatnr(), batch, uniqueFields);
         for (Map<String, Object> map : list2) {
             Loc one = locService.getById(map.get("locId").toString());
-            if(one == null) {
+            if (one == null) {
                 continue;
             }
             locs2.add(one);
diff --git a/zy-asrs-wms/src/main/java/com/zy/asrs/wms/utils/OutUtils.java b/zy-asrs-wms/src/main/java/com/zy/asrs/wms/utils/OutUtils.java
new file mode 100644
index 0000000..5575378
--- /dev/null
+++ b/zy-asrs-wms/src/main/java/com/zy/asrs/wms/utils/OutUtils.java
@@ -0,0 +1,96 @@
+package com.zy.asrs.wms.utils;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.zy.asrs.wms.asrs.entity.LocDetl;
+import com.zy.asrs.wms.asrs.entity.dto.OutDetlDto;
+import com.zy.asrs.wms.asrs.entity.dto.OutLocDto;
+import com.zy.asrs.wms.asrs.entity.param.OutParam;
+import com.zy.asrs.wms.asrs.service.LocDetlService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Component
+public class OutUtils {
+
+    @Autowired
+    private LocDetlService locDetlService;
+
+    public List<OutLocDto> merge(OutParam outParam) {
+        HashMap<Long, OutLocDto> map = new HashMap<>();
+
+        for (OutDetlDto detl : outParam.getDetls()) {
+            LocDetl locDetl = locDetlService.getById(detl.getDetlId());
+            if (locDetl == null) {
+                continue;
+            }
+            detl.setStock(locDetl.getAnfme());
+
+            if (map.containsKey(locDetl.getLocId())) {
+                OutLocDto locDto = map.get(locDetl.getLocId());
+                List<OutDetlDto> detlDtos = locDto.getDetls();
+                detlDtos.add(detl);
+
+                locDto.setDetls(detlDtos);
+            }else {
+                OutLocDto locDto = new OutLocDto();
+                map.put(locDetl.getLocId(), locDto);
+
+                List<OutDetlDto> detlDtos = new ArrayList<>();
+                detlDtos.add(detl);
+
+                locDto.setLocId(locDetl.getLocId());
+                locDto.setDetls(detlDtos);
+            }
+        }
+
+        List<OutLocDto> locDtos = new ArrayList<>();
+        for (Map.Entry<Long, OutLocDto> entry : map.entrySet()) {
+            OutLocDto locDto = entry.getValue();
+            locDtos.add(locDto);
+
+            List<LocDetl> list = locDetlService.list(new LambdaQueryWrapper<LocDetl>().eq(LocDetl::getLocId, locDto.getLocId()));
+
+            Double sum = 0D;
+            for (LocDetl locDetl : list) {
+                sum += locDetl.getAnfme();
+            }
+
+            for (OutDetlDto detl : locDto.getDetls()) {
+                sum -= detl.getAnfme();
+            }
+
+            locDto.setAll(sum == 0);
+            locDto.setOperationPort(outParam.getOperationPort());
+        }
+
+        //add zero stock
+        for (OutLocDto locDto : locDtos) {
+            List<OutDetlDto> detls = locDto.getDetls();
+            List<Long> detlIds = new ArrayList<>();
+            for (OutDetlDto detl : detls) {
+                detlIds.add(detl.getDetlId());
+            }
+
+            List<LocDetl> list = locDetlService.list(new LambdaQueryWrapper<LocDetl>().eq(LocDetl::getLocId, locDto.getLocId()).notIn(LocDetl::getId, detlIds));
+            if (!list.isEmpty()) {
+                List<OutDetlDto> detlDtos = locDto.getDetls();
+                for (LocDetl locDetl : list) {
+                    OutDetlDto outDetlDto = new OutDetlDto();
+                    outDetlDto.setDetlId(locDetl.getId());
+                    outDetlDto.setAnfme(0D);
+                    outDetlDto.setStock(locDetl.getAnfme());
+                    detlDtos.add(outDetlDto);
+                }
+                locDto.setDetls(detlDtos);
+            }
+        }
+
+        return locDtos;
+    }
+
+}
diff --git a/zy-asrs-wms/src/main/resources/application.yml b/zy-asrs-wms/src/main/resources/application.yml
index 67d9fd5..ac88949 100644
--- a/zy-asrs-wms/src/main/resources/application.yml
+++ b/zy-asrs-wms/src/main/resources/application.yml
@@ -13,7 +13,7 @@
       validation-timeout: 3000
       connection-test-query: select 1
     driver-class-name: com.mysql.cj.jdbc.Driver
-    url: jdbc:mysql://192.168.4.61:3306/wms_dev?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
+    url: jdbc:mysql://127.0.0.1:3306/wms_dev?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
     username: root
     password: root
 #    driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
diff --git a/zy-asrs-wms/src/main/resources/mapper/asrs/LocMapper.xml b/zy-asrs-wms/src/main/resources/mapper/asrs/LocMapper.xml
index 3cefabd..252ebca 100644
--- a/zy-asrs-wms/src/main/resources/mapper/asrs/LocMapper.xml
+++ b/zy-asrs-wms/src/main/resources/mapper/asrs/LocMapper.xml
@@ -2,4 +2,9 @@
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="com.zy.asrs.wms.asrs.mapper.LocMapper">
 
+    <select id="listBySts" resultType="long">
+        select * from man_loc
+        where loc_sts_id = #{sts}
+    </select>
+
 </mapper>
diff --git a/zy-asrs-wms/src/main/resources/mapper/asrs/OperationPortMapper.xml b/zy-asrs-wms/src/main/resources/mapper/asrs/OperationPortMapper.xml
new file mode 100644
index 0000000..23b8a87
--- /dev/null
+++ b/zy-asrs-wms/src/main/resources/mapper/asrs/OperationPortMapper.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.wms.asrs.mapper.OperationPortMapper">
+
+</mapper>
diff --git a/zy-asrs-wms/src/main/resources/sql/menu/operationPort.sql b/zy-asrs-wms/src/main/resources/sql/menu/operationPort.sql
new file mode 100644
index 0000000..d1b5d43
--- /dev/null
+++ b/zy-asrs-wms/src/main/resources/sql/menu/operationPort.sql
@@ -0,0 +1,9 @@
+-- save operationPort record
+-- mysql
+insert into `sys_menu` ( `name`, `parent_id`, `route`, `component`, `type`, `sort`, `host_id`, `status`) values ( '浣滀笟鍙g鐞嗙鐞�', '0', '/asrs/operationPort', '/asrs/operationPort', '0' , '0', '1' , '1');
+
+insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `host_id`, `status`) values ( '鏌ヨ浣滀笟鍙g鐞�', '', '1', 'asrs:operationPort:list', '0', '1', '1');
+insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `host_id`, `status`) values ( '娣诲姞浣滀笟鍙g鐞�', '', '1', 'asrs:operationPort:save', '1', '1', '1');
+insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `host_id`, `status`) values ( '淇敼浣滀笟鍙g鐞�', '', '1', 'asrs:operationPort:update', '2', '1', '1');
+insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `host_id`, `status`) values ( '鍒犻櫎浣滀笟鍙g鐞�', '', '1', 'asrs:operationPort:remove', '3', '1', '1');
+

--
Gitblit v1.9.1