Browse Source

促销页面

lilei 1 năm trước cách đây
mục cha
commit
a141e839f7

+ 12 - 0
src/config/router.config.js

@@ -278,6 +278,18 @@ export const asyncRouterMap = [
                   hidden: true,
                   permission: 'B_salesEdit'
                 }
+              },
+              {
+                path: 'waitDispatch/:salesBillSn',
+                name: 'waitDispatchNew',
+                component: () => import(/* webpackChunkName: "salesManagement" */ '@/views/salesManagement/waitDispatchNew/edit.vue'),
+                meta: {
+                  title: '下推销售单(新版)',
+                  icon: 'monitor',
+                  replaceTab: true,
+                  hidden: true,
+                  permission: 'B_salesDispatch'
+                }
               }
             ]
           },

+ 1 - 1
src/utils/util.js

@@ -228,7 +228,7 @@ export function getAuthPriceCode (config, router, store) {
     
     // 从所有的权限菜单中查找当前权限code对应的权限菜单数据
     const authNode = treeFind(authTree,(item)=>item.code == authCode)
-    console.log(authNode)
+    // console.log(authNode)
     if(!authNode.permission){return []}
     // 从找到的对应权限菜单数据中判断当前调用接口的url是否存在,这里和权限菜单中的后台权限code比较
     const hasReqUrl = authNode.permission.split(',').find(item => url.replace(/\//g,'_').indexOf(item)>=0)

+ 9 - 5
src/views/salesManagement/salesQueryNew/comps/activeQueryPart.vue

@@ -43,10 +43,6 @@
               {{ advanced ? '收起' : '展开' }}
               <a-icon :type="advanced ? 'up' : 'down'"/>
             </a>
-            <a-popover>
-              <template slot="content">双击列表配件可快速选中添加</template>
-              <a-icon type="question-circle" theme="twoTone" />
-            </a-popover>
           </a-col>
         </a-row>
       </a-form>
@@ -66,8 +62,9 @@
       :columns="columns"
       :data="loadData"
       :customRow="handleClickRow"
-      :scroll="{ y: 500 }"
+      :scroll="{ y: tableHeight }"
       :defaultLoadData="false"
+      pageSize="50"
       bordered>
       <!-- 销售数量 -->
       <template slot="nums" slot-scope="text, record">
@@ -140,6 +137,7 @@ export default {
         warehouseSn: undefined
       },
       defaultWarehouseSn: undefined, // 默认仓库sn
+      tableHeight: 300,
       disabled: false, //  查询、重置按钮是否可操作
       // 加载数据方法 必须为 Promise 对象
       loadData: parameter => {
@@ -190,6 +188,11 @@ export default {
       return arr
     }
   },
+  watch:{
+    advanced(a,b){
+      this.tableHeight = window.innerHeight - (a ? 395 : 350)
+    }
+  },
   methods: {
     loadWarehouse (sn) {
       this.defaultWarehouseSn = sn
@@ -239,6 +242,7 @@ export default {
     },
     pageInit (buyerSn, warehouseSn) {
       this.buyerSn = buyerSn
+      this.tableHeight = window.innerHeight - 350
     },
     // 刷新当前页面
     resetCurForm () {

+ 31 - 18
src/views/salesManagement/salesQueryNew/comps/chooseProduct.vue

@@ -1,23 +1,25 @@
 <template>
-  <a-modal
-    centered
-    class="chooseProducts-modal"
-    :footer="null"
-    :maskClosable="false"
+  <a-drawer
+    :zIndex="zIndex"
     title="选择产品"
-    v-model="isShow"
-    @cancel="isShow=false"
-    width="70%">
-    <a-spin :spinning="spinning" tip="Loading...">
-      <div class="products-con">
-        <div>
-          <!-- 查询配件列表 -->
-          <queryPart v-if="type==0" ref="partQuery" :newLoading="isInster" @add="insterProduct"></queryPart>
-          <activeQueryPart v-else ref="partQuery" :newLoading="isInster" @add="insterProduct"></activeQueryPart>
+    placement="right"
+    :visible="isShow"
+    width="70%"
+    :get-container="false"
+    :wrap-style="{ position: 'absolute' }"
+    :headerStyle="{ padding: '10px' }"
+    @close="onClose"
+    wrapClassName="chooseProducts-modal">
+      <a-spin :spinning="spinning" tip="Loading...">
+        <div class="products-con">
+          <div>
+            <!-- 查询配件列表 -->
+            <queryPart v-if="cptype==0" ref="partQuery" :newLoading="isInster" @add="insterProduct"></queryPart>
+            <activeQueryPart v-else ref="partQuery" :newLoading="isInster" @add="insterProduct"></activeQueryPart>
+          </div>
         </div>
-      </div>
-    </a-spin>
-  </a-modal>
+      </a-spin>
+  </a-drawer>
 </template>
 
 <script>
@@ -46,23 +48,34 @@ export default {
       default: false
     },
     type: {
-      type: String,
+      type: [String,Number],
       default: '0'
+    },
+    zIndex:{
+      type: [String,Number],
+      default: 1000
     }
   },
   data () {
     return {
       spinning: false,
+      cptype: 0,
       isShow: this.openModal, //  是否打开弹框
     }
   },
   methods: {
+    onClose () {
+      this.$emit('close')
+    },
     // 添加产品
     insterProduct (row, promotionFlag) {
       this.$emit('addProduct', row, promotionFlag)
     }
   },
   watch: {
+    type(newValue, oldValue){
+      this.cptype = newValue
+    },
     //  父页面传过来的弹框状态
     openModal (newValue, oldValue) {
       this.isShow = newValue

+ 13 - 23
src/views/salesManagement/salesQueryNew/comps/productList.vue

@@ -114,7 +114,7 @@
           <a-button
             type="link"
             class="button-info"
-            @click="openCpModal=true"><a-icon type="plus" /> 添加活动产品</a-button>
+            @click="openCpModal"><a-icon type="plus" /> 添加活动产品</a-button>
         </a-col>
       </a-row>
     </div>
@@ -129,7 +129,7 @@
       :data="loadData"
       :row-selection="{ columnWidth: 40 }"
       @rowSelection="rowSelectionFun"
-      :scroll="{ y: 300 }"
+      :pageSize="10"
       bordered>
       <!-- 产品编码 -->
       <template slot="productCode" slot-scope="text, record">
@@ -201,18 +201,10 @@
           :loading="delLoading"
           class="button-primary"
           @click="handleDel(record)"
-        >更换活动</a-button>
+        >换促销</a-button>
       </template>
     </s-table>
-  
-      <!-- 添加产品 -->
-      <chooseProduct
-        ref="chooseProduct"
-        :openModal="openCpModal"
-        :type="1"
-        :buyerSn="detailData&&detailData.buyerSn||''"
-        @close="openCpModal=false"
-        @addProduct="insterProduct"></chooseProduct>
+   
       <!-- 导入产品 -->
       <importGuideModal :openModal="openGuideModal" :params="{salesBillSn: $route.params.sn}" @close="closeGuideModel" @ok="hanldeOk" />
       <!-- 仓库设置 -->
@@ -225,7 +217,6 @@
   import { STable, VSelect } from '@/components'
   import ImportGuideModal from './importGuideModal.vue'
   import setWarehouse from './setWarehouse.vue'
-  import chooseProduct from './chooseProduct.vue'
   import chooseWarehouse from '@/views/common/chooseWarehouse'
   import ProductBrand from '@/views/common/productBrand.js'
   import productTypeAll from '@/views/common/productTypeAll.js'
@@ -241,8 +232,7 @@
       chooseWarehouse,
       setWarehouse,
       ProductBrand,
-      productTypeAll,
-      chooseProduct
+      productTypeAll
     },
     props: {
       openModal: { //  弹框显示状态
@@ -254,6 +244,10 @@
         type: Object,
         default: function(){return null}
       },
+      id: {
+        type: String,
+        default: ''
+      },
       warehouseSn: {
         type: String,
         default: ''
@@ -287,7 +281,6 @@
         },
         showSearchBox: false,
         showDescBox: false,
-        openCpModal: false,
         openWarehouseModal: false, // 打开仓库设置
         openGuideModal: false, //  导入产品引导
         delLoading: false,
@@ -351,6 +344,9 @@
       showDesc(){
         this.showDescBox = !this.showDescBox
       },
+      openCpModal(){
+        this.$emit('openCpModal', 1, 'productList-'+this.id)
+      },
       // 表格选中项
       rowSelectionFun (obj) {
         this.rowSelectionInfo = obj || null
@@ -370,7 +366,6 @@
             deleteAll({ salesBillSn: _this.salesBillSn }).then(res => {
               if (res.status == 200) {
                 _this.resetSearchForm(true)
-                _this.$refs.promotable.resetCurForm()
                 _this.$message.success(res.message)
               }
               _this.spinning = false
@@ -401,7 +396,6 @@
             }).then(res => {
               if (res.status == 200) {
                 _this.resetSearchForm(true)
-                _this.$refs.promotable.resetCurForm()
                 _this.$message.success(res.message)
               }
               _this.spinning = false
@@ -439,7 +433,6 @@
           if (res.status == 200) {
             _this.openWarehouseModal = false
             _this.resetSearchForm(true)
-            _this.$refs.promotable.resetCurForm()
             _this.$message.success(res.message)
           }
           _this.$refs.table.refresh(true)
@@ -478,7 +471,6 @@
             salesBillSn: _this.salesBillSn
           }).then(res => {
             _this.resetSearchForm(true)
-            _this.$refs.promotable.resetCurForm()
             if (res.status == 200) {
               _this.$message.success(res.message)
             }
@@ -514,7 +506,6 @@
             salesDetailDelAll({ salesBillSn: _this.salesBillSn }).then(res => {
               if (res.status == 200) {
                 _this.resetSearchForm()
-                _this.$refs.promotable.resetCurForm()
                 _this.$message.success(res.message)
               }
               _this.delLoading = false
@@ -537,7 +528,6 @@
             salesDetailDel({ salesBillDetailSn: row.salesBillDetailSn, salesBillSn: _this.salesBillSn }).then(res => {
               if (res.status == 200) {
                 _this.resetSearchForm(true)
-                _this.$refs.promotable.resetCurForm()
                 _this.$message.success(res.message)
               }
               _this.delLoading = false
@@ -548,7 +538,7 @@
       },
       // 添加产品
       insterProduct (row, promotionFlag) {
-        console.log(row)
+        console.log(row, promotionFlag)
         // 防止多次添加产品
         if (this.isInster) { return }
         const _this = this

+ 14 - 22
src/views/salesManagement/salesQueryNew/comps/productNormalList.vue

@@ -80,7 +80,7 @@
           <a-button
             type="link"
             class="button-info"
-            @click="openCpModal=true"><a-icon type="plus" /> 添加产品</a-button>
+            @click="openCpModal"><a-icon type="plus" /> 添加产品</a-button>
         </a-col>
       </a-row>
     </div>
@@ -95,7 +95,7 @@
       :data="loadData"
       :row-selection="{ columnWidth: 40 }"
       @rowSelection="rowSelectionFun"
-      :scroll="{ y: 300 }"
+      :pageSize="10"
       bordered>
       <!-- 产品编码 -->
       <template slot="productCode" slot-scope="text, record">
@@ -162,15 +162,7 @@
         >删除</a-button>
       </template>
     </s-table>
-  
-      <!-- 添加产品 -->
-      <chooseProduct
-        ref="chooseProduct"
-        :openModal="openCpModal"
-        :isInster="isInster"
-        :buyerSn="detailData&&detailData.buyerSn||''"
-        @close="openCpModal=false"
-        @addProduct="insterProduct"></chooseProduct>
+
       <!-- 导入产品 -->
       <importGuideModal :openModal="openGuideModal" :params="{salesBillSn: salesBillSn}" @close="closeGuideModel" @ok="hanldeOk" />
       <!-- 仓库设置 -->
@@ -183,11 +175,10 @@
   import { STable, VSelect } from '@/components'
   import ImportGuideModal from './importGuideModal.vue'
   import setWarehouse from './setWarehouse.vue'
-  import chooseProduct from './chooseProduct.vue'
   import chooseWarehouse from '@/views/common/chooseWarehouse'
   import ProductBrand from '@/views/common/productBrand.js'
   import productTypeAll from '@/views/common/productTypeAll.js'
-  import { salesModify, salesDetailBySn, salesWriteSubmit, getPromoacActiveList, deleteAll, submitCheck, updateWarehouse } from '@/api/sales'
+  import { getPromoacActiveList, deleteAll, updateWarehouse } from '@/api/sales'
   import { salesDetailStockList, salesDetailInsert, salesDetailUpdateQty, salesDetailDel, salesDetailBatchDel, salesDetailDelAll, addPromoGoods, salesBatchInsert } from '@/api/salesDetail'
   export default {
     name: 'ProductList',
@@ -199,8 +190,7 @@
       chooseWarehouse,
       setWarehouse,
       ProductBrand,
-      productTypeAll,
-      chooseProduct
+      productTypeAll
     },
     props: {
       openModal: { //  弹框显示状态
@@ -244,7 +234,6 @@
           })
         },
         showSearch: false,
-        openCpModal: false,
         openWarehouseModal: false, // 打开仓库设置
         openGuideModal: false, //  导入产品引导
         delLoading: false,
@@ -302,6 +291,9 @@
       rowSelectionFun (obj) {
         this.rowSelectionInfo = obj || null
       },
+      openCpModal(){
+        this.$emit('openCpModal', 0, 'productNormalList')
+      },
       handleBatchDelAll () {
         const _this = this
         if (_this.dataSource.length == 0) {
@@ -317,7 +309,7 @@
             deleteAll({ salesBillSn: _this.salesBillSn }).then(res => {
               if (res.status == 200) {
                 _this.resetSearchForm(true)
-                _this.$refs.promotable.resetCurForm()
+                // _this.$refs.promotable.resetCurForm()
                 _this.$message.success(res.message)
               }
               _this.spinning = false
@@ -348,7 +340,7 @@
             }).then(res => {
               if (res.status == 200) {
                 _this.resetSearchForm(true)
-                _this.$refs.promotable.resetCurForm()
+                // _this.$refs.promotable.resetCurForm()
                 _this.$message.success(res.message)
               }
               _this.spinning = false
@@ -386,7 +378,7 @@
           if (res.status == 200) {
             _this.openWarehouseModal = false
             _this.resetSearchForm(true)
-            _this.$refs.promotable.resetCurForm()
+            // _this.$refs.promotable.resetCurForm()
             _this.$message.success(res.message)
           }
           _this.$refs.table.refresh(true)
@@ -425,7 +417,7 @@
             salesBillSn: _this.salesBillSn
           }).then(res => {
             _this.resetSearchForm(true)
-            _this.$refs.promotable.resetCurForm()
+            // _this.$refs.promotable.resetCurForm()
             if (res.status == 200) {
               _this.$message.success(res.message)
             }
@@ -461,7 +453,7 @@
             salesDetailDelAll({ salesBillSn: _this.salesBillSn }).then(res => {
               if (res.status == 200) {
                 _this.resetSearchForm()
-                _this.$refs.promotable.resetCurForm()
+                // _this.$refs.promotable.resetCurForm()
                 _this.$message.success(res.message)
               }
               _this.delLoading = false
@@ -484,7 +476,7 @@
             salesDetailDel({ salesBillDetailSn: row.salesBillDetailSn, salesBillSn: _this.salesBillSn }).then(res => {
               if (res.status == 200) {
                 _this.resetSearchForm(true)
-                _this.$refs.promotable.resetCurForm()
+                // _this.$refs.promotable.resetCurForm()
                 _this.$message.success(res.message)
               }
               _this.delLoading = false

+ 10 - 5
src/views/salesManagement/salesQueryNew/comps/queryPart.vue

@@ -43,10 +43,6 @@
               {{ advanced ? '收起' : '展开' }}
               <a-icon :type="advanced ? 'up' : 'down'"/>
             </a>
-            <a-popover>
-              <template slot="content">双击列表配件可快速选中添加</template>
-              <a-icon type="question-circle" theme="twoTone" />
-            </a-popover>
           </a-col>
         </a-row>
       </a-form>
@@ -60,7 +56,8 @@
       :columns="columns"
       :data="loadData"
       :customRow="handleClickRow"
-      :scroll="{ y: 500 }"
+      :scroll="{ y: tableHeight }"
+      :pageSize="50"
       :defaultLoadData="false"
       bordered>
       <!-- 销售数量 -->
@@ -135,6 +132,7 @@ export default {
       },
       defaultWarehouseSn: undefined, // 默认仓库sn
       disabled: false, //  查询、重置按钮是否可操作
+      tableHeight: 300,
       // 加载数据方法 必须为 Promise 对象
       loadData: parameter => {
         this.disabled = true
@@ -182,6 +180,12 @@ export default {
       return arr
     }
   },
+  watch:{
+    advanced(a,b){
+      console.log(a,b)
+      this.tableHeight = window.innerHeight - (a ? 355 : 310)
+    }
+  },
   methods: {
     loadWarehouse (sn) {
       this.defaultWarehouseSn = sn
@@ -227,6 +231,7 @@ export default {
     },
     pageInit (buyerSn, warehouseSn) {
       this.buyerSn = buyerSn
+      this.tableHeight = window.innerHeight - 310
     },
     // 刷新当前页面
     resetCurForm () {

+ 2 - 2
src/views/salesManagement/salesQueryNew/detail.vue

@@ -354,12 +354,12 @@ export default {
   methods: {
     //  返回
     handleBack () {
-      this.$router.push({ name: 'salesQueryList' })
+      this.$router.push({ name: 'salesQueryNewList' })
     },
     // 编辑
     handleEdit () {
       const row = this.detailData
-      this.$router.push({ name: 'salesEdit', params: { sn: row.salesBillSn, wSn: row.warehouseSn } })
+      this.$router.push({ name: 'salesNewEdit', params: { sn: row.salesBillSn, wSn: row.warehouseSn } })
     },
     //  重置
     resetSearchForm () {

+ 32 - 4
src/views/salesManagement/salesQueryNew/edit.vue

@@ -29,7 +29,7 @@
       <!-- 正常产品 -->
       <a-card size="small" :bordered="false" class="salesEdit-cont" v-if="salesBillSn">
         <div style="padding: 10px;">
-          <productNormalList ref="productNormalList" :detailData="detailData" :warehouseSn="warehouseSn" :salesBillSn="salesBillSn"></productNormalList>
+          <productNormalList ref="productNormalList" @openCpModal="openProductModal" :detailData="detailData" :warehouseSn="warehouseSn" :salesBillSn="salesBillSn"></productNormalList>
         </div>
       </a-card>
       <!-- 活动产品 -->
@@ -42,7 +42,7 @@
       >
         <div slot="title" style="display: inline-block;width:80%;">
             <div>
-              <strong style="margin-right:10px;font-size:16px;">{{item.activeName}}</strong> ({{item.activeDesc}})
+              <strong style="margin-right:10px;font-size:14px;">{{item.activeName}}</strong> ({{item.activeDesc}})
               <span style="margin-left:10px;color:#00aaff;cursor: pointer;"  @click="(event) => {showDesc(event, item.activeId)}">
                 <a-icon title="查看活动详情" type="eye"/> 详情
               </span>
@@ -50,7 +50,7 @@
           </div>
         <div slot="extra" @click="tooglePanel(item)" style="cursor: pointer;">{{ item.isActive ? '收起' : '展开' }} <a-icon type="caret-right" :rotate="item.isActive ? 90 : 0"/> </div>
         <div v-show="item.isActive" style="padding: 10px;">
-          <productList :ref="'productList-'+item.activeId" :detailData="detailData" :warehouseSn="warehouseSn" :salesBillSn="salesBillSn"></productList>
+          <productList :ref="'productList-'+item.activeId" :id="item.activeId" @openCpModal="openProductModal" :detailData="detailData" :warehouseSn="warehouseSn" :salesBillSn="salesBillSn"></productList>
         </div>
       </a-card>
     </a-spin>
@@ -104,6 +104,14 @@
           id="productInfoList-handleSubmit">提交</a-button>
       </div>
     </div>
+    <!-- 添加产品 -->
+    <chooseProduct
+        ref="chooseProduct"
+        :openModal="showCpModal"
+        :type="cpModalType"
+        :buyerSn="detailData&&detailData.buyerSn||''"
+        @close="closeProductModal"
+        @addProduct="insterProduct"></chooseProduct>
     <!-- 价格更新弹窗 -->
     <setPriceModal :show="priceUpdateModal" :totalRealAmount="updataData.totalRealAmount" :totalAmount="updataData.totalAmount" @ok="updatePrice" @cancel="priceUpdateModal=false"></setPriceModal>
  </div>
@@ -113,6 +121,7 @@
 import { commonMixin } from '@/utils/mixin'
 import productList from './comps/productList.vue'
 import productNormalList from './comps/productNormalList.vue'
+import chooseProduct from './comps/chooseProduct.vue'
 import setPriceModal from './setPriceModal.vue'
 import { salesDetailBySn, salesWriteSubmit, submitCheck, updateBatch } from '@/api/sales'
 export default {
@@ -121,6 +130,7 @@ export default {
   components:{
     setPriceModal,
     productList,
+    chooseProduct,
     productNormalList
   },
   data () {
@@ -136,7 +146,10 @@ export default {
         totalAmount: ''
       },
       priceUpdateModal: false, // 价格更新弹窗
-      showDetail: false
+      showDetail: false,
+      showCpModal: false,
+      cpModalType: '0',
+      cpCurRefId: ''
     }
   },
   computed: {
@@ -171,6 +184,21 @@ export default {
         this.getActive()
       })
     },
+    closeProductModal(){
+        this.cpModalType = 0
+        this.cpCurRefId = ''
+        this.showCpModal = false
+    },
+    openProductModal(type, refId){
+        console.log(type, refId)
+        this.cpModalType = type
+        this.cpCurRefId = refId
+        this.showCpModal = true
+    },
+    // 新增产品
+    insterProduct(row, promotionFlag){
+      this.$refs[this.cpCurRefId][0].insterProduct(row, promotionFlag)
+    },
     // 选择价格类型  并更新
     updatePrice (type) {
       const _this = this

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

@@ -451,7 +451,7 @@ export default {
       findBySalesBillSn({ salesBillSn: row.salesBillSn }).then(res => {
         this.spinning = false
         if (res.status == 200) {
-          this.$router.push({ name: 'waitDispatch', params: { salesBillSn: row.salesBillSn } })
+          this.$router.push({ name: 'waitDispatchNew', params: { salesBillSn: row.salesBillSn } })
         }
       })
     },

+ 263 - 0
src/views/salesManagement/waitDispatchNew/dsModal.vue

@@ -0,0 +1,263 @@
+<template>
+  <a-modal
+    centered
+    class="dealerAccountEdit-modal"
+    :footer="null"
+    :maskClosable="false"
+    :title="title"
+    v-model="isShow"
+    @cancel="isShow=false"
+    :width="800">
+    <!-- 表单 -->
+    <div>
+      <a-spin :spinning="spinning" tip="Loading...">
+        <a-form-model
+          id="dealerAccountEdit-form"
+          ref="ruleForm"
+          :model="form"
+          :rules="rules"
+          :label-col="formItemLayout.labelCol"
+          :wrapper-col="formItemLayout.wrapperCol"
+        >
+          <a-form-model-item label="客户名称">
+            <span>{{ detailData ? detailData.buyerName : '--' }}</span>
+          </a-form-model-item>
+          <div v-if="!receiverDisabled">
+            <a-form-model-item label="收货客户名称" extra="如果收货客户和下单客户相同,则不需要选择收货客户名称">
+              <dealerSubareaScopeList ref="dealerSubareaScopeList" defValKey="buyerSn" @change="custChange" v-model="form.receiverSn" />
+            </a-form-model-item>
+            <a-form-model-item label="收货地址" prop="dealerRecevieAddressSn" v-if="form.receiverSn">
+              <div style="display:flex;padding-top:6px;">
+                <div style="width:80%;flex-grow:1;line-height: 24px;">{{ chooseAddr }}</div>
+                <a-button size="small" type="link" @click="openAddrModal = true">{{ addressVal }} >></a-button>
+              </div>
+            </a-form-model-item>
+          </div>
+          <div v-else>
+            <a-form-model-item label="收货客户名称" v-if="detailData&&detailData.receiverName">
+              {{ detailData.receiverName }}
+            </a-form-model-item>
+            <a-form-model-item label="收货客户名称" v-else>
+              --
+            </a-form-model-item>
+            <a-form-model-item label="收货地址">
+              {{ chooseAddr }}
+            </a-form-model-item>
+          </div>
+          <a-form-model-item label="发货编号" prop="sendNo">
+            <a-input
+              id="dealerAccountEdit-phone"
+              :maxLength="10"
+              v-model.trim="form.sendNo"
+              placeholder="请输入发货编号"
+              allowClear />
+            <div style="height: 24px;line-height: normal;">
+              常用:<a-button size="small" v-for="i in 5" @click="setSendNo(i)" type="link">{{ i }}</a-button>
+            </div>
+          </a-form-model-item>
+          <a-form-model-item label="发货说明">
+            <a-input
+              id="dealerAccountEdit-explainInfo"
+              type="textarea"
+              :maxLength="100"
+              v-model.trim="form.explainInfo"
+              placeholder="请输入发货说明(最多100字符)"
+              allowClear />
+          </a-form-model-item>
+          <a-form-model-item label="备货打印" prop="printStatus">
+            <a-radio-group v-model="form.printStatus">
+              <a-radio value="NO_PRINT">
+                允许打印
+              </a-radio>
+              <a-radio value="UNABLE_PRINT">
+                暂不打印
+              </a-radio>
+              <a-radio value="CANCEL_PRINT">
+                取消打印
+              </a-radio>
+            </a-radio-group>
+          </a-form-model-item>
+        </a-form-model>
+        <div class="btn-cont">
+          <a-button id="dealerAccountEdit-back" @click="isShow = false">取消下推</a-button>
+          <a-button type="primary" id="dealerAccountEdit-save" @click="handleSave" style="margin-left: 15px;">确定下推</a-button>
+        </div>
+      </a-spin>
+      <!-- 选择地址 -->
+      <choose-address-modal :openModal="openAddrModal" :paramsData="form.receiverSn" @ok="handleOk" @verify="verifyFun" @close="openAddrModal=false" />
+    </div>
+  </a-modal>
+</template>
+
+<script>
+import { commonMixin } from '@/utils/mixin'
+import chooseAddressModal from '../salesQuery/receivingAddress/chooseAddressModal.vue'
+import dealerSubareaScopeList from '@/views/common/dealerSubareaScopeList.vue'
+import { dealerRecevieAddrQuery } from '@/api/dealerRecevieAddr'
+export default {
+  name: 'DsModal',
+  mixins: [commonMixin],
+  components: { dealerSubareaScopeList, chooseAddressModal },
+  props: {
+    openModal: { //  弹框显示状态
+      type: Boolean,
+      default: false
+    },
+    title: {
+      type: String,
+      default: '下推销售单'
+    }
+  },
+  data () {
+    return {
+      isShow: this.openModal, //  是否打开弹框
+      spinning: false,
+      formItemLayout: {
+        labelCol: { span: 4 },
+        wrapperCol: { span: 18 }
+      },
+      form: {
+        sendNo: '',
+        printStatus: undefined,
+        buyerName: '',
+        receiverSn: '',
+        receiverName: '',
+        dealerRecevieAddressSn: '', // 地址sn
+        explainInfo: ''
+      },
+      rules: {
+        sendNo: [{ required: true, message: '请输入发货编号', trigger: 'change' }],
+        printStatus: [{ required: true, message: '请选择备货打印', trigger: 'change' }],
+        dealerRecevieAddressSn: [ { required: true, message: '请选择收货地址', trigger: 'change' } ]
+      },
+      detailData: null, //  详情数据
+      addressVal: '选择地址', //  选择地址/更换地址
+      chooseAddr: '', //  当前已选地址信息
+      openAddrModal: false, // 选择地址弹框是否显示
+      addressId: undefined,
+      receiverDisabled: false
+    }
+  },
+  methods: {
+    setSendNo (i) {
+      this.form.sendNo = i
+      this.$refs.ruleForm.validateField('sendNo')
+    },
+    // 客户 change
+    custChange (val) {
+      if (val && val.key) {
+        this.form.receiverSn = val.key || undefined
+        this.form.receiverName = val.name || ''
+        this.$refs.ruleForm.clearValidate()
+        this.getDefaultAddress()
+      } else {
+        this.form.receiverSn = undefined
+        this.form.receiverName = ''
+        this.verifyFun(this.addressId)
+      }
+    },
+    // 获取默认地址
+    getDefaultAddress () {
+      dealerRecevieAddrQuery({ defaultFlag: 1, dealerSn: this.form.receiverSn }).then(res => {
+        if (res.status == 200) {
+          if (res.data.length == 1) {
+            const ret = res.data[0]
+            ret.address = (ret.provinceName ? (ret.provinceName + '-') : '') + (ret.cityName ? (ret.cityName + '-') : '') + (ret.countyName ? (ret.countyName + '-') : '') + ret.addr
+            this.handleOk(ret)
+          } else {
+            this.verifyFun(this.addressId)
+          }
+        }
+      })
+    },
+    verifyFun (id) {
+      if (id == this.addressId) {
+        this.chooseAddr = ''
+        this.addressVal = '选择地址'
+        this.form.dealerRecevieAddressSn = ''
+      }
+    },
+    //  保存
+    handleSave () {
+      const _this = this
+      _this.$refs.ruleForm.validate(valid => {
+        if (valid) {
+          _this.form.buyerName = _this.detailData.buyerName
+          const formData = JSON.parse(JSON.stringify(_this.form))
+          _this.$emit('ok', formData)
+          _this.isShow = false
+        } else {
+          return false
+        }
+      })
+    },
+    //  地址保存
+    handleOk (data) {
+      console.log(data, 'chooseAddr')
+      this.chooseAddr = (data.consigneeName || '') + '(' + (data.consigneeTel || '-') + ')' + ' ' + (data.address || '')
+      this.addressVal = '更换地址'
+      this.form.dealerRecevieAddressSn = data.dealerRecevieAddressSn || ''
+      this.addressId = data.id || undefined
+      this.openAddrModal = false
+      // 移除表单项的校验结果
+      this.$refs.ruleForm.validateField('dealerRecevieAddressSn')
+    },
+    //  获取详情
+    setDetail (data) {
+      this.detailData = data
+      if (data && data.dispatchBillCount * 1 > 0) {
+        this.receiverDisabled = true
+        this.form.receiverSn = data.receiverSn
+        this.form.receiverName = data.receiverName
+        if (data.salesBillExtEntity) {
+          const address = (data.salesBillExtEntity.shippingAddrProvinceName ? (data.salesBillExtEntity.shippingAddrProvinceName + '-') : '') + (data.salesBillExtEntity.shippingAddrCityName ? (data.salesBillExtEntity.shippingAddrCityName + '-') : '') + (data.salesBillExtEntity.shippingAddrCountyName ? (data.salesBillExtEntity.shippingAddrCountyName + '-') : '') + data.salesBillExtEntity.shippingAddr
+          this.chooseAddr = (data.salesBillExtEntity.consigneeName || '') + '(' + (data.salesBillExtEntity.consigneeTel || '-') + ')' + ' ' + (address || '')
+        }
+      }
+    },
+    // 重置表单
+    resetForm () {
+      this.detailData = null
+      this.$refs.ruleForm.resetFields()
+      this.form = {
+        sendNo: '',
+        printStatus: undefined,
+        buyerName: '',
+        receiverSn: '',
+        receiverName: '',
+        dealerRecevieAddressSn: '',
+        explainInfo: ''
+      }
+      if (!this.receiverDisabled) {
+        this.$refs.dealerSubareaScopeList.resetForm()
+        this.verifyFun(this.addressId)
+      }
+    }
+  },
+  watch: {
+    //  父页面传过来的弹框状态
+    openModal (newValue, oldValue) {
+      this.isShow = newValue
+    },
+    //  重定义的弹框状态
+    isShow (newValue, oldValue) {
+      if (!newValue) {
+        this.$emit('close')
+        this.resetForm()
+      }
+    }
+  }
+}
+</script>
+
+<style lang="less">
+  .dealerAccountEdit-modal{
+    .ant-modal-body {
+      padding: 40px 40px 24px;
+    }
+    .btn-cont {
+      text-align: center;
+      margin: 35px 0 10px;
+    }
+  }
+</style>

+ 445 - 0
src/views/salesManagement/waitDispatchNew/edit.vue

@@ -0,0 +1,445 @@
+<template>
+  <div class="waitDispatch-wrap">
+    <a-spin :spinning="spinning" tip="Loading...">
+      <a-page-header :ghost="false" :backIcon="false" @back="handleBack" >
+        <!-- 自定义的二级文字标题 -->
+        <template slot="subTitle">
+          <a id="waitDispatch-back-btn" href="javascript:;" @click="handleBack"><a-icon type="left" /> 返回列表</a>
+          <span style="margin: 0 15px;color: #666;">客户名称:{{ detailData&&detailData.buyerName || '--' }}</span>
+        </template>
+      </a-page-header>
+      <a-card size="small" :bordered="false" class="waitDispatch-cont">
+        <!-- 查询配件列表 -->
+        <queryPart
+          ref="partQuery"
+          :newLoading="isInster"
+          @oneDispatch="oneDispatch"
+          @cancelProduct="cancelProduct"
+          @addProduct="insterProduct"></queryPart>
+      </a-card>
+      <a-card size="small" :bordered="false" class="waitDispatch-cont">
+        <div slot="title">
+          <div class="p-title">
+            待下推产品
+          </div>
+        </div>
+
+        <div style="margin: 0 0 10px 0;">
+          <a-button
+            type="danger"
+            @click="delSalerDetailAll"
+            :loading="delLoading"
+            id="waitDispatch-del-all">批量移除</a-button>
+
+            <div style="display: inline-block;margin-left: 15px;">
+              本次下推款数:<strong>{{ totalData&&(totalData.totalCategory || totalData.totalCategory==0) ? totalData.totalCategory : '--' }}</strong>;
+              本次下推数量:<strong>{{ totalData&&(totalData.totalQty || totalData.totalQty==0) ? totalData.totalQty : '--' }}</strong>;
+            </div>
+        </div>
+        
+        <!-- 已选配件列表 -->
+        <s-table
+          class="sTable"
+          ref="table"
+          size="small"
+          :rowKey="(record) => record.id"
+          :row-selection="{ columnWidth: 40 }"
+          @rowSelection="rowSelectionFun"
+          :columns="columns"
+          :data="loadData"
+          :showPagination="false"
+          :scroll="{ y: 300 }"
+          :defaultLoadData="false"
+          bordered>
+          <!-- 产品编码 -->
+          <template slot="productCode" slot-scope="text, record">
+            <a-badge count="促" v-if="record.promotionFlag == 1">
+              <div style="padding-right: 15px;">{{ text }}</div>
+            </a-badge>
+            <span v-else>{{ text }}</span>
+          </template>
+          <!-- 本次下推数 -->
+          <template slot="salesNums" slot-scope="text, record">
+            <a-input-number
+              id="salesReturn-qty"
+              size="small"
+              v-model="record.qty"
+              :precision="0"
+              :min="1"
+              :max="record.surplusQty"
+              placeholder="请输入"
+              @blur="e => onCellBlur(e.target.value, record)"
+              style="width: 100%;" />
+          </template>
+          <!-- 操作 -->
+          <template slot="action" slot-scope="text, record">
+            <a-button
+              size="small"
+              type="link"
+              :loading="delLoading"
+              class="button-error"
+              @click="handleDel(record)"
+            >移除</a-button>
+          </template>
+        </s-table>
+      </a-card>
+    </a-spin>
+    <div class="affix-cont">
+      <a-button
+        size="large"
+        style="padding: 0 60px;"
+        :disabled="spinning"
+        type="primary"
+        class="button-primary"
+        @click="handleDispatch()"
+        :loading="loading"
+        id="productInfoList-handleSubmit">下推</a-button>
+    </div>
+    <!-- 下推 -->
+    <dsModal ref="dsModal" :openModal="showDsModal" @close="showDsModal=false" @ok="handleSubmit" />
+  </div>
+</template>
+
+<script>
+import { commonMixin } from '@/utils/mixin'
+import { STable, VSelect } from '@/components'
+import queryPart from './queryPart.vue'
+import dsModal from './dsModal.vue'
+import { salesDetailBySn } from '@/api/sales'
+import { salesDetailDispatchByOneKey, insertBatchOfWaitDispatch, salesDetailUpdateCancelQty } from '@/api/salesDetail'
+import { deleteBatch, pushDown, waitDispatchDetailAllList, updateQty } from '@/api/waitDispatchDetail'
+import { findBySalesBillSn } from '@/api/dispatch'
+import { keys } from 'core-js/fn/array'
+export default {
+  name: 'WaitDispatch',
+  mixins: [commonMixin],
+  components: { STable, VSelect, queryPart, dsModal },
+  data () {
+    return {
+      showDsModal: false,
+      spinning: false,
+      salesBillSn: null, // 销售单sn
+      disabled: false, //  查询、重置按钮是否可操作
+      isInster: false, // 是否正在添加产品
+      delLoading: false, // 是否正在移除产品
+      loading: false, // 是否下推中
+      detailData: { discountAmount: 0, id: null, salesBillSn: '' }, // 订单基础数据
+      dataSource: [],
+      productForm: {
+        dispatchBillSn: ''
+      },
+      // 表头
+      columns: [
+        { title: '序号', dataIndex: 'no', width: '4%', align: 'center' },
+        { title: '产品编码', dataIndex: 'productEntity.code', scopedSlots: { customRender: 'productCode' }, width: '26%', align: 'center' },
+        { title: '产品名称', dataIndex: 'productEntity.name', width: '29%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '出库仓库', dataIndex: 'dispatchBill.warehouseName', width: '8%', align: 'center', customRender: function (text) { return text || '--' }, ellipsis: true },
+        { title: '待下推数量', dataIndex: 'surplusQty', width: '10%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+        { title: '本次下推数', scopedSlots: { customRender: 'salesNums' }, width: '11%', align: 'center' },
+        { title: '单位', dataIndex: 'productEntity.unit', width: '10%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '操作', scopedSlots: { customRender: 'action' }, width: '10%', align: 'center' }
+      ],
+      // 加载数据方法 必须为 Promise 对象
+      loadData: parameter => {
+        this.disabled = true
+        // 查询统计
+        return waitDispatchDetailAllList(Object.assign(parameter, this.productForm)).then(res => {
+          let data
+          if (res.status == 200) {
+            data = res.data
+            const no = 0
+            for (var i = 0; i < data.length; i++) {
+              data[i].no = no + i + 1
+              data[i].qtyBackups = data[i].qty
+            }
+            this.disabled = false
+            this.dataSource = data
+          }
+          return data
+        })
+      },
+      totalData: null,
+      rowSelectionInfo: null
+    }
+  },
+  methods: {
+    // 表格选中项
+    rowSelectionFun (obj) {
+      this.rowSelectionInfo = obj || null
+    },
+    // 统计查询
+    getTotalData () {
+      findBySalesBillSn({ salesBillSn: this.$route.params.salesBillSn }).then(res => {
+        if (res.status == 200) {
+          this.totalData = res.data || null
+          if (res.data && Object.keys(res.data).length > 0) {
+            this.productForm.dispatchBillSn = res.data.dispatchBillSn
+            const _this = this
+            this.$nextTick(() => {
+              _this.$refs.table.refresh()
+            })
+          } else {
+            this.dataSource = []
+            this.$refs.table.clearTable()
+          }
+        } else {
+          this.totalData = null
+        }
+      })
+    },
+    // 已选产品  blur
+    onCellBlur (val, record) {
+      const _this = this
+      if (val && val != record.qtyBackups) {
+        _this.spinning = true
+        updateQty({
+          dispatchBillDetailSn: record.dispatchBillDetailSn,
+          qty: record.qty,
+          salesBillSn: _this.salesBillSn
+        }).then(res => {
+          if (res.status == 200) {
+            _this.$refs.partQuery.resetCurForm()
+            _this.$message.success(res.message)
+            _this.spinning = false
+            _this.resetSearchForm()
+          } else {
+            _this.spinning = false
+          }
+        })
+      } else {
+        record.qty = record.qtyBackups
+      }
+    },
+    //  重置
+    resetSearchForm () {
+      this.getTotalData()
+      this.getOrderDetail()
+    },
+    //  返回
+    handleBack () {
+      this.$router.push({ name: 'salesQueryNewList', query: { closeLastOldTab: true } })
+    },
+    // 批量删除
+    delSalerDetailAll () {
+      const _this = this
+      if (!_this.rowSelectionInfo || (_this.rowSelectionInfo && _this.rowSelectionInfo.selectedRowKeys.length < 1)) {
+        _this.$message.warning('请在选择待下推产品!')
+        return
+      }
+      const obj = []
+      _this.rowSelectionInfo && _this.rowSelectionInfo.selectedRows.map(item => {
+        if (_this.rowSelectionInfo && _this.rowSelectionInfo.selectedRowKeys.indexOf(item.id) != -1) {
+          obj.push(item.dispatchBillDetailSn)
+        }
+      })
+      this.$confirm({
+        title: '提示',
+        content: '确认要批量删除吗?',
+        centered: true,
+        closable: true,
+        onOk () {
+          _this.deleteFun(obj, 1)
+        }
+      })
+    },
+    // 删除产品
+    handleDel (row) {
+      const _this = this
+      this.$confirm({
+        title: '提示',
+        content: '确认要删除吗?',
+        centered: true,
+        closable: true,
+        onOk () {
+          _this.deleteFun(row, 0)
+        }
+      })
+    },
+    // 移除操作
+    deleteFun (row, type) {
+      const _this = this
+      _this.delLoading = true
+      _this.spinning = true
+      deleteBatch(type == 0 ? [row.dispatchBillDetailSn] : row).then(res => {
+        if (res.status == 200) {
+          _this.resetSearchForm()
+          _this.$refs.partQuery.resetCurForm()
+          if (type == 1) { //  批量操作
+            _this.$refs.table.clearSelected() // 清空表格选中项
+          } else if (type == 0) { //  单条
+            const ind = _this.rowSelectionInfo && _this.rowSelectionInfo.selectedRowKeys.findIndex(item => item == row.id)
+            _this.rowSelectionInfo && _this.rowSelectionInfo.selectedRowKeys.splice(ind, 1)
+          }
+          _this.$message.success(res.message)
+          _this.spinning = false
+        } else {
+          _this.spinning = false
+        }
+        _this.delLoading = false
+      })
+    },
+    // 添加产品
+    insterProduct (list) {
+      // 防止多次添加产品
+      if (this.isInster) { return }
+      this.saveNewProduct(list)
+    },
+    // 保存添加的产品到下推列表
+    saveNewProduct (list) {
+      this.$message.loading('正在添加产品...', 1)
+      this.isInster = true
+      this.spinning = true
+      insertBatchOfWaitDispatch({
+        salesBillDetailSnList: list,
+        salesBillSn: this.salesBillSn
+      }).then(res => {
+        if (res.status == 200) {
+          this.resetSearchForm()
+          this.$refs.partQuery.resetCurForm()
+          this.$message.success('添加成功', 2.5)
+          this.spinning = false
+        } else {
+          this.spinning = false
+        }
+        this.isInster = false
+      })
+    },
+    // 批量取消产品
+    cancelProduct (list) {
+      // 防止多次添加产品
+      this.$message.loading('正在批量取消产品...', 1)
+      this.isInster = true
+      this.spinning = true
+      salesDetailUpdateCancelQty(list).then(res => {
+        if (res.status == 200) {
+          this.resetSearchForm()
+          this.$refs.partQuery.resetCurForm()
+          this.$message.success(res.message, 2.5)
+          this.spinning = false
+        } else {
+          this.spinning = false
+        }
+        this.isInster = false
+      })
+    },
+    // 一键下推
+    oneDispatch () {
+      this.isInster = true
+      this.spinning = true
+      salesDetailDispatchByOneKey({ salesBillSn: this.$route.params.salesBillSn }).then(res => {
+        if (res.status == 200) {
+          this.resetSearchForm()
+          this.$refs.partQuery.resetCurForm()
+          this.spinning = false
+        } else {
+          this.spinning = false
+        }
+        this.isInster = false
+      })
+    },
+    //  销售单详情
+    getOrderDetail () {
+      salesDetailBySn({ salesBillSn: this.$route.params.salesBillSn }).then(res => {
+        if (res.status == 200) {
+          this.detailData = res.data
+          this.$refs.partQuery.pageInit(this.$route.params.salesBillSn, this.detailData)
+        }
+      })
+    },
+    // 提交下推
+    handleDispatch () {
+      if (this.dataSource.length) {
+        this.showDsModal = true
+        this.detailData.dispatchBillCount = this.totalData.dispatchBillCount
+        this.detailData.receiverName = this.totalData.receiverName ? this.totalData.receiverName : ''
+        this.detailData.receiverSn = this.totalData.receiverSn ? this.totalData.receiverSn : ''
+        this.$refs.dsModal.setDetail(this.detailData)
+      } else {
+        this.$message.warning('请选择待下推产品')
+      }
+    },
+    handleSubmit (data) {
+      this.delLoading = true
+      this.isInster = true
+      this.loading = true
+      this.spinning = true
+      const params = Object.assign({ dispatchBillSn: this.productForm.dispatchBillSn }, data)
+      pushDown(params).then(res => {
+        if (res.status == 200) {
+          this.handleBack()
+          this.$message.success(res.message)
+        }
+        this.delLoading = false
+        this.isInster = false
+        this.loading = false
+        this.spinning = false
+      })
+    },
+    pageInit () {
+      this.rowSelectionInfo = null
+      // this.$refs.table.clearTable()
+      this.$refs.partQuery.clearTable()
+      this.salesBillSn = this.$route.params.salesBillSn
+      this.getOrderDetail()
+      this.getTotalData()
+    }
+  },
+  mounted () {
+    if (!this.$store.state.app.isNewTab) { // 页签刷新时调用
+      this.pageInit()
+    }
+  },
+  activated () {
+    // 如果是新页签打开或者进入新的子页(例:存在列表第2条数据编辑页页签时再打开第4条数据的编辑页),则重置当前页面
+    if (this.$store.state.app.isNewTab || !this.$store.state.app.isNewSubTab) {
+      this.pageInit()
+    }
+  },
+  beforeRouteEnter (to, from, next) {
+    next(vm => {})
+  }
+}
+</script>
+
+<style lang="less">
+  .waitDispatch-wrap{
+    position: relative;
+    height: 100%;
+    padding-bottom: 51px;
+    box-sizing: border-box;
+    >.ant-spin-nested-loading{
+      overflow-y: scroll;
+      height: 100%;
+    }
+    .waitDispatch-cont{
+      margin-top: 10px;
+    }
+    .p-title{
+      font-weight: bold;
+    }
+    .p-notes{
+      span{
+        color: #FF9900;
+      }
+    }
+    .total-bar{
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      > div{
+        &:last-child{
+          display: flex;
+          align-items: center;
+          justify-content: space-between;
+          > div{
+            padding: 0 10px;
+          }
+        }
+      }
+    }
+    .redBg-row{
+      background-color: #f5cdc8;
+    }
+  }
+
+</style>

+ 338 - 0
src/views/salesManagement/waitDispatchNew/queryPart.vue

@@ -0,0 +1,338 @@
+<template>
+  <div class="productInfoList-wrap">
+    <!-- 搜索条件 -->
+    <div 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="productInfoList-name" v-model.trim="queryParam.productName" allowClear placeholder="请输入产品名称"/>
+            </a-form-item>
+          </a-col>
+          <a-col :md="6" :sm="24">
+            <a-form-item label="产品编码">
+              <a-input id="productInfoList-code" v-model.trim="queryParam.productCode" allowClear placeholder="请输入产品编码"/>
+            </a-form-item>
+          </a-col>
+          <a-col :md="6" :sm="24">
+            <a-form-item label="是否促销品">
+              <v-select
+                code="FLAG"
+                id="productInfoList-promotionFlag"
+                v-model="queryParam.promotionFlag"
+                allowClear
+                placeholder="请选择是否"
+              ></v-select>
+            </a-form-item>
+          </a-col>
+          <a-col :md="6" :sm="24">
+            <a-form-item label="类型">
+              <a-select v-model.trim="queryParam.ptype" :dropdownMatchSelectWidth="false" >
+                <a-select-option value="0">
+                  全部产品
+                </a-select-option>
+                <a-select-option value="1">
+                  剩余待下推数量>0的产品
+                </a-select-option>
+                <a-select-option value="2">
+                  可全部下推的产品
+                </a-select-option>
+                <a-select-option value="3">
+                  不可全部下推的产品
+                </a-select-option>
+              </a-select>
+            </a-form-item>
+          </a-col>
+          <a-col :md="6" :sm="24">
+            <a-form-item label="出库仓库">
+              <chooseWarehouse ref="warehouse" v-model="queryParam.warehouseSn"></chooseWarehouse>
+            </a-form-item>
+          </a-col>
+          <a-col :md="6" :sm="24" style="margin-bottom: 10px;">
+            <a-button type="primary" class="button-info" @click="$refs.table.refresh(true)" :disabled="disabled" id="productInfoList-refresh">查询</a-button>
+            <a-button style="margin-left: 5px" @click="resetSearchForm" id="productInfoList-reset">重置</a-button>
+          </a-col>
+        </a-row>
+      </a-form>
+    </div>
+   
+    <!-- alert -->
+    <div style="margin-bottom: 10px;display: flex;" v-if="detailData">
+      <div>
+        <a-button type="primary" :disabled="newLoading" class="button-info" @click="handlePlAdd">批量添加</a-button>
+        <a-button type="danger" :disabled="newLoading" class="button-error" @click="handlePlCancel">批量取消</a-button>
+        <!-- <a-button type="default" :disabled="newLoading" @click="handleOneDispatch">有货一键下推</a-button> -->
+      </div>
+      <div style="padding-left: 20px;">
+        总销售数量:<strong>{{ detailData&&(detailData.totalQty || detailData.totalQty==0) ? detailData.totalQty : '--' }}</strong>;
+        已取消数量:<strong>{{ detailData&&(detailData.totalCancelQty || detailData.totalCancelQty==0) ? detailData.totalCancelQty : '--' }}</strong>;
+        已下推数量:<strong>{{ detailData&&(detailData.totalPushedQty || detailData.totalPushedQty==0) ? detailData.totalPushedQty : '--' }}</strong>;
+        待下推数量:<strong>{{ detailData&&(detailData.totalUnpushedQty || detailData.totalUnpushedQty==0) ? detailData.totalUnpushedQty : '--' }}</strong>;<br/>
+        <span v-if="$hasPermissions('B_salesDispatch_salesPrice')">总售价:<strong>{{ detailData&&(detailData.totalAmount || detailData.totalAmount==0) ? toThousands(detailData.totalAmount) : '--' }}</strong>;</span>
+        <span v-if="$hasPermissions('B_salesDispatch_costPrice')">总成本:<strong>{{ detailData&&(detailData.totalCost || detailData.totalCost==0) ? toThousands(detailData.totalCost) : '--' }}</strong>;</span>
+        <span v-if="$hasPermissions('B_salesDispatch_costPrice')&&$hasPermissions('B_salesDispatch_salesPrice')">总毛利:<strong>{{ detailData&&(detailData.grossProfit || detailData.grossProfit==0) ? toThousands(detailData.grossProfit) : '--' }}</strong>;</span>
+        <span v-if="$hasPermissions('B_salesDispatch_salesPrice')">已取消金额:<strong>{{ detailData&&(detailData.totalCancelAmount || detailData.totalCancelAmount==0) ? toThousands(detailData.totalCancelAmount) : '--' }}</strong>;</span>
+        <span v-if="$hasPermissions('B_salesDispatch_salesPrice')">已下推金额:<strong>{{ detailData&&(detailData.totalPushedAmount || detailData.totalPushedAmount==0) ? toThousands(detailData.totalPushedAmount) :'--' }}</strong>;</span>
+        <span v-if="$hasPermissions('B_salesDispatch_salesPrice')">待下推金额:<strong>{{ detailData&&(detailData.totalUnpushedAmount || detailData.totalUnpushedAmount==0) ? toThousands(detailData.totalUnpushedAmount) : '--' }}</strong>;</span>
+      </div>
+    </div>
+     
+    <!-- 列表 -->
+    <s-table
+      class="sTable"
+      ref="table"
+      size="small"
+      :rowKey="(record) => record.id"
+      :row-selection="{ columnWidth: 40, getCheckboxProps:record =>({props: { disabled: record.surplusQty<=0 }})}"
+      @rowSelection="rowSelectionFun"
+      :columns="columns"
+      :showPagination="false"
+      :data="loadData"
+      :scroll="{ y: 300 }"
+      :defaultLoadData="false"
+      bordered>
+      <!-- 取消数量 -->
+      <template slot="nums" slot-scope="text, record">
+        <div v-if="record.surplusQty>0" @dblclick.stop>
+          <a-input-number
+            size="small"
+            v-model="record.cancelNums"
+            :precision="0"
+            :min="0"
+            :max="record.surplusQty"
+            style="width: 100%;"
+            placeholder="请输入" />
+        </div>
+        <div v-else>--</div>
+      </template>
+      <!-- 产品编码 -->
+      <template slot="productCode" slot-scope="text, record">
+        <a-badge count="促" v-if="record.promotionFlag == 1">
+          <div style="padding-right: 15px;">{{ text }}</div>
+        </a-badge>
+        <span v-else>{{ text }}</span>
+      </template>
+      <!-- 操作 -->
+      <template slot="action" slot-scope="text, record">
+        <a-button
+          size="small"
+          type="link"
+          class="button-info"
+          :loading="newLoading"
+          @click="handleAdd(record)"
+          v-if="record.surplusQty>0"
+          id="productInfoList-edit-btn">添加</a-button>
+        <span v-else>--</span>
+      </template>
+    </s-table>
+
+  </div>
+</template>
+
+<script>
+import { commonMixin } from '@/utils/mixin'
+import { salesDetailAllStockList } from '@/api/salesDetail'
+import { STable, VSelect } from '@/components'
+import chooseWarehouse from '@/views/common/chooseWarehouse'
+export default {
+  name: 'QueryPart',
+  mixins: [commonMixin],
+  components: { STable, VSelect, chooseWarehouse },
+  props: {
+    newLoading: Boolean
+  },
+  watch: {
+    data (newValue, oldValue) {
+      this.resetSearchForm()
+    }
+  },
+  data () {
+    return {
+      advanced: true, // 高级搜索 展开/关闭
+      showSetting: false, // 设置弹框
+      productType: [],
+      salesBillSn: '',
+      detailData: null,
+      queryParam: {
+        ptype: '0', // 类型
+        productCode: '', //  产品编码
+        productName: '', //  产品名称
+        promotionFlag: undefined, //  是否促销品
+        brandSn: undefined, //  产品品牌
+        productTypeSn1: '', //  产品一级分类
+        productTypeSn2: '', //  产品二级分类
+        productTypeSn3: '', //  产品三级分类
+        salesBillSn: '',
+        warehouseSn: undefined
+      },
+      disabled: false, //  查询、重置按钮是否可操作
+      // 加载数据方法 必须为 Promise 对象
+      loadData: parameter => {
+        this.disabled = true
+        this.queryParam.salesBillSn = this.salesBillSn
+        return salesDetailAllStockList(Object.assign(parameter, this.queryParam)).then(res => {
+          let data
+          if (res.status == 200) {
+            data = res.data
+            if (data) {
+              // 根据类型过滤数据
+              data = data.filter(item => {
+                if (this.queryParam.ptype == '1') {
+                  return item != null && item.surplusQty > 0
+                }
+                if (this.queryParam.ptype == '2') {
+                  return item != null && item.surplusQty > 0 && item.surplusQty <= item.stockQty
+                }
+                if (this.queryParam.ptype == '3') {
+                  return item != null && item.surplusQty > item.stockQty
+                }
+                if (this.queryParam.ptype == '0') {
+                  return item != null
+                }
+              })
+              // 增加编号
+              const no = 0
+              for (var i = 0; i < data.length; i++) {
+                data[i].no = no + i + 1
+                data[i].cancelNums = data[i].surplusQty
+              }
+              this.disabled = false
+            }
+          }
+          return data
+        })
+      },
+      rowSelectionInfo: null
+    }
+  },
+  computed: {
+    columns () {
+      const arr = [
+        // { title: '序号', dataIndex: 'no', width: '4%', align: 'center' },
+        { title: '产品编码', dataIndex: 'productEntity.code', scopedSlots: { customRender: 'productCode' }, width: '14%', align: 'center' },
+        { title: '产品名称', dataIndex: 'productEntity.name', width: '14%', align: 'left', customRender: function (text) { return text || '--' }, ellipsis: true },
+        { title: '原厂编码', dataIndex: 'productEntity.origCode', width: '10%', align: 'center', customRender: function (text) { return text || '--' } },
+        // { title: '销售价', dataIndex: 'price', width: '6%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+        // { title: '成本价', dataIndex: 'showCost', width: '6%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+        { title: '出库仓库', dataIndex: 'warehouseName', width: '8%', align: 'center', customRender: function (text) { return text || '--' }, ellipsis: true },
+        { title: '单位', dataIndex: 'productEntity.unit', width: '4%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '可用库存', dataIndex: 'stockQty', width: '6%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+        { title: '销售数量', dataIndex: 'qty', width: '6%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+        { title: '已取消', dataIndex: 'cancelQty', width: '6%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+        { title: '已下推', dataIndex: 'pushedQty', width: '6%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+        { title: '待下推数量', dataIndex: 'surplusQty', width: '7%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+        { title: '取消数量', dataIndex: 'cancelNums', scopedSlots: { customRender: 'nums' }, width: '7%', align: 'center' },
+        { title: '操作', dataIndex: 'action', scopedSlots: { customRender: 'action' }, width: '8%', align: 'center' }
+      ]
+      if (this.$hasPermissions('B_salesDispatch_salesPrice')) { //  售价权限
+        arr.splice(3, 0, { title: '销售价', dataIndex: 'price', width: '6%', align: 'right', customRender: text => ((text || text == 0) ? this.toThousands(text) : '--') })
+      }
+      if (this.$hasPermissions('B_salesDispatch_costPrice')) {
+        const ind = this.$hasPermissions('B_salesDispatch_salesPrice') ? 4 : 3
+        arr.splice(ind, 0, { title: '成本价', dataIndex: 'showCost', width: '6%', align: 'right', customRender: text => ((text || text == 0) ? this.toThousands(text) : '--') })
+      }
+      return arr
+    }
+  },
+  methods: {
+    // 表格选中项
+    rowSelectionFun (obj) {
+      this.rowSelectionInfo = obj || null
+    },
+    // 类型变化,过滤列表
+    handlePtypeChange () {},
+    //  重置
+    resetSearchForm () {
+      this.queryParam.ptype = '0'
+      this.queryParam.productCode = ''
+      this.queryParam.productName = ''
+      this.queryParam.promotionFlag = undefined
+      this.queryParam.brandSn = undefined
+      this.queryParam.productTypeSn1 = ''
+      this.queryParam.productTypeSn2 = ''
+      this.queryParam.productTypeSn3 = ''
+      this.queryParam.warehouseSn = undefined
+      this.productType = []
+      this.$refs.table.refresh(true)
+    },
+    pageInit (salesBillSn, detailData) {
+      this.salesBillSn = salesBillSn
+      this.detailData = detailData
+      this.$refs.table.clearSelected()
+      this.resetSearchForm()
+    },
+    clearTable () {
+      this.rowSelectionInfo = null
+      this.$refs.table.clearSelected()
+    },
+    // 刷新当前页面
+    resetCurForm () {
+      this.$refs.table.clearSelected() // 清空表格选中项
+      this.$refs.table.refresh()
+    },
+    // 添加
+    handleAdd (row) {
+      if (row.stockQty > 0) { //  可用库存大于0才可添加
+        this.$emit('addProduct', [row.salesBillDetailSn])
+      } else {
+        this.$message.warning('库存为0,不可添加!')
+      }
+    },
+    // 批量添加
+    handlePlAdd () {
+      const _this = this
+      if (!_this.rowSelectionInfo || (_this.rowSelectionInfo && _this.rowSelectionInfo.selectedRowKeys.length < 1)) {
+        _this.$message.warning('请先选择产品!')
+        return
+      }
+      const obj = []
+      _this.rowSelectionInfo && _this.rowSelectionInfo.selectedRows.map(item => {
+        if (item.stockQty > 0) {
+          obj.push(item.salesBillDetailSn)
+        }
+      })
+      if (obj.length < 1) {
+        this.$message.warning('所选产品库存为0,不可添加!')
+        return
+      }
+      this.$confirm({
+        title: '提示',
+        content: '确认要批量添加到待下推列表吗?',
+        centered: true,
+        closable: true,
+        onOk () {
+          _this.$emit('addProduct', obj)
+        }
+      })
+    },
+    // 批量取消
+    handlePlCancel () {
+      const _this = this
+      if (!_this.rowSelectionInfo || (_this.rowSelectionInfo && _this.rowSelectionInfo.selectedRowKeys.length < 1)) {
+        _this.$message.warning('请先选择产品!')
+        return
+      }
+      const obj = []
+      _this.rowSelectionInfo && _this.rowSelectionInfo.selectedRows.map(item => {
+        obj.push({
+          'cancelQty': item.cancelNums,
+          'salesBillDetailSn': item.salesBillDetailSn,
+          'salesBillSn': this.salesBillSn
+        })
+      })
+
+      this.$emit('cancelProduct', obj)
+    },
+    // 一键下推
+    handleOneDispatch () {
+      this.$emit('oneDispatch')
+    },
+    //  产品分类  change
+    changeProductType (val, opt) {
+      this.queryParam.productTypeSn1 = val[0] ? val[0] : ''
+      this.queryParam.productTypeSn2 = val[1] ? val[1] : ''
+      this.queryParam.productTypeSn3 = val[2] ? val[2] : ''
+    }
+  }
+}
+</script>