Browse Source

Merge branch 'develop_yh13' of jianguan-web/qpls-md-html into pre-release

李磊 2 years ago
parent
commit
82fb2e4e03
47 changed files with 4030 additions and 218 deletions
  1. 1 1
      public/version.json
  2. 1 1
      src/App.vue
  3. 9 0
      src/api/product.js
  4. 45 0
      src/api/purchaseCart.js
  5. 2 2
      src/api/purchaseDetail.js
  6. 0 1
      src/components/Table/index.js
  7. 10 1
      src/components/tools/UserMenu.vue
  8. 98 43
      src/config/router.config.js
  9. 4 0
      src/layouts/BasicLayout.vue
  10. 2 1
      src/store/getters.js
  11. 3 1
      src/store/index.js
  12. 28 0
      src/store/modules/shoppingCart.js
  13. 2 2
      src/utils/request.js
  14. 24 1
      src/views/basicData/systemSettings/index.vue
  15. 2 5
      src/views/bulkManagement/bulkWarehousingOrder/edit.vue
  16. 2 1
      src/views/common/print.vue
  17. 25 24
      src/views/common/receivingAddress/chooseAddressModal.vue
  18. 0 0
      src/views/common/receivingAddress/editAddressModal.vue
  19. 88 0
      src/views/common/shopingCatModal.vue
  20. 32 9
      src/views/inventoryManagement/inventoryQuery/list.vue
  21. 137 0
      src/views/inventoryManagement/inventoryQuery/setPurchaseQty.vue
  22. 42 19
      src/views/inventoryManagement/inventoryWarning/list.vue
  23. 4 4
      src/views/numsGoodsShelves/shelfSet/chooseShelfImportModal.vue
  24. 2 2
      src/views/numsGoodsShelves/shelfSet/importHuoweiModal.vue
  25. 22 3
      src/views/productManagement/newProduct/detail.vue
  26. 161 0
      src/views/productManagement/productInfoJg/editPriceModal.vue
  27. 148 50
      src/views/productManagement/productInfoJg/list.vue
  28. 1 1
      src/views/purchasingManagement/purchaseOrder/basicInfoModal.vue
  29. 2 2
      src/views/purchasingManagement/purchaseOrder/chooseImportModal.vue
  30. 4 4
      src/views/purchasingManagement/purchaseOrder/edit.vue
  31. 9 16
      src/views/purchasingManagement/purchaseOrder/list.vue
  32. 77 7
      src/views/purchasingManagement/purchaseOrder/outStockModal.vue
  33. 272 0
      src/views/purchasingManagement/purchaseOrderNew/basicInfoModal.vue
  34. 217 0
      src/views/purchasingManagement/purchaseOrderNew/chooseImportModal.vue
  35. 326 0
      src/views/purchasingManagement/purchaseOrderNew/chooseProductModal.vue
  36. 303 0
      src/views/purchasingManagement/purchaseOrderNew/detail.vue
  37. 578 0
      src/views/purchasingManagement/purchaseOrderNew/edit.vue
  38. 209 0
      src/views/purchasingManagement/purchaseOrderNew/importGuideModal.vue
  39. 390 0
      src/views/purchasingManagement/purchaseOrderNew/list.vue
  40. 312 0
      src/views/purchasingManagement/purchaseOrderNew/outStockModal.vue
  41. 11 3
      src/views/salesManagement/productPricing/list.vue
  42. 5 3
      src/views/salesManagement/salesQuery/edit.vue
  43. 4 4
      src/views/salesManagement/salesQuery/queryPart.vue
  44. 4 3
      src/views/salesManagement/salesReturn/queryPart.vue
  45. 2 2
      src/views/salesManagement/salesReturn/salesReturnEdit.vue
  46. 2 2
      src/views/salesManagement/salesReturn/salesReturnGrabEdit.vue
  47. 408 0
      src/views/shoppingCarManagement/shoppingCar/list.vue

+ 1 - 1
public/version.json

@@ -1,5 +1,5 @@
 {
   "message": "发现有新版本发布,确定更新系统?",
   "vendorJsVersion": "",
-  "version": 1675821179056
+  "version": 1676958704915
 }

+ 1 - 1
src/App.vue

@@ -61,7 +61,7 @@ export default {
     font-size: 30px;
     top: 0;
     left: 0;
-    width: 50%;
+    width: 30%;
     margin-left: 20%;
   }
 </style>

+ 9 - 0
src/api/product.js

@@ -76,3 +76,12 @@ export const productExport = params => {
     responseType: 'blob'
   })
 }
+
+// 自定义报价
+export const settingPrice = params => {
+  return axios({
+    url: '/product/settingPrice',
+    data: params,
+    method: 'post'
+  })
+}

+ 45 - 0
src/api/purchaseCart.js

@@ -0,0 +1,45 @@
+import { axios } from '@/utils/request'
+
+// 购物车列表
+export const purchaseCartList = (params) => {
+  const url = `/purchaseCart/queryPage/${params.pageNo}/${params.pageSize}`
+  delete params.pageNo
+  delete params.pageSize
+  return axios({
+    url: url,
+    data: params,
+    method: 'post'
+  })
+}
+// 添加到购物车
+export const purchaseCartSave = params => {
+  return axios({
+    url: '/purchaseCart/save',
+    data: params,
+    method: 'post'
+  })
+}
+// 购物车已存在的产品
+export const purchaseCartExistProduct = params => {
+  return axios({
+    url: '/purchaseCart/existProduct',
+    data: params,
+    method: 'post'
+  })
+}
+// 批量删除购物车产品
+export const purchaseDeleteBatch = params => {
+  return axios({
+    url: '/purchaseCart/deleteBatch',
+    data: params,
+    method: 'post'
+  })
+}
+// 修改购物车数量
+export const purchaseUpdateQty = params => {
+  return axios({
+    url: '/purchaseCart/updateQty',
+    data: params,
+    method: 'post'
+  })
+}

+ 2 - 2
src/api/purchaseDetail.js

@@ -63,7 +63,7 @@ export const purchaseDetailCancelList = (params) => {
     method: 'post'
   })
 }
-//  采购 详情 上次缺货 列表 分页
+//  采购 详情 上次缺货 购物车 保存
 export const purchaseDetailCancelSave = (params) => {
   return axios({
     url: '/purchaseDetail/saveCancelProduct',
@@ -79,4 +79,4 @@ export const purchaseDetailDownloadFail = params => {
     data: params,
     responseType: 'blob'
   })
-}
+}

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

@@ -128,7 +128,6 @@ export default {
       showTotal: total => `共 ${total} 条记录`,
       showSizeChanger: this.showSizeChanger
     }) || false
-    // console.log('this.localPagination', this.localPagination)
     this.needTotalList = this.initTotalList(this.columns)
     if (this.defaultLoadData) {
       this.loadData()

+ 10 - 1
src/components/tools/UserMenu.vue

@@ -5,6 +5,12 @@
         <img style="width: 22px;height: 22px;vertical-align: middle;margin: 0 5px;" src="../../assets/icon_movie.png"/>
         <span style="vertical-align: middle;">帮助</span>
       </p>
+      <p class="help-cont" @click="showShopCar" v-if="$hasPermissions('M_shoppingCart')">
+        <a-badge :count="cartCount" :overflow-count="999">
+          <a-icon type="shopping-cart" style="font-size:16px;margin: 0 5px;"/>
+          <span>购物车</span>
+        </a-badge>
+      </p>
       <!-- 通知 -->
       <notice-icon class="action"/>
       <!-- 皮肤设置 -->
@@ -102,7 +108,7 @@ export default {
     NoticeIcon
   },
   computed: {
-    ...mapGetters(['nickname', 'avatar', 'authOrgs', 'userInfo', 'nowRoute', 'theme', 'fontSize', 'printDefNeedle']),
+    ...mapGetters(['nickname', 'avatar', 'authOrgs', 'userInfo', 'nowRoute', 'theme', 'fontSize', 'printDefNeedle', 'cartCount']),
     authOrgsList () { //  过滤掉当前登录账户(不可由自己切换为自己)
       const _this = this
       const arr = []
@@ -140,6 +146,9 @@ export default {
     showVideo () {
       store.commit('IS_ShOW_VIDEO', true)
     },
+    showShopCar () {
+      this.$router.push({ name: 'shoppingCarList' })
+    },
     handleLogout () {
       this.$confirm({
         title: '提示',

+ 98 - 43
src/config/router.config.js

@@ -68,6 +68,17 @@ export const asyncRouterMap = [
                   icon: 'bell',
                   hidden: true
                 }
+              },
+              {
+                path: '/shoppingCarList',
+                name: 'shoppingCarList',
+                component: () => import(/* webpackChunkName: "home" */ '@/views/shoppingCarManagement/shoppingCar/list.vue'),
+                meta: {
+                  title: '购物车',
+                  icon: 'contacts',
+                  replaceTab: true,
+                  hidden: true
+                }
               }
             ]
           }
@@ -693,8 +704,7 @@ export const asyncRouterMap = [
           //   children: [
           //     {
           //       path: 'list',
-          //       name: 'accountManagementList',
-          //       component: () => import(/* webpackChunkName: "numsGoodsShelves" */ '@/views/numsGoodsShelves/accountManagement/list.vue'),
+          //       name: 'accountManagementList',        //       component: () => import(/* webpackChunkName: "numsGoodsShelves" */ '@/views/numsGoodsShelves/accountManagement/list.vue'),
           //       meta: {
           //         title: '账户明细列表',
           //         icon: 'monitor',
@@ -754,7 +764,7 @@ export const asyncRouterMap = [
               {
                 path: 'edit/:sn/:dealerSn',
                 name: 'purchaseOrderEdit',
-                component: () => import(/* webpackChunkName: "purchasingManagement" */ '@/views/purchasingManagement/purchaseOrder/edit.vue'),
+                component: () => import(/* webpackChunkName: purchasingManagement" */ '@/views/purchasingManagement/purchaseOrder/edit.vue'),
                 meta: {
                   title: '编辑采购单',
                   icon: 'file-done',
@@ -773,17 +783,64 @@ export const asyncRouterMap = [
                   replaceTab: true,
                   permission: 'B_purchaseDetail'
                 }
+              }
+            ]
+          },
+          {
+            path: '/purchasingManagement/purchaseOrderNew',
+            redirect: '/purchasingManagement/purchaseOrderNew/list',
+            name: 'purchaseOrderNew',
+            component: BlankLayout,
+            meta: {
+              title: '采购单管理(新版)',
+              icon: 'file-done',
+              permission: 'M_purchasingList'
+            },
+            hideChildrenInMenu: true,
+            children: [
+              {
+                path: 'list',
+                name: 'purchaseOrderNewList',
+                component: () => import(/* webpackChunkName: "purchasingManagement" */ '@/views/purchasingManagement/purchaseOrderNew/list.vue'),
+                meta: {
+                  title: '采购单列表(新版)',
+                  icon: 'file-done',
+                  hidden: true,
+                  permission: 'M_purchasingList'
+                }
+              },
+              {
+                path: 'add/:sn/:dealerSn',
+                name: 'purchaseOrderNewAdd',
+                component: () => import(/* webpackChunkName: "purchasingManagement" */ '@/views/purchasingManagement/purchaseOrderNew/edit.vue'),
+                meta: {
+                  title: '新增采购单(新版)',
+                  icon: 'file-done',
+                  hidden: true,
+                  permission: 'B_purchaseNew'
+                }
+              },
+              {
+                path: 'edit/:sn/:dealerSn',
+                name: 'purchaseOrderNewEdit',
+                component: () => import(/* webpackChunkName: "purchasingManagement" */ '@/views/purchasingManagement/purchaseOrderNew/edit.vue'),
+                meta: {
+                  title: '编辑采购单(新版)',
+                  icon: 'file-done',
+                  hidden: true,
+                  permission: 'B_purchaseEdit'
+                }
               },
               {
-                path: 'warehousing/:sn',
-                name: 'purchaseOrderWarehousing',
-                component: () => import(/* webpackChunkName: "purchasingManagement" */ '@/views/purchasingManagement/purchaseOrder/warehousing.vue'),
+                path: 'detail/:sn',
+                name: 'purchaseOrderNewDetail',
+                component: () => import(/* webpackChunkName: "purchasingManagement" */ '@/views/purchasingManagement/purchaseOrderNew/detail.vue'),
                 meta: {
-                  title: '采购入库',
+                  title: '采购单详情(新版)',
                   icon: 'file-done',
                   hidden: true,
                   replaceTab: true,
-                  permission: 'B_purchaseReceiving'
+                  permission: 'B_purchaseDetail'
                 }
               }
             ]
@@ -795,8 +852,8 @@ export const asyncRouterMap = [
             component: BlankLayout,
             meta: {
               title: '签收入库',
-              icon: 'money-collect'
-              // permission: 'M_signWarehousingList'
+              icon: 'money-collect',
+              permission: 'M_signWarehousingList'
             },
             hideChildrenInMenu: true,
             children: [
@@ -807,8 +864,8 @@ export const asyncRouterMap = [
                 meta: {
                   title: '签收入库列表',
                   icon: 'money-collect',
-                  hidden: true
-                  // permission: 'M_signWarehousingList'
+                  hidden: true,
+                  permission: 'M_signWarehousingList'
                 }
               },
               {
@@ -820,7 +877,6 @@ export const asyncRouterMap = [
                   icon: 'money-collect',
                   replaceTab: true,
                   hidden: true
-                  // permission: 'B_signWarehousingDetail'
                 }
               },
               {
@@ -832,7 +888,6 @@ export const asyncRouterMap = [
                   icon: 'money-collect',
                   replaceTab: true,
                   hidden: true
-                  // permission: 'B_signWarehousingStockOrderDetail'
                 }
               }
             ]
@@ -844,8 +899,8 @@ export const asyncRouterMap = [
             component: BlankLayout,
             meta: {
               title: '采购退货申请单',
-              icon: 'money-collect'
-              // permission: 'M_purchaseReturnApplyFormList'
+              icon: 'money-collect',
+              permission: 'M_purchaseReturnApplyFormList'
             },
             hideChildrenInMenu: true,
             children: [
@@ -856,8 +911,8 @@ export const asyncRouterMap = [
                 meta: {
                   title: '采购退货申请单列表',
                   icon: 'money-collect',
-                  hidden: true
-                  // permission: 'M_purchaseReturnApplyFormList'
+                  hidden: true,
+                  permission: 'M_purchaseReturnApplyFormList'
                 }
               },
               {
@@ -3207,32 +3262,32 @@ export const asyncRouterMap = [
                 }
               }
             ]
+          },
+          {
+            path: '/basicData/systemSettings',
+            redirect: '/basicData/systemSettings/index',
+            name: 'systemSettings',
+            component: BlankLayout,
+            meta: {
+              title: '系统参数',
+              icon: 'sound',
+              permission: 'M_systemSettingsList'
+            },
+            hideChildrenInMenu: true,
+            children: [
+              {
+                path: 'index',
+                name: 'systemSettingsList',
+                component: () => import(/* webpackChunkName: "basicData" */ '@/views/basicData/systemSettings/index.vue'),
+                meta: {
+                  title: '系统参数',
+                  icon: 'sound',
+                  hidden: true,
+                  permission: 'M_systemSettingsList'
+                }
+              }
+            ]
           }
-          // {
-          //   path: '/basicData/systemSettings',
-          //   redirect: '/basicData/systemSettings/index',
-          //   name: 'systemSettings',
-          //   component: BlankLayout,
-          //   meta: {
-          //     title: '系统参数',
-          //     icon: 'sound',
-          //     permission: 'M_systemSettingsList'
-          //   },
-          //   hideChildrenInMenu: true,
-          //   children: [
-          //     {
-          //       path: 'index',
-          //       name: 'systemSettingsList',
-          //       component: () => import(/* webpackChunkName: "basicData" */ '@/views/basicData/systemSettings/index.vue'),
-          //       meta: {
-          //         title: '系统参数',
-          //         icon: 'sound',
-          //         hidden: true,
-          //         permission: 'M_systemSettingsList'
-          //       }
-          //     }
-          //   ]
-          // }
         ]
       },
       // auth

+ 4 - 0
src/layouts/BasicLayout.vue

@@ -292,6 +292,8 @@ export default {
 
     // 消息通知
     this.getNotes()
+    // 购物车
+    this.getCartList()
   },
   mounted () {
     const userAgent = navigator.userAgent
@@ -308,6 +310,7 @@ export default {
     ...mapActions([
       'setSidebar',
       'getMessageList', // 查询列表
+      'getCartList', // 购物车列表
       'hasRead' // 设置已读
     ]),
     reloadView () {},
@@ -424,6 +427,7 @@ export default {
   bottom:0;
   min-width:400px;
   z-index: 10000;
+  box-shadow: -8px 7px 11px 2px #d7d7d7;
   .ant-alert-with-description .ant-alert-close-icon{
     top: 13px;
   }

+ 2 - 1
src/store/getters.js

@@ -27,7 +27,8 @@ const getters = {
   printDefInk:state => state.app.printDefInk,
   printUseing:state => state.app.printUseing,
   printSettingType:state => state.app.printSettingType,
-  returnReason: state => state.app.returnReason
+  returnReason: state => state.app.returnReason,
+  cartCount: state => state.cart.cartCount
 }
 
 export default getters

+ 3 - 1
src/store/index.js

@@ -4,6 +4,7 @@ import Vuex from 'vuex'
 import app from './modules/app'
 import user from './modules/user'
 import socket from './modules/websocketStore'
+import cart from './modules/shoppingCart'
 
 // default router permission control
 import permission from './modules/permission'
@@ -19,7 +20,8 @@ export default new Vuex.Store({
     app,
     user,
     permission,
-    socket
+    socket,
+    cart
   },
   state: {
 

+ 28 - 0
src/store/modules/shoppingCart.js

@@ -0,0 +1,28 @@
+import { purchaseCartList } from '@/api/purchaseCart'
+export default {
+  state: {
+    cartCount: 0,
+  },
+  getters: {
+    cartCount: state => {
+      return () => state.cartCount
+    },
+  },
+  mutations: {
+    setCartCount (state, count) {
+      state.cartCount = count
+    },
+  },
+  actions: {
+    // 获取购物车列表
+    getCartList ({ state, commit }) {
+      purchaseCartList({pageNo:1,pageSize:1}).then(res => {
+        commit('setCartCount', res.data ? res.data.count : 0)
+      })
+    },
+    // 更新购物车数量
+    updateCartCount ({ state, commit }, count) {
+      commit('setCartCount', count)
+    }
+  }
+}

+ 2 - 2
src/utils/request.js

@@ -89,7 +89,7 @@ service.interceptors.request.use(config => {
   }
   config.retry = 3
   config.retryDelay = 1000
-  store.commit('SET_loadingStatus', true)
+  // store.commit('SET_loadingStatus', true)
   return config
 }, err)
 
@@ -120,7 +120,7 @@ service.interceptors.response.use((response) => {
       description: response.data.message
     })
   }
-  store.commit('SET_loadingStatus', false)
+  // store.commit('SET_loadingStatus', false)
   return response.data
 }, err)
 

+ 24 - 1
src/views/basicData/systemSettings/index.vue

@@ -2,6 +2,24 @@
   <a-card size="small" :bordered="false" class="systemSettingsList-wrap" :style="{height:conHeight+'px'}">
     <a-spin :spinning="spinning" tip="Loading...">
       <div ref="contentBox">
+        <a-row :gutter="16">
+          <a-col class="gutter-row" :span="12">
+            产品报价,箭冠产品优先获取自定义车主价和终端价
+          </a-col>
+          <a-col class="gutter-row" :span="12">
+            <a-radio-group v-model="priceValue" @change="handleQty">
+              <a-radio :value="1">
+                启用
+              </a-radio>
+              <a-radio :value="2">
+                禁用
+              </a-radio>
+            </a-radio-group>
+          </a-col>
+          <a-col class="priceDesc" :span="24">
+            箭冠产品优先获取自定义车主价和终端价启用后,自定义车主价和终端价存在时,产品报价列表将优先显示自定义价格,自定义车主价和终端价不存在时,获取箭冠建议价。
+          </a-col>
+        </a-row>
         <a-row :gutter="16">
           <a-col class="gutter-row" :span="12">
             销售下单时,是否显示产品库存为0的产品信息
@@ -62,6 +80,7 @@ export default {
   data () {
     return {
       spinning: false,
+      priceValue: 2,
       qtyValue: 1,
       wasteInfoValue: 1,
       wasteNumValue: 1,
@@ -98,7 +117,7 @@ export default {
       })
     },
     setTableH () {
-      this.conHeight = window.innerHeight - 110.5
+      this.conHeight = window.innerHeight - 86.5
     },
     handleQty () {},
     handleWasteInfo () {},
@@ -129,6 +148,10 @@ export default {
     .ant-row{
       padding:23px 10px;
       border-bottom: 1px solid #e0e0e0;
+      .priceDesc{
+        color:gray;
+        margin-top:10px;
+      }
     }
   }
 

+ 2 - 5
src/views/bulkManagement/bulkWarehousingOrder/edit.vue

@@ -13,12 +13,9 @@
           </a-button>
         </template>
         <!-- 操作区,位于 title 行的行尾 -->
-        <template
-          slot="
-            extra"
-          v-if="$hasPermissions('B_bulkWarehousingOrder_print')">
+        <template slot="extra" v-if="$hasPermissions('B_bulkWarehousingOrder_print')">
           <Print :disabled="chooseLoadDataSource.length==0" :showExport="false" @handlePrint="handlePrint"></Print>
-          </p></template>
+        </template>
       </a-page-header>
       <!-- 基础信息 -->
       <div v-show="isShowBisiceInfo" class="bulkWarehousingOrderEdit-cont">

+ 2 - 1
src/views/common/print.vue

@@ -4,7 +4,7 @@
       <a-radio value="NEEDLE">针式</a-radio>
       <a-radio value="INK">喷墨</a-radio>
     </a-radio-group>
-    <a-button key="3" id="print-preview-btn" :disabled="disabled" @click="handlePrint('preview')">打印预览</a-button>
+    <a-button key="3" id="print-preview-btn" :loading="$store.state.app.printLoading" :disabled="disabled" @click="handlePrint('preview')">打印预览</a-button>
     <a-button
       key="2"
       type="primary"
@@ -17,6 +17,7 @@
     <a-button
       key="1"
       type="primary"
+      :loading="$store.state.app.printLoading"
       class="button-warning"
       id="print-export-btn"
       v-if="showExport"

+ 25 - 24
src/views/purchasingManagement/purchaseOrder/receivingAddress/chooseAddressModal.vue → src/views/common/receivingAddress/chooseAddressModal.vue

@@ -39,30 +39,31 @@
         </template>
         <!-- 操作 -->
         <template slot="action" slot-scope="text, record">
-          <a-button
-            size="small"
-            type="link"
-            class="button-primary"
-            v-if="record.defaultFlag!=1"
-            @click="handleDefault(record)"
-            id="chooseAddressList-default-btn">设为默认</a-button>
-          <a-button
-            size="small"
-            type="link"
-            class="button-primary"
-            v-if="record.readOnlyFlag!=1"
-            @click="handleEdit(record)"
-            id="chooseAddressList-edit-btn"
-          >编辑</a-button>
-          <a-button
-            size="small"
-            type="link"
-            class="button-error"
-            v-if="record.readOnlyFlag!=1"
-            @click="handleDel(record)"
-            id="chooseAddressList-del-btn"
-          >删除</a-button>
-          <span v-if="!(record.defaultFlag!=1) && !(record.readOnlyFlag!=1)">--</span>
+          <div>
+            <a-button
+              size="small"
+              type="link"
+              class="button-primary"
+              v-if="record.defaultFlag!=1"
+              @click="handleDefault(record)"
+              id="chooseAddressList-default-btn">设为默认</a-button>
+            <a-button
+              size="small"
+              type="link"
+              class="button-primary"
+              v-if="record.readOnlyFlag!=1"
+              @click="handleEdit(record)"
+              id="chooseAddressList-edit-btn"
+            >编辑</a-button>
+            <a-button
+              size="small"
+              type="link"
+              class="button-error"
+              v-if="record.readOnlyFlag!=1"
+              @click="handleDel(record)"
+              id="chooseAddressList-del-btn"
+            >删除</a-button>
+          </div>
         </template>
         <!-- 选择 -->
         <template slot="choose" slot-scope="text, record">

+ 0 - 0
src/views/purchasingManagement/purchaseOrder/receivingAddress/editAddressModal.vue → src/views/common/receivingAddress/editAddressModal.vue


+ 88 - 0
src/views/common/shopingCatModal.vue

@@ -0,0 +1,88 @@
+<template>
+  <a-drawer
+    :zIndex="zIndex"
+    placement="right"
+    :visible="visible"
+    :width="width"
+    :get-container="false"
+    :wrap-style="{ position: 'absolute' }"
+    @close="onClose"
+    wrapClassName="shopingCat-drawer">
+     <div slot="title">
+       <strong>{{title}}</strong>
+       <span style="color:red;margin-left:10px;">注意:仅可添加本供应商有经销权且总部已上线的产品</span>
+     </div>
+     <shopingCat ref="shopingCat" modes="modals" @ok="handleok"></shopingCat>
+  </a-drawer>
+</template>
+
+<script>
+import { commonMixin } from '@/utils/mixin'
+import shopingCat from '@/views/shoppingCarManagement/shoppingCar/list.vue'
+export default {
+  name:"shopingCatModal",
+  mixins: [commonMixin],
+  components: {
+    shopingCat
+  },
+  props: {
+    showModal: {
+      type: Boolean,
+      default: false
+    },
+    width: {
+      type: [String, Number],
+      default: '70%'
+    },
+    zIndex: {
+      type: Number,
+      default: 1050
+    },
+    paramsData: {
+      type: Object
+    }
+  },
+  watch: {
+    showModal (newValue, oldValue) {
+      this.visible = newValue
+      if (newValue) {
+         setTimeout(()=>{
+           this.$refs.shopingCat.pageInit(this.paramsData)
+         },500)
+      }
+    },
+  },
+  data () {
+    return {
+      visible: this.showModal,
+      title: '购物车',
+    }
+  },
+  methods: {
+    onClose () {
+      this.$emit('close')
+    },
+    handleok () {
+      this.$emit('ok')
+    },
+  }
+}
+</script>
+
+<style lang="less">
+.shopingCat-drawer {
+  .ant-drawer-header{
+    padding: 13px 20px;
+  }
+  .ant-drawer-body {
+    padding: 0 5px;
+    height: calc(100% - 50px);
+    display: flex;
+    flex-direction: column;
+    overflow: auto;
+    > div {
+      height: 100%;
+    }
+  }
+}
+</style>

+ 32 - 9
src/views/inventoryManagement/inventoryQuery/list.vue

@@ -118,7 +118,7 @@
       <s-table
         class="sTable fixPagination"
         ref="table"
-        :style="{ height: tableHeight+84.5+'px' }"
+        :style="{ height: tableHeight+68.5+'px' }"
         size="small"
         :rowKey="(record) => record.id"
         :columns="columns"
@@ -153,27 +153,32 @@
             class="button-primary"
             @click="goWarehouseDetail(record)"
             id="inventoryQueryList-warehouseDetail-btn">出入库明细</a-button>
+          <a-button v-if="record.dealerProduct.sysFlag==1&&record.dealerProduct.onlineFalg==1&&$hasPermissions('M_shoppingCart')" type="link" @click="addShopCar(record)">加入购物车</a-button>
           <span v-if="!$hasPermissions('B_inventoryInventoryQueryDetail') && !$hasPermissions('B_inventoryInventoryQueryStock')">--</span>
         </template>
       </s-table>
     </a-spin>
     <!-- 库存详情 -->
     <inventory-query-detail-modal v-drag :openModal="openModal" :nowData="nowData" @close="closeModal" />
+    <!-- 设置采购数量 -->
+    <set-purchase-qty ref="setPurchaseQty" :openModal="openPurchaseModal" @close="openPurchaseModal=false" v-drag></set-purchase-qty>
   </a-card>
 </template>
 
 <script>
 import { commonMixin } from '@/utils/mixin'
 import { stockList, stockCount, stockExport } from '@/api/stock'
+import { purchaseCartExistProduct } from '@/api/purchaseCart'
 import ProductType from '../../common/productType.js'
 import ProductBrand from '../../common/productBrand.js'
 import Warehouse from '@/views/common/warehouse.js'
 import { STable, VSelect } from '@/components'
 import inventoryQueryDetailModal from './detailModal.vue'
+import setPurchaseQty from './setPurchaseQty.vue'
 import { downloadExcel } from '@/libs/JGPrint.js'
 export default {
   name: 'InventoryQueryList',
-  components: { STable, VSelect, inventoryQueryDetailModal, ProductType, ProductBrand, Warehouse },
+  components: { STable, VSelect, inventoryQueryDetailModal, ProductType, ProductBrand, Warehouse, setPurchaseQty },
   mixins: [commonMixin],
   data () {
     return {
@@ -190,7 +195,7 @@ export default {
         productTypeSn3: '', //  产品分类3
         warehouse: [],
         warehouseSn: '',
-        warehouseLocationSn:'',
+        warehouseLocationSn: '',
         zeroQtyFlag: false, //  库存情况
         enableFlag: true, // 显示禁用产品
         minUnsalableDays: undefined, // 滞销天数最小值
@@ -204,6 +209,7 @@ export default {
         { name: '库存数量为0', id: '1' },
         { name: '库存数量不为0', id: '0' }
       ],
+      openPurchaseModal: false,
       // 加载数据方法 必须为 Promise 对象
       loadData: parameter => {
         console.log(parameter)
@@ -230,11 +236,11 @@ export default {
           params.product = {
             sysFlag: params.productSysFlag || undefined
           }
-          
+
           // 仓库仓位
           params.warehouseSn = params.warehouse[0]
           params.warehouseLocationSn = params.warehouse[1]
-          
+
           return stockList(params).then(res => {
             let data
             if (res.status == 200) {
@@ -280,7 +286,7 @@ export default {
         { title: '可用库存数量(个)', dataIndex: 'currentStockQty', width: '8%', align: 'center', sorter: true, customRender: function (text) { return ((text || text == 0) ? text : '--') } },
         // { title: '可用库存成本(¥)', dataIndex: 'currentStockCost', width: '8%', align: 'center', sorter: true, customRender: function (text) { return ((text || text == 0) ? text : '--') } },
         { title: <div><a-tooltip placement='top' title='1:产品距离最近一次销售的时间,30天算一个月 2:采购退货,调拨等不算销售,不用来计算滞销天数'><a-icon type="question-circle" /></a-tooltip>&nbsp;滞销天数</div>, width: '10%', align: 'center', dataIndex: 'unsalableDays', scopedSlots: { customRender: 'unsalableDays' }, sorter: true },
-        { title: '操作', scopedSlots: { customRender: 'action' }, width: '10%', align: 'center' }
+        { title: <div><a-tooltip placement='top' title='注意:购物车仅限添加箭冠已上线产品。'><a-icon type="question-circle" /></a-tooltip>&nbsp;操作</div>, scopedSlots: { customRender: 'action' }, width: '16%', align: 'center' }
       ]
       if (this.$hasPermissions('M_ShowAllCost')) {
         arr.splice(7, 0, { title: '可用库存成本(¥)', dataIndex: 'currentStockCost', width: '8%', align: 'right', sorter: true, customRender: function (text) { return ((text || text == 0) ? _this.toThousands(text) : '--') } })
@@ -289,6 +295,23 @@ export default {
     }
   },
   methods: {
+    // 加入购物车
+    addShopCar (row) {
+      this.spinning = true
+      purchaseCartExistProduct({
+        productSn: row.productSn
+      }).then(res => {
+        if (res.status == 200) {
+          if (res.data) {
+            this.$message.info('此产品已添加到购物车!')
+          } else {
+            this.$refs.setPurchaseQty.setData(row)
+            this.openPurchaseModal = true
+          }
+        }
+        this.spinning = false
+      })
+    },
     // 校验滞销天数数值范围
     checkValueRange () {
       const isONull = this.queryParam.minUnsalableDays === null || this.queryParam.minUnsalableDays === undefined
@@ -349,7 +372,7 @@ export default {
       this.queryParam.productTypeName = undefined
       this.queryParam.zeroQtyFlag = false
       this.queryParam.warehouse = []
-      this.queryParam.warehouseSn =  ''
+      this.queryParam.warehouseSn = ''
       this.queryParam.warehouseLocationSn = ''
       this.$refs.warehouse.setDefaultVal()
       this.productTypeSn = []
@@ -392,7 +415,7 @@ export default {
       // 仓库仓位
       params.warehouseSn = params.warehouse[0]
       params.warehouseLocationSn = params.warehouse[1]
-      
+
       this.exportLoading = true
       _this.spinning = true
       stockExport(params).then(res => {
@@ -451,7 +474,7 @@ export default {
     },
     setTableH () {
       const tableSearchH = this.$refs.tableSearch.offsetHeight
-      this.tableHeight = window.innerHeight - tableSearchH - 230
+      this.tableHeight = window.innerHeight - tableSearchH - 216
     }
   },
   watch: {

+ 137 - 0
src/views/inventoryManagement/inventoryQuery/setPurchaseQty.vue

@@ -0,0 +1,137 @@
+<template>
+  <a-modal
+    centered
+    class="setPurchaseQty-modal"
+    :footer="null"
+    :maskClosable="false"
+    title="设置采购数量"
+    v-model="isShow"
+    @cancel="isShow = false"
+    :width="600">
+    <a-spin :spinning="spinning" tip="Loading...">
+      <a-form-model
+        id="setPurchaseQty-form"
+        ref="ruleForm"
+        :model="form"
+        :rules="rules"
+        :label-col="formItemLayout.labelCol"
+        :wrapper-col="formItemLayout.wrapperCol"
+      >
+        <a-form-model-item label="产品名称:">
+          {{ dateilData&&dateilData.productName }}
+        </a-form-model-item>
+        <a-form-model-item label="产品编码">
+          {{ dateilData&&dateilData.productCode }}
+        </a-form-model-item>
+        <a-form-model-item label="采购数量" prop="qty">
+          <a-input-number
+            id="shelfMonitoringList-maxUnsalableDays"
+            style="width:60%"
+            v-model="form.qty"
+            :precision="0"
+            :min="1"
+            :max="999999"
+            placeholder="采购数量"/>
+        </a-form-model-item>
+      </a-form-model>
+      <div class="btn-cont">
+        <a-button type="primary" id="setPurchaseQty-modal-save" @click="handleSave">保存</a-button>
+        <a-button id="setPurchaseQty-modal-back" @click="isShow = false" style="margin-left: 15px;">取消</a-button>
+      </div>
+    </a-spin>
+  </a-modal>
+</template>
+
+<script>
+import { commonMixin } from '@/utils/mixin'
+import { purchaseCartSave } from '@/api/purchaseCart'
+import { mapActions } from 'vuex'
+export default {
+  name: 'ChainTransferOutBasicInfoModal',
+  mixins: [commonMixin],
+  props: {
+    openModal: {
+      //  弹框显示状态
+      type: Boolean,
+      default: false
+    }
+  },
+  data () {
+    return {
+      spinning: false,
+      isShow: this.openModal, //  是否打开弹框
+      formItemLayout: {
+        labelCol: { span: 4 },
+        wrapperCol: { span: 20 }
+      },
+      form: {
+        qty: 1,
+        productSn: '',
+        productCode: '',
+        sysFlag: ''
+      },
+      rules: {
+        qty: [{ required: true, message: '请输入采购数量', trigger: 'change' }]
+      },
+      dateilData: null
+    }
+  },
+  methods: {
+    ...mapActions(['getCartList']),
+    setData (row) {
+      this.dateilData = row
+      this.form.productSn = row.productSn
+      this.form.productCode = row.productCode
+      this.form.sysFlag = row.dealerProduct.sysFlag
+      this.form.qty = 1
+    },
+    //  保存
+    handleSave () {
+      const _this = this
+      this.$refs.ruleForm.validate(valid => {
+        if (valid) {
+          const form = JSON.parse(JSON.stringify(_this.form))
+          _this.spinning = true
+          purchaseCartSave(form).then(res => {
+            if (res.status == 200) {
+              _this.$message.success(res.message)
+              setTimeout(() => {
+                _this.isShow = false
+                _this.$emit('ok', res.data)
+                _this.getCartList()
+                _this.spinning = false
+              }, 1000)
+            } else {
+              _this.spinning = false
+            }
+          })
+        } else {
+          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">
+.setPurchaseQty-modal {
+	.btn-cont {
+		text-align: center;
+		margin: 35px 0 10px;
+	}
+}
+</style>

+ 42 - 19
src/views/inventoryManagement/inventoryWarning/list.vue

@@ -62,26 +62,26 @@
             </a-col>
           </a-row>
         </a-form>
-      </div>
-      <!-- 操作按钮 -->
-      <div class="table-operator">
-        <a-button type="primary" v-if="$hasPermissions('B_inventoryWarningBatchSave')" id="inventoryWarningList-update" @click="handleupdate">批量更新</a-button>
-        <a-button
-          type="primary"
-          style="margin-left: 5px"
-          class="button-warning"
-          @click="openGuideModal=true"
-          v-if="$hasPermissions('B_inventoryWarningProductImport')"
-          id="inventoryWarningList-import-btn">导入产品</a-button>
-        <span style="margin-left: 5px" v-if="$hasPermissions('B_inventoryWarningBatchSave')">
-          <template v-if="rowSelectionInfo&&rowSelectionInfo.selectedRowKeys.length>0">{{ `已选 ${rowSelectionInfo.selectedRowKeys.length} 项` }}</template>
-        </span>
+        <!-- 操作按钮 -->
+        <div class="table-operator">
+          <a-button type="primary" v-if="$hasPermissions('B_inventoryWarningBatchSave')" id="inventoryWarningList-update" @click="handleupdate">批量更新</a-button>
+          <a-button
+            type="primary"
+            style="margin-left: 5px"
+            class="button-warning"
+            @click="openGuideModal=true"
+            v-if="$hasPermissions('B_inventoryWarningProductImport')"
+            id="inventoryWarningList-import-btn">导入产品</a-button>
+          <span style="margin-left: 5px" v-if="$hasPermissions('B_inventoryWarningBatchSave')">
+            <template v-if="rowSelectionInfo&&rowSelectionInfo.selectedRowKeys.length>0">{{ `已选 ${rowSelectionInfo.selectedRowKeys.length} 项` }}</template>
+          </span>
+        </div>
       </div>
       <!-- 列表 -->
       <s-table
         class="sTable fixPagination"
         ref="table"
-        :style="{ height: tableHeight+84.5+'px' }"
+        :style="{ height: tableHeight+68.5+'px' }"
         size="small"
         :rowKey="(record) => record.id"
         :row-selection="$hasPermissions('B_inventoryWarningBatchSave') ? { columnWidth: 40 } : null"
@@ -160,13 +160,16 @@
             class="button-primary"
             @click="handleSave(record)"
             id="inventoryWarningList-add-btn">保存</a-button>
+          <a-button type="link" v-if="record.dealerProduct.sysFlag==1&&record.dealerProduct.onlineFalg==1&&$hasPermissions('M_shoppingCart')" @click="addShopCar(record)">加入购物车</a-button>
           <span v-if="!$hasPermissions('B_inventoryWarningSave')">--</span>
         </template>
       </s-table>
     </a-spin>
-    
+
     <!-- 导入产品 -->
     <importGuideModal :openModal="openGuideModal" @close="openGuideModal=false" @ok="resetSearchForm" />
+    <!-- 设置采购数量 -->
+    <set-purchase-qty ref="setPurchaseQty" :openModal="openPurchaseModal" @close="openPurchaseModal=false" v-drag></set-purchase-qty>
   </a-card>
 </template>
 
@@ -174,18 +177,21 @@
 import { commonMixin } from '@/utils/mixin'
 import { STable, VSelect } from '@/components'
 import { stockWarnList, stockWarnSaveBatch, stockWarnExport } from '@/api/stockWarn'
+import { purchaseCartExistProduct } from '@/api/purchaseCart'
 import { downloadExcel } from '@/libs/JGPrint.js'
 import ProductType from '../../common/productType.js'
 import ProductBrand from '../../common/productBrand.js'
 import importGuideModal from './importGuideModal.vue'
+import setPurchaseQty from '@/views/inventoryManagement/inventoryQuery/setPurchaseQty.vue'
 export default {
   name: 'InventoryWarningList',
-  components: { STable, VSelect, ProductType, ProductBrand, importGuideModal },
+  components: { STable, VSelect, ProductType, ProductBrand, importGuideModal, setPurchaseQty },
   mixins: [commonMixin],
   data () {
     return {
       spinning: false,
       openGuideModal: false,
+      openPurchaseModal: false,
       advanced: true, // 高级搜索 展开/关闭
       tableHeight: 0,
       queryParam: { //  查询条件
@@ -216,7 +222,7 @@ export default {
         { title: '最小库存数(个)', scopedSlots: { customRender: 'lowerLimit' }, width: 100, align: 'center' },
         { title: '差异数量', dataIndex: 'differenceNum', width: 80, align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
         { title: '预警提示', scopedSlots: { customRender: 'stockState' }, width: 100, align: 'center' },
-        { title: '操作', scopedSlots: { customRender: 'action' }, width: 80, align: 'center', fixed: 'right' }
+        { title: <div><a-tooltip placement='top' title='注意:购物车仅限添加箭冠已上线产品。'><a-icon type="question-circle" /></a-tooltip>&nbsp;操作</div>, scopedSlots: { customRender: 'action' }, width: 160, align: 'center', fixed: 'right' }
       ],
       // 加载数据方法 必须为 Promise 对象
       loadData: parameter => {
@@ -249,6 +255,23 @@ export default {
     }
   },
   methods: {
+    // 加入购物车
+    addShopCar (row) {
+      this.spinning = true
+      purchaseCartExistProduct({
+        productSn: row.productSn
+      }).then(res => {
+        if (res.status == 200) {
+          if (res.data) {
+            this.$message.info('此产品已添加到购物车!')
+          } else {
+            this.$refs.setPurchaseQty.setData(row)
+            this.openPurchaseModal = true
+          }
+        }
+        this.spinning = false
+      })
+    },
     // 表格选中项
     rowSelectionFun (obj) {
       this.rowSelectionInfo = obj || null
@@ -372,7 +395,7 @@ export default {
     },
     setTableH () {
       const tableSearchH = this.$refs.tableSearch.offsetHeight
-      this.tableHeight = window.innerHeight - tableSearchH - 235
+      this.tableHeight = window.innerHeight - tableSearchH - 190
     }
   },
   watch: {

+ 4 - 4
src/views/numsGoodsShelves/shelfSet/chooseShelfImportModal.vue

@@ -96,8 +96,8 @@ export default {
         { title: '货位号', dataIndex: 'shelfPlaceCode', width: '8%', align: 'center', customRender: function (text) { return text || '--' } },
         { title: '产品编码', dataIndex: 'productCode', width: '15%', align: 'center', customRender: function (text) { return text || '--' } },
         { title: '产品名称', dataIndex: 'productName', width: '45%', align: 'center', customRender: function (text) { return text || '--' } },
-        { title: '销售价', dataIndex: 'price', width: '8%', align: 'right', customRender: function (text) { return ((text || text == 0) ? _this.toThousands(text, 2) : '--') } },
-        { title: '结算价', dataIndex: 'cost', width: '8%', align: 'right', customRender: function (text) { return ((text || text == 0) ? _this.toThousands(text, 2) : '--') } },
+        { title: '销售价', dataIndex: 'price', width: '8%', align: 'right', customRender: function (text) { return ((text || text == 0)&&text.length ? _this.toThousands(text, 2) : '--') } },
+        { title: '结算价', dataIndex: 'cost', width: '8%', align: 'right', customRender: function (text) { return ((text || text == 0)&&text.length ? _this.toThousands(text, 2) : '--') } },
         { title: '最大库容', dataIndex: 'maxQty', width: '8%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } }
       ],
       loadData: [],
@@ -106,8 +106,8 @@ export default {
         { title: '货位号', dataIndex: 'shelfPlaceCode', width: '8%', align: 'center', customRender: function (text) { return text || '--' } },
         { title: '产品编码', dataIndex: 'productCode', width: '15%', align: 'center', customRender: function (text) { return text || '--' } },
         { title: '产品名称', dataIndex: 'productName', width: '30%', align: 'center', customRender: function (text) { return text || '--' } },
-        { title: '销售价', dataIndex: 'price', width: '8%', align: 'right', customRender: function (text) { return ((text || text == 0) ? _this.toThousands(text, 2) : '--') } },
-        { title: '结算价', dataIndex: 'cost', width: '8%', align: 'right', customRender: function (text) { return ((text || text == 0) ? _this.toThousands(text, 2) : '--') } },
+        { title: '销售价', dataIndex: 'price', width: '8%', align: 'right', customRender: function (text) { return ((text || text == 0)&&text.length ? _this.toThousands(text, 2) : '--') } },
+        { title: '结算价', dataIndex: 'cost', width: '8%', align: 'right', customRender: function (text) { return ((text || text == 0)&&text.length ? _this.toThousands(text, 2) : '--') } },
         { title: '最大库容', dataIndex: 'maxQty', width: '8%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
         { title: '错误原因', dataIndex: 'remarks', width: '15%', align: 'center', customRender: function (text) { return text || '--' } }
       ],

+ 2 - 2
src/views/numsGoodsShelves/shelfSet/importHuoweiModal.vue

@@ -26,7 +26,7 @@
           <ul>
             <li>1) 导入的Excel文件中必须包含名为“货位号”、“产品编码”、“销售价”、“结算价”、“最大库容”的列,且名称必须相同,其他列可自定义,不影响数据导入。</li>
             <li>2) 如果“产品编码”列为空,则表示此货位暂时不绑定产品,也可以正常导入货位。</li>
-            <li>3) 当“销售价”和“结算价”都为空,系统会自动取该产品的车主价和终端会员价,作为销售价和结算价。</li>
+            <li>3) 当“销售价”和“结算价”都为空,系统会自动获取销售价和结算价,规则如下:历史销售价>自定义车主价和自定义终端价>车主价和终端价。</li>
             <li>4) 如果货位已经绑定产品,则不会导入该行。</li>
           </ul>
 
@@ -92,7 +92,7 @@ export default {
     return {
       isShow: this.openModal, //  是否打开弹框
       openImportModal: false, //  导入
-      filePath: location.protocol + '//' +location.host + '/templ/货位导入模板.xlsx',
+      filePath: location.protocol + '//' + location.host + '/templ/货位导入模板.xlsx',
       attachAction: process.env.VUE_APP_API_BASE_URL + '/upload',
       paramsData: null,
       uploadParams: {

+ 22 - 3
src/views/productManagement/newProduct/detail.vue

@@ -14,6 +14,10 @@
       <h4>{{ (detailsData && detailsData.name) || '--' }}</h4>
       <div class="productHead">
         <div class="productInfo">
+          <!--
+          ***省级经销商:市场价、特约价1显示 0不显示
+          ***市级经销商:特约价1显示 0不显示
+          -->
           <a-descriptions bordered :column="2" size="small">
             <a-descriptions-item label="产品品牌:">{{ (detailsData && detailsData.productBrandName) || '--' }}</a-descriptions-item>
             <a-descriptions-item label="产品编码:">{{ (detailsData && detailsData.code) || '--' }}</a-descriptions-item>
@@ -21,6 +25,10 @@
             <a-descriptions-item label="商品尺寸:">{{ (detailsData && detailsData.size) || '--' }}</a-descriptions-item>
             <a-descriptions-item label="重量:">{{ (detailsData && detailsData.weight) || '--' }}</a-descriptions-item>
             <a-descriptions-item label="计量单位:">{{ (detailsData && detailsData.unit) || '--' }}</a-descriptions-item>
+            <a-descriptions-item label="市级价:" v-if="this.specialPriceObj.dealerLevel&&this.specialPriceObj.dealerLevel == 'PROVINCE'">{{ detailsData&&(detailsData.cityPrice||detailsData.cityPrice==0) ? toThousands(detailsData.cityPrice):'--' }}</a-descriptions-item>
+            <a-descriptions-item label="特约价:" v-if="(this.specialPriceObj.isShowSpecialPrice&&this.specialPriceObj.isShowSpecialPrice != 0)">{{ detailsData && (detailsData.specialPrice||detailsData.specialPrice==0)?toThousands(detailsData.specialPrice) : '--' }}</a-descriptions-item>
+            <a-descriptions-item label="终端价:">{{ detailsData && (detailsData.terminalPrice || detailsData.terminalPrice==0)?toThousands(detailsData.terminalPrice):'--' }}</a-descriptions-item>
+            <a-descriptions-item label="车主价:">{{ detailsData && (detailsData.carOwnersPrice || detailsData.carOwnersPrice==0)?toThousands(detailsData.carOwnersPrice):'--' }}</a-descriptions-item>
           </a-descriptions>
           <div class="productDetail">
             <h4>产品介绍</h4>
@@ -29,7 +37,7 @@
               <span v-else>暂无产品介绍</span>
             </div>
           </div>
-        </div>
+          </a-descriptions></div>
         <div class="productImg" v-if="detailsData && detailsData.productPicList && detailsData.productPicList.length>0">
           <a-carousel arrows dots-class="slick-dots slick-thumb">
             <a slot="customPaging" slot-scope="props">
@@ -50,7 +58,7 @@
 <script>
 import { commonMixin } from '@/utils/mixin'
 import imgZoom from 'vue2.0-zoom'
-import { productDetail } from '@/api/product.js'
+import { productDetail, getCurrentDealer } from '@/api/product.js'
 export default {
   name: 'ProductInfoDetail',
   components: { imgZoom },
@@ -75,7 +83,8 @@ export default {
         maskHeight: 80,
         maskColor: 'red',
         maskOpacity: 0.2
-      }
+      },
+      specialPriceObj: {}
     }
   },
   methods: {
@@ -90,6 +99,14 @@ export default {
         }
       })
     },
+    // 获取特约价
+    getSpecialPriceInfo () {
+      getCurrentDealer().then(res => {
+        if (res.status == 200) {
+          this.specialPriceObj = res.data
+        }
+      })
+    },
     // 返回
     goBack () {
       this.$router.push({ path: this.prevPageInfo && this.prevPageInfo.path })
@@ -99,11 +116,13 @@ export default {
     if (!this.$store.state.app.isNewTab) { // 页签刷新时调用
       this.itemId = this.$route.params.sn
       this.getDetail()
+      this.getSpecialPriceInfo()
     }
   },
   activated () {
     this.itemId = this.$route.params.sn
     this.getDetail()
+    this.getSpecialPriceInfo()
   },
   beforeRouteEnter (to, from, next) {
     next(vm => {

+ 161 - 0
src/views/productManagement/productInfoJg/editPriceModal.vue

@@ -0,0 +1,161 @@
+<template>
+  <a-modal
+    centered
+    class="editPrice-modal"
+    :footer="null"
+    :maskClosable="false"
+    title="自定义报价"
+    v-model="isShow"
+    @cancel="isShow = false"
+    :width="800">
+    <a-spin :spinning="spinning" tip="Loading...">
+      <a-form-model
+        id="editPrice-form"
+        ref="ruleForm"
+        :model="form"
+        :label-col="formItemLayout.labelCol"
+        :wrapper-col="formItemLayout.wrapperCol">
+        <a-form-model-item label="产品编码" prop="code">
+          <div>{{ form.code }}</div>
+        </a-form-model-item>
+        <a-form-model-item label="产品名称" prop="name">
+          <div>{{ form.name }}</div>
+        </a-form-model-item>
+        <a-form-model-item label="终端价" prop="terminalPrice">
+          <div>{{ form.terminalPrice?form.terminalPrice : '--' }}</div>
+        </a-form-model-item>
+        <a-form-model-item label="自定义终端价" prop="dealerProductPrice.terminalPrice">
+          <a-input-number
+            :min="0.01"
+            :max="999999"
+            :precision="2"
+            v-model.trim="form.dealerProductPrice.terminalPrice"
+            style="width: 90%;margin-right: 5px;"
+            placeholder="请输入自定义终端价"
+            allowClear /><span>元</span>
+        </a-form-model-item>
+        <a-form-model-item label="车主价" prop="carOwnersPrice">
+          <div>{{ form.carOwnersPrice?form.carOwnersPrice:'--' }}</div>
+        </a-form-model-item>
+        <a-form-model-item label="自定义车主价" prop="dealerProductPrice.carOwnersPrice">
+          <a-input-number
+            :min="0.01"
+            :max="999999"
+            :precision="2"
+            v-model.trim="form.dealerProductPrice.carOwnersPrice"
+            placeholder="请输入自定义车主价"
+            style="width: 90%;margin-right: 5px;"
+            allowClear /><span>元</span>
+        </a-form-model-item>
+      </a-form-model>
+      <div class="btn-cont">
+        <a-button type="primary" size="large" id="editPrice-btn-submit" @click="handleSubmit">保存</a-button>
+        <a-button id="editPrice-btn-back" size="large" @click="isShow = false" style="margin-left: 15px;">取消</a-button>
+      </div>
+    </a-spin>
+  </a-modal>
+</template>
+
+<script>
+import { commonMixin } from '@/utils/mixin'
+import { productDetail, settingPrice } from '@/api/product.js'
+export default {
+  name: 'EditPriceModal',
+  mixins: [commonMixin],
+  props: {
+    openModal: {
+      //  弹框显示状态
+      type: Boolean,
+      default: false
+    },
+    itemId: {
+      type: [Number, String],
+      default: ''
+    }
+  },
+  data () {
+    return {
+      spinning: false,
+      isShow: this.openModal, //  是否打开弹框
+      formItemLayout: {
+        labelCol: { span: 6 },
+        wrapperCol: { span: 16 }
+      },
+      form: {
+        code: '',
+        name: '',
+        terminalPrice: '', // 终端建议价
+        carOwnersPrice: '', //  车主建议价
+        dealerProductPrice: {
+          terminalPrice: '',
+          carOwnersPrice: ''
+        }
+      }
+    }
+  },
+  methods: {
+    // 详情
+    getDetail () {
+      const _this = this
+      productDetail({ sn: this.itemId }).then(res => {
+        if (res.status == 200) {
+          const objInfo = {}
+          objInfo.code = res.data.code
+          objInfo.name = res.data.name
+          objInfo.terminalPrice = (res.data.terminalPrice || res.data.terminalPrice == 0) ? _this.toThousands(res.data.terminalPrice) : ''
+          objInfo.carOwnersPrice = (res.data.carOwnersPrice || res.data.carOwnersPrice == 0) ? _this.toThousands(res.data.carOwnersPrice) : ''
+          objInfo.dealerProductPrice = {}
+          Object.assign(objInfo.dealerProductPrice, { terminalPrice: res.data.dealerProductPrice && (res.data.dealerProductPrice.terminalPrice || res.data.dealerProductPrice.terminalPrice == 0) ? res.data.dealerProductPrice.terminalPrice : '', carOwnersPrice: res.data.dealerProductPrice && (res.data.dealerProductPrice.carOwnersPrice || res.data.dealerProductPrice.carOwnersPrice == 0) ? res.data.dealerProductPrice.carOwnersPrice : '' })
+          _this.form = objInfo
+        }
+      })
+    },
+    //  保存
+    handleSubmit (e) {
+      e.preventDefault()
+      const _this = this
+      _this.spinning = true
+      const ajaxData = {}
+      ajaxData.productSn = this.itemId
+      ajaxData.dealerProductPrice = {}
+      Object.assign(ajaxData.dealerProductPrice, _this.form.dealerProductPrice)
+      settingPrice(ajaxData).then(res => {
+        if (res.status == 200) {
+          _this.$message.success(res.message)
+          _this.$emit('ok')
+          _this.isShow = false
+          _this.spinning = false
+        } else {
+          _this.spinning = false
+        }
+      })
+    }
+  },
+  watch: {
+    //  父页面传过来的弹框状态
+    openModal (newValue, oldValue) {
+      this.isShow = newValue
+    },
+    //  重定义的弹框状态
+    isShow (newValue, oldValue) {
+      if (!newValue) {
+        this.$emit('close')
+      } else {
+        this.getDetail()
+      }
+    }
+  }
+}
+</script>
+
+<style lang="less">
+.editPrice-modal {
+  .ant-modal-body {
+    padding: 40px 40px 24px;
+  }
+  .btn-cont {
+    text-align: center;
+    margin: 35px 0 10px;
+  }
+}
+</style>

+ 148 - 50
src/views/productManagement/productInfoJg/list.vue

@@ -50,14 +50,59 @@
     </div>
     <!-- 操作按钮 -->
     <div class="table-operator" v-if="$hasPermissions('B_JgProduct_enable')">
-      <a-dropdown>
-        <a-menu slot="overlay" @click="handleMenuClick">
-          <a-menu-item key="1"> 批量启用</a-menu-item>
-          <a-menu-item key="2"> 批量禁用</a-menu-item>
-        </a-menu>
-        <a-button ghost type="danger"> 批量操作 <a-icon type="down" /> </a-button>
-      </a-dropdown>
-      <span v-if="rowSelectionInfo&&rowSelectionInfo.selectedRowKeys">已选 {{ rowSelectionInfo.selectedRowKeys.length }} 项</span>
+      <a-row :gutter="16">
+        <a-col class="gutter-row" :span="12">
+          <a-dropdown>
+            <a-menu slot="overlay" @click="handleMenuClick">
+              <a-menu-item key="1"> 批量启用</a-menu-item>
+              <a-menu-item key="2"> 批量禁用</a-menu-item>
+            </a-menu>
+            <a-button ghost type="danger"> 批量操作 <a-icon type="down" /> </a-button>
+          </a-dropdown>
+          <span v-if="rowSelectionInfo&&rowSelectionInfo.selectedRowKeys">已选 {{ rowSelectionInfo.selectedRowKeys.length }} 项</span>
+        </a-col>
+        <a-col class="gutter-row" :span="12">
+          <div class="setTableList">
+            <a-checkbox v-model="isTerminalPrice">
+              自定义终端价
+            </a-checkbox>
+            <a-checkbox v-model="isCarOwnersPrice">
+              自定义车主价
+            </a-checkbox>
+          </div>
+          <!-- <div class="setTableList">
+            <span @click="iconShowFlag=!iconShowFlag">列表显示配置</span>
+            <a-icon :type="iconShowFlag?'up':'down'" :style="{ color: '#d5d5d5' }" @click="iconShowFlag=!iconShowFlag"/>
+            <div class="setTableList-box" v-show="iconShowFlag">
+              <a-checkbox-group @change="onChangeList" :value="chooseShowList">
+                <div>
+                  <a-checkbox value="A">
+                    省级价
+                  </a-checkbox>
+                </div>
+                <div><a-checkbox value="B">
+                  市级建议价
+                </a-checkbox></div>
+                <div><a-checkbox value="C">
+                  特约建议价
+                </a-checkbox></div>
+                <div><a-checkbox value="D">
+                  建议终端价
+                </a-checkbox></div>
+                <div> <a-checkbox value="E">
+                  建议车主价
+                </a-checkbox></div>
+                <div> <a-checkbox value="F">
+                  自定义终端价
+                </a-checkbox></div>
+                <div><a-checkbox value="G">
+                  自定义车主价
+                </a-checkbox></div>
+              </a-checkbox-group>
+            </div>
+          </div> -->
+        </a-col>
+      </a-row>
     </div>
     <!-- 列表 -->
     <s-table
@@ -65,7 +110,7 @@
       ref="table"
       :style="{ height: tableHeight+84.5+'px' }"
       size="small"
-      :row-selection="$hasPermissions('B_JgProduct_enable')?rowSelection:null"
+      :row-selection="$hasPermissions('B_JgProduct_enable')?{columnWidth: '3%', getCheckboxProps: record => ({props: {disabled: record.enabledFlag == undefined}})}:null"
       @rowSelection="rowSelectionFun"
       rowKeyName="productSn"
       :rowKey="(record) => record.productSn"
@@ -107,8 +152,16 @@
           class="button-success"
           @click="handleDetail(record)"
           id="productInfoList-detail-btn">详情</a-button>
+        <a-button
+          size="small"
+          type="link"
+          class="button-primary"
+          @click="handleEditPrice(record)"
+          id="productInfoList-price-btn">自定义报价</a-button>
       </template>
     </s-table>
+    <!-- 自定义报价弹窗 -->
+    <editPriceModal :openModal="openEditPriceModal" :itemId="itemId" @ok="searchForm" @close="openEditPriceModal=false"></editPriceModal>
   </a-card>
 </template>
 
@@ -119,9 +172,10 @@ import ProductType from '../../common/productType.js'
 import ProductBrand from '../../common/productBrand.js'
 import { STable, VSelect } from '@/components'
 // import { downloadExcel } from '@/libs/JGPrint.js'
+import editPriceModal from './editPriceModal.vue'
 export default {
   name: 'ProductJgList',
-  components: { STable, VSelect, ProductType, ProductBrand },
+  components: { STable, VSelect, ProductType, ProductBrand, editPriceModal },
   mixins: [commonMixin],
   data () {
     return {
@@ -140,10 +194,13 @@ export default {
         onlineFalg: '',
         enabledFlag: '1'
       },
+      isTerminalPrice: false,
+      isCarOwnersPrice: false,
+      openEditPriceModal: false, // 自定义报价弹窗
+      iconShowFlag: false, // 列表配置图标显示
       disabled: false, //  查询、重置按钮是否可操作
       exportLoading: false, // 导出loading
       dateFormat: 'YYYY-MM-DD',
-      columns: [],
       // 加载数据方法 必须为 Promise 对象
       loadData: parameter => {
         this.disabled = true
@@ -165,18 +222,50 @@ export default {
       openModal: false, //  查看客户详情  弹框
       itemId: '', //  当前产品id
       productTypeList: [], //  分类下拉数据
-      rowSelectionInfo: null
+      rowSelectionInfo: null,
+      currentDealerInfo: {}
     }
   },
   computed: {
-    rowSelection () {
-      return {
-        getCheckboxProps: record => ({
-          props: {
-            disabled: record.enabledFlag == undefined // Column configuration not to be checked
-          }
-        })
+    columns () {
+      const _this = this
+      let arr = [
+        { title: '序号', dataIndex: 'no', width: '4%', align: 'center' },
+        { title: '产品编码', dataIndex: 'code', width: '12%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '产品名称', dataIndex: 'name', width: '16%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '原厂编码', dataIndex: 'origCode', width: '12%', align: 'center', customRender: function (text) { return (!text || text == ' ') ? '--' : text } }
+      ]
+      const cArr = [
+        { title: '终端价', dataIndex: 'terminalPrice', width: '8%', align: 'right', customRender: function (text) { return ((text || text == 0) ? _this.toThousands(text) : '--') } },
+        { title: '车主价', dataIndex: 'carOwnersPrice', width: '8%', align: 'right', customRender: function (text) { return ((text || text == 0) ? _this.toThousands(text) : '--') } },
+        // { title: '自定义终端价', dataIndex: 'price1', width: '8%', align: 'right', customRender: function (text) { return ((text || text == 0) ? _this.toThousands(text) : '--') } },
+        // { title: '自定义车主价', dataIndex: 'price2', width: '8%', align: 'right', customRender: function (text) { return ((text || text == 0) ? _this.toThousands(text) : '--') } },
+        { title: '状态', scopedSlots: { customRender: 'enabledFlag' }, width: '7%', align: 'center' },
+        { title: '产品图片', scopedSlots: { customRender: 'imageUrl' }, width: '6%', align: 'center' },
+        { title: '操作', scopedSlots: { customRender: 'action' }, width: '12%', align: 'center' }
+      ]
+      if (_this.currentDealerInfo.dealerLevel && _this.currentDealerInfo.dealerLevel == 'PROVINCE') { //  省级
+        arr.push(
+          { title: '省级价', dataIndex: 'provincePrice', width: '6%', align: 'right', customRender: function (text) { return ((text || text == 0) ? _this.toThousands(text) : '--') } },
+          { title: '市级价', dataIndex: 'cityPrice', width: '6%', align: 'right', customRender: function (text) { return ((text || text == 0) ? _this.toThousands(text) : '--') } }
+        )
+      } else if (_this.currentDealerInfo.dealerLevel && _this.currentDealerInfo.dealerLevel == 'CITY') { //  市级
+        arr.push(
+          { title: '市级价', dataIndex: 'cityPrice', width: '6%', align: 'right', customRender: function (text) { return ((text || text == 0) ? _this.toThousands(text) : '--') } }
+        )
+      }
+      if (_this.currentDealerInfo.isShowSpecialPrice && _this.currentDealerInfo.isShowSpecialPrice == '1') { //  是否展示特约价
+        arr.push({ title: '特约价', dataIndex: 'specialPrice', width: '6%', align: 'right', customRender: function (text) { return ((text || text == 0) ? _this.toThousands(text) : '--') } })
       }
+      if (_this.isTerminalPrice) {
+        cArr.splice(1, 0, { title: '自定义终端价', dataIndex: 'dealerProductPrice.terminalPrice', width: '8%', align: 'right', customRender: function (text) { return ((text || text == 0) ? _this.toThousands(text) : '--') } })
+      }
+      if (_this.isCarOwnersPrice) {
+        const pos = _this.isTerminalPrice ? 3 : 2
+        cArr.splice(pos, 0, { title: '自定义车主价', dataIndex: 'dealerProductPrice.carOwnersPrice', width: '8%', align: 'right', customRender: function (text) { return ((text || text == 0) ? _this.toThousands(text) : '--') } })
+      }
+      arr = [...arr, ...cArr]
+      return arr
     }
   },
   methods: {
@@ -216,38 +305,11 @@ export default {
       this.rowSelectionInfo = null
       this.$refs.table.clearSelected()
     },
-    // 设置表头
-    getColumns () {
-      const _this = this
-      this.columns = [
-        { title: '序号', dataIndex: 'no', width: '4%', align: 'center' },
-        { title: '产品编码', dataIndex: 'code', width: '18%', align: 'center', customRender: function (text) { return text || '--' } },
-        { title: '产品名称', dataIndex: 'name', width: '18%', align: 'center', customRender: function (text) { return text || '--' } },
-        { title: '原厂编码', dataIndex: 'origCode', width: '17%', align: 'center', customRender: function (text) { return (!text || text == ' ') ? '--' : text } }
-      ]
-      const cArr = [
-        { title: '终端价', dataIndex: 'terminalPrice', width: '6%', align: 'right', customRender: function (text) { return ((text || text == 0) ? _this.toThousands(text) : '--') } },
-        { title: '车主价', dataIndex: 'carOwnersPrice', width: '6%', align: 'right', customRender: function (text) { return ((text || text == 0) ? _this.toThousands(text) : '--') } },
-        { title: '状态', scopedSlots: { customRender: 'enabledFlag' }, width: '7%', align: 'center' },
-        { title: '产品图片', scopedSlots: { customRender: 'imageUrl' }, width: '6%', align: 'center' },
-        { title: '操作', scopedSlots: { customRender: 'action' }, width: '7%', align: 'center' }
-      ]
+    // 获取省级经销商、市级经销商和特约经销商信息
+    getCurrentDealerInfo () {
       getCurrentDealer().then(res => {
         if (res.status == 200) {
-          if (res.data.dealerLevel && res.data.dealerLevel == 'PROVINCE') { //  省级
-            this.columns.push(
-              { title: '省级价', dataIndex: 'provincePrice', width: '6%', align: 'right', customRender: function (text) { return ((text || text == 0) ? _this.toThousands(text) : '--') } },
-              { title: '市级价', dataIndex: 'cityPrice', width: '6%', align: 'right', customRender: function (text) { return ((text || text == 0) ? _this.toThousands(text) : '--') } }
-            )
-          } else if (res.data.dealerLevel && res.data.dealerLevel == 'CITY') { //  市级
-            this.columns.push(
-              { title: '市级价', dataIndex: 'cityPrice', width: '6%', align: 'right', customRender: function (text) { return ((text || text == 0) ? _this.toThousands(text) : '--') } }
-            )
-          }
-          if (res.data.isShowSpecialPrice && res.data.isShowSpecialPrice == '1') { //  是否展示特约价
-            this.columns.push({ title: '特约价', dataIndex: 'specialPrice', width: '6%', align: 'right', customRender: function (text) { return ((text || text == 0) ? _this.toThousands(text) : '--') } })
-          }
-          this.columns = [...this.columns, ...cArr]
+          this.currentDealerInfo = res.data
         }
       })
     },
@@ -321,11 +383,19 @@ export default {
       this.$nextTick(() => { // 页面渲染完成后的回调
         _this.setTableH()
       })
-      this.getColumns()
+      this.getCurrentDealerInfo()
     },
     setTableH () {
       const tableSearchH = this.$refs.tableSearch.offsetHeight
       this.tableHeight = window.innerHeight - tableSearchH - 235
+    },
+    // 打开自定义报价弹窗
+    handleEditPrice (row) {
+      this.itemId = row.productSn
+      const _this = this
+      this.$nextTick(() => {
+        _this.openEditPriceModal = true
+      })
     }
   },
   watch: {
@@ -338,6 +408,7 @@ export default {
     '$store.state.app.winHeight' (newValue, oldValue) { //  窗口变更时,需同时更改表格高度
       this.setTableH()
     }
+
   },
   mounted () {
     if (!this.$store.state.app.isNewTab) { // 页签刷新时调用
@@ -357,3 +428,30 @@ export default {
   }
 }
 </script>
+<style lang="less" scoped>
+.setTableList{
+  text-align: right;
+  // position: relative;
+  span{
+    margin-right: 10px;
+    color:#56a2fb;
+  }
+  .setTableList-box{
+    padding:10px 12px;
+    border:1px solid #d5d5d5;
+    border-radius: 5px;
+    background:#fff;
+    text-align: left;
+    position: absolute;
+    top:22px;
+    right:0;
+    z-index: 99999;
+    div{
+      margin-bottom: 10px;
+      &:last-child{
+        margin-bottom: 0px;
+      }
+    }
+  }
+}
+</style>

+ 1 - 1
src/views/purchasingManagement/purchaseOrder/basicInfoModal.vue

@@ -54,7 +54,7 @@
 <script>
 import { commonMixin } from '@/utils/mixin'
 import { VSelect } from '@/components'
-import chooseAddressModal from './receivingAddress/chooseAddressModal.vue'
+import chooseAddressModal from '@/views/common/receivingAddress/chooseAddressModal.vue'
 import { shippingAddressQuery } from '@/api/shippingAddress'
 import { purchaseSave, purchaseTargetList } from '@/api/purchase'
 export default {

+ 2 - 2
src/views/purchasingManagement/purchaseOrder/chooseImportModal.vue

@@ -98,14 +98,14 @@ export default {
         { title: '产品编码', dataIndex: 'productCode', width: '27%', align: 'center', customRender: function (text) { return text || '--' } },
         { title: '产品名称', dataIndex: 'productName', width: '28%', align: 'center', customRender: function (text) { return text || '--' } },
         { title: '数量', dataIndex: 'qtyText', width: '15%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
-        { title: '单位', dataIndex: 'productUnit', width: '15%', align: 'center', customRender: function (text) { return text || '--' } }
+        { title: '单位', dataIndex: 'dealerProductEntity.unit', width: '15%', align: 'center', customRender: function (text) { return text || '--' } }
       ],
       nowUnColumns: [ //  促销品
         { title: '序号', dataIndex: 'no', width: '13%', align: 'center' },
         { title: '产品编码', dataIndex: 'productCode', width: '26%', align: 'center', customRender: function (text) { return text || '--' } },
         { title: '产品名称', dataIndex: 'productName', width: '26%', align: 'center', customRender: function (text) { return text || '--' } },
         { title: '数量', dataIndex: 'qtyText', width: '15%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
-        { title: '单位', dataIndex: 'productUnit', width: '15%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '单位', dataIndex: 'dealerProductEntity.unit', width: '15%', align: 'center', customRender: function (text) { return text || '--' } },
         { title: '备注', dataIndex: 'errorDesc', width: '30%', align: 'center', customRender: function (text) { return text || '--' } }
       ],
       loadData: [],

+ 4 - 4
src/views/purchasingManagement/purchaseOrder/edit.vue

@@ -23,7 +23,7 @@
             <template slot="header">
               基础信息
             </template>
-            <a-row :gutter="16" type="flex" sjustify="center">
+            <a-row :gutter="16" type="flex" align="middle" sjustify="center">
               <a-col class="gutter-row" :span="12">
                 供应商:{{ detail&&detail.purchaseTargetName || '--' }}
               </a-col>
@@ -35,7 +35,7 @@
               </a-col>
               <a-col class="gutter-row" :span="12">
                 <span>收货地址:</span>
-                <div style="display: inline-block;width:90%;vertical-align: top;" v-if="detail&&(detail.shippingAddressProvinceName || detail.shippingAddressCityName || detail.shippingAddressCountyName || detail.shippingAddress)">
+                <div style="display: inline-block;width:90%;vertical-align: middle;" v-if="detail&&(detail.shippingAddressProvinceName || detail.shippingAddressCityName || detail.shippingAddressCountyName || detail.shippingAddress)">
                   {{ detail&&detail.shippingAddressProvinceName || '' }}
                   {{ detail&&detail.shippingAddressCityName || '' }}
                   {{ detail&&detail.shippingAddressCountyName || '' }}
@@ -125,7 +125,7 @@
                 </template>
                 <!-- 包装数 -->
                 <template slot="baozh" slot-scope="text, record">
-                  {{ record.packQty||'--' }}/{{ record.packQtyUnit||'--' }}
+                  {{ record.packQty||'--' }}{{ record.packQty ? record.unit : '' }}/{{ record.packQtyUnit||'--' }}
                 </template>
                 <!-- 产品编码 -->
                 <template slot="code" slot-scope="text, record">
@@ -276,7 +276,7 @@ import { commonMixin } from '@/utils/mixin'
 import { STable, VSelect } from '@/components'
 import ImportGuideModal from './importGuideModal.vue'
 import outStockModal from './outStockModal.vue'
-import chooseAddressModal from './receivingAddress/chooseAddressModal.vue'
+import chooseAddressModal from '@/views/common/receivingAddress/chooseAddressModal.vue'
 import ProductType from '../../common/productType.js'
 import ProductBrand from '../../common/productBrand.js'
 import { purchaseDetailBySn, purchaseWriteSubmit, purchaseDetailPrint, purchaseDetailExport, purchaseDetailAddress } from '@/api/purchase'

+ 9 - 16
src/views/purchasingManagement/purchaseOrder/list.vue

@@ -134,13 +134,6 @@
             v-if="(record.billStatus == 'WAIT_SUBMIT'||record.billStatus == 'AUDIT_REJECT') && $hasPermissions('B_purchaseEdit')"
             @click="handleEdit(record)"
           >编辑</a-button>
-          <!-- <a-button
-            size="small"
-            type="link"
-            class="button-warning"
-            v-if="record.billStatus == 'WAIT_PUT_WAREHOUSE'&&$hasPermissions('B_purchaseReceiving')"
-            @click="handleWarehouse(record)"
-          >签收入库</a-button> -->
           <a-button
             size="small"
             type="link"
@@ -171,7 +164,7 @@ export default {
   components: { STable, VSelect, basicInfoModal, rangeDate, stateIcon },
   mixins: [commonMixin],
   data () {
-    let _this=this
+    const _this = this
     return {
       spinning: false,
       advanced: true, //  高级搜索 展开/关闭
@@ -208,9 +201,9 @@ export default {
         { title: '供应商', dataIndex: 'purchaseTargetName', width: '10%', align: 'center', customRender: function (text) { return text || '--' }, ellipsis: true },
         { title: '产品款数', dataIndex: 'totalCategory', width: '6%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
         { title: '采购数量', dataIndex: 'totalQty', width: '6%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
-        { title: '采购金额', dataIndex: 'discountedAmount', width: '6%', align: 'right', customRender: function (text) { return ((text || text == 0) ? _this.toThousands(text,2) : '--') } },
+        { title: '采购金额', dataIndex: 'discountedAmount', width: '6%', align: 'right', customRender: function (text) { return ((text || text == 0) ? _this.toThousands(text, 2) : '--') } },
         { title: '审核数量', dataIndex: 'totalPushedQty', width: '6%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
-        { title: '审核金额', dataIndex: 'totalPushedAmount', width: '6%', align: 'right', customRender: function (text) { return ((text || text == 0) ? _this.toThousands(text,2)  : '--') } },
+        { title: '审核金额', dataIndex: 'totalPushedAmount', width: '6%', align: 'right', customRender: function (text) { return ((text || text == 0) ? _this.toThousands(text, 2) : '--') } },
         { title: '已取消数量', dataIndex: 'totalCancelQty', width: '7%', align: 'center', customRender: function (text) { return text || '--' } },
         { title: '采购状态', dataIndex: 'billStatusDictValue', width: '6%', align: 'center', customRender: function (text) { return text || '--' } },
         { title: '审核', scopedSlots: { customRender: 'audit' }, width: '3%', align: 'center' },
@@ -223,9 +216,13 @@ export default {
       loadData: parameter => {
         this.disabled = true
         this.spinning = true
+        const params = Object.assign(parameter, this.queryParam)
+        if (!params.billStatus) {
+          params.billStatus = undefined
+        }
         // 获取统计数据
-        this.getTotalData(Object.assign(parameter, this.queryParam))
-        return purchaseList(Object.assign(parameter, this.queryParam)).then(res => {
+        this.getTotalData(params)
+        return purchaseList(params).then(res => {
           let data
           if (res.status == 200) {
             data = res.data
@@ -278,10 +275,6 @@ export default {
     handleDetail (row) {
       this.$router.push({ name: `purchaseOrderDetail`, params: { sn: row.purchaseBillSn } })
     },
-    //  签收入库
-    handleWarehouse (row) {
-      this.$router.push({ name: `purchaseOrderWarehousing`, params: { sn: row.purchaseBillSn } })
-    },
     //  删除
     handleDel (row) {
       const _this = this

+ 77 - 7
src/views/purchasingManagement/purchaseOrder/outStockModal.vue

@@ -4,14 +4,45 @@
     class="outStock-modal"
     :footer="null"
     :maskClosable="false"
-    title="上次采购缺货产品明细"
+    :title="title"
     v-model="isShow"
     @cancel="isShow=false"
     :width="800">
     <a-spin :spinning="spinning" tip="Loading...">
       <div class="outStock-con">
         <div>
-          <p style="font-weight: bold;">当前已选:{{ rowSelectionInfo&&rowSelectionInfo.selectedRowKeys.length }}个</p>
+          <div ref="tableSearch" class="table-page-search-wrapper">
+            <a-form layout="inline" @keyup.enter.native="searchForm">
+              <a-row :gutter="15">
+                <a-col :md="8" :sm="24">
+                  <a-form-item label="产品编码">
+                    <a-input id="productInfoList-code" v-model.trim="queryParam.dealerProductEntity.code" allowClear placeholder="请输入产品编码"/>
+                  </a-form-item>
+                </a-col>
+                <a-col :md="8" :sm="24">
+                  <a-form-item label="产品名称">
+                    <a-input id="productInfoList-name" v-model.trim="queryParam.dealerProductEntity.name" allowClear placeholder="请输入产品名称"/>
+                  </a-form-item>
+                </a-col>
+                <a-col :md="8" :sm="24">
+                  <a-form-item label="产品分类">
+                    <ProductType id="productInfoList-productType" placeholder="请选择产品分类" :isDealer="true" @change="changeProductType" v-model="productType"></ProductType>
+                  </a-form-item>
+                </a-col>
+                <a-col :md="8" :sm="24">
+                  <a-form-item label="产品品牌">
+                    <ProductBrand id="productInfoList-productBrandSn" placeholder="请选择产品品牌" v-model="queryParam.dealerProductEntity.productBrandSn"></ProductBrand>
+                    </a-select>
+                  </a-form-item>
+                </a-col>
+                <a-col :md="8" :sm="24" style="margin-bottom: 10px;">
+                  <a-button type="primary" @click="searchForm" :disabled="disabled" id="productInfoList-refresh">查询</a-button>
+                  <a-button style="margin-left: 5px" @click="resetSearchForm" :disabled="disabled" id="productInfoList-reset">重置</a-button>
+                </a-col>
+              </a-row>
+            </a-form>
+          </div>
+          <p style="font-weight: bold;">当前已选:{{ rowSelectionInfo&&rowSelectionInfo.selectedRowKeys?rowSelectionInfo.selectedRowKeys.length:0 }}个</p>
           <!-- 列表 -->
           <s-table
             class="sTable"
@@ -35,7 +66,7 @@
             size="large"
             class="button-primary"
             @click="handleSave"
-            style="padding: 0 36px;">加入本次采购</a-button>
+            style="padding: 0 36px;">批量添加</a-button>
           <a-button
             id="outStock-cancel"
             size="large"
@@ -44,7 +75,7 @@
             style="padding: 0 60px;margin-left: 15px;">取消</a-button>
         </div>
       </div>
-    </a-spin>
+      </div></a-spin>
   </a-modal>
 </template>
 
@@ -52,9 +83,11 @@
 import { commonMixin } from '@/utils/mixin'
 import { STable } from '@/components'
 import { purchaseDetailCancelList, purchaseDetailCancelSave } from '@/api/purchaseDetail'
+import ProductType from '../../common/productType.js'
+import ProductBrand from '../../common/productBrand.js'
 export default {
   name: 'OutStockModal',
-  components: { STable },
+  components: { STable, ProductType, ProductBrand },
   mixins: [commonMixin],
   props: {
     openModal: { //  弹框显示状态
@@ -89,25 +122,46 @@ export default {
         { title: '上次缺货数量', dataIndex: 'cancelQty', width: '18%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
         { title: '单位', dataIndex: 'dealerProductEntity.unit', width: '8%', align: 'center', customRender: function (text) { return text || '--' } }
       ],
+      title: '',
       // 加载数据方法 必须为 Promise 对象
       loadData: parameter => {
         this.disabled = true
         this.spinning = true
-        return purchaseDetailCancelList(parameter).then(res => {
+        return purchaseDetailCancelList(Object.assign(parameter, this.queryParam)).then(res => {
           let data
           if (res.status == 200) {
             data = res.data
             this.disabled = false
           }
           this.spinning = false
+          const purchaseBillNo = data && data.list.length > 0 ? data.list[0].purchaseBillNo : '--'
+          this.title = '上次采购缺货产品明细(采购单号:' + purchaseBillNo + ')'
           return data
         })
       },
       spinning: false,
-      rowSelectionInfo: null
+      rowSelectionInfo: null,
+      productType: [],
+      dataList: [],
+      queryParam: { //  查询条件
+        dealerProductEntity: {
+          code: '', //  产品编码
+          name: '', //  产品名称
+          productBrandSn: undefined, //  产品品牌
+          productTypeSn1: '', //  产品一级分类
+          productTypeSn2: '', //  产品二级分类
+          productTypeSn3: '' //  产品三级分类
+        }
+      }
     }
   },
   methods: {
+    //  产品分类  change
+    changeProductType (val, opt) {
+      this.queryParam.dealerProductEntity.productTypeSn1 = val[0] ? val[0] : ''
+      this.queryParam.dealerProductEntity.productTypeSn2 = val[1] ? val[1] : ''
+      this.queryParam.dealerProductEntity.productTypeSn3 = val[2] ? val[2] : ''
+    },
     // 表格选中项
     rowSelectionFun (obj) {
       this.rowSelectionInfo = obj || null
@@ -180,6 +234,22 @@ export default {
           _this.$refs.table.clearSelected() // 清空表格选中项
         }
       })
+    },
+    searchForm () {
+      this.$refs.table.refresh(true)
+    },
+    resetSearchForm () {
+      const info = {
+        productBrandSn: undefined,
+        code: '', //  产品编码
+        name: '', //  产品名称
+        productTypeSn1: '', //  产品一级分类
+        productTypeSn2: '', //  产品二级分类
+        productTypeSn3: '' //  产品三级分类
+      }
+      Object.assign(this.queryParam.dealerProductEntity, info)
+      this.productType = []
+      this.$refs.table.refresh(true)
     }
   },
   watch: {

+ 272 - 0
src/views/purchasingManagement/purchaseOrderNew/basicInfoModal.vue

@@ -0,0 +1,272 @@
+<template>
+  <a-modal
+    centered
+    class="purchaseOrder-basicInfo-modal"
+    :footer="null"
+    :maskClosable="false"
+    title="新增采购单"
+    v-model="isShow"
+    @cancel="isShow=false"
+    :width="800">
+    <a-spin :spinning="spinning" tip="Loading...">
+      <a-form-model
+        id="purchaseOrder-basicInfo-form"
+        ref="ruleForm"
+        :model="form"
+        :rules="rules"
+        :label-col="formItemLayout.labelCol"
+        :wrapper-col="formItemLayout.wrapperCol" >
+        <a-form-model-item label="供应商" prop="purchaseTargetSn">
+          <a-radio-group
+            name="radioGroup"
+            v-model="form.purchaseTargetSn"
+            @change="tragetTypeChange"
+            v-if="purchaseTragetType.length"
+            id="purchaseOrder-basicInfo-purchaseTargetSn" >
+            <a-radio v-for="item in purchaseTragetType" :key="item.purchaseTargetSn" :value="item.purchaseTargetSn" class="radio-s">{{ item.purchaseTargetName }}</a-radio>
+          </a-radio-group>
+          <span v-else>没有可选择的供应商</span>
+        </a-form-model-item>
+        <a-form-model-item label="支付方式" prop="settleStyleSn">
+          <v-select
+            code="SETTLE_STYLE"
+            id="purchaseOrder-basicInfo-settleStyleSn"
+            v-model="form.settleStyleSn"
+            allowClear
+            placeholder="请选择支付方式"
+          ></v-select>
+        </a-form-model-item>
+        <a-form-model-item label="收货地址" prop="consigneeTel">
+          {{ chooseAddr }}
+          <a-button type="link" id="purchaseOrder-basicInfo-chooseAddr" @click="handleChoose">{{ addressVal }} >></a-button>
+        </a-form-model-item>
+        <a-form-model-item :wrapper-col="{ span: 12, offset: 6 }" style="text-align: center;">
+          <a-button type="primary" :loading="confirmLoading" @click="handleSubmit" id="chooseCustom-btn-submit">保存</a-button>
+          <a-button @click="isShow=false" style="margin-left: 15px" id="chooseCustom-btn-back">取消</a-button>
+        </a-form-model-item>
+      </a-form-model>
+    </a-spin>
+    <!-- 选择地址 -->
+    <choose-address-modal :openModal="openAddrModal" @ok="handleOk" @verify="verifyFun" @close="openAddrModal=false" />
+  </a-modal>
+</template>
+
+<script>
+import { commonMixin } from '@/utils/mixin'
+import { VSelect } from '@/components'
+import chooseAddressModal from '@/views/common/receivingAddress/chooseAddressModal.vue'
+import { shippingAddressQuery } from '@/api/shippingAddress'
+import { purchaseSave, purchaseTargetList } from '@/api/purchase'
+export default {
+  name: 'BasicInfoModal',
+  components: { VSelect, chooseAddressModal },
+  mixins: [commonMixin],
+  props: {
+    openModal: { //  弹框显示状态
+      type: Boolean,
+      default: false
+    }
+  },
+  data () {
+    return {
+      spinning: false,
+      confirmLoading: false,
+      isShow: this.openModal, //  是否打开弹框
+      formItemLayout: {
+        labelCol: { span: 4 },
+        wrapperCol: { span: 18 }
+      },
+      form: {
+        purchaseTargetType: '', // 供应商
+        shippingAddressProvinceName: '', // 省
+        shippingAddressCityName: '', // 市
+        shippingAddressCountyName: '', // 区
+        shippingAddress: '', // 详细地址
+        consigneeTel: '', // 联系电话
+        consigneeName: '', // 联系人名称
+        settleStyleSn: undefined, //  支付方式
+        purchaseTargetSn: undefined,
+        purchaseTargetName: ''
+      },
+      rules: {
+        purchaseTargetSn: [
+          { required: true, message: '请选择供应商', trigger: 'change' }
+        ],
+        settleStyleSn: [
+          { required: true, message: '请选择支付方式', trigger: 'change' }
+        ],
+        consigneeTel: [
+          { required: true, message: '请选择收货地址(联系电话不能为空)', trigger: 'change' }
+        ]
+      },
+      purchaseTragetType: [],
+      addressVal: '选择地址', //  选择地址/更换地址
+      chooseAddr: '', //  当前已选地址信息
+      addressId: undefined,
+      openAddrModal: false // 选择地址弹框是否显示
+    }
+  },
+  methods: {
+    resetForm () {
+      this.$refs.ruleForm.resetFields()
+      this.chooseAddr = ''
+      this.addressVal = '选择地址'
+      this.form.shippingAddressProvinceName = ''// 省
+      this.form.shippingAddressCityName = '' // 市
+      this.form.shippingAddressCountyName = '' // 区
+      this.form.shippingAddress = ''// 详细地址
+      this.form.consigneeTel = '' // 联系电话
+      this.form.consigneeName = ''
+      this.form.purchaseTargetType = ''
+      this.form.purchaseTargetSn = undefined
+      this.form.purchaseTargetName = ''
+    },
+    // 供应商change
+    tragetTypeChange (e) {
+      const val = e.target.value
+      const ind = this.purchaseTragetType.findIndex(item => item.purchaseTargetSn == val)
+      if (ind != -1) {
+        this.form.purchaseTargetType = this.purchaseTragetType[ind].purchaseTargetType
+        this.form.purchaseTargetName = this.purchaseTragetType[ind].purchaseTargetName
+      }
+    },
+    //  保存
+    handleSubmit (e) {
+      e.preventDefault()
+      const _this = this
+      this.$refs.ruleForm.validate(valid => {
+        if (valid) {
+          if (_this.form.consigneeTel == '') {
+            _this.$message.info('请选择收货地址')
+            return false
+          }
+          _this.spinning = true
+          purchaseSave(_this.form).then(res => {
+            if (res.status == 200) {
+              _this.isShow = false
+              _this.$emit('ok', res.data)
+              _this.spinning = false
+              _this.$message.info(res.message)
+            } else {
+              _this.spinning = false
+            }
+          })
+        } else {
+          return false
+        }
+      })
+    },
+    //  选择地址
+    handleChoose () {
+      this.openAddrModal = true
+    },
+    //  地址保存
+    handleOk (data) {
+      this.chooseAddr = (data.consigneeName || '') + '(' + (data.consigneeTel || '--') + ')' + ' ' + (data.address || '')
+      this.addressVal = '更换地址'
+      this.form.shippingAddressProvinceName = data.provinceName // 省
+      this.form.shippingAddressCityName = data.cityName // 市
+      this.form.shippingAddressCountyName = data.countyName // 区
+      this.form.shippingAddress = data.addr// 详细地址
+      this.form.consigneeTel = data.consigneeTel // 联系电话
+      this.form.consigneeName = data.consigneeName
+      this.openAddrModal = false
+    },
+    // 编辑信息
+    setData (data) {
+      this.form = JSON.parse(JSON.stringify(data))
+      this.chooseAddr = data.consigneeName + '(' + (data.consigneeTel || '--') + ')' + ' ' + data.shippingAddressProvinceName + '-' + data.shippingAddressCityName + '-' + data.shippingAddressCountyName + ' ' + data.shippingAddress
+      this.addressVal = '更换地址'
+    },
+    getParentDealer () {
+      const zb = this.$hasPermissions('B_SUPPLIER_ZB')
+      const sj = this.$hasPermissions('B_SUPPLIER_SJ')
+      let params = {}
+      // 只能向上级采购
+      if (sj) {
+        params.purchaseTargetType = 'DEALER_UP'
+      }
+      // 只能向总部采购
+      if (zb) {
+        params.purchaseTargetType = 'SUPPLIER_SYS'
+      }
+      // 总部和上级都可以
+      if (sj && zb) {
+        params = {}
+      }
+      purchaseTargetList(params).then(res => {
+        if (res.status == 200 && res.data[0]) {
+          this.purchaseTragetType = res.data
+        } else {
+          this.purchaseTragetType = []
+        }
+      })
+    },
+    // 获取默认地址
+    getDefaultAddress () {
+      shippingAddressQuery({ defaultFlag: 1 }).then(res => {
+        if (res.status == 200) {
+          if (res.data.length == 1) {
+            res.data[0].address = ''
+            if (res.data[0].provinceName) {
+              res.data[0].address += res.data[0].provinceName + '-'
+            }
+            if (res.data[0].cityName) {
+              res.data[0].address += res.data[0].cityName + '-'
+            }
+            if (res.data[0].countyName) {
+              res.data[0].address += res.data[0].countyName + '-'
+            }
+            res.data[0].address += res.data[0].addr
+            this.addressId = res.data[0].id || undefined
+            this.handleOk(res.data[0])
+          }
+        }
+      })
+    },
+    verifyFun (id) {
+      if (id == this.addressId) {
+        this.chooseAddr = ''
+        this.addressVal = '选择地址'
+        this.form.shippingAddressProvinceName = ''// 省
+        this.form.shippingAddressCityName = '' // 市
+        this.form.shippingAddressCountyName = '' // 区
+        this.form.shippingAddress = ''// 详细地址
+        this.form.consigneeTel = '' // 联系电话
+        this.form.consigneeName = ''
+      }
+    }
+  },
+  watch: {
+    //  父页面传过来的弹框状态
+    openModal (newValue, oldValue) {
+      this.isShow = newValue
+    },
+    //  重定义的弹框状态
+    isShow (newValue, oldValue) {
+      if (!newValue) {
+        this.$emit('close')
+        this.resetForm()
+      } else {
+        this.getParentDealer()
+        this.getDefaultAddress()
+      }
+    }
+  }
+}
+</script>
+
+<style lang="less">
+  .purchaseOrder-basicInfo-modal{
+    .ant-modal-body {
+      padding: 40px 40px 24px;
+    }
+    .radio-s{
+      margin-bottom: 8px;
+    }
+    .btn-cont {
+      text-align: center;
+      margin: 35px 0 10px;
+    }
+  }
+</style>

+ 217 - 0
src/views/purchasingManagement/purchaseOrderNew/chooseImportModal.vue

@@ -0,0 +1,217 @@
+<template>
+  <a-modal
+    centered
+    class="chooseImport-modal"
+    :footer="null"
+    :maskClosable="false"
+    title="导入"
+    :closable="false"
+    v-model="isShow"
+    @cancel="isShow=false"
+    :width="900">
+    <a-spin :spinning="spinning" tip="Loading...">
+      <div class="chooseImport-con">
+        <!-- 可导入数据 -->
+        <p class="chooseImport-tit">可导入数据{{ loadData.length }}条</p>
+        <a-table
+          class="sTable"
+          ref="table"
+          size="small"
+          :rowKey="(record) => record.purchaseBillSn"
+          :columns="nowColumns"
+          :dataSource="loadData"
+          :loading="loading"
+          :scroll="{ y: 200 }"
+          :pagination="false"
+          bordered>
+        </a-table>
+        <a-divider />
+        <!-- 不可导入数据 -->
+        <p class="chooseImport-tit red">不可导入数据{{ unLoadData.length }}条</p>
+        <a-table
+          class="sTable"
+          ref="unTable"
+          size="small"
+          :rowClassName="(record, index) => 'yellowBg-row'"
+          :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 60px;">确认导入</a-button>
+          <a-button
+            id="chooseImport-cancel"
+            size="large"
+            class="button-cancel"
+            @click="isShow=false"
+            style="padding: 0 60px;margin-left: 15px;">取消</a-button>
+          <a-button
+            type="primary"
+            id="chooseImport-error"
+            size="large"
+            class="button-error"
+            @click="handleError"
+            style="padding: 0 40px;margin-left: 15px;">导出错误项</a-button>
+        </div>
+      </div>
+    </a-spin>
+  </a-modal>
+</template>
+
+<script>
+import { commonMixin } from '@/utils/mixin'
+import { hdPrint } from '@/libs/JGPrint'
+import { purchaseDetailParseProducts, purchaseDetailBatchInsert } from '@/api/purchase'
+import { purchaseDetailDownloadFail } from '@/api/purchaseDetail'
+export default {
+  name: 'ChooseImportModal',
+  mixins: [commonMixin],
+  props: {
+    openModal: { //  弹框显示状态
+      type: Boolean,
+      default: false
+    },
+    paramsData: {
+      type: Object,
+      default: () => {
+        return {}
+      }
+    }
+  },
+  data () {
+    return {
+      spinning: false,
+      isShow: this.openModal, //  是否打开弹框
+      nowColumns: [ //  正品
+        { title: '序号', dataIndex: 'no', width: '15%', align: 'center' },
+        { title: '产品编码', dataIndex: 'productCode', width: '27%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '产品名称', dataIndex: 'productName', width: '28%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '数量', dataIndex: 'qtyText', width: '15%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+        { title: '单位', dataIndex: 'dealerProductEntity.unit', width: '15%', align: 'center', customRender: function (text) { return text || '--' } }
+      ],
+      nowUnColumns: [ //  促销品
+        { title: '序号', dataIndex: 'no', width: '13%', align: 'center' },
+        { title: '产品编码', dataIndex: 'productCode', width: '26%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '产品名称', dataIndex: 'productName', width: '26%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '数量', dataIndex: 'qtyText', width: '15%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+        { title: '单位', dataIndex: 'dealerProductEntity.unit', width: '15%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '备注', dataIndex: 'errorDesc', width: '30%', align: 'center', customRender: function (text) { return text || '--' } }
+      ],
+      loadData: [],
+      unLoadData: [],
+      loading: false
+    }
+  },
+  methods: {
+    getData () {
+      const _this = this
+      this.loading = true
+      purchaseDetailParseProducts(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.spinning = true
+        purchaseDetailBatchInsert(this.loadData).then(res => {
+          this.spinning = false
+          if (res.status == 200) {
+            this.$emit('ok', '')
+            this.isShow = false
+          }
+        })
+      }
+    },
+    // 导出
+    handleError () {
+      const _this = this
+      if (_this.unLoadData.length < 1) {
+        _this.$message.info('暂无可导出错误项~')
+        return
+      }
+      _this.spinning = true
+      // 导出
+      hdPrint('', 'export', purchaseDetailDownloadFail, _this.unLoadData, '产品导入错误项', function () {
+        _this.spinning = 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">
+  .chooseImport-modal{
+    .chooseImport-con{
+      .chooseImport-tit{
+        font-size: 14px;
+        font-weight: bold;
+      }
+      .unTable{
+        box-shadow: 0px 0px 4px rgb(89,89,89,.9);
+        .ant-table-bordered .ant-table-tbody > tr > td, .ant-table-bordered .ant-table-thead > tr > th{
+          border-right: 1px solid #595959;
+        }
+        .ant-table-tbody > tr > td, .ant-table-thead > tr > th{
+          border-bottom: 1px solid #595959;
+        }
+      }
+      .red{
+        color: #f30;
+      }
+      .btn-con{
+        text-align: center;
+        margin: 30px 0 20px;
+        .button-cancel{
+          font-size: 12px;
+        }
+      }
+    }
+  }
+  .yellowBg-row{
+    background-color: #ffe58f;
+  }
+</style>

+ 326 - 0
src/views/purchasingManagement/purchaseOrderNew/chooseProductModal.vue

@@ -0,0 +1,326 @@
+<template>
+  <a-drawer
+    :zIndex="zIndex"
+    :title="title"
+    placement="right"
+    :visible="visible"
+    :width="width"
+    :get-container="false"
+    :wrap-style="{ position: 'absolute' }"
+    @close="onClose"
+    wrapClassName="chooseProduct-drawer">
+    <a-spin :spinning="spinning" tip="Loading...">
+      <div class="chooseProduct-drawer-box">
+        <!-- 搜索条件 -->
+        <div ref="searchBox" class="table-page-search-wrapper">
+          <a-form layout="inline" @keyup.enter.native="searchForm">
+            <a-row type="flex" :gutter="12" justify="start">
+              <a-col flex="auto">
+                <a-form-model-item label="产品编码">
+                  <a-input id="purchaseOrderEdit-code" ref="searchProductCode" v-model.trim="queryParam.code" allowClear placeholder="请输入产品编码"/>
+                </a-form-model-item>
+              </a-col>
+              <a-col flex="auto">
+                <a-form-model-item label="产品名称">
+                  <a-input id="purchaseOrderEdit-name" v-model.trim="queryParam.name" allowClear placeholder="请输入产品名称"/>
+                </a-form-model-item>
+              </a-col>
+              <!-- <a-col :flex="2">
+                <a-form-model-item label="原厂编码">
+                  <a-input id="purchaseOrderEdit-origCode" v-model.trim="queryParam.origCode" allowClear placeholder="请输入原厂编码"/>
+                </a-form-model-item>
+              </a-col> -->
+              <a-col flex="250px">
+                <a-form-item label="产品分类">
+                  <ProductType id="purchaseOrderEdit-productType" :isDealer="true" :tenantId="$route.params.dealerSn" @change="changeProductType" v-model="productType"></ProductType>
+                </a-form-item>
+              </a-col>
+              <a-col flex="250px">
+                <a-form-item label="产品品牌">
+                  <ProductBrand id="purchaseOrderEdit-productBrand" :tenantId="$route.params.dealerSn" v-model="queryParam.productBrandSn"></ProductBrand>
+                </a-form-item>
+              </a-col>
+              <a-col flex="auto">
+                <a-button type="primary" @click="searchForm" id="purchaseOrderEdit-refresh">查询</a-button>
+                <a-button style="margin-left: 5px" @click="resetSearchForm" id="purchaseOrderEdit-reset">重置</a-button>
+              </a-col>
+            </a-row>
+          </a-form>
+        </div>
+        <!-- 列表 -->
+        <s-table
+          v-if="hasVaild&&showTable"
+          class="sTable"
+          ref="table"
+          size="small"
+          :rowKey="(record) => record.id"
+          :columns="columns"
+          :data="loadData"
+          :scroll="{ x: tableWidth , y:tableHeight }"
+          @dblclick="handleAdd"
+          :pageSize="30"
+          bordered>
+          <!-- 产品图片 -->
+          <template slot="imageUrl" slot-scope="text, record">
+            <img
+              :src="record.productMainPic && record.productMainPic.imageUrl?(record.productMainPic.imageUrl+'?x-oss-process=image/resize,h_30,m_lfit'):defImg"
+              width="30"
+              height="30"
+              style="cursor: pointer;"
+              @click="handlePicDetail(record)" />
+          </template>
+          <!-- 包装数 -->
+          <template slot="baozh" slot-scope="text, record">
+            {{ record.packQty||'--' }}{{ record.packQty ? record.unit : '' }}/{{ record.packQtyUnit||'--' }}
+          </template>
+          <!-- 产品编码 -->
+          <template slot="code" slot-scope="text, record">
+            <a-tooltip placement="top" v-if="record.stockState=='NOT_ENOUGH'">
+              <template slot="title">
+                该产品暂时缺货!
+              </template>
+              <span class="noStock">{{ record.code || '--' }}</span>
+            </a-tooltip>
+            <span v-else>{{ record.code || '--' }}</span>
+          </template>
+          <!-- 采购数量 -->
+          <template slot="storageQuantity" slot-scope="text, record">
+            <div @dblclick.stop>
+              <a-input-number
+                size="small"
+                v-model="record.qty"
+                :precision="0"
+                :min="0"
+                :max="999999"
+                style="width: 100%;"
+                placeholder="请输入数量" />
+            </div>
+          </template>
+          <!-- 操作 -->
+          <template slot="action" slot-scope="text, record">
+            <a-button
+              size="small"
+              type="link"
+              class="button-primary"
+              :loading="addLoading"
+              @click="handleAdd(record)"
+              v-if="record.purchasePrice>0"
+              id="purchaseOrderEdit-add-btn">添加</a-button>
+            <span v-else>--</span>
+          </template>
+        </s-table>
+        <div v-else>
+          <a-empty
+            :image="simpleImage"
+            :image-style="{
+              height: '60px',
+            }"
+          >
+            <span style="color:red" slot="description">请输入查询条件</span>
+          </a-empty>
+        </div>
+      </div>
+    </a-spin>
+  </a-drawer>
+</template>
+
+<script>
+import { Empty } from 'ant-design-vue'
+import { commonMixin } from '@/utils/mixin'
+import { STable, VSelect } from '@/components'
+import ProductType from '../../common/productType.js'
+import ProductBrand from '../../common/productBrand.js'
+import defImg from '@/assets/def_img@2x.png'
+import { productListPurchase } from '@/api/product'
+export default {
+  mixins: [commonMixin],
+  components: {
+    STable, VSelect, ProductType, ProductBrand
+  },
+  props: {
+    showModal: {
+      type: Boolean,
+      default: false
+    },
+    width: {
+      type: [String, Number],
+      default: '70%'
+    },
+    zIndex: {
+      type: Number,
+      default: 1050
+    },
+    isDealerUp: {
+      type: Boolean
+    },
+    purchaseBillSn: {
+      type: String
+    }
+  },
+  watch: {
+    showModal (newValue, oldValue) {
+      this.visible = newValue
+      if (newValue) {
+        this.resetSearchForm()
+        this.$refs.searchProductCode.focus()
+        this.setTableH()
+      }
+    },
+    '$store.state.app.winHeight' (newValue, oldValue) { //  窗口变更时,需同时更改表格高度
+      this.setTableH()
+    }
+  },
+  data () {
+    return {
+      visible: this.showModal,
+      title: '添加产品',
+      tableHeight: 0,
+      simpleImage: Empty.PRESENTED_IMAGE_SIMPLE,
+      // 选择产品
+      addLoading: false,
+      spinning: false,
+      productType: [],
+      queryParam: {
+        productBrandSn: undefined,
+        code: '', //  产品编码
+        name: '', //  产品名称
+        origCode: '', //  原厂编码
+        productTypeSn1: '', //  产品一级分类
+        productTypeSn2: '', //  产品二级分类
+        productTypeSn3: '' //  产品三级分类
+      },
+      advanced: false, //  高级搜索 展开/关闭
+      disabled: false, //  查询、重置按钮是否可操作
+      showTable: false,
+      // 加载数据方法 必须为 Promise 对象
+      loadData: parameter => {
+        this.disabled = true
+        return productListPurchase(Object.assign(parameter, this.queryParam, { purchaseBillSn: this.purchaseBillSn })).then(res => {
+          const 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].qty = 1
+            data.list[i].qtyBackups = data.list[i].qty
+          }
+          this.disabled = false
+          return data
+        })
+      },
+      defImg
+    }
+  },
+  computed: {
+    hasVaild () {
+      return this.queryParam.code || this.queryParam.name || this.queryParam.productBrandSn || this.queryParam.productTypeSn1
+    },
+    tableWidth () {
+      let w = 1100
+      if (this.isDealerUp) {
+        w = 1200
+      }
+      if (this.$hasPermissions('M_ShowAllCost')) {
+        w = this.isDealerUp ? 1200 : 1100
+      }
+      return w
+    },
+    columns () {
+      const _this = this
+      const arr = [
+        { title: '产品编码', scopedSlots: { customRender: 'code' }, width: '150px', align: 'center', fixed: 'left' },
+        { title: '产品名称', dataIndex: 'name', width: '250px', align: 'center', customRender: function (text) { return text || '--' }, ellipsis: true },
+        // { title: '原厂编码', dataIndex: 'origCode', width: '14%', align: 'center', customRender: function (text) { return text && text != ' ' ? text : '--' } },
+        { title: '产品图片', scopedSlots: { customRender: 'imageUrl' }, width: '80px', align: 'center' },
+        { title: '单位', dataIndex: 'unit', width: '60px', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '包装数', scopedSlots: { customRender: 'baozh' }, width: '60px', align: 'center' },
+        { title: '终端会员价', dataIndex: 'terminalPrice', width: '100px', align: 'right', customRender: function (text) { return ((text || text == 0) ? _this.toThousands(text, 2) : '--') } },
+        { title: '车主零售价', dataIndex: 'carOwnersPrice', width: '100px', align: 'right', customRender: function (text) { return ((text || text == 0) ? _this.toThousands(text, 2) : '--') } },
+        { title: '采购数量', dataIndex: 'qty', scopedSlots: { customRender: 'storageQuantity' }, width: '100px', align: 'center', fixed: 'right' },
+        { title: '操作', scopedSlots: { customRender: 'action' }, width: '100px', align: 'center', fixed: 'right' }
+      ]
+      // 产品来源
+      if (this.isDealerUp) {
+        arr.splice(2, 0, { title: '产品来源', dataIndex: 'sysFlagDictValue', width: '100px', align: 'center', customRender: function (text) { return text || '--' } })
+      }
+      if (this.$hasPermissions('M_ShowAllCost')) {
+        arr.splice(this.isDealerUp ? 3 : 2, 0, { title: '成本价', dataIndex: 'purchasePrice', width: '100px', align: 'right', customRender: function (text) { return ((text || text == 0) ? _this.toThousands(text, 2) : '--') } })
+      }
+
+      return arr
+    }
+  },
+  methods: {
+    // 查看产品
+    handlePicDetail (row) {
+      this.$router.push({ name: 'viewProduct', params: { sn: row.productSn } })
+    },
+    //  产品分类  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] : ''
+    },
+    // 查询
+    searchForm () {
+      if (this.hasVaild) {
+        this.showTable = true
+        this.$refs.table.refresh(true)
+      } else {
+        this.$message.info('请输入查询条件')
+      }
+    },
+    // 重置产品库
+    resetSearchForm () {
+      this.queryParam = {
+        productBrandSn: undefined,
+        code: '', //  产品编码
+        name: '', //  产品名称
+        origCode: '', //  原厂编码
+        productTypeSn1: '', //  产品一级分类
+        productTypeSn2: '', //  产品二级分类
+        productTypeSn3: '' //  产品三级分类
+      }
+      this.productType = []
+      this.showTable = false
+    },
+    onClose () {
+      this.$emit('close')
+    },
+    handleAdd (record) {
+      this.spinning = true
+      this.$emit('add', record, 0)
+    },
+    setTableH () {
+      this.$nextTick(() => {
+        const searchBoxH = this.$refs.searchBox.offsetHeight
+        this.tableHeight = window.innerHeight - searchBoxH - 285
+      })
+    }
+  }
+}
+</script>
+
+<style lang="less">
+.chooseProduct-drawer {
+  .ant-drawer-header{
+    padding: 13px 20px;
+  }
+  .ant-drawer-body {
+    padding: 15px 20px;
+    height: calc(100% - 50px);
+    display: flex;
+    flex-direction: column;
+    overflow: auto;
+    > div {
+      height: 100%;
+    }
+    .noStock{
+      text-decoration: line-through;
+      color: red;
+    }
+    .ant-input-number-sm input{
+      text-align: center;
+    }
+  }
+}
+</style>

+ 303 - 0
src/views/purchasingManagement/purchaseOrderNew/detail.vue

@@ -0,0 +1,303 @@
+<template>
+  <div class="purchaseOrderDetail-wrap">
+    <a-spin :spinning="spinning" tip="Loading...">
+      <a-page-header :ghost="false" :backIcon="false" @back="handleBack" class="purchaseOrderDetail-cont" :style="{ padding: !outBizSn ? '16px 24px' : '0px 24px' }">
+        <!-- 自定义的二级文字标题 -->
+        <template slot="subTitle">
+          <a id="purchaseOrderDetail-back-btn" href="javascript:;" @click="handleBack" v-if="!outBizSn"><a-icon type="left" /> 返回列表</a>
+          <span class="billno">单号:{{ detail&&detail.purchaseBillNo }}</span>
+          <a-tag color="blue" v-if="detail&&detail.billStatusDictValue">{{ detail&&detail.billStatusDictValue }}</a-tag>
+          <a-tag color="orange" v-if="detail&&detail.financialStatusDictValue">{{ detail&&detail.financialStatusDictValue }}</a-tag>
+          <span class="billno" v-if="detail&&detail.purchaseBillNoSource" style="font-size: 14px;margin: 0;">(原:{{ detail&&detail.purchaseBillNoSource }})</span>
+        </template>
+        <!-- 操作区,位于 title 行的行尾 -->
+        <template slot="extra">
+          <Print v-if="$hasPermissions('B_purchasePrint')" :disabled="localDataSource.length==0" @handlePrint="handlePrint"></Print>
+          <a-button
+            key="1"
+            v-if="$hasPermissions('B_purchaseExportProduct') && (detail&&(detail.billStatus=='AUDIT_PASS' || detail.billStatus=='CANCEL' || detail.billStatus=='WAIT_PUT_WAREHOUSE' || detail.billStatus=='WAIT_PUT_WAREHOUSE_AUDIT' || detail.billStatus=='FINISH'))"
+            type="primary"
+            class="button-info"
+            id="purchaseOrderDetail-export-btn"
+            :disabled="localDataSource.length==0"
+            @click="handleExportProduct()">导出审核订单产品</a-button>
+        </template>
+      </a-page-header>
+      <!-- 基础信息 -->
+      <a-card size="small" :bordered="false" class="purchaseOrderDetail-cont">
+        <a-collapse :activeKey="['1']">
+          <a-collapse-panel key="1" header="基础信息">
+            <a-descriptions :column="3">
+              <a-descriptions-item label="供应商">{{ (detail&&detail.purchaseTargetName) || '--' }}</a-descriptions-item>
+              <a-descriptions-item label="支付方式">{{ (detail&&detail.settleStyleSnDictValue) || '--' }}</a-descriptions-item>
+              <a-descriptions-item label="采购员工" v-if="detail&&detail.purchaseBillSource=='PURCHASE'">{{ detail&&detail.operatorName || '--' }}</a-descriptions-item>
+              <a-descriptions-item label="收货人">{{ detail&&detail.consigneeName || '--' }}<span v-if="detail&&detail.consigneeTel">({{ detail&&detail.consigneeTel }})</span></a-descriptions-item>
+              <a-descriptions-item label="收货地址">
+                <div v-if="detail&&(detail.shippingAddressProvinceName || detail.shippingAddressCityName || detail.shippingAddressCountyName || detail.shippingAddress)">
+                  {{ detail&&detail.shippingAddressProvinceName || '' }}
+                  {{ detail&&detail.shippingAddressCityName || '' }}
+                  {{ detail&&detail.shippingAddressCountyName || '' }}
+                  {{ detail&&detail.shippingAddress || '' }}
+                </div>
+                <span v-else>--</span>
+              </a-descriptions-item>
+              <a-descriptions-item label="备注">{{ (detail&&detail.remarks) || '--' }}</a-descriptions-item>
+            </a-descriptions>
+          </a-collapse-panel>
+        </a-collapse>
+      </a-card>
+      <!-- 产品详情 -->
+      <a-card size="small" :bordered="false" class="purchaseOrderDetail-cont">
+        <a-collapse :activeKey="['1']">
+          <a-collapse-panel key="1" header="产品详情">
+            <!-- 总计 -->
+            <a-alert type="info" style="margin-bottom:10px">
+              <div slot="message">
+                产品款数:<strong>{{ detail && (detail.totalCategory || detail.totalCategory==0) ? detail.totalCategory : '--' }}</strong>,
+                采购数量合计:<strong>{{ detail && (detail.totalQty || detail.totalQty==0) ? detail.totalQty : '--' }}</strong>,
+                审核订单数量:<strong>{{ detail && (detail.totalPushedQty || detail.totalPushedQty==0) ? detail.totalPushedQty : '--' }}</strong>,
+                已取消数量:<strong>{{ detail && (detail.totalCancelQty || detail.totalCancelQty==0) ? detail.totalCancelQty : '--' }}</strong>,
+                <div style="display: inline-block;" v-if="$hasPermissions('M_ShowAllCost')">
+                  采购金额合计:<strong>{{ detail && (detail.discountedAmount || detail.discountedAmount==0) ? toThousands(detail.discountedAmount,2) : '--' }}</strong>,
+                  审核订单金额:<strong>{{ detail && (detail.totalPushedAmount || detail.totalPushedAmount==0) ? toThousands(detail.totalPushedAmount,2) : '--' }}</strong>,
+                  已取消金额:<strong>{{ detail && (detail.totalCancelAmount || detail.totalCancelAmount==0) ? toThousands(detail.totalCancelAmount,2) : '--' }}</strong>
+                </div>
+              </div>
+            </a-alert>
+            <!-- 列表 -->
+            <s-table
+              class="sTable"
+              ref="table"
+              size="small"
+              :rowKey="(record) => record.id"
+              :columns="columns"
+              :data="loadData"
+              :defaultLoadData="false"
+              bordered>
+              <!-- 采购数量 -->
+              <template slot="origqty" slot-scope="text, record">
+                <div>{{ text }}</div>
+                <div v-if="record.origqty">原采购数量:{{ record.origqty }}</div>
+              </template>
+              <!-- 已取消数量 -->
+              <template slot="outOfStockNum" slot-scope="text, record">
+                <span>{{ record.outOfStockNum }}</span>
+              </template>
+            </s-table>
+          </a-collapse-panel>
+        </a-collapse>
+      </a-card>
+      <!-- 促销品详情 -->
+      <a-card size="small" v-if="false" :bordered="false" class="purchaseOrderDetail-cont">
+        <a-collapse :activeKey="['1']">
+          <a-collapse-panel key="1" header="促销品详情">
+            <!-- 总计 -->
+            <a-alert type="info" style="margin-bottom:10px">
+              <div slot="message">产品款数 <strong>{{ detail&&(detail.totalCategory || detail.totalCategory==0) ? detail.totalCategory : '--' }}</strong> ,
+                采购数量合计 <strong>{{ detail&&(detail.totalQty || detail.totalQty==0) ? detail.totalQty : '--' }}</strong> ,
+                采购金额合计 <strong>{{ detail&&(detail.totalAmount || detail.totalAmount==0) ? toThousands(detail.totalAmount,2) : '--' }}</strong></div>
+            </a-alert>
+            <!-- 列表 -->
+            <s-table
+              class="sTable"
+              ref="table-1"
+              size="small"
+              :rowKey="(record) => record.id"
+              :columns="columns"
+              :data="loadData"
+              :scroll="{ x: 1060 }"
+              bordered>
+              <!-- 采购数量 -->
+              <template slot="origqty" slot-scope="text, record">
+                <div>{{ text }}</div>
+                <div v-if="record.origqty">原采购数量:{{ record.origqty }}</div>
+              </template>
+              <!-- 已取消数量 -->
+              <template slot="outOfStockNum" slot-scope="text, record">
+                <span>{{ record.outOfStockNum }}</span>
+              </template>
+            </s-table>
+          </a-collapse-panel>
+        </a-collapse>
+      </a-card>
+      <!-- 单据记录 -->
+      <a-card size="small" v-if="false" :bordered="false" class="purchaseOrderDetail-cont">
+        <a-collapse :activeKey="['1']">
+          <a-collapse-panel key="1" header="单据记录">
+            <a-timeline class="timeline-box">
+              <a-timeline-item>2021-02-01 15:22:38   王凯   审核通过</a-timeline-item>
+              <a-timeline-item>
+                <p>2021-02-01 15:22:38   王凯   审核通过</p>
+                <p class="auxiliary-txt">产品编号JA-11076P的采购数量,由【10】修改为【5】</p>
+                <p class="auxiliary-txt">产品编号JA-11076P的采购数量,由【10】修改为【5】</p>
+              </a-timeline-item>
+              <a-timeline-item>Technical testing 2015-09-01</a-timeline-item>
+              <a-timeline-item>Network problems being solved 2015-09-01</a-timeline-item>
+            </a-timeline>
+          </a-collapse-panel>
+        </a-collapse>
+      </a-card>
+    </a-spin>
+  </div>
+</template>
+
+<script>
+import { commonMixin } from '@/utils/mixin'
+import { STable, VSelect } from '@/components'
+import { purchaseDetailBySn, purchaseDetailPrint, purchaseDetailExport, purchaseExportDetail } from '@/api/purchase'
+import { purchaseDetailList } from '@/api/purchaseDetail'
+import Print from '@/views/common/print.vue'
+import { hdPrint, downloadExcel } from '@/libs/JGPrint'
+export default {
+  name: 'PurchaseDetail',
+  components: { STable, VSelect, Print },
+  mixins: [commonMixin],
+  props: {
+    outBizSn: { //  有值则为弹框,无值则为页面
+      type: [Number, String],
+      default: ''
+    }
+  },
+  data () {
+    return {
+      spinning: false,
+      // 加载数据方法 必须为 Promise 对象
+      loadData: parameter => {
+        this.disabled = true
+        return purchaseDetailList(Object.assign(parameter, { purchaseBillSn: this.outBizSn || this.$route.params.sn, orderBy: 'product_type.FIRST_CHAR,dealer_product.CODE' })).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.localDataSource = data.list
+            this.disabled = false
+          }
+          return data
+        })
+      },
+      detail: null, //  详情数据
+      localDataSource: [],
+      printerType: 'NEEDLE' //  打印机类型
+    }
+  },
+  computed: {
+    columns () {
+      let _this=this
+      const arr = [
+        { title: '序号', dataIndex: 'no', width: '4%', align: 'center' },
+        { title: '产品编码', dataIndex: 'dealerProductEntity.code', width: '16%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '产品名称', dataIndex: 'dealerProductEntity.name', width: '16%', align: 'center', customRender: function (text) { return text || '--' }, ellipsis: true },
+        { title: '原厂编码', dataIndex: 'dealerProductEntity.origCode', width: '15%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '单位', dataIndex: 'dealerProductEntity.unit', width: '5%', align: 'center', customRender: function (text) { return text || '--' } },
+        // { title: '采购单价', dataIndex: 'discountedPrice', width: '7%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+        // { title: '采购金额', dataIndex: 'discountedAmount', width: '7%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+        { title: '采购数量', dataIndex: 'qty', width: '7%', align: 'center', scopedSlots: { customRender: 'origqty' } },
+        // { title: '审核订单金额', dataIndex: 'pushedAmount', width: '8%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+        { title: '审核订单数量', dataIndex: 'pushedQty', width: '8%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+        { title: '已取消数量', dataIndex: 'cancelQty', width: '7%', align: 'center', customRender: function (text) { return text || '--' } }
+      ]
+      if (this.$hasPermissions('M_ShowAllCost')) {
+        arr.splice(5, 0, { title: '采购单价', dataIndex: 'discountedPrice', width: '7%', align: 'right', customRender: function (text) { return ((text || text == 0) ? _this.toThousands(text,2) : '--') } })
+        arr.splice(6, 0, { title: '采购金额', dataIndex: 'discountedAmount', width: '7%', align: 'right', customRender: function (text) { return ((text || text == 0) ? _this.toThousands(text,2) : '--') } })
+        arr.splice(8, 0, { title: '审核订单金额', dataIndex: 'pushedAmount', width: '8%', align: 'right', customRender: function (text) { return ((text || text == 0) ? _this.toThousands(text,2) : '--') } })
+      }
+      return arr
+    }
+  },
+  methods: {
+    //  返回列表
+    handleBack () {
+      if (this.$route.query.pageType) {
+        this.$router.push({ name: this.$route.query.pageType })
+      } else {
+        this.$router.push({ name: 'purchaseOrderNewList' })
+      }
+    },
+    //  详情
+    getDetail () {
+      purchaseDetailBySn({ sn: this.outBizSn || this.$route.params.sn }).then(res => {
+        if (res.status == 200) {
+          this.detail = res.data
+        } else {
+          this.detail = null
+        }
+      })
+    },
+    // 打印预览/快捷打印
+    handlePrint (type, printerType) {
+      const _this = this
+      _this.spinning = true
+      let url = purchaseDetailPrint
+      let params = { sn: this.outBizSn || this.$route.params.sn, type: printerType }
+      if (type == 'export') { //  导出
+        url = purchaseDetailExport
+        params = { sn: this.outBizSn || this.$route.params.sn }
+      }
+      // 打印或导出
+      hdPrint(printerType, type, url, params, '采购单', function () {
+        _this.spinning = false
+      })
+    },
+    // 导出产品
+    handleExportProduct () {
+      const _this = this
+      _this.spinning = true
+      purchaseExportDetail({ sn: this.outBizSn || this.$route.params.sn }).then(res => {
+        _this.spinning = false
+        if (res.type == 'application/json') {
+          var reader = new FileReader()
+          reader.addEventListener('loadend', function () {
+            const obj = JSON.parse(reader.result)
+            _this.$notification.error({
+              message: '提示',
+              description: obj.message
+            })
+          })
+          reader.readAsText(res)
+        } else {
+          downloadExcel(res, '采购产品')
+        }
+      })
+    }
+  },
+  mounted () {
+    if (!this.$store.state.app.isNewTab || this.outBizSn) { // 页签刷新时调用
+      this.$refs.table.refresh(true)
+      this.getDetail()
+    }
+  },
+  activated () {
+    console.log(this.$store.state.app.isNewTab, !this.$store.state.app.isNewSubTab)
+    // 如果是新页签打开或者进入新的子页(例:存在列表第2条数据编辑页页签时再打开第4条数据的编辑页),则重置当前页面
+    if (this.$store.state.app.isNewTab || !this.$store.state.app.isNewSubTab) {
+      this.$refs.table.refresh(true)
+      this.getDetail()
+    }
+  },
+  beforeRouteEnter (to, from, next) {
+    next(vm => {})
+  }
+}
+</script>
+
+<style lang="less">
+  .purchaseOrderDetail-cont{
+    margin-bottom: 10px;
+    .timeline-box{
+      margin-top: 30px;
+      .auxiliary-txt{
+        color: #808695;
+      }
+    }
+  }
+  .purchaseOrderDetail-wrap{
+    .billno{
+      font-size: 16px;
+      font-weight: bold;
+      margin: 0 15px;
+    }
+  }
+</style>

+ 578 - 0
src/views/purchasingManagement/purchaseOrderNew/edit.vue

@@ -0,0 +1,578 @@
+<template>
+  <div v-if="showPage" class="purchaseNewOrderEdit-wrap">
+    <a-page-header :ghost="false" :backIcon="false" class="purchaseNewOrderEdit-cont">
+      <!-- 自定义的二级文字标题 -->
+      <template slot="subTitle">
+        <a id="purchaseNewOrderEdit-back-btn" href="javascript:;" @click="handleBack"><a-icon type="left" /> 返回列表</a>
+        <p class="billno">单号:{{ detail&&detail.purchaseBillNo }}</p>
+        <a-button type="danger" ghost @click="isShowBisiceInfo=!isShowBisiceInfo" style="margin-left:30px;vertical-align:middle;">
+          基础信息
+          <a-icon :type="isShowBisiceInfo ? 'up' : 'down'"/>
+        </a-button>
+      </template>
+      <!-- 操作区,位于 title 行的行尾 -->
+      <template slot="extra" v-if="$hasPermissions('B_purchasePrint')">
+        <Print :disabled="localDataSource.length==0" @handlePrint="handlePrint"></Print>
+      </template>
+    </a-page-header>
+    <!-- 产品列表 -->
+    <div ref="tableSearch" class="choosedList-cont">
+      <!-- 基础信息 -->
+      <div style="padding:10px 10px 0 10px;border-bottom:8px solid #f3f3f3;" v-if="isShowBisiceInfo">
+        <a-descriptions title="基础信息" size="small">
+          <a-descriptions-item label="供应商">
+            {{ detail&&detail.purchaseTargetName || '--' }}
+          </a-descriptions-item>
+          <a-descriptions-item label="支付方式">
+            {{ detail&&detail.settleStyleSnDictValue || '--' }}
+          </a-descriptions-item>
+          <a-descriptions-item label="收货人">
+            {{ detail&&detail.consigneeName || '--' }}({{ detail&&detail.consigneeTel || '--' }})
+          </a-descriptions-item>
+          <a-descriptions-item label="收货地址" span="3">
+            <div v-if="detail&&(detail.shippingAddressProvinceName || detail.shippingAddressCityName || detail.shippingAddressCountyName || detail.shippingAddress)">
+              {{ detail&&detail.shippingAddressProvinceName || '' }}
+              {{ detail&&detail.shippingAddressCityName || '' }}
+              {{ detail&&detail.shippingAddressCountyName || '' }}
+              {{ detail&&detail.shippingAddress || '' }}
+              <a-button type="link" @click="openAddrModal=true">更换地址 >></a-button>
+            </div>
+            <div v-else><a-button type="link" @click="openAddrModal=true">选择地址 >></a-button></div>
+          </a-descriptions-item>
+        </a-descriptions>
+      </div>
+
+      <!-- 添加产品 -->
+      <chooseProductModal
+        ref="chooseProduct"
+        :isDealerUp="isDealerUp"
+        :purchaseBillSn="$route.params.sn"
+        :showModal="openChooseProduct"
+        @close="openChooseProduct=false"
+        @add="handleAdd"
+      ></chooseProductModal>
+      <!-- 上次缺货 -->
+      <outStockModal :openModal="openOutStockModal" :paramsData="paramsData" @close="openOutStockModal=false" @ok="hanldeOkOutStock" />
+      <!-- 购物车 -->
+      <shopingCatModal :showModal="openShopCatModal" :paramsData="paramsData" @close="openShopCatModal=false" @ok="getOrderDetail(false, true)"></shopingCatModal>
+      <!-- 已选产品 -->
+      <div>
+        <div class="chooseBox-title">
+          <div class="sub-title" style="display: flex;">
+            已选产品
+            <p class="tag-txt">注意:仅限采购【箭冠】产品。自建产品的采购入库请使用“散件入库”功能</p>
+          </div>
+          <div class="actions-button">
+            <a-button v-if="detail&&detail.totalCategory" id="purchaseNewOrderEdit-add-btn" type="danger" @click="openChooseProduct=true"><a-icon type="plus-circle" />添加产品</a-button>
+            <a-button id="purchaseNewOrderEdit-import-btn" type="danger" ghost @click="openGuideModal=true"><a-icon type="import" />产品导入</a-button>
+            <a-button id="purchaseNewOrderEdit-outStock-btn" type="danger" ghost @click="handleOutStock"><a-icon type="funnel-plot" />上次缺货</a-button>
+            <a-button id="purchaseNewOrderEdit-cart-btn" v-if="$hasPermissions('M_shoppingCart')" type="danger" ghost @click="hanldCart"><a-icon type="shopping" />购物车</a-button>
+          </div>
+        </div>
+        <div class="choosed-table" v-if="detail&&detail.totalCategory">
+          <!-- 搜索条件 -->
+          <div class="table-page-search-wrapper">
+            <a-row :gutter="15">
+              <a-col :span="24">
+                <a-form-model :model="productForm" layout="inline" @keyup.enter.native="$refs.purchaseTable.refresh(true)" >
+                  <a-row :gutter="15">
+                    <a-col :md="6" :sm="24">
+                      <a-form-model-item label="产品编码">
+                        <a-input v-model.trim="productForm.productCode" allowClear placeholder="输入产品编码" />
+                      </a-form-model-item>
+                    </a-col>
+                    <a-col :md="6" :sm="24">
+                      <a-form-model-item label="产品名称">
+                        <a-input v-model.trim="productForm.productName" allowClear placeholder="输入产品名称" />
+                      </a-form-model-item>
+                    </a-col>
+                    <a-col :md="8" :sm="24">
+                      <a-form-model-item style="margin-bottom: 10px;">
+                        <a-button type="primary" @click="$refs.purchaseTable.refresh(true)" :disabled="purchaseDisabled" id="purchaseNewOrderEdit-refresh">查询</a-button>
+                        <a-button style="margin-left: 5px" @click="resetPurchaseForm" id="purchaseNewOrderEdit-reset">重置</a-button>
+                      </a-form-model-item>
+                    </a-col>
+                  </a-row>
+                </a-form-model>
+              </a-col>
+            </a-row>
+          </div>
+          <!-- 列表 -->
+          <s-table
+            class="sTable"
+            ref="purchaseTable"
+            :style="{ height: tableHeight +'px', overflow: 'auto' }"
+            size="small"
+            :rowKey="(record) => record.id"
+            :columns="chooseColumns"
+            :data="chooseLoadData"
+            :defaultLoadData="false"
+            :showPagination="false"
+            :pageSize="5000"
+            bordered>
+            <!-- 采购数量 -->
+            <template slot="storageQuantity" slot-scope="text, record">
+              <a-input-number
+                size="small"
+                id="purchaseNewOrderEdit-qty"
+                v-model="record.qty"
+                :precision="0"
+                :min="1"
+                :max="999999"
+                @blur="e => qtyBlur(e.target.value, record)"
+                style="width: 100%;"
+                placeholder="请输入" />
+            </template>
+            <!-- 操作 -->
+            <template slot="action" slot-scope="text, record">
+              <a-button
+                size="small"
+                type="link"
+                class="button-error"
+                :loading="delLoading"
+                @click="handleDel(record)"
+                id="purchaseNewOrderEdit-del-btn">删除</a-button>
+            </template>
+          </s-table>
+        </div>
+        <div v-else>
+          <div v-if="!spinning&&localDataSource.length==0">
+            <a-empty
+              :image="simpleImage"
+              :image-style="{
+                height: '60px',
+              }"
+            >
+              <span slot="description"> 暂无产品 </span>
+              <a-button type="primary" class="button-error" @click="openChooseProduct=true"><a-icon type="plus-circle" />立即添加产品</a-button>
+            </a-empty>
+          </div>
+          <div style="text-align: center;padding: 30px 50px;" v-if="spinning">
+            <a-spin :spinning="spinning" tip="Loading..."></a-spin>
+          </div>
+        </div>
+      </div>
+      <!-- 底部栏 -->
+      <div class="footer-cont">
+        <!-- 总计 -->
+        <div>
+          <span style="color:#666;">
+            共计 {{ detail && (detail.totalCategory || detail.totalCategory==0) ? detail.totalCategory : '--' }} 款
+            {{ detail && (detail.totalQty || detail.totalQty==0) ? detail.totalQty : '--' }} 件产品 ,
+          </span>
+          <div style="display: inline-block;" v-if="$hasPermissions('M_ShowAllCost')">
+            合计: <strong>{{ detail && (detail.discountedAmount || detail.discountedAmount==0) ?toThousands(detail.discountedAmount, 2) : '--' }}</strong>
+          </div>
+        </div>
+        <div>
+          <a-button
+            type="primary"
+            id="purchaseNewOrderEdit-submit-btn"
+            size="large"
+            class="button-primary"
+            :loading="subLoading"
+            @click="handleSubmit"
+            style="padding: 0 60px;">提交</a-button>
+        </div>
+      </div>
+    </div>
+    <!-- 导入产品 -->
+    <importGuideModal :openModal="openGuideModal" :params="{purchaseBillSn: $route.params.sn}" @close="openGuideModal=false" @ok="hanldeOks" />
+    <!-- 选择地址 -->
+    <choose-address-modal :openModal="openAddrModal" @ok="handleAddrOk" @close="openAddrModal=false" />
+  </div>
+</template>
+
+<script>
+import { Empty } from 'ant-design-vue'
+import { commonMixin } from '@/utils/mixin'
+import { STable, VSelect } from '@/components'
+import ImportGuideModal from './importGuideModal.vue'
+import outStockModal from './outStockModal.vue'
+import chooseAddressModal from '@/views/common/receivingAddress/chooseAddressModal.vue'
+import { purchaseDetailBySn, purchaseWriteSubmit, purchaseDetailPrint, purchaseDetailExport, purchaseDetailAddress } from '@/api/purchase'
+import { purchaseDetailList, purchaseDetailSave, purchaseDetailDel, purchaseDetailCount, purchaseDetailCancelList } from '@/api/purchaseDetail'
+// 选择产品
+import chooseProductModal from './chooseProductModal.vue'
+// 打印
+import Print from '@/views/common/print.vue'
+import { hdPrint } from '@/libs/JGPrint'
+const shopingCatModal = () => import(/* webpackChunkName: "shopingCatModal" */ '@/views/common/shopingCatModal.vue')
+export default {
+  name: 'PurchaseEdit',
+  components: { STable, VSelect, ImportGuideModal, outStockModal, Print, chooseAddressModal, chooseProductModal, shopingCatModal },
+  mixins: [commonMixin],
+  data () {
+    return {
+      isShowBisiceInfo: false,
+      showPage: false,
+      spinning: false,
+      detail: null, // 详细信息
+      openChooseProduct: false,
+      openShopCatModal: false,
+      tableHeight: 0,
+      simpleImage: Empty.PRESENTED_IMAGE_SIMPLE,
+      // -------已选产品-------------
+      subLoading: false,
+      orderCountData: null,
+      delLoading: false,
+      productForm: {
+        productName: '',
+        productCode: '',
+        orderBy: 'purchase_bill_detail.CREATE_DATE desc'
+      },
+      purchaseDisabled: false, //  查询、重置按钮是否可操作
+      // 加载数据方法 必须为 Promise 对象
+      chooseLoadData: parameter => {
+        this.disabled = true
+        this.spinning = true
+        // 查询总计
+        const params = Object.assign({ pageNo: 1, pageSize: 5000 }, this.productForm, { purchaseBillSn: this.$route.params.sn })
+        return purchaseDetailList(params).then(res => {
+          const 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].qtyBackups = data.list[i].qty
+          }
+          this.localDataSource = data.list
+          this.disabled = false
+          this.spinning = false
+          return data
+        })
+      },
+      localDataSource: [],
+      openGuideModal: false, //  导入产品引导
+      openOutStockModal: false,
+      paramsData: null,
+      openAddrModal: false // 选择地址弹框是否显示
+    }
+  },
+  computed: {
+    isDealerUp () {
+      return this.detail && this.detail.purchaseTargetType == 'DEALER_UP'
+    },
+    chooseColumns () {
+      const _this = this
+      const arr = [
+        { title: '序号', dataIndex: 'no', width: '5%', align: 'center' },
+        { title: '产品编码', dataIndex: 'dealerProductEntity.code', width: '20%', align: 'center' },
+        { title: '产品名称', dataIndex: 'dealerProductEntity.name', width: '35%', align: 'center', customRender: function (text) { return text || '--' }, ellipsis: true },
+        { title: '采购数量', scopedSlots: { customRender: 'storageQuantity' }, width: '8%', align: 'center' },
+        { title: '单位', dataIndex: 'dealerProductEntity.unit', width: '8%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '操作', scopedSlots: { customRender: 'action' }, width: '8%', align: 'center' }
+      ]
+      if (this.$hasPermissions('M_ShowAllCost')) {
+        arr.splice(3, 0, { title: '采购单价', dataIndex: 'discountedPrice', width: '8%', align: 'right', customRender: function (text) { return ((text || text == 0) ? _this.toThousands(text, 2) : '--') } })
+        arr.splice(6, 0, { title: '采购金额', dataIndex: 'discountedAmount', width: '8%', align: 'right', customRender: function (text) { return ((text || text == 0) ? _this.toThousands(text, 2) : '--') } })
+      }
+      return arr
+    }
+  },
+  methods: {
+    // 获取采购单基本信息
+    getOrderDetail (noRefashTable, isReset, flag) {
+      this.spinning = true
+      purchaseDetailBySn({ sn: this.$route.params.sn }).then(res => {
+        if (res.status == 200) {
+          this.detail = res.data
+          if (!noRefashTable) {
+            if (this.detail.totalCategory) {
+              if (isReset) {
+                this.resetPurchaseForm()
+              } else {
+                this.$refs.purchaseTable.refresh(!!flag)
+              }
+            } else {
+              this.localDataSource = []
+              this.spinning = false
+            }
+          } else {
+            this.spinning = false
+          }
+        } else {
+          this.spinning = false
+        }
+      })
+    },
+    // 删除产品
+    handleDel (row) {
+      const _this = this
+      this.$confirm({
+        title: '提示',
+        content: '确认要删除吗?',
+        centered: true,
+        closable: true,
+        onOk () {
+          _this.delLoading = true
+          purchaseDetailDel({ id: row.id }).then(res => {
+            if (res.status == 200) {
+              _this.getOrderDetail(false, false, true)
+              _this.$message.success(res.message)
+              _this.delLoading = false
+            } else {
+              _this.delLoading = false
+            }
+          })
+        }
+      })
+    },
+    // 修改数量后
+    qtyBlur (val, record) {
+      //  光标移出,值发生改变再调用编辑接口
+      if (val != record.qtyBackups) {
+        this.handleAdd(record, 1)
+      }
+    },
+    // 重置已选产品列表
+    resetPurchaseForm () {
+      this.productForm.productName = ''
+      this.productForm.productCode = ''
+      this.$nextTick(() => {
+        this.$refs.purchaseTable.refresh(true)
+      })
+    },
+    //  添加或修改
+    handleAdd (row, type) {
+      let params = {}
+      if (type == 0 && !row.qty) {
+        this.$message.warning('请输入数量后再添加!')
+        this.$refs.chooseProduct.spinning = false
+        return
+      }
+      // 添加
+      if (type == 0) {
+        params.productSn = row.productSn
+        params.purchaseBillSn = this.detail.purchaseBillSn
+        params.purchaseBillNo = this.detail.purchaseBillNo
+        params.price = row.purchasePrice
+        params.qty = row.qty
+      } else { //  编辑
+        // 清空成本价或数量时,值应保持未清空前的值,因成本价和数量都不可为空
+        if (!row.qty) {
+          row.qty = row.qtyBackups
+          return
+        }
+        params = row
+      }
+      this.addLoading = true
+      purchaseDetailSave(params).then(res => {
+        if (res.status == 200) {
+          this.getOrderDetail(false, true, true)
+          this.$message.success(res.message)
+          if (type == 0) {
+            row.qtyBackups = row.qty
+          }
+        } else {
+          row.qty = row.qtyBackups
+        }
+        this.addLoading = false
+        this.$refs.chooseProduct.spinning = false
+      })
+    },
+    //  提交
+    handleSubmit () {
+      const _this = this
+      if (_this.detail && !_this.detail.totalCategory) {
+        this.$message.info('请添加产品')
+        return false
+      }
+      this.subLoading = true
+      purchaseWriteSubmit({ id: this.detail.id }).then(res => {
+        if (res.status == 200) {
+          this.$message.success(res.message)
+          setTimeout(() => {
+            _this.handleBack()
+          }, 1000)
+        }
+        _this.subLoading = false
+      })
+    },
+    // 导入产品
+    hanldeOks () {
+      this.getOrderDetail(false, true, true)
+    },
+    // 打开购物车
+    hanldCart () {
+      this.paramsData = {
+        purchaseBillSn: this.$route.params.sn,
+        purchaseBillNo: this.detail && this.detail.purchaseBillNo ? this.detail.purchaseBillNo : undefined
+      }
+      this.openShopCatModal = true
+    },
+    // 上次缺货
+    handleOutStock () {
+      // 校验是否存在历史采购单,且上次采购存在缺货产品
+      purchaseDetailCancelList({ pageNo: 1, pageSize: 5 }).then(res => {
+        if (res.status == 200) {
+          const purchaseBillNo = res.data && res.data.list && res.data.list[0].purchaseBillNo || '--'
+          this.paramsData = {
+            purchaseBillSn: this.$route.params.sn,
+            purchaseBillNo: purchaseBillNo
+          }
+          this.openOutStockModal = true
+        }
+      })
+    },
+    //  地址保存
+    handleAddrOk (data) {
+      const params = {
+        purchaseBillSn: this.$route.params.sn,
+        shippingAddressProvinceName: data.provinceName,
+        shippingAddressCityName: data.cityName,
+        shippingAddressCountyName: data.countyName,
+        shippingAddress: data.addr,
+        consigneeName: data.consigneeName,
+        consigneeTel: data.consigneeTel
+      }
+      purchaseDetailAddress(params).then(res => {
+        if (res.status == 200) {
+          this.openAddrModal = false
+          this.getOrderDetail(true)
+        }
+      })
+    },
+    // 上次缺货 导入成功
+    hanldeOkOutStock () {
+      this.getOrderDetail(false, true, true)
+      this.paramsData = null
+      this.openOutStockModal = false
+    },
+    // 打印预览/快捷打印
+    handlePrint (type, printerType) {
+      const _this = this
+      if (type == 'preview') {
+        _this.openChooseProduct = false
+        _this.openOutStockModal = false
+      }
+      _this.$store.state.app.printLoading = true
+      let url = purchaseDetailPrint
+      let params = { sn: this.$route.params.sn, type: printerType }
+      if (type == 'export') { //  导出
+        url = purchaseDetailExport
+        params = { sn: this.$route.params.sn }
+      }
+      // 打印或导出
+      hdPrint(printerType, type, url, params, '采购单', function () {
+        _this.$store.state.app.printLoading = false
+      })
+    },
+    //  返回列表
+    handleBack () {
+      this.$router.push({ name: 'purchaseOrderNewList' })
+    },
+    setTableH () {
+      this.tableHeight = window.innerHeight - (this.isShowBisiceInfo ? 440 : 310)
+    },
+    pageInit () {
+      this.$nextTick(() => {
+        this.setTableH()
+        this.getOrderDetail(false, true)
+      })
+    }
+  },
+  watch: {
+    isShowBisiceInfo (newValue, oldValue) {
+      this.setTableH()
+    }
+  },
+  mounted () {
+    this.showPage = true
+    if (!this.$store.state.app.isNewTab) { // 页签刷新时调用
+      this.pageInit()
+    }
+  },
+  activated () {
+    this.showPage = true
+    // 如果是新页签打开或者进入新的子页(例:存在列表第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">
+  .purchaseNewOrderEdit-wrap{
+    position: relative;
+    height: 100%;
+    box-sizing: border-box;
+    .billno{
+      margin: 0 0 0 30px;
+      font-size: 18px;
+      font-weight: 600;
+      display: inline-block;
+      vertical-align: middle;
+      color: #666;
+    }
+    .choosedList-cont{
+      position: relative;
+      background-color: #fff;
+      height: calc(100% - 60px);
+      .chooseBox-title{
+        display:flex;
+        justify-content: space-between;
+        align-items: center;
+        border-top: 1px solid #eee;
+        border-bottom: 1px solid #eee;
+        padding: 8px 0;
+        .actions-button{
+          button{
+            margin-left: 10px;
+            margin-right: 10px;
+          }
+        }
+        .import-btn{
+          margin-left: 15px;
+        }
+        .sub-title{
+          font-size: 14px;
+          color: #333;
+          margin-left: 10px;
+          font-weight:bold;
+        }
+        .tag-txt{
+          font-size: 12px;
+          color: #ed1c24;
+          margin: 0 15px;
+        }
+      }
+      .choosed-table{
+        padding:10px;
+      }
+      .footer-cont{
+        position:absolute;
+        width:100%;
+        bottom:0;
+        display:flex;
+        justify-content: flex-end;
+        align-items: center;
+        padding: 8px;
+        border-top: 1px solid #eee;
+        > div{
+          &:first-child{
+            padding: 0 15px;
+            strong{
+              color: #ff8d00;
+              font-size: 18px;
+            }
+          }
+        }
+      }
+      .ant-input-number-sm input{
+        text-align: center;
+      }
+    }
+    .purchaseNewOrderEdit-cont{
+      margin-bottom: 8px;
+      .sub-title{
+        font-size: 12px;
+        color: #808695;
+        margin-left: 10px;
+      }
+    }
+  }
+</style>

+ 209 - 0
src/views/purchasingManagement/purchaseOrderNew/importGuideModal.vue

@@ -0,0 +1,209 @@
+<template>
+  <a-modal
+    centered
+    class="importGuide-modal"
+    :footer="null"
+    :maskClosable="false"
+    title="导入产品"
+    v-model="isShow"
+    @cancel="isShow=false"
+    :width="750">
+    <div class="importGuide-con">
+      <div class="explain-con">
+        <div class="explain-item">
+          <div class="explain-tit">
+            <span>1</span>准备导入
+          </div>
+          <ul>
+            <li>1) 导入的Excel文件中必须包含名为“产品编码”、“数量”的列,且名称必须相同</li>
+            <li>2) 除了“产品编码”、“数量”两列,其他列可自定义,不影响数据导入</li>
+            <li>3) 如果导入的产品已经存在,则不会导入该行</li>
+          </ul>
+          <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>
+          <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 { commonMixin } from '@/utils/mixin'
+import ChooseImportModal from './chooseImportModal.vue'
+import { Upload } from '@/components'
+import { purchaseDetailDownload } from '@/api/purchase'
+import { downloadExcel } from '@/libs/JGPrint.js'
+export default {
+  name: 'ImportGuideModal',
+  components: { ChooseImportModal, Upload },
+  mixins: [commonMixin],
+  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 = {
+          purchaseBillSn: this.params.purchaseBillSn || '',
+          path: file
+        }
+      }
+    },
+    // 导入
+    hanldeOk () {
+      this.$emit('ok')
+    },
+    // 关闭
+    handleClose () {
+      this.openImportModal = false
+      this.isShow = false
+    },
+    //  导出
+    handleExport () {
+      const _this = this
+      _this.spinning = true
+      purchaseDetailDownload({}).then(res => {
+        _this.spinning = false
+        if (res.type == 'application/json') {
+          var reader = new FileReader()
+          reader.addEventListener('loadend', function () {
+            const obj = JSON.parse(reader.result)
+            _this.$notification.error({
+              message: '提示',
+              description: obj.message
+            })
+          })
+          reader.readAsText(res)
+        } else {
+		  const fileName = '采购单产品导入模板'
+		  downloadExcel(res, fileName)
+        }
+      })
+    }
+  },
+  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>

+ 390 - 0
src/views/purchasingManagement/purchaseOrderNew/list.vue

@@ -0,0 +1,390 @@
+<template>
+  <a-card size="small" :bordered="false" class="purchaseOrderList-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 type="flex" :gutter="15">
+            <a-col flex="400px">
+              <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="采购单号">
+                <a-input id="purchaseOrderList-purchaseBillNo" v-model.trim="queryParam.purchaseBillNo" allowClear placeholder="请输入采购单号"/>
+              </a-form-item>
+            </a-col>
+            <a-col :md="6" :sm="24">
+              <a-form-item label="供应商">
+                <a-select
+                  id="purchaseOrderList-purchaseTargetSn"
+                  placeholder="请选择供应商"
+                  allowClear
+                  v-model="queryParam.purchaseTargetSn"
+                  :showSearch="true"
+                  option-filter-prop="children"
+                  :filter-option="filterOption"
+                  @change="tragetTypeChange">
+                  <a-select-option v-for="item in supplierList" :pyCode="item.pyCode" :key="item.purchaseTargetSn" :value="item.purchaseTargetSn">{{ item.purchaseTargetName }}</a-select-option>
+                </a-select>
+              </a-form-item>
+            </a-col>
+            <a-col :md="6" :sm="24" v-show="advanced">
+              <a-form-item label="业务状态">
+                <a-select id="purchaseOrderList-billStatus" allowClear v-model="queryParam.billStatus" placeholder="请选择业务状态">
+                  <a-select-option value="">全部</a-select-option>
+                  <a-select-option value="WAIT_SUBMIT">待提交</a-select-option>
+                  <a-select-option value="SUBMIT">已提交</a-select-option>
+                </a-select>
+              </a-form-item>
+            </a-col>
+            <a-col :md="6" :sm="24" v-show="advanced">
+              <a-form-item label="财务状态">
+                <v-select
+                  v-model="queryParam.financialStatus"
+                  ref="financialStatus"
+                  id="purchaseOrderList-financialStatus"
+                  code="FINANCIAL_PAY_STATUS"
+                  placeholder="请选择财务状态"
+                  allowClear></v-select>
+              </a-form-item>
+            </a-col>
+            <a-col :md="6" :sm="24" v-show="advanced">
+              <a-form-item label="单据来源">
+                <v-select
+                  v-model="queryParam.purchaseBillSource"
+                  ref="purchaseBillSource"
+                  id="purchaseOrderList-purchaseBillSource"
+                  code="PURCHASE_SOURCE"
+                  placeholder="请选择单据来源"
+                  allowClear></v-select>
+              </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="purchaseOrderList-refresh">查询</a-button>
+                <a-button style="margin-left: 8px" @click="resetSearchForm()" :disabled="disabled" id="purchaseOrderList-reset">重置</a-button>
+                <a @click="advanced=!advanced" style="margin-left: 8px">
+                  {{ advanced ? '收起' : '展开' }}
+                  <a-icon :type="advanced ? 'up' : 'down'"/>
+                </a>
+              </span>
+            </a-col>
+          </a-row>
+        </a-form>
+      </div>
+      <!-- 操作按钮 -->
+      <div class="table-operator">
+        <a-button id="purchaseOrderList-add" type="primary" v-if="$hasPermissions('B_purchaseNew')&&($hasPermissions('B_SUPPLIER_SJ')||$hasPermissions('B_SUPPLIER_ZB'))" class="button-error" @click="handleAdd">新增</a-button>
+      </div>
+      <!-- alert -->
+      <a-alert type="info" style="margin-bottom:10px">
+        <div slot="message">
+          共 <strong>{{ totalData&&(totalData.totalRecord || totalData.totalRecord==0) ? totalData.totalRecord : '--' }}</strong> 条记录,
+          采购数量合计 <strong>{{ totalData&&(totalData.totalQty || totalData.totalQty==0) ? totalData.totalQty : '--' }}</strong> ,
+          采购金额合计 <strong>{{ totalData&&(totalData.totalAmount || totalData.totalAmount==0) ? toThousands(totalData.totalAmount,2) : '--' }}</strong>,
+          审核金额合计 <strong>{{ totalData&&(totalData.totalAuthAmount || totalData.totalAuthAmount==0) ? toThousands(totalData.totalAuthAmount,2) : '--' }}</strong>
+        </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="purchaseBillNo" slot-scope="text, record">
+          <span class="table-td-link" v-if="$hasPermissions('B_purchaseDetail')" @click="handleDetail(record)">{{ record.purchaseBillNo }}</span>
+          <span v-else>{{ record.purchaseBillNo }}</span>
+          <a-badge count="改" :offset="[10,0]" v-if="record.billStatus=='HQ_CHANGE'||record.billStatus=='SUPERIOR_CHANGE'"></a-badge>
+        </template>
+        <!-- 审核 -->
+        <template slot="audit" slot-scope="text, record">
+          <stateIcon :title="record.billStatusDictValue" v-if="record.billStatus!='AUDIT_REJECT'" :state="record.billStatus == 'WAIT_PUT_WAREHOUSE'||record.billStatus=='AUDIT_PASS'||record.billStatus == 'FINISH'?'1':'2'"></stateIcon>
+          <stateIcon :title="record.billStatusDictValue" v-else :state="0"></stateIcon>
+        </template>
+        <!-- 付款 -->
+        <template slot="financial" slot-scope="text, record">
+          <stateIcon :title="record.financialStatusDictValue" :state="record.financialStatus == 'FINISH'?'1':'2'"></stateIcon>
+        </template>
+        <!-- 入库 -->
+        <template slot="waitOut" slot-scope="text, record">
+          <stateIcon :state="record.billStatus == 'FINISH'?'1':'2'"></stateIcon>
+        </template>
+        <!-- 操作 -->
+        <template slot="action" slot-scope="text, record">
+          <a-button
+            size="small"
+            type="link"
+            class="button-primary"
+            v-if="(record.billStatus == 'WAIT_SUBMIT'||record.billStatus == 'AUDIT_REJECT') && $hasPermissions('B_purchaseEdit')"
+            @click="handleEdit(record)"
+          >编辑</a-button>
+          <a-button
+            size="small"
+            type="link"
+            class="button-error"
+            v-if="(record.billStatus == 'WAIT_SUBMIT'||record.billStatus == 'AUDIT_REJECT') &&$hasPermissions('B_purchaseDel')"
+            @click="handleDel(record)"
+          >删除</a-button>
+          <span v-if="!((record.billStatus == 'WAIT_SUBMIT'||record.billStatus == 'AUDIT_REJECT') && $hasPermissions('B_purchaseEdit')) && !((record.billStatus == 'WAIT_SUBMIT'||record.billStatus == 'AUDIT_REJECT') &&$hasPermissions('B_purchaseDel'))">--</span>
+        </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 rangeDate from '@/views/common/rangeDate.vue'
+import basicInfoModal from './basicInfoModal.vue'
+import stateIcon from '@/views/common/stateIcon'
+import getDate from '@/libs/getDate.js'
+import { purchaseList, purchaseDel, purchaseCount } from '@/api/purchase'
+import { queryReturnSupplierList } from '@/api/purchaseReturn'
+export default {
+  name: 'PurchaseOrderNewList',
+  components: { STable, VSelect, basicInfoModal, rangeDate, stateIcon },
+  mixins: [commonMixin],
+  data () {
+    const _this = this
+    return {
+      spinning: false,
+      advanced: true, //  高级搜索 展开/关闭
+      disabled: false, //  查询、重置按钮是否可操作
+      openModal: false, // 基本信息弹框是否显示
+      supplierList: [],
+      tableHeight: 0,
+      time: [
+        getDate.getCurrMonthDays().starttime,
+        getDate.getCurrMonthDays().endtime
+      ],
+      // 查询参数
+      queryParam: {
+        purchaseBillNo: '',
+        purchaseTargetSn: undefined,
+        purchaseTargetType: undefined,
+        billStatus: undefined,
+        financialStatus: undefined,
+        purchaseBillSource: undefined,
+        beginDate: getDate.getCurrMonthDays().starttime,
+        endDate: getDate.getCurrMonthDays().endtime
+      },
+      totalData: {
+        totalRecord: 0,
+        totalCategory: 0,
+        totalQty: 0,
+        totalAmount: 0
+      },
+      // 表头
+      columns: [
+        { title: '序号', dataIndex: 'no', width: '4%', align: 'center' },
+        { title: '采购单号', scopedSlots: { customRender: 'purchaseBillNo' }, width: '13%', align: 'center' },
+        { title: '创建时间', dataIndex: 'createDate', width: '10%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '供应商', dataIndex: 'purchaseTargetName', width: '10%', align: 'center', customRender: function (text) { return text || '--' }, ellipsis: true },
+        { title: '产品款数', dataIndex: 'totalCategory', width: '6%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+        { title: '采购数量', dataIndex: 'totalQty', width: '6%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+        { title: '采购金额', dataIndex: 'discountedAmount', width: '6%', align: 'right', customRender: function (text) { return ((text || text == 0) ? _this.toThousands(text, 2) : '--') } },
+        { title: '审核数量', dataIndex: 'totalPushedQty', width: '6%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+        { title: '审核金额', dataIndex: 'totalPushedAmount', width: '6%', align: 'right', customRender: function (text) { return ((text || text == 0) ? _this.toThousands(text, 2) : '--') } },
+        { title: '已取消数量', dataIndex: 'totalCancelQty', width: '7%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '采购状态', dataIndex: 'billStatusDictValue', width: '6%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '审核', scopedSlots: { customRender: 'audit' }, width: '3%', align: 'center' },
+        { title: '入库', scopedSlots: { customRender: 'waitOut' }, width: '3%', align: 'center' },
+        { title: '付款', scopedSlots: { customRender: 'financial' }, width: '3%', align: 'center' },
+        { title: '操作', scopedSlots: { customRender: 'action' }, width: '9%', align: 'center' }
+      ],
+      // 加载数据方法 必须为 Promise 对象
+      loadData: parameter => {
+        this.disabled = true
+        this.spinning = true
+        const params = Object.assign(parameter, this.queryParam)
+        if (!params.billStatus) {
+          params.billStatus = undefined
+        }
+        // 获取统计数据
+        this.getTotalData(params)
+        return purchaseList(params).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: {
+    getTotalData (params) {
+      purchaseCount(params).then(res => {
+        this.totalData = res.data || null
+      })
+    },
+    // 供应商change
+    tragetTypeChange (val) {
+      const ind = this.supplierList.findIndex(item => item.purchaseTargetSn == val)
+      if (ind != -1) {
+        this.queryParam.purchaseTargetType = this.supplierList[ind].purchaseTargetType
+      } else {
+        this.queryParam.purchaseTargetSn = undefined
+        this.queryParam.purchaseTargetType = undefined
+      }
+    },
+    //  时间  change
+    dateChange (date) {
+      this.queryParam.beginDate = date[0]
+      this.queryParam.endDate = date[1]
+    },
+    //  新增
+    handleAdd () {
+      this.openModal = true
+    },
+    //  基本信息  保存
+    handleOk (row) {
+      this.$router.push({ name: `purchaseOrderNewAdd`, params: { sn: row.purchaseBillSn, dealerSn: (row.purchaseTargetType == 'DEALER_UP' ? row.purchaseTargetSn : 'NONE') } })
+    },
+    //  编辑
+    handleEdit (row) {
+      this.$router.push({ name: `purchaseOrderNewEdit`, params: { sn: row.purchaseBillSn, dealerSn: (row.purchaseTargetType == 'DEALER_UP' ? row.purchaseTargetSn : 'NONE') } })
+    },
+    //  详情
+    handleDetail (row) {
+      this.$router.push({ name: `purchaseOrderNewDetail`, params: { sn: row.purchaseBillSn } })
+    },
+    //  删除
+    handleDel (row) {
+      const _this = this
+      this.$confirm({
+        title: '提示',
+        content: '删除后不可恢复,确定要进行删除吗?',
+        centered: true,
+        onOk () {
+          _this.spinning = true
+          purchaseDel({
+            id: row.id
+          }).then(res => {
+            if (res.status == 200) {
+              _this.$message.success(res.message)
+              _this.$refs.table.refresh()
+              _this.spinning = false
+            } else {
+              _this.spinning = false
+            }
+          })
+        }
+      })
+    },
+    //  重置
+    resetSearchForm (flag) {
+      this.$refs.rangeDate.resetDate(flag ? '' : this.time)
+      this.queryParam.beginDate = flag ? '' : getDate.getCurrMonthDays().starttime
+      this.queryParam.endDate = flag ? '' : getDate.getCurrMonthDays().endtime
+      this.queryParam.orderBundleNo = ''
+      this.queryParam.purchaseBillNo = ''
+      this.queryParam.purchaseTargetSn = undefined
+      this.queryParam.purchaseTargetType = undefined
+      this.queryParam.billStatus = undefined
+      this.queryParam.financialStatus = undefined
+      this.queryParam.purchaseBillSource = undefined
+      if (!flag) {
+        this.$refs.table.refresh(true)
+        this.setIsHomeNav(this.$route.name, null)
+      }
+    },
+    filterOption (input, option) {
+      return (
+        option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
+      )
+    },
+    // 获取供应商数据
+    getSupperList () {
+      queryReturnSupplierList({}).then(res => {
+        if (res.status == 200) {
+          this.supplierList = res.data
+        } else {
+          this.supplierList = []
+        }
+      })
+    },
+    pageInit () {
+      const _this = this
+      this.$nextTick(() => { // 页面渲染完成后的回调
+        _this.setTableH()
+      })
+      this.openModal = false
+      this.getSupperList()
+
+      // 是否打开的页签
+      const a = this.$store.state.app.isNewTab
+      // 是否要刷新列表
+      const b = this.$store.state.app.updateList
+      // 是否从首页点击进入
+      const isHomeNav = this.getIsHomeNav()[this.$route.name]
+      console.log(a, b, this.getIsHomeNav(), isHomeNav, this.$route.name)
+
+      // 从首页进入,判断式新建还式待办查询
+      if (isHomeNav) {
+        // 新增
+        if (isHomeNav.type == 'new') {
+          this.resetSearchForm()
+          this.openModal = true
+        }
+        // 待办
+        if (isHomeNav.type == 'todo') {
+          this.resetSearchForm(true)
+          this.queryParam = Object.assign(this.queryParam, isHomeNav.pageParams)
+          this.$refs.rangeDate.resetDate([this.queryParam.beginDate, this.queryParam.endDate])
+          this.$refs.table.refresh(true)
+        }
+      } else {
+        // 如果是新页签打开,则重置当前页面
+        if (a && !b) {
+          this.resetSearchForm()
+        }
+      }
+      // 仅刷新列表,不重置页面
+      if (b || a == b) {
+        this.$refs.table.refresh()
+      }
+    },
+    setTableH () {
+      const tableSearchH = this.$refs.tableSearch.offsetHeight
+      this.tableHeight = window.innerHeight - tableSearchH - 275
+    }
+  },
+  watch: {
+    advanced (newValue, oldValue) {
+      const _this = this
+      this.$nextTick(() => { // 页面渲染完成后的回调
+        _this.setTableH()
+      })
+    },
+    '$store.state.app.winHeight' (newValue, oldValue) { //  窗口变更时,需同时更改表格高度
+      this.setTableH()
+    }
+  },
+  activated () {
+    this.pageInit()
+  },
+  beforeRouteEnter (to, from, next) {
+    next(vm => {
+    })
+  }
+}
+</script>

+ 312 - 0
src/views/purchasingManagement/purchaseOrderNew/outStockModal.vue

@@ -0,0 +1,312 @@
+<template>
+  <a-drawer
+    :zIndex="zIndex"
+    :title="title"
+    placement="right"
+    :visible="isShow"
+    :width="width"
+    :get-container="false"
+    :wrap-style="{ position: 'absolute' }"
+    @close="onCancel"
+    wrapClassName="outStock-modal"
+  >
+    <a-spin :spinning="spinning" tip="Loading...">
+      <div class="outStock-con">
+        <div>
+          <div ref="searchBox" class="table-page-search-wrapper">
+            <a-form layout="inline" @keyup.enter.native="searchForm">
+              <a-row type="flex" :gutter="12" justify="start">
+                <a-col flex="auto">
+                  <a-form-item label="产品编码">
+                    <a-input id="productInfoList-code" v-model.trim="queryParam.code" allowClear placeholder="请输入产品编码"/>
+                  </a-form-item>
+                </a-col>
+                <a-col flex="auto">
+                  <a-form-item label="产品名称">
+                    <a-input id="productInfoList-name" v-model.trim="queryParam.name" allowClear placeholder="请输入产品名称"/>
+                  </a-form-item>
+                </a-col>
+                <a-col flex="250px">
+                  <a-form-item label="产品分类">
+                    <ProductType id="productInfoList-productType" placeholder="请选择产品分类" :isDealer="true" @change="changeProductType" v-model="productType"></ProductType>
+                  </a-form-item>
+                </a-col>
+                <a-col flex="250px">
+                  <a-form-item label="产品品牌">
+                    <ProductBrand id="productInfoList-productBrandSn" placeholder="请选择产品品牌" v-model="queryParam.productBrandSn"></ProductBrand>
+                    </a-select>
+                  </a-form-item>
+                </a-col>
+                <a-col flex="auto">
+                  <a-button type="primary" @click="searchForm" :disabled="disabled" id="productInfoList-refresh">查询</a-button>
+                  <a-button style="margin-left: 5px" @click="resetSearchForm" :disabled="disabled" id="productInfoList-reset">重置</a-button>
+                </a-col>
+              </a-row>
+            </a-form>
+          </div>
+          <div class="actions-buttons">
+            <a-button
+              type="primary"
+              ghost
+              id="outStock-save"
+              @click="handleSave"
+              style="padding: 0 20px;">批量添加</a-button>
+            <span style="font-weight: bold;margin-left:15px;" v-if="rowSelectionInfo&&rowSelectionInfo.selectedRowKeys.length">已选:{{ rowSelectionInfo&&rowSelectionInfo.selectedRowKeys.length }}个</span>
+          </div>
+          <!-- 列表 -->
+          <s-table
+            class="sTable"
+            ref="table"
+            size="small"
+            :rowKey="(record) => record.productSn"
+            rowKeyName="productSn"
+            :row-selection="{ columnWidth: 40 }"
+            :scroll="{ y:tableHeight, x: 1000 }"
+            @rowSelection="rowSelectionFun"
+            :data="loadData"
+            :defaultLoadData="false"
+            :columns="columns"
+            :pageSize="30"
+            bordered>
+          </s-table>
+        </div>
+      </div>
+      </div>
+    </a-spin>
+  </a-drawer>
+</template>
+
+<script>
+import { commonMixin } from '@/utils/mixin'
+import { STable } from '@/components'
+import { purchaseDetailCancelList, purchaseDetailCancelSave } from '@/api/purchaseDetail'
+import ProductType from '../../common/productType.js'
+import ProductBrand from '../../common/productBrand.js'
+export default {
+  name: 'OutStockModal',
+  components: { STable, ProductType, ProductBrand },
+  mixins: [commonMixin],
+  props: {
+    openModal: { //  弹框显示状态
+      type: Boolean,
+      default: false
+    },
+    chooseData: {
+      type: Array,
+      default: () => {
+        return []
+      }
+    },
+    paramsData: {
+      type: Object,
+      default: () => {
+        return {}
+      }
+    },
+    width: {
+      type: [String, Number],
+      default: '70%'
+    },
+    zIndex: {
+      type: Number,
+      default: 1050
+    }
+  },
+  data () {
+    return {
+      isShow: this.openModal, //  是否打开弹框
+      tableHeight: 0,
+      formItemLayout: {
+        labelCol: { span: 4 },
+        wrapperCol: { span: 20 }
+      },
+      disabled: false, //  查询、重置按钮是否可操作
+      columns: [
+        { title: '产品编码', dataIndex: 'dealerProductEntity.code', width: '240px', align: 'center', customRender: function (text) { return text || '--' }, fixed: 'left' },
+        { title: '产品名称', dataIndex: 'dealerProductEntity.name', width: '320px', align: 'left', customRender: function (text) { return text || '--' }, ellipsis: true },
+        { title: '上次采购数量', dataIndex: 'qty', width: '180px', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+        { title: '上次缺货数量', dataIndex: 'cancelQty', width: '180px', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+        { title: '单位', dataIndex: 'dealerProductEntity.unit', width: '80px', align: 'center', customRender: function (text) { return text || '--' } }
+      ],
+      title: '',
+      // 加载数据方法 必须为 Promise 对象
+      loadData: parameter => {
+        this.disabled = true
+        this.spinning = true
+        return purchaseDetailCancelList(Object.assign(parameter, { dealerProductEntity: this.queryParam })).then(res => {
+          let data
+          if (res.status == 200) {
+            data = res.data
+            this.disabled = false
+          }
+          this.spinning = false
+          return data
+        })
+      },
+      spinning: false,
+      rowSelectionInfo: null,
+      productType: [],
+      queryParam: { //  查询条件
+        code: '', //  产品编码
+        name: '', //  产品名称
+        productBrandSn: undefined, //  产品品牌
+        productTypeSn1: '', //  产品一级分类
+        productTypeSn2: '', //  产品二级分类
+        productTypeSn3: '' //  产品三级分类
+      }
+    }
+  },
+  methods: {
+    setTableH () {
+      this.$nextTick(() => {
+        const searchBoxH = this.$refs.searchBox.offsetHeight
+        this.tableHeight = window.innerHeight - searchBoxH - 340
+      })
+    },
+    //  产品分类  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] : ''
+    },
+    // 表格选中项
+    rowSelectionFun (obj) {
+      this.rowSelectionInfo = obj || null
+    },
+    // 保存
+    handleSave () {
+      const _this = this
+      if (!this.rowSelectionInfo || (this.rowSelectionInfo && this.rowSelectionInfo.selectedRowKeys.length < 1)) {
+        this.$message.warning('请在列表勾选后再进行操作!')
+        return
+      }
+      const rows = this.rowSelectionInfo && this.rowSelectionInfo.selectedRows || []
+      const list = []
+      rows.map(item => {
+        list.push({
+          cancelQty: item.cancelQty,
+          qty: item.qty,
+          productSn: item.productSn,
+          price: item.price
+        })
+      })
+
+      const params = {
+        confirm: false,
+        purchaseBillSn: this.paramsData.purchaseBillSn,
+        purchaseBillNo: this.paramsData.purchaseBillNo,
+        purchaseBillDetailEntityList: list
+      }
+      purchaseDetailCancelSave(params).then(res => {
+        if (res.status == 200 && res.data) {
+          let content = ''
+          if ((res.data.productSizeRepeat != res.data.productSize) && (res.data.productSizeRepeat != 0)) {
+            content = `您已经选择 ${res.data.productSize} 个产品,其中 ${res.data.productSizeRepeat} 个产品已经存在于采购单中。本次只会加入不重复的产品,上次缺货数量将作为本次采购数量。确认加入本次采购吗?`
+            this.confirmFun(content, params)
+          } else if (res.data.productSizeRepeat == res.data.productSize) {
+            content = `抱歉,您选择的 ${res.data.productSize} 个产品,采购单中已经全部存在,无需加入!`
+            this.$info({
+              title: '提示',
+              content: content,
+              okText: '好的',
+              centered: true,
+              zIndex: 1100,
+              onOk () {
+                _this.$refs.table.clearSelected() // 清空表格选中项
+              }
+            })
+          } else {
+            content = `您已经选择 ${res.data.productSize} 个产品,上次缺货数量将作为本次采购数量。确认加入本次采购吗?`
+            this.confirmFun(content, params)
+          }
+        }
+      })
+    },
+    confirmFun (content, params) {
+      const _this = this
+      this.$confirm({
+        title: '提示',
+        content: content,
+        okText: '确认加入',
+        cancelText: '重新选择',
+        centered: true,
+        closable: true,
+        zIndex: 1100,
+        onOk () {
+          _this.spinning = true
+          params.confirm = true
+          purchaseDetailCancelSave(params).then(res => {
+            if (res.status == 200) {
+              _this.$emit('ok')
+              _this.isShow = false
+              _this.spinning = false
+            } else {
+              _this.spinning = false
+            }
+          })
+        },
+        onCancel () {
+          _this.$refs.table.clearSelected() // 清空表格选中项
+        }
+      })
+    },
+    onCancel () {
+      this.$emit('close')
+      this.$refs.table.clearSelected() // 清空表格选中项
+    },
+    searchForm () {
+      this.$refs.table.refresh(true)
+    },
+    resetSearchForm () {
+      this.queryParam = {
+        productBrandSn: undefined,
+        code: '', //  产品编码
+        name: '', //  产品名称
+        productTypeSn1: '', //  产品一级分类
+        productTypeSn2: '', //  产品二级分类
+        productTypeSn3: '' //  产品三级分类
+      }
+      this.productType = []
+      this.$refs.table.refresh(true)
+    }
+  },
+  watch: {
+    '$store.state.app.winHeight' (newValue, oldValue) { //  窗口变更时,需同时更改表格高度
+      this.setTableH()
+    },
+    //  父页面传过来的弹框状态
+    openModal (newValue, oldValue) {
+      this.isShow = newValue
+    },
+    //  重定义的弹框状态
+    isShow (newValue, oldValue) {
+      if (!newValue) {
+        this.onCancel()
+      } else {
+        setTimeout(() => {
+          this.setTableH()
+        }, 200)
+        this.resetSearchForm()
+        this.title = '上次采购缺货产品明细(采购单号:' + this.paramsData.purchaseBillNo + ')'
+      }
+    }
+  }
+}
+</script>
+
+<style lang="less">
+  .outStock-modal{
+    .ant-drawer-header{
+      padding: 13px 20px;
+    }
+    .ant-drawer-body{
+      padding: 15px 20px;
+      height: calc(100% - 50px);
+    }
+    .outStock-con{
+      .actions-buttons{
+        padding: 10px 0;
+      }
+    }
+  }
+</style>

+ 11 - 3
src/views/salesManagement/productPricing/list.vue

@@ -61,7 +61,7 @@
       <a-checkbox v-model="isCityPrice" v-if="dealerData && dealerData.dealerLevel != 'SPECIAL'"><span style="display: inline-block;">市级价</span></a-checkbox>
       <!-- 是否展示特约价 -->
       <a-checkbox v-model="isSpecialPrice" v-if="dealerData && dealerData.isShowSpecialPrice == '1'"><span style="display: inline-block;">特约价</span></a-checkbox>
-      <a-checkbox v-model="isTerminalPrice"><span style="display: inline-block;">终端会员价</span></a-checkbox>
+      <a-checkbox v-model="isTerminalPrice"><span style="display: inline-block;">终端价/自定义终端价</span></a-checkbox>
     </div>
     <!-- 列表 -->
     <s-table
@@ -75,6 +75,14 @@
       :scroll="{ y: tableHeight }"
       :defaultLoadData="false"
       bordered>
+      <!-- 车主价 -->
+      <template slot="carOwners" slot-scope="text, record">
+        {{ (record.carOwnersPrice ||record.carOwnersPrice==0)?toThousands(record.carOwnersPrice):'--' }}/{{ record.dealerProductPrice &&(record.dealerProductPrice.carOwnersPrice ||record.dealerProductPrice.carOwnersPrice==0)? toThousands(record.dealerProductPrice.carOwnersPrice):'--' }}
+      </template>
+      <!-- 终端价 -->
+      <template slot="terminal" slot-scope="text, record">
+        {{ (record.terminalPrice ||record.terminalPrice==0)?toThousands(record.terminalPrice):'--' }}/{{ record.dealerProductPrice &&(record.dealerProductPrice.terminalPrice ||record.dealerProductPrice.terminalPrice==0)? toThousands(record.dealerProductPrice.terminalPrice):'--' }}
+      </template>
       <!-- 操作 -->
       <template slot="action" slot-scope="text, record">
         <a-button
@@ -157,7 +165,7 @@ export default {
         { title: '原厂编码', dataIndex: 'origCode', width: '11%', align: 'center', customRender: function (text) { return text || '--' } },
         { title: '品牌', dataIndex: 'productBrandName', width: '11%', align: 'center', customRender: function (text) { return text || '--' }, sorter: true },
         { title: '库存数量', dataIndex: 'stockQty', width: '6%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
-        { title: '车主价', dataIndex: 'carOwnersPrice', width: '6%', align: 'right', customRender: function (text) { return ((text || text == 0) ? _this.toThousands(text) : '--') } },
+        { title: '车主价/自定义车主价', scopedSlots: { customRender: 'carOwners' }, width: '12%', align: 'right' },
         { title: '产品状态', dataIndex: 'onlineFalgDictValue', width: '6%', align: 'center', customRender: function (text) { return text || '--' }, ellipsis: true },
         { title: '操作', scopedSlots: { customRender: 'action' }, width: '6%', align: 'center' }
       ]
@@ -180,7 +188,7 @@ export default {
         arr.splice(ind, 0, { title: '特约价', dataIndex: 'specialPrice', width: '6%', align: 'right', customRender: function (text) { return ((text || text == 0) ? _this.toThousands(text) : '--') } })
       }
       if (this.isTerminalPrice) {
-        arr.splice(arr.length - 2, 0, { title: '终端会员价', dataIndex: 'terminalPrice', width: '6%', align: 'right', customRender: function (text) { return ((text || text == 0) ? _this.toThousands(text) : '--') } })
+        arr.splice(arr.length - 2, 0, { title: '终端价/自定义终端价', scopedSlots: { customRender: 'terminal' }, width: '12%', align: 'right' })
       }
       return arr
     }

+ 5 - 3
src/views/salesManagement/salesQuery/edit.vue

@@ -66,7 +66,7 @@
         <!-- 搜索条件 -->
         <div class="table-page-search-wrapper">
           <a-row :gutter="15">
-            <a-col :md="24" :lg="14">
+            <a-col :md="24" :lg="12">
               <a-form-model :model="productForm" ref="ruleForm" layout="inline" @keyup.enter.native="$refs.table.refresh(true)" >
                 <a-row :gutter="15">
                   <a-col :md="8" :sm="24">
@@ -88,7 +88,7 @@
                 </a-row>
               </a-form-model>
             </a-col>
-            <a-col :md="24" :lg="10">
+            <a-col :md="24" :lg="12">
               <div style="float:right;overflow: hidden;margin-bottom:10px;">
                 <a-checkbox :value="0" :checked="tbForm.indexOf('AUDIT')>=0" @change="(e)=>{tbFormChange(e,0)}" id="salesQuery-tbsh">同步审核</a-checkbox>
                 <a-checkbox :value="1" :checked="tbForm.indexOf('STOCK_OUT')>=0" @change="(e)=>{tbFormChange(e,1)}" id="salesQuery-tbck">同步出库</a-checkbox>
@@ -109,9 +109,11 @@
                   type="default"
                   v-if="shelfInfo&&shelfInfo.state=='ENABLE'"
                   @click="showShelfModal=true"
+                  style="margin-right:5px;"
                   id="salesEdit-shelf">货架产品</a-button>
                 <a-button
-                  type="link"
+                  type="primary"
+                  ghost
                   @click="delSalerOrder"
                   :loading="delLoading"
                   id="salesEdit-del-all">整单删除</a-button>

+ 4 - 4
src/views/salesManagement/salesQuery/queryPart.vue

@@ -9,7 +9,7 @@
         :rules="rules"
         :model="queryParam"
         @keyup.enter.native="$refs.table.refresh(true)" >
-        <a-row :gutter="5">
+        <a-row type="flex" :gutter="5">
           <a-col :lg="4" :md="6" :sm="12">
             <a-form-model-item label="产品编码">
               <a-input id="productInfoList-code" ref="searchProductCode" v-model.trim="queryParam.productCode" allowClear placeholder="请输入产品编码"/>
@@ -59,7 +59,7 @@
               </a-form-model-item>
             </a-col>
           </template>
-          <a-col :lg="3" :md="8" :sm="12" style="margin-bottom: 10px;">
+          <a-col flex="200px" style="margin-bottom: 10px;">
             <a-button type="primary" @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 @click="advanced=!advanced" style="margin:0 0 0 10px">
@@ -67,7 +67,7 @@
               <a-icon :type="advanced ? 'up' : 'down'"/>
             </a>
           </a-col>
-          <a-col :lg="5" :md="8" :sm="12" style="margin-top: 6px;">
+          <a-col flex="240px" style="margin-bottom: 15px;display:flex;align-items:center;">
             <a-checkbox v-model="cost" v-if="$hasPermissions('M_ShowAllCost')" id="salesQuery-cost">成本价</a-checkbox>
             <a-checkbox v-model="cityPrice" id="salesQuery-cityPrice">市级价</a-checkbox>
             <a-checkbox v-model="tyuePrice" v-if="$store.state.user.isShowSpecialPrice==1" id="salesQuery-tyuePrice">特约价</a-checkbox>
@@ -323,7 +323,7 @@ export default {
             data.list[i].no = data.list[i].productSn + '_' + (no + i + 1)
             data.list[i].salesNums = 1
             data.list[i].currentQty = data.list[i].currentQty || 0
-            data.list[i].price = data.list[i].lastSalePrice ? data.list[i].lastSalePrice : data.list[i].salePrice
+            data.list[i].price = data.list[i].origSalePriceFlag == 0 ? data.list[i].lastSalePrice : data.list[i].origSalePriceFlag == 1 ? data.list[i].salePrice : data.list[i].selfSaleprice
             data.list[i].productOrigCode = data.list[i].productOrigCode ? data.list[i].productOrigCode.trim() : ''
           }
           if (!params.vinCode) {

+ 4 - 3
src/views/salesManagement/salesReturn/queryPart.vue

@@ -164,9 +164,10 @@ export default {
       loadData: parameter => {
         this.disabled = true
         // 抓单时
-        if (this.grabFlag == 1) {
-          this.queryParam.buyerSn = this.buyerSn
-        }
+        // if (this.grabFlag == 1) {
+        //   this.queryParam.buyerSn = this.buyerSn
+        // }
+        this.queryParam.buyerSn = this.buyerSn
         const fun = [stockList, salesReturnProductList]
         if (this.grabFlag == 0) {
           this.queryParam.salePriceType = this.priceType

+ 2 - 2
src/views/salesManagement/salesReturn/salesReturnEdit.vue

@@ -80,8 +80,8 @@
                   @click="handleSubmit()"
                   id="salesReturn-handleSubmit">提交</a-button>
                 <a-button
-                  size="small"
-                  type="link"
+                  type="primary"
+                  ghost
                   @click="salesReturnDelAll"
                   :loading="delLoading"
                   style="margin-left: 10px"

+ 2 - 2
src/views/salesManagement/salesReturn/salesReturnGrabEdit.vue

@@ -81,8 +81,8 @@
                   @click="handleSubmit()"
                   id="salesReturn-handleSubmit">提交</a-button>
                 <a-button
-                  size="small"
-                  type="link"
+                  type="primary"
+                  ghost
                   @click="salesReturnDelAll"
                   :loading="delLoading"
                   style="margin-left: 10px"

+ 408 - 0
src/views/shoppingCarManagement/shoppingCar/list.vue

@@ -0,0 +1,408 @@
+<template>
+  <a-card size="small" :bordered="false" class="shoppingCar-wrap">
+    <!-- 搜索条件 -->
+    <div ref="tableSearch" class="table-page-search-wrapper">
+      <a-form layout="inline" @keyup.enter.native="searchForm()">
+        <a-row type="flex" :gutter="12" justify="start">
+          <a-col flex="auto">
+            <a-form-item label="产品编码">
+              <a-input id="shoppingCar-code" v-model.trim="queryParam.code" allowClear placeholder="请输入产品编码"/>
+            </a-form-item>
+          </a-col>
+          <a-col flex="auto">
+            <a-form-item label="产品名称">
+              <a-input id="shoppingCar-name" v-model.trim="queryParam.name" allowClear placeholder="请输入产品名称"/>
+            </a-form-item>
+          </a-col>
+          <a-col flex="250px">
+            <a-form-item label="产品分类">
+              <ProductType id="shoppingCar-productType" placeholder="请选择产品分类" :isDealer="true" @change="changeProductType" v-model="productType"></ProductType>
+            </a-form-item>
+          </a-col>
+          <a-col flex="250px">
+            <a-form-item label="产品品牌">
+              <ProductBrand id="shoppingCar-productBrandSn" placeholder="请选择产品品牌" v-model="queryParam.productBrandSn"></ProductBrand>
+              </a-select>
+            </a-form-item>
+          </a-col>
+          <a-col flex="250px" v-if="modes=='pages'">
+            <a-form-item label="产品状态">
+              <v-select
+                code="ONLINE_FLAG2"
+                id="productPricingList-onlineFalg"
+                v-model="queryParam.onlineFalg"
+                allowClear
+                placeholder="请选择产品状态"
+              ></v-select>
+            </a-form-item>
+          </a-col>
+          <a-col flex="auto" style="margin-bottom:10px;">
+            <a-button type="primary" @click="searchForm()" :disabled="disabled" id="shoppingCar-refresh">查询</a-button>
+            <a-button style="margin-left: 5px" @click="resetSearchForm()" :disabled="disabled" id="shoppingCar-reset">重置</a-button>
+          </a-col>
+        </a-row>
+      </a-form>
+      <!-- 操作按钮 -->
+      <div class="table-operator">
+        <a-row :gutter="16">
+          <a-col class="gutter-row" :span="24">
+            <a-button type="primary" :loading="loading" ghost v-if="modes=='pages'" @click="deleteMore">
+              批量删除
+            </a-button>
+            <a-button type="primary" :loading="loading" ghost v-if="modes=='modals'" @click="addMore">
+              批量添加
+            </a-button>
+            <span style="font-weight: bold;margin-left:15px;" v-if="rowSelectionInfo&&rowSelectionInfo.selectedRowKeys.length">已选 {{ rowSelectionInfo.selectedRowKeys.length }} 项</span>
+          </a-col>
+        </a-row>
+      </div>
+    </div>
+    <!-- 列表 -->
+    <s-table
+      class="sTable"
+      ref="table"
+      :style="modes=='pages'?{ height: tableHeight+84.5+'px' }:{}"
+      size="small"
+      :row-selection="modes=='pages'?{ columnWidth: 40 }:{ columnWidth: 40, getCheckboxProps: record => ({ props: { disabled: !record.productEntity.purchasePrice || !(record.productEntity.onlineFalg == 1&& record.dealerScopeFlag == 1) } }) }"
+      @rowSelection="rowSelectionFun"
+      rowKeyName="productSn"
+      :rowKey="(record) => record.productSn"
+      :columns="columns"
+      :data="loadData"
+      :scroll="modes=='pages'?{ y: tableHeight }:{ x:tableWidth, y: tableHeight }"
+      :defaultLoadData="false"
+      :pageSize="30"
+      bordered>
+      <!-- 采购数量 -->
+      <template slot="purchaseQty" slot-scope="text, record">
+        <a-input-number
+          size="small"
+          v-model="record.qty"
+          :precision="0"
+          :min="1"
+          :max="999999"
+          @blur="updateQty(record)"
+          style="width: 100%;"
+          placeholder="请输入采购数量" />
+      </template>
+      <!-- 包装数 -->
+      <template slot="baozh" slot-scope="text, record">
+        {{ record.productEntity.packQty||'--' }}{{ record.productEntity.packQty ? record.productEntity.unit : '' }}/{{ record.productEntity.packQtyUnit||'--' }}
+      </template>
+      <!-- 产品编码 -->
+      <template slot="productCode" slot-scope="text, record">
+        <div v-if="modes=='pages'">
+          <span style="padding-right: 15px;">{{ text }}</span>
+          <a-tag v-if="record.productEntity.onlineFalg == 0">下架</a-tag>
+        </div>
+        <div v-else>
+          <span style="padding-right: 15px;">{{ text }}</span>
+          <a-tag v-if="record.productEntity.onlineFalg == 0">下架</a-tag>
+          <a-tag color="red" v-else-if="record.productEntity.onlineFalg == 1&& record.dealerScopeFlag == 0">无权限</a-tag>
+        </div>
+      </template>
+    </s-table>
+  </a-card>
+</template>
+
+<script>
+import { commonMixin } from '@/utils/mixin'
+import { mapActions } from 'vuex'
+import { purchaseCartList, purchaseDeleteBatch, purchaseUpdateQty } from '@/api/purchaseCart'
+import { purchaseDetailCancelSave } from '@/api/purchaseDetail'
+import ProductType from '../../common/productType.js'
+import ProductBrand from '../../common/productBrand.js'
+import { STable, VSelect } from '@/components'
+export default {
+  name: 'ShoppingCarList',
+  components: { STable, VSelect, ProductType, ProductBrand },
+  mixins: [commonMixin],
+  props: {
+    modes: {
+      type: String,
+      default: 'pages'
+    }
+  },
+  data () {
+    return {
+      loading: false,
+      tableHeight: 0,
+      tableWidth: 960,
+      productType: [],
+      queryParam: { //  查询条件
+        code: '', //  产品编码
+        name: '', //  产品名称
+        productBrandSn: undefined, //  产品品牌
+        productTypeSn1: '', //  产品一级分类
+        productTypeSn2: '', //  产品二级分类
+        productTypeSn3: '', //  产品三级分类
+        onlineFalg: undefined
+      },
+      paramsData: null,
+      openEditPriceModal: false, // 自定义报价弹窗
+      disabled: false, //  查询、重置按钮是否可操作
+      columns: [],
+      // 加载数据方法 必须为 Promise 对象
+      loadData: parameter => {
+        this.disabled = true
+        this.spinning = true
+        return purchaseCartList(Object.assign(parameter, { productEntity: this.queryParam }, this.paramsData)).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].qtyBack = data.list[i].qty
+            }
+            this.disabled = false
+          }
+          this.spinning = false
+          return data
+        })
+      },
+      rowSelectionInfo: null
+    }
+  },
+  methods: {
+    ...mapActions(['getCartList']),
+    // 查询
+    searchForm (flag) {
+      this.$refs.table.refresh(true)
+      if (flag) {
+        this.$refs.table.clearSelected()
+        this.rowSelectionInfo = null
+      }
+    },
+    //  重置
+    resetSearchForm (flag) {
+      this.queryParam.code = ''
+      this.queryParam.name = ''
+      this.queryParam.productBrandSn = undefined
+      this.queryParam.productTypeSn1 = ''
+      this.queryParam.productTypeSn2 = ''
+      this.queryParam.productTypeSn3 = ''
+      this.queryParam.onlineFalg = undefined
+      this.productType = []
+      this.$refs.table.refresh(true)
+      if (flag) {
+        this.$refs.table.clearSelected()
+        this.rowSelectionInfo = null
+      }
+    },
+    // 设置表头
+    getColumns () {
+      const _this = this
+      if (this.modes == 'pages') {
+        this.columns = [
+          { title: '产品编码', dataIndex: 'productEntity.code', scopedSlots: { customRender: 'productCode' }, width: '20%', align: 'center' },
+          { title: '产品名称', dataIndex: 'productEntity.name', width: '30%', align: 'center', customRender: function (text) { return text || '--' }, ellipsis: true },
+          { title: '可用库存数量', dataIndex: 'currentStockQty', width: '14%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+          { title: '成本价', dataIndex: 'productEntity.purchasePrice', width: '8%', align: 'right', customRender: function (text) { return ((text || text == 0) ? _this.toThousands(text) : '--') } },
+          { title: '单位', dataIndex: 'productEntity.unit', width: '8%', align: 'center', customRender: function (text) { return (!text || text == ' ') ? '--' : text } },
+          { title: '包装数', scopedSlots: { customRender: 'baozh' }, dataIndex: 'productEntity.packQty', width: '8%', align: 'center' },
+          { title: '采购数量', scopedSlots: { customRender: 'purchaseQty' }, width: '12%', align: 'center' }
+        ]
+      } else {
+        this.columns = [
+          { title: '产品编码', dataIndex: 'productEntity.code', scopedSlots: { customRender: 'productCode' }, width: '200px', align: 'center', fixed: 'left' },
+          { title: '产品名称', dataIndex: 'productEntity.name', width: '250px', align: 'center', customRender: function (text) { return text || '--' }, ellipsis: true },
+          { title: '可用库存数量', dataIndex: 'currentStockQty', width: '140px', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+          { title: '成本价', dataIndex: 'productEntity.purchasePrice', width: '80px', align: 'right', customRender: function (text) { return ((text || text == 0) ? _this.toThousands(text) : '--') } },
+          { title: '单位', dataIndex: 'productEntity.unit', width: '80px', align: 'center', customRender: function (text) { return (!text || text == ' ') ? '--' : text } },
+          { title: '包装数', scopedSlots: { customRender: 'baozh' }, dataIndex: 'productEntity.packQty', width: '80px', align: 'center' },
+          { title: '采购数量', scopedSlots: { customRender: 'purchaseQty' }, width: '120px', align: 'center', fixed: 'right' }
+        ]
+      }
+    },
+    //  产品分类  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] : ''
+    },
+    // 表格选中项
+    rowSelectionFun (obj) {
+      this.rowSelectionInfo = obj || null
+    },
+    // 修改数量
+    updateQty (row) {
+      if (row.qty != row.qtyBack && row.qty) {
+        purchaseUpdateQty({ qty: row.qty, purchaseCartSn: row.purchaseCartSn }).then(res => {
+          if (res.status == 200) {
+            this.$message.info(res.message)
+            row.qtyBack = row.qty
+          } else {
+            row.qty = row.qtyBack
+          }
+        })
+      } else {
+        row.qty = row.qtyBack
+      }
+    },
+    // 批量删除
+    deleteMore () {
+      const rows = this.rowSelectionInfo && this.rowSelectionInfo.selectedRowKeys || []
+      if (!this.rowSelectionInfo || (rows.length <= 0)) {
+        this.$message.warning('请在列表勾选后再进行批量操作!')
+        return
+      }
+      this.$confirm({
+        title: '提示',
+        content: '您已经选择' + rows.length + '个产品,确认要将已选产品从购物车中移除吗?',
+        centered: true,
+        onOk: () => {
+          this.loading = true
+          purchaseDeleteBatch({
+            productSnList: rows
+          }).then(res => {
+            if (res.status == 200) {
+              this.$message.info(res.message)
+              this.getCartList()
+              this.searchForm(true)
+            }
+            this.loading = false
+          })
+        }
+      })
+    },
+    // 保存
+    addMore () {
+      const _this = this
+      const rows = this.rowSelectionInfo && this.rowSelectionInfo.selectedRowKeys || []
+      if (!this.rowSelectionInfo || (rows.length <= 0)) {
+        this.$message.warning('请在列表勾选后再进行批量操作!')
+        return
+      }
+      const rowsList = this.rowSelectionInfo && this.rowSelectionInfo.selectedRows || []
+      const list = []
+      rowsList.map(item => {
+        list.push({
+          cancelQty: item.qty,
+          qty: item.qty,
+          productSn: item.productSn,
+          price: item.productEntity.purchasePrice
+        })
+      })
+      const params = {
+        confirm: false,
+        purchaseBillSn: this.paramsData.purchaseBillSn,
+        purchaseBillNo: this.paramsData.purchaseBillNo,
+        purchaseBillDetailEntityList: list,
+        purchaseCartFlag: true
+      }
+      purchaseDetailCancelSave(params).then(res => {
+        if (res.status == 200 && res.data) {
+          let content = ''
+          if ((res.data.productSizeRepeat != res.data.productSize) && (res.data.productSizeRepeat != 0)) {
+            content = `您已经选择 ${res.data.productSize} 个产品,其中 ${res.data.productSizeRepeat} 个产品已经存在于采购单中,本次只会加入不重复的产品。确认加入本次采购吗?`
+            this.confirmFun(content, params)
+          } else if (res.data.productSizeRepeat == res.data.productSize) {
+            content = `抱歉,您选择的 ${res.data.productSize} 个产品,采购单中已经全部存在,无需加入!`
+            this.$info({
+              title: '提示',
+              content: content,
+              okText: '好的',
+              centered: true,
+              zIndex: 1100,
+              onOk () {
+                _this.$refs.table.clearSelected() // 清空表格选中项
+              }
+            })
+          } else {
+            content = `您已经选择 ${res.data.productSize} 个产品,确认要将已选产品加入本次采购吗?`
+            this.confirmFun(content, params)
+          }
+        }
+      })
+    },
+    confirmFun (content, params) {
+      const _this = this
+      this.$confirm({
+        title: '提示',
+        content: content,
+        okText: '确认加入',
+        cancelText: '重新选择',
+        centered: true,
+        closable: true,
+        zIndex: 1100,
+        onOk () {
+          _this.loading = true
+          params.confirm = true
+          purchaseDetailCancelSave(params).then(res => {
+            if (res.status == 200) {
+              _this.$emit('ok')
+              _this.getCartList()
+              _this.searchForm(true)
+              _this.loading = false
+            } else {
+              _this.loading = false
+            }
+          })
+        },
+        onCancel () {
+          _this.$refs.table.clearSelected() // 清空表格选中项
+        }
+      })
+    },
+    pageInit (paramsData) {
+      this.paramsData = paramsData || {}
+      this.getColumns()
+      this.setTableH()
+      this.resetSearchForm()
+    },
+    setTableH () {
+      this.$nextTick(() => { // 页面渲染完成后的回调
+        const tableSearchH = this.$refs.tableSearch.offsetHeight
+        this.tableHeight = window.innerHeight - tableSearchH - (this.modes == 'pages' ? 200 : 290)
+      })
+    }
+  },
+  watch: {
+    '$store.state.app.winHeight' (newValue, oldValue) { //  窗口变更时,需同时更改表格高度
+      this.setTableH()
+    }
+  },
+  mounted () {
+    if (!this.$store.state.app.isNewTab) { // 页签刷新时调用
+      this.pageInit()
+    }
+  },
+  activated () {
+    // 如果是新页签打开,则重置当前页面
+    if (this.$store.state.app.isNewTab) {
+      this.pageInit()
+    }
+  },
+  beforeRouteEnter (to, from, next) {
+    next(vm => {})
+  }
+}
+</script>
+<style lang="less" scoped>
+.setTableList{
+  text-align: right;
+  position: relative;
+  span{
+    margin-right: 10px;
+    color:#56a2fb;
+  }
+  .setTableList-box{
+    padding:10px 12px;
+    border:1px solid #d5d5d5;
+    border-radius: 5px;
+    background:#fff;
+    text-align: left;
+    position: absolute;
+    top:22px;
+    right:0;
+    z-index: 99999;
+    div{
+      margin-bottom: 10px;
+      &:last-child{
+        margin-bottom: 0px;
+      }
+    }
+  }
+}
+</style>