Pārlūkot izejas kodu

数字货架 页面更新

chenrui 3 gadi atpakaļ
vecāks
revīzija
11a0f7bc85

+ 4 - 1
src/components/Table/index.js

@@ -346,6 +346,9 @@ export default {
           </template>
         </a-alert>
       )
+    },
+    expandFun (expanded, record) {
+      this.$emit('expand', expanded, record)
     }
   },
 
@@ -390,7 +393,7 @@ export default {
     }
     // isSucceed
     const table = (
-      <a-table {...{ props, scopedSlots: { ...this.$scopedSlots } }} onChange={this.loadData}>
+      <a-table {...{ props, scopedSlots: { ...this.$scopedSlots } }} onChange={this.loadData} onExpand={this.expandFun}>
         { Object.keys(this.$slots).map(name => (<template slot={name}>{this.$slots[name]}</template>)) }
       </a-table>
     )

+ 59 - 21
src/config/router.config.js

@@ -38,7 +38,7 @@ export const asyncRouterMap = [
               hidden: true
             },
             hideChildrenInMenu: true,
-            children:[
+            children: [
               {
                 path: '/home',
                 name: 'home',
@@ -47,7 +47,7 @@ export const asyncRouterMap = [
                   title: '首页',
                   icon: 'home',
                   hidden: true
-                },
+                }
               },
               {
                 path: '/changePwd',
@@ -68,7 +68,7 @@ export const asyncRouterMap = [
                   title: '公告',
                   icon: 'bell',
                   hidden: true
-                },
+                }
               }
             ]
           }
@@ -85,6 +85,43 @@ export const asyncRouterMap = [
           // permission: 'M_salesManage'
         },
         children: [
+          {
+            path: '/numsGoodsShelves/shelfSet',
+            redirect: '/numsGoodsShelves/shelfSet/list',
+            name: 'shelfSet',
+            component: BlankLayout,
+            meta: {
+              title: '货架设置',
+              icon: 'monitor'
+              // permission: 'M_salesQueryList'
+            },
+            hideChildrenInMenu: true,
+            children: [
+              {
+                path: 'list',
+                name: 'shelfSetList',
+                component: () => import(/* webpackChunkName: "numsGoodsShelves" */ '@/views/numsGoodsShelves/shelfSet/list.vue'),
+                meta: {
+                  title: '货架设置列表',
+                  icon: 'monitor',
+                  hidden: true
+                  // permission: 'M_salesQueryList'
+                }
+              },
+              {
+                path: 'set/:sn',
+                name: 'shelfSetting',
+                component: () => import(/* webpackChunkName: "numsGoodsShelves" */ '@/views/numsGoodsShelves/shelfSet/set.vue'),
+                meta: {
+                  title: '货架设置',
+                  icon: 'monitor',
+                  hidden: true,
+                  replaceTab: true
+                  // permission: 'M_salesQueryList'
+                }
+              }
+            ]
+          },
           {
             path: '/numsGoodsShelves/settlementManagement',
             redirect: '/numsGoodsShelves/settlementManagement/list',
@@ -100,7 +137,7 @@ export const asyncRouterMap = [
               {
                 path: 'list',
                 name: 'settlementManagementList',
-                component: () => import(/* webpackChunkName: "salesManagement" */ '@/views/numsGoodsShelves/settlementManagement/list.vue'),
+                component: () => import(/* webpackChunkName: "numsGoodsShelves" */ '@/views/numsGoodsShelves/settlementManagement/list.vue'),
                 meta: {
                   title: '结算管理列表',
                   icon: 'monitor',
@@ -125,7 +162,7 @@ export const asyncRouterMap = [
               {
                 path: 'list',
                 name: 'accountManagementList',
-                component: () => import(/* webpackChunkName: "salesManagement" */ '@/views/numsGoodsShelves/accountManagement/list.vue'),
+                component: () => import(/* webpackChunkName: "numsGoodsShelves" */ '@/views/numsGoodsShelves/accountManagement/list.vue'),
                 meta: {
                   title: '账户管理列表',
                   icon: 'monitor',
@@ -150,7 +187,7 @@ export const asyncRouterMap = [
               {
                 path: 'list',
                 name: 'shelfMonitoringList',
-                component: () => import(/* webpackChunkName: "salesManagement" */ '@/views/numsGoodsShelves/shelfMonitoring/list.vue'),
+                component: () => import(/* webpackChunkName: "numsGoodsShelves" */ '@/views/numsGoodsShelves/shelfMonitoring/list.vue'),
                 meta: {
                   title: '货架监控列表',
                   icon: 'monitor',
@@ -161,11 +198,12 @@ export const asyncRouterMap = [
               {
                 path: 'warehouseDetail/:sn',
                 name: 'shelfMonitoringWarehouseDetail',
-                component: () => import(/* webpackChunkName: "salesManagement" */ '@/views/numsGoodsShelves/shelfMonitoring/warehouseDetail.vue'),
+                component: () => import(/* webpackChunkName: "numsGoodsShelves" */ '@/views/numsGoodsShelves/shelfMonitoring/warehouseDetail.vue'),
                 meta: {
                   title: '货架监控出入库明细',
                   icon: 'monitor',
-                  hidden: true
+                  hidden: true,
+                  replaceTab: true
                   // permission: 'M_salesQueryList'
                 }
               }
@@ -186,7 +224,7 @@ export const asyncRouterMap = [
               {
                 path: 'list',
                 name: 'replenishmentManagementList',
-                component: () => import(/* webpackChunkName: "salesManagement" */ '@/views/numsGoodsShelves/replenishmentManagement/list.vue'),
+                component: () => import(/* webpackChunkName: "numsGoodsShelves" */ '@/views/numsGoodsShelves/replenishmentManagement/list.vue'),
                 meta: {
                   title: '补货管理列表',
                   icon: 'monitor',
@@ -211,7 +249,7 @@ export const asyncRouterMap = [
               {
                 path: 'list',
                 name: 'recallManagementList',
-                component: () => import(/* webpackChunkName: "salesManagement" */ '@/views/numsGoodsShelves/recallManagement/list.vue'),
+                component: () => import(/* webpackChunkName: "numsGoodsShelves" */ '@/views/numsGoodsShelves/recallManagement/list.vue'),
                 meta: {
                   title: '调回管理列表',
                   icon: 'monitor',
@@ -1298,7 +1336,7 @@ export const asyncRouterMap = [
                   title: '库存预警',
                   icon: 'alert',
                   permission: 'M_inventoryWarningList'
-                },
+                }
               }
             ]
           },
@@ -1322,7 +1360,7 @@ export const asyncRouterMap = [
                   title: '卫星仓库存',
                   icon: 'flag',
                   permission: 'M_satelliteWarehouseInventoryList'
-                }, 
+                }
               }
             ]
           },
@@ -2195,7 +2233,7 @@ export const asyncRouterMap = [
                   hidden: true,
                   permission: 'B_product_dealerProduct_edit'
                 }
-              },
+              }
             ]
           },
           {
@@ -2245,7 +2283,7 @@ export const asyncRouterMap = [
                   hidden: true,
                   permission: 'M_productOnlineInfoList'
                 }
-              },
+              }
             ]
           },
           {
@@ -2268,8 +2306,8 @@ export const asyncRouterMap = [
                 meta: {
                   title: '新品信息',
                   icon: 'file-text',
-                  hidden: true,
-                },
+                  hidden: true
+                }
               },
               // 产品详情
               {
@@ -2281,8 +2319,8 @@ export const asyncRouterMap = [
                   icon: 'file-text',
                   replaceTab: true,
                   hidden: true
-                },
-              },
+                }
+              }
             ]
           },
           {
@@ -2632,7 +2670,7 @@ export const asyncRouterMap = [
                   title: '用户管理',
                   icon: 'user',
                   permission: 'M_powerMD_user_list'
-                },
+                }
               }
             ]
           },
@@ -2656,12 +2694,12 @@ export const asyncRouterMap = [
                   title: '角色管理',
                   icon: 'solution',
                   permission: 'M_powerMD_role_list'
-                },
+                }
               }
             ]
           }
         ]
-      },
+      }
     ]
   },
   {

+ 111 - 0
src/views/common/commonModal.vue

@@ -0,0 +1,111 @@
+<template>
+  <a-modal
+    centered
+    class="common-modal"
+    :footer="null"
+    :maskClosable="false"
+    v-model="isShow"
+    :title="modalTit"
+    :bodyStyle="{padding: modalTit?'25px 32px 20px':'50px 32px 15px'}"
+    @cancle="isShow=false"
+    :width="416">
+    <a-spin :spinning="spinning" tip="Loading...">
+      <div class="common-main" v-html="modalHtml"></div>
+      <div class="btn-box">
+        <a-button type="primary" class="button-warning" @click="handleCommonCancel" v-if="isCancel">{{ cancelText }}</a-button>
+        <a-button type="primary" class="button-info" @click="handleCommonOk">{{ okText }}</a-button>
+      </div>
+    </a-spin>
+  </a-modal>
+</template>
+
+<script>
+export default {
+  name: 'CommonModal',
+  props: {
+    openModal: { //  弹框显示状态
+      type: Boolean,
+      default: false
+    },
+    modalTit: { // 弹框标题
+      type: String,
+      default: null
+    },
+    modalHtml: {
+      type: String,
+      default: ''
+    },
+    okText: { // 确定 按钮文字
+      type: String,
+      default: '确定'
+    },
+    cancelText: { // 取消 按钮文字
+      type: String,
+      default: '取消'
+    },
+    isCancel: { // 是否显示  取消 按钮
+      type: Boolean,
+      default: true
+    },
+    spinning: { // 加载中
+      type: Boolean,
+      default: false
+    }
+  },
+  data () {
+    return {
+      isShow: this.openModal //  是否打开弹框
+    }
+  },
+  methods: {
+    // 确定
+    handleCommonOk () {
+      this.$emit('ok')
+    },
+    // 取消
+    handleCommonCancel () {
+      this.$emit('cancel')
+    }
+  },
+  watch: {
+    //  父页面传过来的弹框状态
+    openModal (newValue, oldValue) {
+      this.isShow = newValue
+    },
+    //  重定义的弹框状态
+    isShow (newValue, oldValue) {
+      if (!newValue) {
+        this.$emit('close')
+      }
+    }
+  }
+}
+</script>
+
+<style lang="less">
+  .common-modal{
+    .common-main{
+      display: flex;
+      line-height: 20px;
+      .common-cont{
+        .common-tit{
+          color: rgba(0, 0, 0);
+          font-weight: 500;
+          font-size: 16px;
+          line-height: 1.4;
+          margin: 0;
+        }
+        .common-txt{
+          margin: 8px 0 0;
+          color: rgba(0, 0, 0);
+          font-size: 14px;
+          line-height: 1.5;
+        }
+      }
+    }
+    .btn-box{
+      text-align: right;
+      margin-top: 20px;
+    }
+  }
+</style>

+ 159 - 0
src/views/numsGoodsShelves/replenishmentManagement/confirmModal.vue

@@ -0,0 +1,159 @@
+<template>
+  <a-modal
+    centered
+    class="replenishmentManagement-confirm-modal"
+    :footer="null"
+    :maskClosable="false"
+    :title="modalTit"
+    v-model="isShow"
+    @cancle="isShow = false"
+    :width="800">
+    <a-spin :spinning="spinning" tip="Loading...">
+      <a-descriptions>
+        <a-descriptions-item label="补货单号">BH202101010001</a-descriptions-item>
+        <a-descriptions-item label="单据来源">系统创建</a-descriptions-item>
+      </a-descriptions>
+      <!-- 列表 -->
+      <s-table
+        class="sTable"
+        ref="table"
+        size="small"
+        :rowKey="(record) => record.id"
+        :columns="columns"
+        :data="loadData"
+        :scroll="{ y: 400 }"
+        :showPagination="false"
+        :defaultLoadData="false"
+        bordered>
+        <!-- 实发数量 -->
+        <template slot="outQty" slot-scope="text, record">
+          <a-input-number
+            size="small"
+            id="replenishmentManagement-confirm-outQty"
+            v-model="record.outQty"
+            :precision="0"
+            :min="0"
+            :max="record.currentQty"
+            placeholder="请输入"
+            :style="{width: '100%', color: record.outQty==0 ? 'red': ''}" />
+        </template>
+      </s-table>
+      <div class="btn-cont">
+        <a-button type="primary" id="replenishmentManagement-confirm-modal-save" @click="handleSave">确认补货</a-button>
+        <a-button id="replenishmentManagement-confirm-modal-back" @click="isShow = false" style="margin-left: 15px;">取消</a-button>
+      </div>
+    </a-spin>
+  </a-modal>
+</template>
+
+<script>
+import { commonMixin } from '@/utils/mixin'
+import { STable, VSelect } from '@/components'
+import { storeCallOutList } from '@/api/storeCallOut'
+export default {
+  name: 'ConfirmModal',
+  components: { STable, VSelect },
+  mixins: [commonMixin],
+  props: {
+    openModal: { //  弹框显示状态
+      type: Boolean,
+      default: false
+    },
+    nowData: {
+      type: Object,
+      default: () => {
+        return {}
+      }
+    }
+  },
+  data () {
+    return {
+      spinning: false,
+      isShow: this.openModal, //  是否打开弹框
+      columns: [
+        { title: '序号', dataIndex: 'no', width: '8%', align: 'center' },
+        { title: '产品编码', dataIndex: 'allocationLinkagePutNo', width: '22%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '产品名称', dataIndex: 'outTenantName', width: '32%', align: 'left', customRender: function (text) { return text || '--' }, ellipsis: true },
+        { title: '补货应发数量', dataIndex: 'productTotalCategory', width: '15%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+        { title: '实发数量', scopedSlots: { customRender: 'outQty' }, width: '15%', align: 'center' },
+        { title: '单位', dataIndex: 'productUnit', width: '8%', align: 'center', customRender: function (text) { return text || '--' } }
+      ],
+      // 加载数据方法 必须为 Promise 对象
+      loadData: parameter => {
+        this.disabled = true
+        this.spinning = true
+        return storeCallOutList(Object.assign(parameter, this.queryParam)).then(res => {
+          let data
+          if (res.status == 200) {
+            data = res.data
+            const no = (data.pageNo - 1) * data.pageSize
+            for (var i = 0; i < data.list.length; i++) {
+              data.list[i].no = no + i + 1
+            }
+            this.disabled = false
+          }
+          this.spinning = false
+          return data
+        })
+      }
+    }
+  },
+  computed: {
+    modalTit () {
+      const hjName = this.nowData && this.nowData.settleClientName ? this.nowData.settleClientName : ''
+      return '补货单确认——' + hjName
+    }
+  },
+  methods: {
+    //  确认补货
+    handleSave () {
+      const _this = this
+      this.$confirm({
+        title: '提示',
+        content: '确认对该数字货架进行补货吗?',
+        centered: true,
+        onOk () {
+          _this.$emit('ok', 'confirm')
+          // _this.spinning = true
+          // storeCallOutOut({ storeCallOutSn: row.storeCallOutSn }).then(res => {
+          //   if (res.status == 200) {
+          //     _this.$message.success(res.message)
+          //     _this.$refs.table.refresh()
+          //     _this.spinning = false
+          //   } else {
+          //     _this.spinning = false
+          //   }
+          // })
+        }
+      })
+    }
+  },
+  watch: {
+    //  父页面传过来的弹框状态
+    openModal (newValue, oldValue) {
+      this.isShow = newValue
+    },
+    //  重定义的弹框状态
+    isShow (newValue, oldValue) {
+      if (!newValue) {
+        this.$emit('close')
+        this.$refs.table.clearTable()
+      } else {
+        const _this = this
+        this.$nextTick(() => { // 页面渲染完成后的回调
+          _this.$refs.table.refresh(true)
+        })
+      }
+    }
+  }
+}
+</script>
+
+<style lang="less">
+.replenishmentManagement-confirm-modal {
+	.btn-cont {
+		text-align: center;
+		margin: 35px 0 10px;
+	}
+}
+</style>

+ 388 - 1
src/views/numsGoodsShelves/replenishmentManagement/list.vue

@@ -1,8 +1,395 @@
 <template>
+  <a-card size="small" :bordered="false" class="replenishmentManagementList-wrap">
+    <a-spin :spinning="spinning" tip="Loading...">
+      <!-- 搜索条件 -->
+      <div ref="tableSearch" class="table-page-search-wrapper">
+        <a-form layout="inline" @keyup.enter.native="$refs.table.refresh(true)">
+          <a-row :gutter="15">
+            <a-col :md="6" :sm="24">
+              <a-form-item label="创建时间">
+                <rangeDate ref="rangeDate" @change="dateChange" />
+              </a-form-item>
+            </a-col>
+            <a-col :md="6" :sm="24">
+              <a-form-item label="补货单号"><a-input id="replenishmentManagementList-settleNo" v-model.trim="queryParam.settleNo" allowClear placeholder="请输入补货单号" /></a-form-item>
+            </a-col>
+            <a-col :md="6" :sm="24">
+              <a-form-item label="货架名称">
+                <custList ref="custList" @change="custChange" :itemSn="queryParam.customerSn"></custList>
+              </a-form-item>
+            </a-col>
+            <template v-if="advanced">
+              <a-col :md="6" :sm="24">
+                <a-form-item label="产品编码"><a-input id="replenishmentManagementList-bizNo" v-model.trim="queryParam.bizNo" allowClear placeholder="请输入关联单号" /></a-form-item>
+              </a-col>
+              <a-col :md="6" :sm="24">
+                <a-form-item label="产品名称">
+                  <a-input id="replenishmentManagementList-settleClientName" v-model.trim="queryParam.settleClientName" allowClear placeholder="请输入商户名称" />
+                </a-form-item>
+              </a-col>
+            </template>
+            <a-col :md="6" :sm="24">
+              <span class="table-page-search-submitButtons">
+                <a-button type="primary" @click="$refs.table.refresh(true)" :disabled="disabled" id="replenishmentManagementList-refresh">查询</a-button>
+                <a-button style="margin-left: 5px" @click="resetSearchForm()" :disabled="disabled" id="replenishmentManagementList-reset">重置</a-button>
+                <a @click="advanced = !advanced" style="margin-left: 5px">
+                  {{ advanced ? '收起' : '展开' }}
+                  <a-icon :type="advanced ? 'up' : 'down'" />
+                </a>
+              </span>
+            </a-col>
+          </a-row>
+        </a-form>
+      </div>
+      <!-- 标签页 -->
+      <a-tabs type="card" v-model="queryParam.bizType" @change="handleTabChange" class="replenishmentManagementList-tabs ">
+        <a-tab-pane v-for="item in tabPaneData" :key="item.bizType">
+          <span slot="tab">{{ item.bizName }}({{ item.countNum }})</span>
+        </a-tab-pane>
+      </a-tabs>
+      <!-- 列表 -->
+      <!-- <s-table
+        class="sTable fixPagination"
+        ref="table"
+        :style="{ height: tableHeight+84.5+'px' }"
+        size="small"
+        :rowKey="(record) => record.id"
+        :columns="columns"
+        :data="loadData"
+        @expand="expandFun"
+        :expandRowByClick="true"
+        :scroll="{ y: tableHeight }"
+        :expandIcon="(props) => this.customExpandIcon(props)"
+        :showPagination="false"
+        :defaultLoadData="false"
+        bordered> -->
+      <s-table
+        class="sTable fixPagination"
+        ref="table"
+        :style="{ height: tableHeight+84.5+'px' }"
+        size="small"
+        :rowKey="(record) => record.id"
+        :columns="columns"
+        :data="loadData"
+        @expand="expandFun"
+        :expandRowByClick="true"
+        :scroll="{ y: tableHeight }"
+        :showPagination="false"
+        :defaultLoadData="false"
+        bordered>
+        <a-table
+          slot="expandedRowRender"
+          slot-scope="record, index"
+          size="small"
+          :rowKey="(record) => record.id"
+          :columns="subColumns"
+          :data-source="listData[index].subList"
+          :pagination="false"
+          bordered>
+        </a-table>
+        <!-- 操作 -->
+        <template slot="action" slot-scope="text, record">
+          <a-button size="small" type="link" class="button-primary" @click.stop="handleConfirm(record)">确认</a-button>
+          <a-button size="small" type="link" class="button-primary" @click.stop="handlePrintSticker(record)">打印贴签</a-button>
+          <a-button size="small" type="link" class="button-primary" @click.stop="handleOutWarehousing(record)">出库</a-button>
+          <a-button size="small" type="link" class="button-primary" @click.stop="handlePutWarehousing(record)">入库</a-button>
+          <a-button size="small" type="link" class="button-primary" @click.stop="handleCancelOrder(record)">取消补货单</a-button>
+        </template>
+      </s-table>
+      <!-- 确认 -->
+      <confirm-modal :openModal="openConfirmModal" :nowData="nowData" @ok="handleValidate" @close="handleCancel" />
+      <!-- 库存不足,确认弹框 -->
+      <stock-modal :openModal="openStockModal" :nowData="nowData" @ok="handleStockOk" @close="handleStockCancel" />
+      <!-- 打印贴签 -->
+      <print-sticker-modal :openModal="openPrintStickerModal" :nowData="nowData" @ok="handlePrintStickerOk" @close="handleCancel" />
+      <!-- 出库 -->
+      <out-warehousing-modal :openModal="openOutWarehousingModal" :nowData="nowData" @ok="handleValidate" @close="handleCancel" />
+      <!-- 入库 -->
+      <put-warehousing-modal :openModal="openPutWarehousingModal" :nowData="nowData" @ok="handlePutWarehousingOk" @close="handleCancel" />
+    </a-spin>
+  </a-card>
 </template>
 
 <script>
+import { commonMixin } from '@/utils/mixin'
+import { STable, VSelect } from '@/components'
+import rangeDate from '@/views/common/rangeDate.vue'
+import custList from '@/views/common/custList.vue'
+import confirmModal from './confirmModal.vue'
+import stockModal from './stockModal.vue'
+import printStickerModal from './printStickerModal.vue'
+import outWarehousingModal from './outWarehousingModal.vue'
+import putWarehousingModal from './putWarehousingModal.vue'
+import { settleReceiptQuery, queryByTypeSum } from '@/api/settleReceipt'
+import { storeCallOutTypeList } from '@/api/storeCallOutType'
+export default {
+  components: { STable, VSelect, rangeDate, custList, confirmModal, stockModal, printStickerModal, outWarehousingModal, putWarehousingModal },
+  mixins: [commonMixin],
+  data () {
+    return {
+      spinning: false,
+      advanced: true, //  高级搜索 展开/关闭
+      tableHeight: 0,
+      disabled: false, //  查询、重置按钮是否可操作
+      curBizType: 'ALL',
+      queryParam: {
+        bizType: 'ALL',
+        beginDate: null,
+        endDate: null,
+        customerSn: undefined,
+        billStatus: undefined
+      },
+      columns: [
+        { title: '序号', dataIndex: 'no', width: '4%', align: 'center' },
+        { title: '创建时间', dataIndex: 'createDate', width: '11%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '补货单号', dataIndex: 'salesBfillNo', width: '16%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '货架名称', dataIndex: 'dealerProductEntity.name', width: '21%', align: 'left', customRender: function (text) { return text || '--' }, ellipsis: true },
+        { title: '状态', dataIndex: 'salesBillNo', width: '8%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '补货应发总量', dataIndex: 'qsty', width: '8%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+        { title: '实发总量', dataIndex: 'qty', width: '7%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+        { title: '入库总量', dataIndex: 'qtssy', width: '7%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+        { title: '操作', scopedSlots: { customRender: 'action' }, width: '18%', align: 'center' }
+      ],
+      // 加载数据方法 必须为 Promise 对象
+      loadData: parameter => {
+        this.disabled = true
+        this.spinning = true
+        return settleReceiptQuery(Object.assign(parameter, this.queryParam)).then(res => {
+          let data
+          if (res.status == 200) {
+            data = res.data
+            const no = (data.pageNo - 1) * data.pageSize
+            for (var i = 0; i < data.list.length; i++) {
+              data.list[i].no = no + i + 1
+              data.list[i].subList = []
+            }
+            this.listData = data.list || []
+            this.disabled = false
+          }
+          this.spinning = false
+          return data
+        })
+      },
+      subColumns: [
+        { title: '序号', dataIndex: 'no', width: '8%', align: 'center' },
+        { title: '产品编码', dataIndex: 'salesBilslNo', width: '20%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '产品名称', dataIndex: 'name', width: '28%', align: 'left', customRender: function (text) { return text || '--' }, ellipsis: true },
+        { title: '补货应发总量', dataIndex: 'qsty', width: '12%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+        { title: '实发总量', dataIndex: 'qty', width: '12%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+        { title: '入库总量', dataIndex: 'qtssy', width: '12%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+        { title: '单位', dataIndex: 'salesBisslslNo', width: '8%', align: 'center', customRender: function (text) { return text || '--' } }
+      ],
+      listData: [],
+      tabPaneData: [],
+      nowData: null,
+      openConfirmModal: false,
+      openStockModal: false,
+      openPrintStickerModal: false,
+      openOutWarehousingModal: false,
+      openPutWarehousingModal: false
+    }
+  },
+  methods: {
+    // 确认
+    handleConfirm (row) {
+      this.nowData = row
+      this.openConfirmModal = true
+    },
+    // 确认 ok
+    handleConfirmOk () {
+      // 校验产品库存是否足够
+      this.openStockModal = true
+    },
+    // cancel
+    handleCancel () {
+      this.nowData = null
+      this.openConfirmModal = false
+      this.openStockModal = false
+      this.openPrintStickerModal = false
+      this.openOutWarehousingModal = false
+      this.openPutWarehousingModal = false
+    },
+    // 库存不足 确认 ok
+    handleStockOk () {
+      this.openStockModal = false
+      this.openConfirmModal = false
+      this.openOutWarehousingModal = false
+    },
+    // 库存不足 确认 cancel
+    handleStockCancel () {
+      this.openStockModal = false
+    },
+    // 打印贴签
+    handlePrintSticker (row) {
+      this.nowData = row
+      this.openPrintStickerModal = true
+    },
+    // 打印贴签 ok
+    handlePrintStickerOk () {},
+    // 出库
+    handleOutWarehousing (row) {
+      this.nowData = row
+      this.openOutWarehousingModal = true
+    },
+    // 出库 ok
+    handleOutWarehousingOk () {
+
+    },
+    handleValidate (type) {
+      // 校验产品库存是否足够
+      this.openStockModal = true
+    },
+    // 入库
+    handlePutWarehousing (row) {
+      this.nowData = row
+      this.openPutWarehousingModal = true
+    },
+    // 入库 ok
+    handlePutWarehousingOk () {
+      this.openPutWarehousingModal = false
+    },
+    // 取消补货单
+    handleCancelOrder (row) {
+      const _this = this
+      this.$confirm({
+        title: '提示',
+        content: '确认取消补货单吗?',
+        centered: true,
+        onOk () {
+          // _this.spinning = true
+          // storeCallOutOut({ storeCallOutSn: row.storeCallOutSn }).then(res => {
+          //   if (res.status == 200) {
+          //     _this.$message.success(res.message)
+          //     _this.$refs.table.refresh()
+          //     _this.spinning = false
+          //   } else {
+          //     _this.spinning = false
+          //   }
+          // })
+        }
+      })
+    },
+    // 自定义展开图标
+    customExpandIcon (props) {
+      if (props.expanded) {
+        return <a style={{ color: 'black', marginRight: 8 }} onClick={e => { props.onExpand(props.record, e) }}><a-button size="small" type="link" class="button-primary">收起</a-button></a>
+      } else {
+        return <a style={{ color: 'black', marginRight: 8 }} onClick={e => { props.onExpand(props.record, e) }}><a-button size="small" type="link" class="button-primary">展开</a-button></a>
+      }
+    },
+    expandFun (expanded, record) {
+      if (expanded) {
+        this.getSubItem(record) // 获取表格内部数据
+      }
+    },
+    // 获取子节点数据
+    getSubItem (record) {
+      this.spinning = true
+      storeCallOutTypeList({ pageNo: 1, pageSize: 20 }).then(res => {
+        const ind = this.listData.findIndex(item => item.id == record.id)
+        if (ind >= 0) {
+          // if (res.status == 200 && res.data && res.data.length) {
+          if (res.status == 200 && res.data && res.data.list.length) {
+            // this.listData[ind].subList = res.data
+            this.listData[ind].subList = res.data.list
+          } else {
+            this.listData[ind].subList = []
+          }
+        }
+        this.spinning = false
+      })
+    },
+    // 重置
+    resetSearchForm () {
+      this.resetData()
+      this.$refs.table.refresh(true)
+    },
+    // 重置数据
+    resetData () {
+      this.$refs.rangeDate.resetDate()
+      this.queryParam.bizType = this.curBizType
+      this.queryParam.customerSn = undefined
+      this.queryParam.beginDate = null
+      this.queryParam.endDate = null
+    },
+    //  时间  change
+    dateChange (date) {
+      this.queryParam.beginDate = date[0] || null
+      this.queryParam.endDate = date[1] || null
+    },
+    // 选择类型
+    handleTabChange (key) {
+      this.queryParam.bizType = key
+      this.$refs.table.refresh(true)
+      this.curBizType = key
+    },
+    // 客户 change
+    custChange (obj) {
+      this.queryParam.customerSn = obj.key || undefined
+    },
+    // 获取类型
+    queryByTypeSum () {
+      queryByTypeSum({}).then(res => {
+        if (res.data && res.status == 200) {
+          this.tabPaneData = res.data
+          this.queryParam.bizType = res.data[0].bizType
+          this.$refs.table.refresh(true)
+        }
+      })
+    },
+    setTableH () {
+      const tableSearchH = this.$refs.tableSearch.offsetHeight
+      this.tableHeight = window.innerHeight - tableSearchH - 240
+    },
+    pageInit () {
+      const _this = this
+      this.$nextTick(() => { // 页面渲染完成后的回调
+        _this.setTableH()
+      })
+      this.queryByTypeSum()
+    }
+  },
+  watch: {
+    advanced (newValue, oldValue) {
+      const _this = this
+      this.$nextTick(() => { // 页面渲染完成后的回调
+        _this.setTableH()
+      })
+    },
+    '$store.state.app.winHeight' (newValue, oldValue) { //  窗口变更时,需同时更改表格高度
+      this.setTableH()
+    }
+  },
+  mounted () {
+    if (!this.$store.state.app.isNewTab) { // 页签刷新时调用
+      this.resetData()
+      this.pageInit()
+    }
+  },
+  activated () {
+    // 如果是新页签打开,则重置当前页面
+    if (this.$store.state.app.isNewTab) {
+      this.resetData()
+      this.pageInit()
+    }
+  }
+}
 </script>
 
-<style>
+<style lang="less">
+	.replenishmentManagementList-wrap{
+    .replenishmentManagementList-tabs.ant-tabs.ant-tabs-card .ant-tabs-bar{
+      margin: 0 0 10px 0!important;
+    }
+		.replenishmentManagementList-tabs.ant-tabs.ant-tabs-card .ant-tabs-card-bar .ant-tabs-nav-container{
+      height: 30px!important;
+		}
+    .replenishmentManagementList-tabs.ant-tabs.ant-tabs-card .ant-tabs-card-bar .ant-tabs-tab-active{
+      height: 30px!important;
+    }
+    .replenishmentManagementList-tabs.ant-tabs.ant-tabs-card .ant-tabs-card-bar .ant-tabs-tab{
+      line-height: 26px!important;
+      height: 30px!important;
+    }
+	}
 </style>

+ 182 - 0
src/views/numsGoodsShelves/replenishmentManagement/outWarehousingModal.vue

@@ -0,0 +1,182 @@
+<template>
+  <a-modal
+    centered
+    class="replenishmentManagement-outWarehousing-modal"
+    :footer="null"
+    :maskClosable="false"
+    :title="modalTit"
+    v-model="isShow"
+    @cancle="isShow = false"
+    :width="800">
+    <a-spin :spinning="spinning" tip="Loading...">
+      <a-form-model
+        id="replenishmentManagement-outWarehousing-form"
+        ref="ruleForm"
+        layout="inline"
+        :model="form"
+        :rules="rules"
+        style="margin-bottom: 10px;" >
+        <a-row :gutter="15">
+          <a-col :md="12" :sm="24">
+            <a-form-model-item label="补货单号">BH202101010001</a-form-model-item>
+          </a-col>
+          <a-col :md="12" :sm="24">
+            <a-form-model-item label="单据来源">系统创建</a-form-model-item>
+          </a-col>
+          <a-col :md="12" :sm="24">
+            <a-form-model-item label="调往对象" prop="type">
+              <a-radio-group v-model="form.type">
+                <a-radio v-for="(item,index) in typeList" :key="index" :value="item.val">{{ item.name }}</a-radio>
+              </a-radio-group>
+            </a-form-model-item>
+          </a-col>
+          <a-col :md="12" :sm="24">
+            <a-form-model-item label="出库备注">
+              <a-input id="replenishmentManagement-outWarehousing-remark" v-model.trim="form.remark" allowClear placeholder="请输入出库备注"/>
+            </a-form-model-item>
+          </a-col>
+        </a-row>
+      </a-form-model>
+      <!-- 列表 -->
+      <s-table
+        class="sTable"
+        ref="table"
+        size="small"
+        :rowKey="(record) => record.id"
+        :columns="columns"
+        :data="loadData"
+        :scroll="{ y: 400 }"
+        :showPagination="false"
+        :defaultLoadData="false"
+        bordered>
+      </s-table>
+      <div class="btn-cont">
+        <a-button type="primary" id="replenishmentManagement-outWarehousing-modal-save" @click="handleSave">确认出库</a-button>
+        <a-button id="replenishmentManagement-outWarehousing-modal-back" @click="isShow = false" style="margin-left: 15px;">取消</a-button>
+      </div>
+    </a-spin>
+  </a-modal>
+</template>
+
+<script>
+import { commonMixin } from '@/utils/mixin'
+import { STable, VSelect } from '@/components'
+import { storeCallOutList } from '@/api/storeCallOut'
+export default {
+  name: 'OutWarehousingModal',
+  components: { STable, VSelect },
+  mixins: [commonMixin],
+  props: {
+    openModal: { //  弹框显示状态
+      type: Boolean,
+      default: false
+    },
+    nowData: {
+      type: Object,
+      default: () => {
+        return {}
+      }
+    }
+  },
+  data () {
+    return {
+      spinning: false,
+      isShow: this.openModal, //  是否打开弹框
+      columns: [
+        { title: '序号', dataIndex: 'no', width: '8%', align: 'center' },
+        { title: '产品编码', dataIndex: 'allocationLinkagePutNo', width: '22%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '产品名称', dataIndex: 'outTenantName', width: '32%', align: 'left', customRender: function (text) { return text || '--' }, ellipsis: true },
+        { title: '补货应发数量', dataIndex: 'productTotalCategory', width: '15%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+        { title: '实发数量', dataIndex: 'outQty', width: '15%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+        { title: '单位', dataIndex: 'productUnit', width: '8%', align: 'center', customRender: function (text) { return text || '--' } }
+      ],
+      // 加载数据方法 必须为 Promise 对象
+      loadData: parameter => {
+        this.disabled = true
+        this.spinning = true
+        return storeCallOutList(Object.assign(parameter, this.queryParam)).then(res => {
+          let data
+          if (res.status == 200) {
+            data = res.data
+            const no = (data.pageNo - 1) * data.pageSize
+            for (var i = 0; i < data.list.length; i++) {
+              data.list[i].no = no + i + 1
+            }
+            this.disabled = false
+          }
+          this.spinning = false
+          return data
+        })
+      },
+      form: {
+        type: undefined,
+        remark: ''
+      },
+      rules: {
+        'type': [{ required: true, message: '请选择配送方式', trigger: ['blur', 'change'] }]
+      },
+      typeList: [
+        { name: '送货到店', val: 1 },
+        { name: '快递到店', val: 2 }
+      ]
+    }
+  },
+  computed: {
+    modalTit () {
+      const hjName = this.nowData && this.nowData.settleClientName ? this.nowData.settleClientName : ''
+      return '补货单出库——' + hjName
+    }
+  },
+  methods: {
+    //  确认出库
+    handleSave () {
+      const _this = this
+      this.$confirm({
+        title: '提示',
+        content: '确认信息无误并进行出库吗?',
+        centered: true,
+        onOk () {
+          _this.$emit('ok', 'outWarehousing')
+          // _this.spinning = true
+          // storeCallOutOut({ storeCallOutSn: row.storeCallOutSn }).then(res => {
+          //   if (res.status == 200) {
+          //     _this.$message.success(res.message)
+          //     _this.$refs.table.refresh()
+          //     _this.spinning = false
+          //   } else {
+          //     _this.spinning = false
+          //   }
+          // })
+        }
+      })
+    }
+  },
+  watch: {
+    //  父页面传过来的弹框状态
+    openModal (newValue, oldValue) {
+      this.isShow = newValue
+    },
+    //  重定义的弹框状态
+    isShow (newValue, oldValue) {
+      if (!newValue) {
+        this.$emit('close')
+        this.$refs.table.clearTable()
+      } else {
+        const _this = this
+        this.$nextTick(() => { // 页面渲染完成后的回调
+          _this.$refs.table.refresh(true)
+        })
+      }
+    }
+  }
+}
+</script>
+
+<style lang="less">
+.replenishmentManagement-outWarehousing-modal {
+	.btn-cont {
+		text-align: center;
+		margin: 35px 0 10px;
+	}
+}
+</style>

+ 158 - 0
src/views/numsGoodsShelves/replenishmentManagement/printStickerModal.vue

@@ -0,0 +1,158 @@
+<template>
+  <a-modal
+    centered
+    class="replenishmentManagement-printSticker-modal"
+    :footer="null"
+    :maskClosable="false"
+    :title="modalTit"
+    v-model="isShow"
+    @cancle="isShow = false"
+    :width="800">
+    <a-spin :spinning="spinning" tip="Loading...">
+      <div style="display: flex;justify-content: space-between;margin-bottom: 10px;">
+        <a-descriptions>
+          <a-descriptions-item label="补货单号">BH202101010001</a-descriptions-item>
+          <a-descriptions-item label="单据来源">系统创建</a-descriptions-item>
+        </a-descriptions>
+        <a-button type="primary" class="button-primary" id="replenishmentManagement-printSticker-export" @click="handlePrint">开始打印</a-button>
+      </div>
+      <!-- 列表 -->
+      <s-table
+        class="sTable"
+        ref="table"
+        size="small"
+        :rowKey="(record) => record.id"
+        rowKeyName="id"
+        :row-selection="{ columnWidth: 40, getCheckboxProps: record => ({ props: { disabled: record.state == 'FINISH' } }) }"
+        @rowSelection="rowSelectionFun"
+        :columns="columns"
+        :data="loadData"
+        :scroll="{ y: 400 }"
+        :showPagination="false"
+        :defaultLoadData="false"
+        bordered>
+        <!-- 打印数量 -->
+        <template slot="outQty" slot-scope="text, record">
+          <a-input-number
+            size="small"
+            id="replenishmentManagement-printSticker-outQty"
+            v-model="record.outQty"
+            :precision="0"
+            :min="0"
+            :max="record.currentQty"
+            placeholder="请输入"
+            :style="{width: '100%', color: record.outQty==0 ? 'red': ''}" />
+        </template>
+      </s-table>
+      <div class="btn-cont">
+        <a-button type="primary" id="replenishmentManagement-printSticker-modal-save" @click="handleSave">确认打印完成</a-button>
+        <a-button id="replenishmentManagement-printSticker-modal-back" @click="isShow = false" style="margin-left: 15px;">取消</a-button>
+      </div>
+    </a-spin>
+  </a-modal>
+</template>
+
+<script>
+import { commonMixin } from '@/utils/mixin'
+import { STable, VSelect } from '@/components'
+import { storeCallOutList } from '@/api/storeCallOut'
+export default {
+  name: 'PrintStickerModal',
+  components: { STable, VSelect },
+  mixins: [commonMixin],
+  props: {
+    openModal: { //  弹框显示状态
+      type: Boolean,
+      default: false
+    },
+    nowData: {
+      type: Object,
+      default: () => {
+        return {}
+      }
+    }
+  },
+  data () {
+    return {
+      spinning: false,
+      isShow: this.openModal, //  是否打开弹框
+      columns: [
+        { title: '产品编码', dataIndex: 'allocationLinkagePutNo', width: '22%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '产品名称', dataIndex: 'outTenantName', width: '30%', align: 'left', customRender: function (text) { return text || '--' }, ellipsis: true },
+        { title: '补货应发数量', dataIndex: 'productTotalCategory', width: '13%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+        { title: '实发数量', dataIndex: 'productTotalCategssory', width: '12%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+        { title: '打印数量', scopedSlots: { customRender: 'outQty' }, width: '15%', align: 'center' },
+        { title: '单位', dataIndex: 'productUnit', width: '8%', align: 'center', customRender: function (text) { return text || '--' } }
+      ],
+      // 加载数据方法 必须为 Promise 对象
+      loadData: parameter => {
+        this.disabled = true
+        this.spinning = true
+        return storeCallOutList(Object.assign(parameter, this.queryParam)).then(res => {
+          let data
+          if (res.status == 200) {
+            data = res.data
+            const no = (data.pageNo - 1) * data.pageSize
+            for (var i = 0; i < data.list.length; i++) {
+              data.list[i].no = no + i + 1
+            }
+            this.disabled = false
+          }
+          this.spinning = false
+          return data
+        })
+      },
+      rowSelectionInfo: null
+    }
+  },
+  computed: {
+    modalTit () {
+      const hjName = this.nowData && this.nowData.settleClientName ? this.nowData.settleClientName : ''
+      return '补货单打印贴签——' + hjName
+    }
+  },
+  methods: {
+    // 表格选中项
+    rowSelectionFun (obj) {
+      this.rowSelectionInfo = obj || null
+    },
+    //  确认打印完成
+    handleSave () {
+      this.$emit('ok')
+    },
+    // 开始打印
+    handlePrint () {
+      if (!this.rowSelectionInfo || (this.rowSelectionInfo && this.rowSelectionInfo.selectedRows.length < 1)) {
+        this.$message.warning('请至少选择一个产品')
+      }
+    }
+  },
+  watch: {
+    //  父页面传过来的弹框状态
+    openModal (newValue, oldValue) {
+      this.isShow = newValue
+    },
+    //  重定义的弹框状态
+    isShow (newValue, oldValue) {
+      if (!newValue) {
+        this.$emit('close')
+        this.$refs.table.clearTable()
+      } else {
+        const _this = this
+        this.$nextTick(() => { // 页面渲染完成后的回调
+          _this.$refs.table.refresh(true)
+        })
+      }
+    }
+  }
+}
+</script>
+
+<style lang="less">
+.replenishmentManagement-printSticker-modal {
+	.btn-cont {
+		text-align: center;
+		margin: 35px 0 10px;
+	}
+}
+</style>

+ 177 - 0
src/views/numsGoodsShelves/replenishmentManagement/putWarehousingModal.vue

@@ -0,0 +1,177 @@
+<template>
+  <a-modal
+    centered
+    class="replenishmentManagement-outWarehousing-modal"
+    :footer="null"
+    :maskClosable="false"
+    :title="modalTit"
+    v-model="isShow"
+    @cancle="isShow = false"
+    :width="800">
+    <a-spin :spinning="spinning" tip="Loading...">
+      <a-descriptions>
+        <a-descriptions-item label="补货单号">BH202101010001</a-descriptions-item>
+        <a-descriptions-item label="单据来源">系统创建</a-descriptions-item>
+        <a-descriptions-item label="调往对象">送货到店</a-descriptions-item>
+        <a-descriptions-item label="出库备注" :span="3">
+          <a-tooltip placement="bottom">
+            <template slot="title">
+              <span>这里显示出库备注,没有显示--,超长显示...,鼠标移到此处显示全部鼠标移到此处显示全部鼠标移到此处显示全部鼠标移到此处显示全部鼠标移到此处显示全部鼠标移到此处显示全部鼠标移到此处显示全部鼠标移到此处显示全部鼠标移到此处显示全部鼠标移到此处显示全部鼠标移到此处显示全部鼠标移到此处显示全部鼠标移到此处显示全部鼠标移到此处显示全部鼠标移到此处显示全部</span>
+            </template>
+            <p class="text-ellipsis">这里显示出库备注,没有显示--,超长显示...,鼠标移到此处显示全部鼠标移到此处显示全部鼠标移到此处显示全部鼠标移到此处显示全部鼠标移到此处显示全部鼠标移到此处显示全部鼠标移到此处显示全部鼠标移到此处显示全部鼠标移到此处显示全部鼠标移到此处显示全部鼠标移到此处显示全部鼠标移到此处显示全部鼠标移到此处显示全部鼠标移到此处显示全部鼠标移到此处显示全部</p>
+          </a-tooltip>
+        </a-descriptions-item>
+      </a-descriptions>
+      <!-- 列表 -->
+      <s-table
+        class="sTable"
+        ref="table"
+        size="small"
+        :rowKey="(record) => record.id"
+        :columns="columns"
+        :data="loadData"
+        :scroll="{ y: 400 }"
+        :showPagination="false"
+        :defaultLoadData="false"
+        bordered>
+        <!-- 入库数量 -->
+        <template slot="outQty" slot-scope="text, record">
+          <a-input-number
+            size="small"
+            id="replenishmentManagement-outWarehousing-outQty"
+            v-model="record.outQty"
+            :precision="0"
+            :min="0"
+            :max="record.currentQty"
+            placeholder="请输入"
+            :style="{width: '100%', color: record.outQty==0 ? 'red': ''}" />
+        </template>
+      </s-table>
+      <div class="btn-cont">
+        <a-button type="primary" id="replenishmentManagement-outWarehousing-modal-save" @click="handleSave">确认入库</a-button>
+        <a-button id="replenishmentManagement-outWarehousing-modal-back" @click="isShow = false" style="margin-left: 15px;">取消</a-button>
+      </div>
+    </a-spin>
+  </a-modal>
+</template>
+
+<script>
+import { commonMixin } from '@/utils/mixin'
+import { STable, VSelect } from '@/components'
+import { storeCallOutList } from '@/api/storeCallOut'
+export default {
+  name: 'PutWarehousingModal',
+  components: { STable, VSelect },
+  mixins: [commonMixin],
+  props: {
+    openModal: { //  弹框显示状态
+      type: Boolean,
+      default: false
+    },
+    nowData: {
+      type: Object,
+      default: () => {
+        return {}
+      }
+    }
+  },
+  data () {
+    return {
+      spinning: false,
+      isShow: this.openModal, //  是否打开弹框
+      columns: [
+        { title: '序号', dataIndex: 'no', width: '5%', align: 'center' },
+        { title: '产品编码', dataIndex: 'allocationLinkagePutNo', width: '22%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '产品名称', dataIndex: 'outTenantName', width: '28%', align: 'left', customRender: function (text) { return text || '--' }, ellipsis: true },
+        { title: '补货应发数量', dataIndex: 'productTotalCategory', width: '12%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+        { title: '实发数量', dataIndex: 'productTotalCsategory', width: '12%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+        { title: '入库数量', scopedSlots: { customRender: 'outQty' }, width: '15%', align: 'center' },
+        { title: '单位', dataIndex: 'productUnit', width: '6%', align: 'center', customRender: function (text) { return text || '--' } }
+      ],
+      // 加载数据方法 必须为 Promise 对象
+      loadData: parameter => {
+        this.disabled = true
+        this.spinning = true
+        return storeCallOutList(Object.assign(parameter, this.queryParam)).then(res => {
+          let data
+          if (res.status == 200) {
+            data = res.data
+            const no = (data.pageNo - 1) * data.pageSize
+            for (var i = 0; i < data.list.length; i++) {
+              data.list[i].no = no + i + 1
+            }
+            this.disabled = false
+          }
+          this.spinning = false
+          return data
+        })
+      }
+    }
+  },
+  computed: {
+    modalTit () {
+      const hjName = this.nowData && this.nowData.settleClientName ? this.nowData.settleClientName : ''
+      return '补货单入库——' + hjName
+    }
+  },
+  methods: {
+    //  确认出库
+    handleSave () {
+      const _this = this
+      this.$confirm({
+        title: '提示',
+        content: '入库后数字货架的产品数量将增加,确认入库吗?',
+        centered: true,
+        onOk () {
+          _this.$emit('ok')
+          // _this.spinning = true
+          // storeCallOutOut({ storeCallOutSn: row.storeCallOutSn }).then(res => {
+          //   if (res.status == 200) {
+          //     _this.$message.success(res.message)
+          //     _this.$refs.table.refresh()
+          //     _this.spinning = false
+          //   } else {
+          //     _this.spinning = false
+          //   }
+          // })
+        }
+      })
+    }
+  },
+  watch: {
+    //  父页面传过来的弹框状态
+    openModal (newValue, oldValue) {
+      this.isShow = newValue
+    },
+    //  重定义的弹框状态
+    isShow (newValue, oldValue) {
+      if (!newValue) {
+        this.$emit('close')
+        this.$refs.table.clearTable()
+      } else {
+        const _this = this
+        this.$nextTick(() => { // 页面渲染完成后的回调
+          _this.$refs.table.refresh(true)
+        })
+      }
+    }
+  }
+}
+</script>
+
+<style lang="less">
+.replenishmentManagement-outWarehousing-modal {
+  .text-ellipsis{
+    margin: 0;
+    overflow:hidden;
+    text-overflow:ellipsis;
+    display:-webkit-box;
+    -webkit-box-orient:vertical;
+    -webkit-line-clamp:1;
+  }
+	.btn-cont {
+		text-align: center;
+		margin: 35px 0 10px;
+	}
+}
+</style>

+ 120 - 0
src/views/numsGoodsShelves/replenishmentManagement/stockModal.vue

@@ -0,0 +1,120 @@
+<template>
+  <a-modal
+    centered
+    class="replenishmentManagement-stock-modal"
+    :footer="null"
+    :maskClosable="false"
+    title="提示"
+    v-model="isShow"
+    @cancle="isShow = false"
+    :width="800">
+    <a-spin :spinning="spinning" tip="Loading...">
+      <p style="text-align: center;margin: 0 0 20px;font-size: 14px;font-weight: bold;">以下产品库存不足,确认继续补货吗?</p>
+      <!-- 列表 -->
+      <s-table
+        class="sTable"
+        ref="table"
+        size="small"
+        :rowKey="(record) => record.id"
+        :columns="columns"
+        :data="loadData"
+        :scroll="{ y: 400 }"
+        :showPagination="false"
+        :defaultLoadData="false"
+        bordered>
+      </s-table>
+      <div class="btn-cont">
+        <a-button type="primary" id="replenishmentManagement-stock-modal-save" @click="handleSave">仍然补货</a-button>
+        <a-button id="replenishmentManagement-stock-modal-back" @click="isShow = false" style="margin-left: 15px;">返回修改</a-button>
+      </div>
+    </a-spin>
+  </a-modal>
+</template>
+
+<script>
+import { commonMixin } from '@/utils/mixin'
+import { STable, VSelect } from '@/components'
+import { storeCallOutList } from '@/api/storeCallOut'
+export default {
+  name: 'StockModal',
+  components: { STable, VSelect },
+  mixins: [commonMixin],
+  props: {
+    openModal: { //  弹框显示状态
+      type: Boolean,
+      default: false
+    },
+    nowData: {
+      type: Object,
+      default: () => {
+        return {}
+      }
+    }
+  },
+  data () {
+    return {
+      spinning: false,
+      isShow: this.openModal, //  是否打开弹框
+      columns: [
+        { title: '序号', dataIndex: 'no', width: '8%', align: 'center' },
+        { title: '产品编码', dataIndex: 'allocationLinkagePutNo', width: '22%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '产品名称', dataIndex: 'outTenantName', width: '32%', align: 'left', customRender: function (text) { return text || '--' }, ellipsis: true },
+        { title: '可用库存数量', dataIndex: 'outQty', width: '15%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+        { title: '补货实发数量', dataIndex: 'productTotalCategory', width: '15%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+        { title: '单位', dataIndex: 'productUnit', width: '8%', align: 'center', customRender: function (text) { return text || '--' } }
+      ],
+      // 加载数据方法 必须为 Promise 对象
+      loadData: parameter => {
+        this.disabled = true
+        this.spinning = true
+        return storeCallOutList(Object.assign(parameter, this.queryParam)).then(res => {
+          let data
+          if (res.status == 200) {
+            data = res.data
+            const no = (data.pageNo - 1) * data.pageSize
+            for (var i = 0; i < data.list.length; i++) {
+              data.list[i].no = no + i + 1
+            }
+            this.disabled = false
+          }
+          this.spinning = false
+          return data
+        })
+      }
+    }
+  },
+  methods: {
+    //  仍然补货
+    handleSave () {
+      this.$emit('ok')
+    }
+  },
+  watch: {
+    //  父页面传过来的弹框状态
+    openModal (newValue, oldValue) {
+      this.isShow = newValue
+    },
+    //  重定义的弹框状态
+    isShow (newValue, oldValue) {
+      if (!newValue) {
+        this.$emit('close')
+        this.$refs.table.clearTable()
+      } else {
+        const _this = this
+        this.$nextTick(() => { // 页面渲染完成后的回调
+          _this.$refs.table.refresh(true)
+        })
+      }
+    }
+  }
+}
+</script>
+
+<style lang="less">
+.replenishmentManagement-stock-modal {
+	.btn-cont {
+		text-align: center;
+		margin: 35px 0 10px;
+	}
+}
+</style>

+ 150 - 0
src/views/numsGoodsShelves/shelfMonitoring/addModal.vue

@@ -0,0 +1,150 @@
+<template>
+  <a-modal
+    centered
+    class="shelfMonitoring-add-modal"
+    :footer="null"
+    :maskClosable="false"
+    title="新增调回单"
+    v-model="isShow"
+    @cancle="isShow = false"
+    :width="800">
+    <a-spin :spinning="spinning" tip="Loading...">
+      <a-descriptions>
+        <a-descriptions-item label="货架名称">西安车领主常青二路数字货架</a-descriptions-item>
+      </a-descriptions>
+      <!-- 提示 -->
+      <a-alert type="info" style="margin-bottom:10px">
+        <div slot="message">调回数量不能大于当前库存。如果调回数量为0,请移除此产品。</div>
+      </a-alert>
+      <!-- 列表 -->
+      <s-table
+        class="sTable"
+        ref="table"
+        size="small"
+        :rowKey="(record) => record.id"
+        :columns="columns"
+        :data="loadData"
+        :scroll="{ y: 400 }"
+        :showPagination="false"
+        bordered>
+        <!-- 调回数量 -->
+        <template slot="outQty" slot-scope="text, record">
+          <a-input-number
+            size="small"
+            id="shelfMonitoring-add-outQty"
+            v-model="record.outQty"
+            :precision="0"
+            :min="0"
+            :max="record.currentQty"
+            placeholder="请输入"
+            :style="{width: '100%', color: record.outQty==0 ? 'red': ''}" />
+        </template>
+        <!-- 操作 -->
+        <template slot="action" slot-scope="text, record">
+          <a-button
+            size="small"
+            type="link"
+            class="button-primary"
+            @click="handleDel(record)"
+            id="shelfMonitoring-add-btn">移除</a-button>
+        </template>
+      </s-table>
+      <div class="btn-cont">
+        <a-button type="primary" id="shelfMonitoring-add-modal-save" @click="handleSave">确认调回</a-button>
+        <a-button id="shelfMonitoring-add-modal-back" @click="isShow = false" style="margin-left: 15px;">取消</a-button>
+      </div>
+    </a-spin>
+  </a-modal>
+</template>
+
+<script>
+import { commonMixin } from '@/utils/mixin'
+import { STable, VSelect } from '@/components'
+import { storeCallOutList } from '@/api/storeCallOut'
+export default {
+  name: 'ShelfMonitoringAddModal',
+  components: { STable, VSelect },
+  mixins: [commonMixin],
+  props: {
+    openModal: { //  弹框显示状态
+      type: Boolean,
+      default: false
+    },
+    nowData: {
+      type: Array,
+      default: () => {
+        return []
+      }
+    }
+  },
+  data () {
+    return {
+      spinning: false,
+      isShow: this.openModal, //  是否打开弹框
+      columns: [
+        { title: '序号', dataIndex: 'no', width: '5%', align: 'center' },
+        { title: '货位号', dataIndex: 'createDate', width: '16%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '产品编码', dataIndex: 'allocationLinkagePutNo', width: '13%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '产品名称', dataIndex: 'outTenantName', width: '17%', align: 'left', customRender: function (text) { return text || '--' }, ellipsis: true },
+        { title: '当前库存', dataIndex: 'productTotalCategory', width: '8%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+        { title: '最大库容', dataIndex: 'productTotalQty', width: '8%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+        { title: '滞销天数', dataIndex: 'productTotalCost', width: '10%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '调货数量', scopedSlots: { customRender: 'outQty' }, width: '10%', align: 'center' },
+        { title: '单位', dataIndex: 'productUnit', width: '5%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '操作', scopedSlots: { customRender: 'action' }, width: '8%', align: 'center' }
+      ],
+      // 加载数据方法 必须为 Promise 对象
+      loadData: parameter => {
+        this.disabled = true
+        this.spinning = true
+        return storeCallOutList(Object.assign(parameter, this.queryParam)).then(res => {
+          let data
+          if (res.status == 200) {
+            data = res.data
+            const no = (data.pageNo - 1) * data.pageSize
+            for (var i = 0; i < data.list.length; i++) {
+              data.list[i].no = no + i + 1
+            }
+            this.disabled = false
+          }
+          this.spinning = false
+          return data
+        })
+      }
+    }
+  },
+  methods: {
+    //  确认调回
+    handleSave () {
+      this.$emit('ok')
+      this.$message.info('保存并确认成功,返回并刷新列表')
+    },
+    // 移除
+    handleDel (row) {
+
+    }
+  },
+  watch: {
+    //  父页面传过来的弹框状态
+    openModal (newValue, oldValue) {
+      this.isShow = newValue
+    },
+    //  重定义的弹框状态
+    isShow (newValue, oldValue) {
+      if (!newValue) {
+        this.$emit('close')
+        this.$refs.table.clearTable()
+      }
+    }
+  }
+}
+</script>
+
+<style lang="less">
+.shelfMonitoring-add-modal {
+	.btn-cont {
+		text-align: center;
+		margin: 35px 0 10px;
+	}
+}
+</style>

+ 123 - 25
src/views/numsGoodsShelves/shelfMonitoring/list.vue

@@ -62,6 +62,35 @@
                     allowClear></v-select>
                 </a-form-model-item>
               </a-col>
+              <a-col :md="6" :sm="24">
+                <a-form-model-item label="滞销天数">
+                  <a-input-group>
+                    <a-row>
+                      <a-col :span="11">
+                        <a-input-number
+                          id="shelfMonitoringList-beginDay"
+                          v-model="queryParam.beginDay"
+                          :precision="0"
+                          :min="0"
+                          :max="999999"
+                          placeholder="起始天数"
+                          style="width: 100%;display: inline-block;" />
+                      </a-col>
+                      <a-col :span="2"><span style="display: block;text-align: center;line-height: 32px;">至</span></a-col>
+                      <a-col :span="11">
+                        <a-input-number
+                          id="shelfMonitoringList-endDay"
+                          v-model="queryParam.endDay"
+                          :precision="0"
+                          :min="0"
+                          :max="999999"
+                          placeholder="截止天数"
+                          style="width: 100%;display: inline-block;" />
+                      </a-col>
+                    </a-row>
+                  </a-input-group>
+                </a-form-model-item>
+              </a-col>
             </template>
             <a-col :md="6" :sm="24" style="margin-bottom: 10px;">
               <a-button type="primary" @click="handleSearch" :disabled="disabled" id="shelfMonitoringList-refresh">查询</a-button>
@@ -81,7 +110,11 @@
       </div>
       <div v-show="isSearch">
         <div style="margin-bottom: 10px">
-          <a-button type="primary" id="shelfMonitoringList-export" @click="handleAddBack">新增调回单</a-button>
+          <div style="display: inline-block;margin-right: 15px;vertical-align: middle;">
+            <a-divider type="vertical" style="background: #FF7D0C;width: 3px;heigh: 16px;" />
+            <span>西安车领主常青二路数字货架</span>
+          </div>
+          <a-button type="primary" class="button-error" id="shelfMonitoringList-export" @click="handleAddBack">新增调回单</a-button>
           <span style="margin-left: 5px">
             <template v-if="rowSelectionInfo&&rowSelectionInfo.selectedRowKeys.length > 0">
               {{ `已选 ${rowSelectionInfo.selectedRowKeys.length} 项` }}
@@ -108,23 +141,25 @@
             <a-button
               size="small"
               type="link"
-              class="button-warning"
-              @click="handleEdit(record)"
+              class="button-primary"
+              @click="handleDetail(record)"
               id="shelfMonitoringList-warehousing-btn">出入库明细</a-button>
           </template>
         </s-table>
       </div>
     </a-spin>
+    <!-- 新增调回单 -->
+    <add-modal :openModal="openModal" :nowData="rowSelectionInfo&&rowSelectionInfo.selectedRows" @ok="handleOk" @close="handleCancel" />
   </a-card>
 </template>
 
 <script>
 import { commonMixin } from '@/utils/mixin'
 import { STable, VSelect } from '@/components'
+import addModal from './addModal.vue'
 import { storeCallOutList } from '@/api/storeCallOut'
 export default {
-  name: 'ShelfMonitoring',
-  components: { STable, VSelect },
+  components: { STable, VSelect, addModal },
   mixins: [commonMixin],
   data () {
     return {
@@ -137,7 +172,9 @@ export default {
         hjName: undefined, //  调出对象
         allocationType: undefined, //  调拨产品类型
         state: undefined, //  业务状态
-        settleState: undefined
+        settleState: undefined,
+        beginDay: undefined,
+        endDay: undefined
       },
       rules: {
         'hjName': [{ required: true, message: '请输入货架名称', trigger: 'change' }]
@@ -155,30 +192,75 @@ export default {
       ],
       // 加载数据方法 必须为 Promise 对象
       loadData: parameter => {
-        this.disabled = true
-        this.spinning = true
-        return storeCallOutList(Object.assign(parameter, this.queryParam)).then(res => {
-          let data
-          if (res.status == 200) {
-            data = res.data
-            const no = (data.pageNo - 1) * data.pageSize
-            for (var i = 0; i < data.list.length; i++) {
-              data.list[i].no = no + i + 1
+        // 校验滞销天数数值范围
+        if (this.checkValueRange()) {
+          this.disabled = true
+          this.spinning = true
+          return storeCallOutList(Object.assign(parameter, this.queryParam)).then(res => {
+            let data
+            if (res.status == 200) {
+              data = res.data
+              const no = (data.pageNo - 1) * data.pageSize
+              for (var i = 0; i < data.list.length; i++) {
+                data.list[i].no = no + i + 1
+              }
+              this.disabled = false
+            }
+            this.spinning = false
+            return data
+          })
+        } else {
+          const _this = this
+          this.disabled = true
+          this.spinning = true
+          return new Promise(function (resolve, reject) {
+            const data = {
+              pageNo: 1,
+              pageSize: 10,
+              list: [],
+              count: 0
             }
-            this.disabled = false
-          }
-          this.spinning = false
-          return data
-        })
+            _this.disabled = false
+            _this.spinning = false
+            resolve(data)
+          })
+        }
       },
       hjNameData: [],
       rowSelectionInfo: null,
-      isSearch: false
+      isSearch: false,
+      openModal: false //  新增编辑  弹框
     }
   },
   methods: {
+    // 校验滞销天数数值范围
+    checkValueRange () {
+      const isONull = this.queryParam.beginDay === null || this.queryParam.beginDay === undefined
+      const isOEmpty = this.queryParam.beginDay === ''
+      const isOZero = this.queryParam.beginDay === 0
+      const isTNull = this.queryParam.endDay === null || this.queryParam.endDay === undefined
+      const isTEmpty = this.queryParam.endDay === ''
+      const isTZero = this.queryParam.endDay === 0
+      //  第一个为空(可为null可为空字符)第二个不为空
+      //  第一个不为空第二个为空(可为null可为空字符)
+      //  第一个大于第二个
+      if ((isONull || isOEmpty) && (this.queryParam.endDay || isTZero)) {
+        this.$message.info('请输入正确的滞销天数查询范围!')
+        return false
+      }
+      if ((this.queryParam.beginDay || isOZero) && (isTNull || isTEmpty)) {
+        this.$message.info('请输入正确的滞销天数查询范围!')
+        return false
+      }
+      if (this.queryParam.beginDay > this.queryParam.endDay) {
+        this.$message.info('请输入正确的滞销天数查询范围!')
+        return false
+      }
+      this.queryParam.beginDay = this.queryParam.beginDay > 999999999 ? 999999999 : this.queryParam.beginDay
+      this.queryParam.endDay = this.queryParam.endDay > 999999999 ? 999999999 : this.queryParam.endDay
+      return true
+    },
     rowSelectionFun (obj) {
-      console.log('rowSelection', obj)
       this.rowSelectionInfo = obj || null
     },
     //  查询
@@ -202,14 +284,30 @@ export default {
       this.queryParam.allocationType = undefined
       this.queryParam.state = undefined
       this.queryParam.settleState = undefined
+      this.queryParam.beginDay = undefined
+      this.queryParam.endDay = undefined
       this.$refs.ruleForm.resetFields()
       this.$refs.table.clearTable()
     },
     // 新增调回单
-    handleAddBack () {},
+    handleAddBack () {
+      if (!this.rowSelectionInfo || (this.rowSelectionInfo && this.rowSelectionInfo.selectedRows.length < 1)) {
+        this.$message.warning('请至少选择一个产品')
+      } else {
+        this.openModal = true
+      }
+    },
     //  详情
     handleDetail (row) {
-      this.$router.push({ path: `/allocationManagement/chainTransferIn/detail/${row.allocationLinkagePutSn}` })
+      // this.$router.push({ path: `/numsGoodsShelves/shelfMonitoring/warehouseDetail/${row.allocationLinkagePutSn}` })
+      this.$router.push({ path: `/numsGoodsShelves/shelfMonitoring/warehouseDetail/1` })
+    },
+    handleOk () {
+      this.$refs.table.refresh()
+      this.isSearch = true
+    },
+    handleCancel () {
+      this.openModal = false
     },
     filterOption (input, option) {
       return (
@@ -261,7 +359,7 @@ export default {
   .shelfMonitoringList-wrap{
     .unChoose {
       text-align: center;
-      margin: 240px 0 300px;
+      margin: 280px 0 340px;
       font-size: 16px;
     }
   }

+ 149 - 1
src/views/numsGoodsShelves/shelfMonitoring/warehouseDetail.vue

@@ -1,8 +1,156 @@
 <template>
+  <div class="shelfMonitoringWarehousing-wrap">
+    <a-spin :spinning="spinning" tip="Loading...">
+      <a-page-header :ghost="false" :backIcon="false" @back="handleBack" >
+        <!-- 自定义的二级文字标题 -->
+        <template slot="subTitle">
+          <a id="shelfMonitoringWarehousing-back-btn" href="javascript:;" @click="handleBack"><a-icon type="left" /> 返回列表</a>
+          <span class="store-info">西安车领主常青二路数字货架——货位号A01</span>
+        </template>
+      </a-page-header>
+      <!-- 内容 -->
+      <a-card size="small" :bordered="false" class="shelfMonitoringWarehousing-cont">
+        <!-- 搜索条件 -->
+        <div ref="tableSearch" class="table-page-search-wrapper">
+          <a-form layout="inline" @keyup.enter.native="$refs.table.refresh(true)">
+            <a-row :gutter="15">
+              <a-col :md="6" :sm="24">
+                <a-form-item label="变动时间">
+                  <rangeDate ref="rangeDate" :value="time" @change="dateChange" />
+                </a-form-item>
+              </a-col>
+              <a-col :md="6" :sm="24">
+                <a-form-item label="关联单据类型">
+                  <v-select
+                    v-model="queryParam.financialStatus"
+                    ref="financialStatus"
+                    id="shelfMonitoringWarehousing-financialStatus"
+                    code="FINANCIAL_PAY_STATUS"
+                    placeholder="请选择关联单据类型"
+                    allowClear></v-select>
+                </a-form-item>
+              </a-col>
+              <a-col :md="6" :sm="24">
+                <a-form-item label="关联单据号">
+                  <a-input id="shelfMonitoringWarehousing-purchaseBillNo" v-model.trim="queryParam.purchaseBillNo" allowClear placeholder="请输入关联单据号"/>
+                </a-form-item>
+              </a-col>
+              <a-col :md="6" :sm="24">
+                <span class="table-page-search-submitButtons">
+                  <a-button type="primary" @click="$refs.table.refresh(true)" :disabled="disabled" id="shelfMonitoringWarehousing-refresh">查询</a-button>
+                  <a-button style="margin-left: 5px" @click="resetSearchForm()" :disabled="disabled" id="shelfMonitoringWarehousing-reset">重置</a-button>
+                </span>
+              </a-col>
+            </a-row>
+          </a-form>
+        </div>
+        <!-- 列表 -->
+        <s-table
+          class="sTable"
+          ref="table"
+          size="small"
+          :rowKey="(record) => record.id"
+          :columns="columns"
+          :data="loadData"
+          :defaultLoadData="false"
+          bordered>
+        </s-table>
+      </a-card>
+    </a-spin>
+  </div>
 </template>
 
 <script>
+import { commonMixin } from '@/utils/mixin'
+import { STable, VSelect } from '@/components'
+import rangeDate from '@/views/common/rangeDate.vue'
+import { storeCallOutList } from '@/api/storeCallOut'
+export default {
+  components: { STable, VSelect, rangeDate },
+  mixins: [commonMixin],
+  data () {
+    return {
+      spinning: false,
+      disabled: false, //  查询、重置按钮是否可操作
+      time: [],
+      queryParam: {
+        beginDate: undefined,
+        endDate: undefined,
+        financialStatus: undefined,
+        purchaseBillNo: ''
+      },
+      columns: [
+        { title: '序号', dataIndex: 'no', width: '6%', align: 'center' },
+        { title: '变动时间', dataIndex: 'createDate', width: '15%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '产品编码', dataIndex: 'allocationLinkagePutNo', width: '17%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '产品名称', dataIndex: 'outTenantName', width: '24%', align: 'left', customRender: function (text) { return text || '--' }, ellipsis: true },
+        { title: '关联单据类型', dataIndex: 'productTotalQty', width: '10%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '关联单据号', dataIndex: 'productTotalCost', width: '10%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '数量', dataIndex: 'allocationTypeDictValue', width: '8%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+        { title: '状态', dataIndex: 'productUnit', width: '10%', align: 'center', customRender: function (text) { return text || '--' } }
+      ],
+      // 加载数据方法 必须为 Promise 对象
+      loadData: parameter => {
+        this.disabled = true
+        this.spinning = true
+        return storeCallOutList(Object.assign(parameter, this.queryParam)).then(res => {
+          let data
+          if (res.status == 200) {
+            data = res.data
+            const no = (data.pageNo - 1) * data.pageSize
+            for (var i = 0; i < data.list.length; i++) {
+              data.list[i].no = no + i + 1
+            }
+            this.disabled = false
+          }
+          this.spinning = false
+          return data
+        })
+      }
+    }
+  },
+  methods: {
+    //  重置
+    resetSearchForm () {
+      this.$refs.rangeDate.resetDate()
+      this.queryParam.beginDate = undefined
+      this.queryParam.endDate = undefined
+      this.queryParam.purchaseBillNo = ''
+      this.queryParam.financialStatus = undefined
+      this.$refs.table.refresh(true)
+    },
+    //  返回列表
+    handleBack () {
+      this.$router.push({ path: '/numsGoodsShelves/shelfMonitoring/list' })
+    },
+    //  时间  change
+    dateChange (date) {
+      this.queryParam.beginDate = date[0] || null
+      this.queryParam.endDate = date[1] || null
+    }
+  },
+  mounted () {
+    if (!this.$store.state.app.isNewTab) { // 页签刷新时调用
+      this.resetSearchForm()
+    }
+  },
+  activated () {
+    // 如果是新页签打开或者进入新的子页(例:存在列表第2条数据编辑页页签时再打开第4条数据的编辑页),则重置当前页面
+    if (this.$store.state.app.isNewTab || !this.$store.state.app.isNewSubTab) {
+      this.resetSearchForm()
+    }
+  }
+}
 </script>
 
-<style>
+<style lang="less">
+  .shelfMonitoringWarehousing-wrap{
+    .store-info{
+      margin: 0 15px;
+      color: rgb(102, 102, 102);
+    }
+    .shelfMonitoringWarehousing-cont{
+      margin-top: 10px;
+    }
+  }
 </style>

+ 145 - 0
src/views/numsGoodsShelves/shelfSet/basicInfoModal.vue

@@ -0,0 +1,145 @@
+<template>
+  <a-modal
+    centered
+    class="shelfSet-basicInfo-modal"
+    :footer="null"
+    :maskClosable="false"
+    title="数字货架基础设置"
+    v-model="isShow"
+    @cancle="isShow = false"
+    :width="600">
+    <a-spin :spinning="spinning" tip="Loading...">
+      <p style="text-align: center;margin: 0 0 20px;font-size: 14px;font-weight: bold;">西安车领主常青二路数字货架</p>
+      <a-form-model
+        id="shelfSet-basicInfo-form"
+        ref="ruleForm"
+        :model="form"
+        :rules="rules"
+        :label-col="formItemLayout.labelCol"
+        :wrapper-col="formItemLayout.wrapperCol">
+        <a-form-model-item label="关联客户" prop="customerSn">
+          <custList ref="custList" @change="custChange"></custList>
+        </a-form-model-item>
+        <a-form-model-item label="临配运费" prop="beginDay">
+          <a-row>
+            <a-col :span="20">
+              <a-input-number
+                id="shelfSet-basicInfo-beginDay"
+                v-model="form.beginDay"
+                :precision="2"
+                :min="0"
+                :max="999999"
+                placeholder="请输入正数(最多允许两位小数)"
+                suffix="元"
+                style="width: 100%;display: inline-block;" />
+            </a-col>
+            <a-col :span="4"><span style="margin-left: 10px;">元</span></a-col>
+          </a-row>
+        </a-form-model-item>
+      </a-form-model>
+      <div class="btn-cont">
+        <a-button type="primary" id="shelfSet-basicInfo-modal-save" @click="handleSave">下一步</a-button>
+        <a-button id="shelfSet-basicInfo-modal-back" @click="isShow = false" style="margin-left: 15px;">取消</a-button>
+      </div>
+    </a-spin>
+  </a-modal>
+</template>
+
+<script>
+import { commonMixin } from '@/utils/mixin'
+import { VSelect } from '@/components'
+import custList from '@/views/common/custList.vue'
+import { getTenantList, allocLinkageOutSave } from '@/api/allocLinkageOut'
+export default {
+  name: 'ShelfSetBasicInfoModal',
+  components: { VSelect, custList },
+  mixins: [commonMixin],
+  props: {
+    openModal: {
+      //  弹框显示状态
+      type: Boolean,
+      default: false
+    }
+  },
+  data () {
+    return {
+      spinning: false,
+      isShow: this.openModal, //  是否打开弹框
+      formItemLayout: {
+        labelCol: { span: 4 },
+        wrapperCol: { span: 18 }
+      },
+      form: {
+        customerSn: undefined, //  调往对象
+        beginDay: undefined
+      },
+      rules: {
+        customerSn: [{ required: true, message: '请选择关联客户', trigger: 'change' }],
+        beginDay: [{ required: true, message: '请输入临配运费', trigger: 'blur' }]
+      },
+      putTenantSnData: [] //  调往对象  下拉数据
+    }
+  },
+  methods: {
+    // 客户 change
+    custChange (obj) {
+      this.form.customerSn = obj.key || undefined
+    },
+    //  保存
+    handleSave () {
+      const _this = this
+      this.$refs.ruleForm.validate(valid => {
+        if (valid) {
+          _this.isShow = false
+          _this.$router.push({ path: `/numsGoodsShelves/shelfSet/set/1` })
+          // const form = JSON.parse(JSON.stringify(_this.form))
+          // _this.spinning = true
+          // allocLinkageOutSave(form).then(res => {
+          //   if (res.status == 200) {
+          //     _this.$message.success(res.message)
+          //     setTimeout(() => {
+          //       _this.isShow = false
+          //       _this.$emit('ok', res.data)
+          //       _this.spinning = false
+          //     }, 1000)
+          //   } else {
+          //     _this.spinning = false
+          //   }
+          // })
+        } else {
+          console.log('error submit!!')
+          return false
+        }
+      })
+    }
+  },
+  watch: {
+    //  父页面传过来的弹框状态
+    openModal (newValue, oldValue) {
+      this.isShow = newValue
+    },
+    //  重定义的弹框状态
+    isShow (newValue, oldValue) {
+      if (!newValue) {
+        this.$emit('close')
+        this.$refs.ruleForm.resetFields()
+      }
+    }
+  }
+}
+</script>
+
+<style lang="less">
+.shelfSet-basicInfo-modal {
+	.ant-modal-body {
+		padding: 40px 40px 24px;
+	}
+  .ant-form-item{
+    margin-bottom: 15px;
+  }
+	.btn-cont {
+		text-align: center;
+		margin: 35px 0 10px;
+	}
+}
+</style>

+ 189 - 0
src/views/numsGoodsShelves/shelfSet/bindProductModal.vue

@@ -0,0 +1,189 @@
+<template>
+  <a-modal
+    centered
+    class="shelfSet-bindProduct-modal"
+    :footer="null"
+    :maskClosable="false"
+    :title="modalTit"
+    v-model="isShow"
+    @cancle="isShow = false"
+    :width="600">
+    <a-spin :spinning="spinning" tip="Loading...">
+      <a-form-model
+        id="shelfSet-bindProduct-form"
+        ref="ruleForm"
+        :model="form"
+        :rules="rules"
+        :label-col="formItemLayout.labelCol"
+        :wrapper-col="formItemLayout.wrapperCol">
+        <a-form-model-item label="货架名称">货架名称</a-form-model-item>
+        <a-form-model-item label="货位号">货位号</a-form-model-item>
+        <a-form-model-item label="绑定产品" prop="customerSn">
+          <custList ref="custList" @change="custChange"></custList>
+        </a-form-model-item>
+        <a-form-model-item label="销售价" prop="beginDay">
+          <a-row>
+            <a-col :span="20">
+              <a-input-number
+                id="shelfSet-bindProduct-beginDay"
+                v-model="form.beginDay"
+                :precision="2"
+                :min="0"
+                :max="999999"
+                placeholder="请输入正数(最多允许两位小数)"
+                suffix="元"
+                style="width: 100%;display: inline-block;" />
+            </a-col>
+            <a-col :span="4"><span style="margin-left: 10px;">元</span></a-col>
+          </a-row>
+        </a-form-model-item>
+        <a-form-model-item label="结算价" prop="beginDay">
+          <a-row>
+            <a-col :span="20">
+              <a-input-number
+                id="shelfSet-bindProduct-beginDay"
+                v-model="form.beginDay"
+                :precision="2"
+                :min="0"
+                :max="999999"
+                placeholder="请输入正数(最多允许两位小数)"
+                suffix="元"
+                style="width: 100%;display: inline-block;" />
+            </a-col>
+            <a-col :span="4"><span style="margin-left: 10px;">元</span></a-col>
+          </a-row>
+        </a-form-model-item>
+        <a-form-model-item label="最大库容" prop="beginDay">
+          <a-input-number
+            id="shelfSet-bindProduct-beginDay"
+            v-model="form.beginDay"
+            :precision="0"
+            :min="0"
+            :max="999999"
+            placeholder="请输入最大库容(正整数)"
+            suffix="元"
+            style="width: 100%;display: inline-block;" />
+        </a-form-model-item>
+      </a-form-model>
+      <div class="btn-cont">
+        <a-button type="primary" id="shelfSet-bindProduct-modal-save" @click="handleSave">下一步</a-button>
+        <a-button id="shelfSet-bindProduct-modal-back" @click="isShow = false" style="margin-left: 15px;">取消</a-button>
+      </div>
+    </a-spin>
+  </a-modal>
+</template>
+
+<script>
+import { commonMixin } from '@/utils/mixin'
+import { VSelect } from '@/components'
+import custList from '@/views/common/custList.vue'
+import { getTenantList, allocLinkageOutSave } from '@/api/allocLinkageOut'
+export default {
+  name: 'ShelfSetBasicInfoModal',
+  components: { VSelect, custList },
+  mixins: [commonMixin],
+  props: {
+    openModal: { //  弹框显示状态
+      type: Boolean,
+      default: false
+    },
+    type: {
+      type: String,
+      default: ''
+    }
+  },
+  data () {
+    return {
+      spinning: false,
+      isShow: this.openModal, //  是否打开弹框
+      formItemLayout: {
+        labelCol: { span: 4 },
+        wrapperCol: { span: 18 }
+      },
+      form: {
+        customerSn: undefined, //  调往对象
+        beginDay: undefined
+      },
+      rules: {
+        customerSn: [{ required: true, message: '请选择关联客户', trigger: 'change' }],
+        beginDay: [{ required: true, message: '请输入临配运费', trigger: 'blur' }]
+      },
+      putTenantSnData: [] //  调往对象  下拉数据
+    }
+  },
+  computed: {
+    modalTit () {
+      let title = ''
+      if (this.type == 'edit') {
+        title = '修改信息'
+      } else if (this.type == 'bind') {
+        title = '绑定产品'
+      } else if (this.type == 'replace') {
+        title = '更换产品'
+      }
+      return title
+    }
+  },
+  methods: {
+    // 客户 change
+    custChange (obj) {
+      this.form.customerSn = obj.key || undefined
+    },
+    //  保存
+    handleSave () {
+      const _this = this
+      this.$refs.ruleForm.validate(valid => {
+        if (valid) {
+          _this.isShow = false
+          _this.$router.push({ path: `/numsGoodsShelves/shelfSet/set/1` })
+          // const form = JSON.parse(JSON.stringify(_this.form))
+          // _this.spinning = true
+          // allocLinkageOutSave(form).then(res => {
+          //   if (res.status == 200) {
+          //     _this.$message.success(res.message)
+          //     setTimeout(() => {
+          //       _this.isShow = false
+          //       _this.$emit('ok', res.data)
+          //       _this.spinning = false
+          //     }, 1000)
+          //   } else {
+          //     _this.spinning = false
+          //   }
+          // })
+        } else {
+          console.log('error submit!!')
+          return false
+        }
+      })
+    }
+  },
+  watch: {
+    //  父页面传过来的弹框状态
+    openModal (newValue, oldValue) {
+      this.isShow = newValue
+    },
+    //  重定义的弹框状态
+    isShow (newValue, oldValue) {
+      if (!newValue) {
+        this.$emit('close')
+        this.$refs.ruleForm.resetFields()
+      }
+    }
+  }
+}
+</script>
+
+<style lang="less">
+.shelfSet-bindProduct-modal {
+	.ant-modal-body {
+		padding: 40px 40px 24px;
+	}
+  .ant-form-item{
+    margin-bottom: 15px;
+  }
+	.btn-cont {
+		text-align: center;
+		margin: 35px 0 10px;
+	}
+}
+</style>

+ 170 - 0
src/views/numsGoodsShelves/shelfSet/chooseImportModal.vue

@@ -0,0 +1,170 @@
+<template>
+  <a-modal
+    centered
+    class="chooseImport-modal"
+    :footer="null"
+    :maskClosable="false"
+    title="确认导入"
+    v-model="isShow"
+    @cancle="isShow=false"
+    :width="900">
+    <div class="chooseImport-con">
+      <!-- 可导入数据 -->
+      <p class="">可导入数据{{ loadData.length }}条</p>
+      <a-table
+        class="sTable"
+        ref="table"
+        size="small"
+        :rowKey="(record) => record.supplierSn"
+        :columns="nowColumns"
+        :dataSource="loadData"
+        :loading="loading"
+        :scroll="{ y: 200 }"
+        :pagination="false"
+        bordered>
+      </a-table>
+      <a-divider />
+      <!-- 不可导入数据 -->
+      <p class="red">不可导入数据{{ unLoadData.length }}条</p>
+      <a-table
+        class="sTable unTable"
+        ref="unTable"
+        size="small"
+        :rowKey="(record) => record.errorDesc"
+        :columns="nowUnColumns"
+        :dataSource="unLoadData"
+        :loading="loading"
+        :scroll="{ y: 200 }"
+        :pagination="false"
+        bordered>
+      </a-table>
+      <!-- 按钮 -->
+      <div class="btn-con">
+        <a-button
+          type="primary"
+          id="chooseImport-submit"
+          size="large"
+          :class="loadData.length==0?'button-grey':'button-primary'"
+          @click="handleSubmit"
+          style="padding: 0 40px;">确认导入</a-button>
+        <a-button
+          id="chooseImport-cancel"
+          size="large"
+          class="button-cancel"
+          @click="isShow=false"
+          style="padding: 0 40px;margin-left: 15px;">取消</a-button>
+      </div>
+    </div>
+  </a-modal>
+</template>
+
+<script>
+import { supplierProductParseProducts } from '@/api/supplier'
+export default {
+  name: 'ChooseImportModal',
+  props: {
+    openModal: { //  弹框显示状态
+      type: Boolean,
+      default: false
+    },
+    paramsData: {
+      type: Object,
+      default: () => {
+        return {}
+      }
+    }
+  },
+  data () {
+    return {
+      isShow: this.openModal, //  是否打开弹框
+      nowColumns: [ //  可导入
+        { title: '序号', dataIndex: 'no', width: '6%', align: 'center' },
+        { title: '货位号', dataIndex: 'productCode', width: '19%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '绑定产品编码', dataIndex: 'productCode', width: '17%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '绑定产品名称', dataIndex: 'product.name', width: '26%', align: 'left', customRender: function (text) { return text || '--' }, ellipsis: true },
+        { title: '销售价', dataIndex: 'costText', width: '10%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+        { title: '结算价', dataIndex: 'costText', width: '10%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+        { title: '最大库容', dataIndex: 'costText', width: '10%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } }
+      ],
+      nowUnColumns: [ //  不可导入
+        { title: '序号', dataIndex: 'no', width: '6%', align: 'center' },
+        { title: '货位号', dataIndex: 'productCode', width: '18%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '绑定产品编码', dataIndex: 'productCode', width: '13%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '绑定产品名称', dataIndex: 'product.name', width: '20%', align: 'left', customRender: function (text) { return text || '--' }, ellipsis: true },
+        { title: '销售价', dataIndex: 'costText', width: '8%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+        { title: '结算价', dataIndex: 'costText', width: '8%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+        { title: '最大库容', dataIndex: 'costText', width: '8%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+        { title: '错误原因', dataIndex: 'errorDesc', width: '17%', align: 'left', customRender: function (text) { return text || '--' }, ellipsis: true }
+      ],
+      loadData: [],
+      unLoadData: [],
+      loading: false
+    }
+  },
+  methods: {
+    getData () {
+      const _this = this
+      this.loading = true
+      supplierProductParseProducts(this.paramsData).then(res => {
+        this.loading = false
+        if (res.status == 200) {
+          if (res.data.okList && res.data.okList.length > 0) {
+            res.data.okList.map((item, index) => {
+              item.no = index + 1
+            })
+          }
+          if (res.data.failList && res.data.failList.length > 0) {
+            res.data.failList.map((item, index) => {
+              item.no = index + 1
+            })
+          }
+          _this.loadData = res.data.okList || []
+          _this.unLoadData = res.data.failList || []
+        }
+      })
+    },
+    // 确认导入
+    handleSubmit () {
+      if (this.loadData.length == 0) {
+        this.$message.warning('无可导入产品!')
+      } else {
+        this.$emit('ok', this.loadData)
+        this.isShow = false
+      }
+    }
+  },
+  watch: {
+    //  父页面传过来的弹框状态
+    openModal (newValue, oldValue) {
+      this.isShow = newValue
+    },
+    //  重定义的弹框状态
+    isShow (newValue, oldValue) {
+      if (!newValue) {
+        this.$emit('close')
+        this.loadData = []
+        this.unLoadData = []
+      } else {
+        this.getData()
+      }
+    }
+  }
+}
+</script>
+
+<style lang="less" scoped>
+  .chooseImport-modal{
+    .chooseImport-con{
+      .red{
+        color: #f30;
+      }
+      .btn-con{
+        text-align: center;
+        margin: 30px 0 20px;
+        .button-cancel,.button-error{
+          font-size: 12px;
+        }
+      }
+    }
+  }
+</style>

+ 202 - 0
src/views/numsGoodsShelves/shelfSet/importGuideModal.vue

@@ -0,0 +1,202 @@
+<template>
+  <a-modal
+    centered
+    class="importGuide-modal"
+    :footer="null"
+    :maskClosable="false"
+    title="导入绑定产品"
+    v-model="isShow"
+    @cancle="isShow=false"
+    :width="750">
+    <div class="importGuide-con">
+      <div class="explain-con">
+        <div class="explain-item">
+          <div class="explain-tit">
+            <span>1</span>下载导入模板
+          </div>
+          <p>请按照下载的Excel模板填写数据</p>
+          <a-button type="link" icon="download" style="padding: 0 0 0 23px;" @click="handleExport">下载模板</a-button>
+        </div>
+        <div class="explain-item">
+          <div class="explain-tit">
+            <span>2</span>准备导入数据
+          </div>
+          <ul>
+            <li>1) 导入的Excel文件中必须包含名为“货位号”、“产品编码”、“销售价”、“结算价”、“最大库容”的列,且名称必须相同</li>
+            <li>2) 除了“货位号”、“产品编码”、“销售价”、“结算价”、“最大库容”四列,其他列可自定义,不影响数据导入</li>
+          </ul>
+        </div>
+        <div class="explain-item">
+          <div class="explain-tit">
+            <span>3</span>上传数据文件
+          </div>
+          <p>目前支持的文件类型*.xls,*.xlsx.</p>
+          <div style="overflow: hidden;padding-left: 23px;">
+            <Upload
+              id="importGuide-attachList"
+              ref="importUpload"
+              :maxNums="1"
+              fileType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel"
+              uploadType="import"
+              :action="attachAction"
+              :uploadParams="uploadParams"
+              upText="添加文件"
+              @change="changeImport"></Upload>
+          </div>
+        </div>
+      </div>
+      <!-- 按钮 -->
+      <div class="btn-con">
+        <a-button
+          type="primary"
+          id="importGuide-nextStep"
+          size="large"
+          class="button-primary"
+          @click="handlerNextStep"
+          style="padding: 0 60px;">下一步</a-button>
+        <a-button
+          id="importGuide-cancel"
+          size="large"
+          class="button-cancel"
+          @click="isShow=false"
+          style="padding: 0 60px;margin-left: 15px;">取消</a-button>
+      </div>
+    </div>
+    <!-- 导入 -->
+    <chooseImportModal :openModal="openImportModal" :paramsData="paramsData" @close="handleClose" @ok="hanldeOk" />
+  </a-modal>
+</template>
+
+<script>
+import { hdPrint } from '@/libs/JGPrint.js'
+import ChooseImportModal from './chooseImportModal.vue'
+import { Upload } from '@/components'
+import { supplierProductDownload } from '@/api/supplier'
+export default {
+  name: 'ImportGuideModal',
+  components: { ChooseImportModal, Upload },
+  props: {
+    openModal: { //  弹框显示状态
+      type: Boolean,
+      default: false
+    },
+    params: {
+      type: Object,
+      default: null
+    }
+  },
+  data () {
+    return {
+      isShow: this.openModal, //  是否打开弹框
+      openImportModal: false, //  导入
+      attachAction: process.env.VUE_APP_API_BASE_URL + '/upload',
+      paramsData: null,
+      uploadParams: {
+        savePathType: 'local'
+      }
+    }
+  },
+  methods: {
+    // 下一步
+    handlerNextStep () {
+      // if (this.paramsData) {
+      this.openImportModal = true
+      // } else {
+      //   this.$message.warning('添加文件后再进行下一步操作!')
+      // }
+    },
+    // 上传文件  change
+    changeImport (file) {
+      if (file) {
+        this.paramsData = {
+          supplierSn: this.params.supplierSn || '',
+          path: file
+        }
+      }
+    },
+    // 导入
+    hanldeOk (obj) {
+      if (obj && obj.length > 0) {
+        this.$emit('ok', obj)
+        this.isShow = false
+      }
+    },
+    // 关闭
+    handleClose () {
+      this.openImportModal = false
+      this.isShow = false
+    },
+    //  导出
+    handleExport () {
+      const _this = this
+      _this.spinning = true
+      // 导出
+      hdPrint('', 'export', supplierProductDownload, {}, '关联产品导入模板', function () {
+        _this.spinning = false
+      })
+    }
+  },
+  watch: {
+    //  父页面传过来的弹框状态
+    openModal (newValue, oldValue) {
+      this.isShow = newValue
+    },
+    //  重定义的弹框状态
+    isShow (newValue, oldValue) {
+      if (!newValue) {
+        this.$emit('close')
+        this.paramsData = null
+        this.$refs.importUpload.setFileList('')
+      }
+    }
+  }
+}
+</script>
+
+<style lang="less" scoped>
+  .importGuide-modal{
+    .importGuide-con{
+      .explain-con{
+        .explain-item{
+          margin-bottom: 10px;
+          .explain-tit{
+            font-weight: bold;
+            span{
+              display: inline-block;
+              width: 18px;
+              height: 18px;
+              line-height: 16px;
+              text-align: center;
+              margin-right: 5px;
+              border-radius: 50%;
+              border: 1px solid rgba(0, 0, 0, 0.3);
+            }
+          }
+          p{
+            margin: 8px 0;
+            padding-left: 23px;
+          }
+          ul{
+            list-style: none;
+            padding: 0;
+            padding-left: 23px;
+            margin: 0;
+            li{
+              line-height: 26px;
+            }
+          }
+        }
+        #importGuide-attachList{
+          width: 100%;
+        }
+      }
+      .btn-con{
+        margin: 10px 0 20px;
+        text-align: center;
+        .button-cancel{
+          font-size: 12px;
+        }
+      }
+    }
+  }
+</style>

+ 173 - 0
src/views/numsGoodsShelves/shelfSet/list.vue

@@ -0,0 +1,173 @@
+<template>
+  <a-card size="small" :bordered="false" class="shelfSetList-wrap">
+    <a-spin :spinning="spinning" tip="Loading...">
+      <!-- 搜索条件 -->
+      <div ref="tableSearch" class="table-page-search-wrapper">
+        <a-form layout="inline" @keyup.enter.native="$refs.table.refresh(true)">
+          <a-row :gutter="15">
+            <a-col :md="6" :sm="24">
+              <a-form-item label="货架名称">
+                <custList ref="custList" @change="custChange" :itemSn="queryParam.customerSn"></custList>
+              </a-form-item>
+            </a-col>
+            <a-col :md="6" :sm="24">
+              <a-form-item label="关联客户">
+                <custList ref="custList" @change="custChange" :itemSn="queryParam.customerSn"></custList>
+              </a-form-item>
+            </a-col>
+            <a-col :md="6" :sm="24">
+              <a-form-item label="是否设置完成">
+                <v-select
+                  v-model="queryParam.billStatus"
+                  ref="billStatus"
+                  id="shelfSetList-billStatus"
+                  code="SALES_BILL_STATUS"
+                  placeholder="请选择"
+                  allowClear></v-select>
+              </a-form-item>
+            </a-col>
+            <a-col :md="6" :sm="24" style="margin-bottom: 10px">
+              <a-button type="primary" @click="$refs.table.refresh(true)" :disabled="disabled" id="shelfSetList-refresh">查询</a-button>
+              <a-button style="margin-left: 5px" @click="resetSearchForm" :disabled="disabled" id="shelfSetList-reset">重置</a-button>
+            </a-col>
+          </a-row>
+        </a-form>
+      </div>
+      <!-- 提示 -->
+      <a-alert type="info" style="margin-bottom: 10px">
+        <div slot="message">注意:只有当数字货架的所有信息都设置完成,才能在其他功能中看到该数字货架</div>
+      </a-alert>
+      <!-- 列表 -->
+      <s-table
+        class="sTable fixPagination"
+        ref="table"
+        :style="{ height: tableHeight+84.5+'px' }"
+        size="small"
+        :rowKey="(record) => record.id"
+        :columns="columns"
+        :data="loadData"
+        :scroll="{ y: tableHeight }"
+        :defaultLoadData="false"
+        bordered>
+        <!-- 操作 -->
+        <template slot="action" slot-scope="text, record">
+          <a-button
+            size="small"
+            type="link"
+            class="button-primary"
+            @click="handleSet(record)">设置</a-button>
+        </template>
+      </s-table>
+    </a-spin>
+    <!-- 基础设置 -->
+    <basic-info-modal :openModal="openModal" @ok="handleOk" @close="openModal=false" />
+  </a-card>
+</template>
+
+<script>
+import { commonMixin } from '@/utils/mixin'
+import { STable, VSelect } from '@/components'
+import custList from '@/views/common/custList.vue'
+import basicInfoModal from './basicInfoModal.vue'
+import { giftsDetailList } from '@/api/dealerProduct'
+export default {
+  components: { STable, VSelect, custList, basicInfoModal },
+  mixins: [commonMixin],
+  data () {
+    return {
+      spinning: false,
+      tableHeight: 0,
+      disabled: false, //  查询、重置按钮是否可操作
+      queryParam: {
+        customerSn: undefined,
+        billStatus: undefined
+      },
+      columns: [
+        { title: '序号', dataIndex: 'no', width: '5%', align: 'center' },
+        { title: '货架名称', dataIndex: 'dealerProductEntity.name', width: '25%', align: 'left', customRender: function (text) { return text || '--' }, ellipsis: true },
+        { title: '关联客户', dataIndex: 'dealerProductEntity.origCode', width: '25%', align: 'left', customRender: function (text) { return text || '--' }, ellipsis: true },
+        { title: '临配运费', dataIndex: 'qsty', width: '10%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+        { title: '货位数量', dataIndex: 'qty', width: '10%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+        { title: '是否设置完成', dataIndex: 'salesBillNo', width: '15%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '操作', scopedSlots: { customRender: 'action' }, width: '10%', align: 'center' }
+      ],
+      // 加载数据方法 必须为 Promise 对象
+      loadData: parameter => {
+        this.disabled = true
+        this.spinning = true
+        return giftsDetailList(Object.assign(parameter, this.queryParam)).then(res => {
+          let data
+          if (res.status == 200) {
+            data = res.data
+            const no = (data.pageNo - 1) * data.pageSize
+            for (var i = 0; i < data.list.length; i++) {
+              data.list[i].no = no + i + 1
+            }
+            this.disabled = false
+          }
+          this.spinning = false
+          return data
+        })
+      },
+      openModal: false
+    }
+  },
+  methods: {
+    // 设置/修改
+    handleSet (row) {
+      this.openModal = true
+    },
+    handleOk () {},
+    // 客户 change
+    custChange (obj) {
+      this.queryParam.buyerSn = obj.key || undefined
+    },
+    // 重置
+    resetSearchForm () {
+      this.$refs.custList.resetForm()
+      this.queryParam.customerSn = undefined
+      this.queryParam.billStatus = undefined
+      this.$refs.table.refresh(true)
+    },
+    setTableH () {
+      const tableSearchH = this.$refs.tableSearch.offsetHeight
+      this.tableHeight = window.innerHeight - tableSearchH - 235
+    },
+    pageInit () {
+      const _this = this
+      this.$nextTick(() => { // 页面渲染完成后的回调
+        _this.setTableH()
+      })
+    }
+  },
+  mounted () {
+    if (!this.$store.state.app.isNewTab) { // 页签刷新时调用
+      this.pageInit()
+      this.resetSearchForm()
+    }
+  },
+  watch: {
+    '$store.state.app.winHeight' (newValue, oldValue) { //  窗口变更时,需同时更改表格高度
+      this.setTableH()
+    }
+  },
+  activated () {
+    // 如果是新页签打开,则重置当前页面
+    if (this.$store.state.app.isNewTab) {
+      this.pageInit()
+      this.resetSearchForm()
+    }
+    // 仅刷新列表,不重置页面
+    if (this.$store.state.app.updateList) {
+      this.pageInit()
+      this.$refs.table.refresh()
+    }
+  }
+}
+</script>
+
+<style lang="less">
+  .shelfSetList-wrap{
+
+  }
+</style>

+ 224 - 0
src/views/numsGoodsShelves/shelfSet/set.vue

@@ -0,0 +1,224 @@
+<template>
+  <div class="shelfSet-wrap">
+    <a-spin :spinning="spinning" tip="Loading...">
+      <a-page-header :ghost="false" :backIcon="false" @back="handleBack" >
+        <!-- 自定义的二级文字标题 -->
+        <template slot="subTitle">
+          <a id="shelfSet-back-btn" href="javascript:;" @click="handleBack"><a-icon type="left" /> 返回列表</a>
+          <span class="store-info">西安车领主常青二路数字货架——货位号A01</span>
+        </template>
+      </a-page-header>
+      <!-- 内容 -->
+      <a-card size="small" :bordered="false" class="shelfSet-cont">
+        <a-collapse :activeKey="['1']">
+          <a-collapse-panel key="1">
+            <template slot="header">
+              <span>基础信息</span>
+              <a-button icon="edit" size="small" type="link" style="margin-left: 20px;color: #39f;" @click.stop="handleInfoEdit">编辑</a-button>
+            </template>
+            <a-descriptions :column="3">
+              <a-descriptions-item label="关联客户">{{ (basicInfoData&&basicInfoData.outWarehouseName) || '--' }}</a-descriptions-item>
+              <a-descriptions-item label="临配运费">{{ (basicInfoData&&basicInfoData.putWarehouseName) || '--' }}</a-descriptions-item>
+            </a-descriptions>
+          </a-collapse-panel>
+        </a-collapse>
+      </a-card>
+      <a-card size="small" :bordered="false" class="shelfSet-cont">
+        <!-- 搜索条件 -->
+        <div ref="tableSearch" class="table-page-search-wrapper">
+          <a-form layout="inline" @keyup.enter.native="$refs.table.refresh(true)">
+            <a-row :gutter="15">
+              <a-col :md="6" :sm="24">
+                <a-form-item label="产品编码">
+                  <a-input id="shelfSet-productCode" v-model.trim="queryParam.productCode" allowClear placeholder="请输入产品编码"/>
+                </a-form-item>
+              </a-col>
+              <a-col :md="6" :sm="24">
+                <a-form-item label="产品名称">
+                  <a-input id="shelfSet-productName" v-model.trim="queryParam.productName" allowClear placeholder="请输入产品名称"/>
+                </a-form-item>
+              </a-col>
+              <a-col :md="6" :sm="24">
+                <span class="table-page-search-submitButtons">
+                  <a-button type="primary" @click="$refs.table.refresh(true)" :disabled="disabled" id="shelfSet-refresh">查询</a-button>
+                  <a-button style="margin-left: 5px" @click="resetSearchForm()" :disabled="disabled" id="shelfSet-reset">重置</a-button>
+                </span>
+              </a-col>
+            </a-row>
+          </a-form>
+        </div>
+        <!-- 操作按钮 -->
+        <div class="table-operator">
+          <a-button id="shelfSet-import" type="primary" class="button-error" @click="openGuideModal=true">导入绑定产品</a-button>
+          <a-tooltip placement="top">
+            <template slot="title">
+              <span>如果货位还没有绑定产品,可使用此功能通过Excel批量导入</span>
+            </template>
+            <a-icon type="question-circle" theme="filled" style="color: rgba(0,0,0,.45);font-size: 16px;margin-left: 5px;vertical-align: middle;cursor: pointer;" />
+          </a-tooltip>
+        </div>
+        <!-- 列表 -->
+        <s-table
+          class="sTable"
+          ref="table"
+          size="small"
+          :rowKey="(record) => record.id"
+          :columns="columns"
+          :data="loadData"
+          bordered>
+          <!-- 操作 -->
+          <template slot="action" slot-scope="text, record">
+            <a-button
+              size="small"
+              type="link"
+              class="button-primary"
+              @click="handleProduct(record, 'edit')"
+              id="shelfMonitoringList-edit-btn">修改信息</a-button>
+            <a-button
+              size="small"
+              type="link"
+              class="button-primary"
+              @click="handleReplace(record)"
+              id="shelfMonitoringList-replace-btn">更换产品</a-button>
+            <a-button
+              size="small"
+              type="link"
+              class="button-primary"
+              @click="handleProduct(record, 'bind')"
+              id="shelfMonitoringList-bind-btn">绑定产品</a-button>
+          </template>
+        </s-table>
+      </a-card>
+    </a-spin>
+    <!-- 修改信息/绑定产品 -->
+    <bind-product-modal :openModal="openModal" :type="modalType" :nowData="nowData" @ok="handleOk" @close="handleCancel" />
+    <!-- 更换产品 -->
+    <common-modal
+      :openModal="openTipsModal"
+      modalHtml="只有当前库存为0时,才能更换产品您可以在“货架监控”功能中将产品调回"
+      okText="好的"
+      :isCancel="false"
+      @ok="openTipsModal=false"
+      @close="openTipsModal=false" />
+    <!-- 导入产品 -->
+    <importGuideModal :openModal="openGuideModal" :params="{supplierSn: $route.params.sn}" @close="openGuideModal=false" @ok="handleGuideOk" />
+  </div>
+</template>
+
+<script>
+import { commonMixin } from '@/utils/mixin'
+import { STable, VSelect } from '@/components'
+import commonModal from '@/views/common/commonModal.vue'
+import bindProductModal from './bindProductModal.vue'
+import ImportGuideModal from './importGuideModal.vue'
+import { storeCallOutList } from '@/api/storeCallOut'
+export default {
+  name: 'ShelfMonitoringWarehousing',
+  components: { STable, VSelect, commonModal, bindProductModal, ImportGuideModal },
+  mixins: [commonMixin],
+  data () {
+    return {
+      spinning: false,
+      disabled: false, //  查询、重置按钮是否可操作
+      queryParam: {
+        productCode: '',
+        productName: ''
+      },
+      columns: [
+        { title: '序号', dataIndex: 'no', width: '4%', align: 'center' },
+        { title: '货位号', dataIndex: 'createDate', width: '15%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '绑定产品编码', dataIndex: 'allocationLinkagePutNo', width: '16%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '绑定产品名称', dataIndex: 'outTenantName', width: '23%', align: 'left', customRender: function (text) { return text || '--' }, ellipsis: true },
+        { title: '销售价', dataIndex: 'allocatione', width: '9%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+        { title: '结算价', dataIndex: 'alloeDictValue', width: '9%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+        { title: '最大库容', dataIndex: 'allocatialue', width: '9%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+        { title: '当前库存', dataIndex: 'allolue', width: '9%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+        { title: '操作', scopedSlots: { customRender: 'action' }, width: '15%', align: 'center' }
+      ],
+      // 加载数据方法 必须为 Promise 对象
+      loadData: parameter => {
+        this.disabled = true
+        this.spinning = true
+        return storeCallOutList(Object.assign(parameter, this.queryParam)).then(res => {
+          let data
+          if (res.status == 200) {
+            data = res.data
+            const no = (data.pageNo - 1) * data.pageSize
+            for (var i = 0; i < data.list.length; i++) {
+              data.list[i].no = no + i + 1
+            }
+            this.disabled = false
+          }
+          this.spinning = false
+          return data
+        })
+      },
+      basicInfoData: null,
+      openTipsModal: false,
+      openModal: false,
+      nowData: null,
+      openGuideModal: false,
+      modalType: null
+    }
+  },
+  methods: {
+    // 编辑基本信息
+    handleInfoEdit () {},
+    // 更换产品
+    handleReplace (row) {
+      this.openTipsModal = true
+      // this.handleProduct(row, 'replace')
+    },
+    // 更换产品/绑定产品/修改信息
+    handleProduct (row, type) {
+      this.modalType = type
+      this.openModal = true
+    },
+    handleOk () {
+      this.$refs.table.refresh()
+      this.handleCancel()
+    },
+    handleCancel () {
+      this.nowData = null
+      this.openModal = false
+    },
+    // 导入成功
+    handleGuideOk () {
+
+    },
+    //  重置
+    resetSearchForm () {
+      this.queryParam.productCode = ''
+      this.queryParam.productName = ''
+      this.$refs.table.refresh(true)
+    },
+    //  返回列表
+    handleBack () {
+      this.$router.push({ path: '/numsGoodsShelves/shelfSet/list' })
+    }
+  },
+  mounted () {
+    if (!this.$store.state.app.isNewTab) { // 页签刷新时调用
+      this.resetSearchForm()
+    }
+  },
+  activated () {
+    // 如果是新页签打开或者进入新的子页(例:存在列表第2条数据编辑页页签时再打开第4条数据的编辑页),则重置当前页面
+    if (this.$store.state.app.isNewTab || !this.$store.state.app.isNewSubTab) {
+      this.resetSearchForm()
+    }
+  }
+}
+</script>
+
+<style lang="less">
+  .shelfSet-wrap{
+    .store-info{
+      margin: 0 15px;
+      color: rgb(102, 102, 102);
+    }
+    .shelfSet-cont{
+      margin-top: 10px;
+    }
+  }
+</style>

+ 1 - 1
src/views/salesManagement/giftRecord/list.vue

@@ -72,7 +72,7 @@ export default {
   data () {
     return {
       tableHeight: 0,
-      advanced: true, // 高级搜索 展开/关闭setTimeout
+      advanced: true, // 高级搜索 展开/关闭
       time: [
         getDate.getCurrMonthDays().starttime,
         getDate.getCurrMonthDays().endtime