Sfoglia il codice sorgente

Merge branch 'develop_yh13' of http://git.chelingzhu.com/jianguan-web/qpls-md-html into develop_yh13

chenrui 2 anni fa
parent
commit
c2166c460c

BIN
public/logo1.png


BIN
public/templ/库存预警产品导入模板.xlsx


+ 1 - 1
public/version.json

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

+ 61 - 16
src/config/router.config.js

@@ -774,18 +774,65 @@ export const asyncRouterMap = [
                   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 +842,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 +854,8 @@ export const asyncRouterMap = [
                 meta: {
                   title: '签收入库列表',
                   icon: 'money-collect',
-                  hidden: true
-                  // permission: 'M_signWarehousingList'
+                  hidden: true,
+                  permission: 'M_signWarehousingList'
                 }
               },
               {
@@ -820,7 +867,6 @@ export const asyncRouterMap = [
                   icon: 'money-collect',
                   replaceTab: true,
                   hidden: true
-                  // permission: 'B_signWarehousingDetail'
                 }
               },
               {
@@ -832,7 +878,6 @@ export const asyncRouterMap = [
                   icon: 'money-collect',
                   replaceTab: true,
                   hidden: true
-                  // permission: 'B_signWarehousingStockOrderDetail'
                 }
               }
             ]
@@ -844,8 +889,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 +901,8 @@ export const asyncRouterMap = [
                 meta: {
                   title: '采购退货申请单列表',
                   icon: 'money-collect',
-                  hidden: true
-                  // permission: 'M_purchaseReturnApplyFormList'
+                  hidden: true,
+                  permission: 'M_purchaseReturnApplyFormList'
                 }
               },
               {

+ 1 - 0
src/views/chainReportData/chainStockReport/list.vue

@@ -338,6 +338,7 @@ export default {
     handleExport () {
       const _this = this
       const params = JSON.parse(JSON.stringify(this.queryParam))
+      params.showCost = this.$hasPermissions('M_ShowAllCost') ? '1' : '0'
       if (params.tenantId) {
         this.exportLoading = true
         _this.spinning = true

+ 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


+ 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 {

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

@@ -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'

+ 3 - 14
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' },
@@ -278,10 +271,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

+ 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="unTable 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: 'productUnit', 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: '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>

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

@@ -0,0 +1,285 @@
+<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 class="table-page-search-wrapper">
+          <a-form layout="inline" @keyup.enter.native="$refs.table.refresh(true)">
+            <a-row :gutter="15">
+              <a-col :md="5" :sm="24">
+                <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 :md="5" :sm="24">
+                <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 :md="4" :sm="24">
+              <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 :md="5" :sm="24">
+                <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 :md="5" :sm="24">
+                <a-form-item label="产品品牌">
+                  <ProductBrand id="purchaseOrderEdit-productBrand" :tenantId="$route.params.dealerSn" v-model="queryParam.productBrandSn"></ProductBrand>
+                </a-form-item>
+              </a-col>
+              <a-col :md="4" :sm="24" style="margin-bottom: 10px;">
+                <a-button type="primary" @click="$refs.table.refresh(true)" :disabled="disabled" id="purchaseOrderEdit-refresh">查询</a-button>
+                <a-button style="margin-left: 5px" @click="resetSearchForm" :disabled="disabled" id="purchaseOrderEdit-reset">重置</a-button>
+              </a-col>
+            </a-row>
+          </a-form>
+        </div>
+        <!-- 列表 -->
+        <s-table
+          class="sTable"
+          ref="table"
+          size="small"
+          :rowKey="(record) => record.id"
+          :columns="columns"
+          :data="loadData"
+          :defaultLoadData="false"
+          :scroll="{ x: tableWidth , y:tableHeight }"
+          @dblclick="handleAdd"
+          :pageSize="20"
+          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.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">
+            <a-input-number
+              size="small"
+              v-model="record.qty"
+              :precision="0"
+              :min="0"
+              :max="999999"
+              style="width: 100%;"
+              placeholder="请输入数量" />
+          </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>
+    </a-spin>
+  </a-drawer>
+</template>
+
+<script>
+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()
+      }
+    }
+  },
+  data () {
+    return {
+      visible: this.showModal,
+      title: '添加产品',
+      tableHeight: 0,
+      // 选择产品
+      addLoading: false,
+      spinning: false,
+      productType: [],
+      queryParam: {
+        productBrandSn: undefined,
+        code: '', //  产品编码
+        name: '', //  产品名称
+        origCode: '', //  原厂编码
+        productTypeSn1: '', //  产品一级分类
+        productTypeSn2: '', //  产品二级分类
+        productTypeSn3: '' //  产品三级分类
+      },
+      advanced: false, //  高级搜索 展开/关闭
+      disabled: 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
+          }
+          this.disabled = false
+          return data
+        })
+      },
+      defImg
+    }
+  },
+  computed: {
+    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] : ''
+    },
+    // 重置产品库
+    resetSearchForm () {
+      this.queryParam = {
+        productBrandSn: undefined,
+        code: '', //  产品编码
+        name: '', //  产品名称
+        origCode: '', //  原厂编码
+        productTypeSn1: '', //  产品一级分类
+        productTypeSn2: '', //  产品二级分类
+        productTypeSn3: '' //  产品三级分类
+      }
+      this.productType = []
+      this.$refs.table.refresh(true)
+    },
+    onClose () {
+      this.$emit('close')
+    },
+    handleAdd (record) {
+      this.spinning = true
+      this.$emit('add', record, 0)
+    },
+    setTableH () {
+      this.tableHeight = window.innerHeight - 330
+    }
+  }
+}
+</script>
+
+<style lang="less">
+.chooseProduct-drawer {
+  .ant-drawer-header{
+    padding: 13px 20px;
+  }
+  .ant-drawer-body {
+    padding: 15px 20px;
+    height: calc(100% - 55px);
+    display: flex;
+    flex-direction: column;
+    overflow: auto;
+    > div {
+      height: 100%;
+    }
+  }
+}
+</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>

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

@@ -0,0 +1,541 @@
+<template>
+  <div v-if="showPage" class="purchaseOrderEdit-wrap">
+    <a-page-header :ghost="false" :backIcon="false" class="purchaseOrderEdit-cont">
+      <!-- 自定义的二级文字标题 -->
+      <template slot="subTitle">
+        <a id="purchaseOrderEdit-back-btn" href="javascript:;" @click="handleBack"><a-icon type="left" /> 返回列表</a>
+        <p class="billno">单号:{{ detail&&detail.purchaseBillNo }}</p>
+        <a-button type="primary" 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;" 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>
+      <!-- 已选产品 -->
+      <div>
+        <div class="chooseBox-title">
+          <div class="sub-title" style="display: flex;">
+            已选产品
+            <p class="tag-txt">注意:仅限采购【箭冠】产品。自建产品的采购入库请使用“散件入库”功能</p>
+          </div>
+          <div class="actions-button">
+            <a-button id="purchaseOrderEdit-add-btn" type="primary" ghost @click="openChooseProduct=true">添加产品</a-button>
+            <a-button id="purchaseOrderEdit-import-btn" type="primary" ghost @click="openGuideModal=true">产品导入</a-button>
+            <a-button id="purchaseOrderEdit-outStock-btn" type="primary" ghost @click="handleOutStock">上次缺货</a-button>
+            <a-button id="purchaseOrderEdit-cart-btn" type="primary" ghost>购物车</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="8" :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="8" :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="purchaseOrderEdit-refresh">查询</a-button>
+                        <a-button style="margin-left: 5px" @click="resetPurchaseForm" id="purchaseOrderEdit-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"
+            size="small"
+            :rowKey="(record) => record.id"
+            :columns="chooseColumns"
+            :data="chooseLoadData"
+            :defaultLoadData="false"
+            :showPagination="false"
+            :scroll="{ y:tableHeight }"
+            bordered>
+            <!-- 采购数量 -->
+            <template slot="storageQuantity" slot-scope="text, record">
+              <a-input-number
+                size="small"
+                id="purchaseOrderEdit-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="purchaseOrderEdit-del-btn">删除</a-button>
+            </template>
+          </s-table>
+        </div>
+        <div v-else>
+          <div v-if="!spinning">
+            <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-else>
+            <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="purchaseOrderEdit-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" />
+    <!-- 上次缺货 -->
+    <outStockModal :openModal="openOutStockModal" :paramsData="paramsData" @close="openOutStockModal=false" @ok="hanldeOkOutStock" />
+    <!-- 选择地址 -->
+    <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'
+export default {
+  name: 'PurchaseEdit',
+  components: { STable, VSelect, ImportGuideModal, outStockModal, Print, chooseAddressModal, chooseProductModal },
+  mixins: [commonMixin],
+  data () {
+    return {
+      isShowBisiceInfo: false,
+      showPage: false,
+      spinning: false,
+      detail: null, // 详细信息
+      openChooseProduct: 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
+        // 查询总计
+        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: '30%', align: 'center', customRender: function (text) { return text || '--' }, ellipsis: true },
+        { title: '采购数量', scopedSlots: { customRender: 'storageQuantity' }, width: '10%', 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: '20%', align: 'right', customRender: function (text) { return ((text || text == 0) ? _this.toThousands(text, 2) : '--') } })
+        arr.splice(6, 0, { title: '采购金额', dataIndex: 'discountedAmount', width: '9%', 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 (isReset) {
+              this.resetPurchaseForm()
+            } else {
+              this.$refs.purchaseTable.refresh(!!flag)
+            }
+          } 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)
+        }
+        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)
+    },
+    // 上次缺货
+    handleOutStock () {
+      // 校验是否存在历史采购单,且上次采购存在缺货产品
+      purchaseDetailCancelList({ pageNo: 1, pageSize: 5 }).then(res => {
+        if (res.status == 200) {
+          this.paramsData = {
+            purchaseBillSn: this.$route.params.sn,
+            purchaseBillNo: this.detail && this.detail.purchaseBillNo ? this.detail.purchaseBillNo : undefined
+          }
+          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
+      _this.spinning = 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.spinning = false
+      })
+    },
+    //  返回列表
+    handleBack () {
+      this.$router.push({ name: 'purchaseOrderNewList' })
+    },
+    setTableH () {
+      this.tableHeight = window.innerHeight - 350
+    },
+    pageInit () {
+      this.$nextTick(() => {
+        this.setTableH()
+        this.getOrderDetail(false, true)
+      })
+    }
+  },
+  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">
+  .purchaseOrderEdit-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;
+            }
+          }
+        }
+      }
+    }
+    .purchaseOrderEdit-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>

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

@@ -0,0 +1,393 @@
+<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 :gutter="15">
+            <a-col :md="6" :sm="24">
+              <a-form-item label="创建时间">
+                <rangeDate ref="rangeDate" :value="time" @change="dateChange" />
+              </a-form-item>
+            </a-col>
+            <a-col :md="6" :sm="24">
+              <a-form-item label="采购单号">
+                <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="供应商" :label-col="{ span:7 }" :wrapper-col="{ span:17}">
+                <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="业务状态">
+                <!-- <v-select
+                  v-model="queryParam.billStatus"
+                  ref="billStatus"
+                  id="purchaseOrderList-billStatus"
+                  code="PURCHASE_BILL_STATUS"
+                  placeholder="请选择业务状态"
+                  allowClear></v-select> -->
+                <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">
+              <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
+        // 获取统计数据
+        this.getTotalData(Object.assign(parameter, this.queryParam))
+        return purchaseList(Object.assign(parameter, this.queryParam)).then(res => {
+          let data
+          if (res.status == 200) {
+            data = res.data
+            const no = (data.pageNo - 1) * data.pageSize
+            for (var i = 0; i < data.list.length; i++) {
+              data.list[i].no = no + i + 1
+            }
+            this.disabled = false
+          }
+          this.spinning = false
+          return data
+        })
+      }
+    }
+  },
+  methods: {
+    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>

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

@@ -0,0 +1,213 @@
+<template>
+  <a-modal
+    centered
+    class="outStock-modal"
+    :footer="null"
+    :maskClosable="false"
+    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>
+          <!-- 列表 -->
+          <s-table
+            class="sTable"
+            ref="table"
+            size="small"
+            :rowKey="(record) => record.productSn"
+            rowKeyName="productSn"
+            :row-selection="{ columnWidth: 40 }"
+            @rowSelection="rowSelectionFun"
+            :data="loadData"
+            :columns="columns"
+            :scroll="{ y: 450 }"
+            bordered>
+          </s-table>
+        </div>
+        <!-- 按钮 -->
+        <div class="btn-con">
+          <a-button
+            type="primary"
+            id="outStock-save"
+            size="large"
+            class="button-primary"
+            @click="handleSave"
+            style="padding: 0 36px;">加入本次采购</a-button>
+          <a-button
+            id="outStock-cancel"
+            size="large"
+            class="button-cancel"
+            @click="isShow=false"
+            style="padding: 0 60px;margin-left: 15px;">取消</a-button>
+        </div>
+      </div>
+    </a-spin>
+  </a-modal>
+</template>
+
+<script>
+import { commonMixin } from '@/utils/mixin'
+import { STable } from '@/components'
+import { purchaseDetailCancelList, purchaseDetailCancelSave } from '@/api/purchaseDetail'
+export default {
+  name: 'OutStockModal',
+  components: { STable },
+  mixins: [commonMixin],
+  props: {
+    openModal: { //  弹框显示状态
+      type: Boolean,
+      default: false
+    },
+    chooseData: {
+      type: Array,
+      default: () => {
+        return []
+      }
+    },
+    paramsData: {
+      type: Object,
+      default: () => {
+        return {}
+      }
+    }
+  },
+  data () {
+    return {
+      isShow: this.openModal, //  是否打开弹框
+      formItemLayout: {
+        labelCol: { span: 4 },
+        wrapperCol: { span: 20 }
+      },
+      disabled: false, //  查询、重置按钮是否可操作
+      columns: [
+        { title: '产品编码', dataIndex: 'dealerProductEntity.code', width: '24%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '产品名称', dataIndex: 'dealerProductEntity.name', width: '32%', align: 'left', customRender: function (text) { return text || '--' }, ellipsis: true },
+        { title: '上次采购数量', dataIndex: 'qty', width: '18%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+        { 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 || '--' } }
+      ],
+      // 加载数据方法 必须为 Promise 对象
+      loadData: parameter => {
+        this.disabled = true
+        this.spinning = true
+        return purchaseDetailCancelList(parameter).then(res => {
+          let data
+          if (res.status == 200) {
+            data = res.data
+            this.disabled = false
+          }
+          this.spinning = false
+          return data
+        })
+      },
+      spinning: false,
+      rowSelectionInfo: null
+    }
+  },
+  methods: {
+    // 表格选中项
+    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 params = {
+        confirm: false,
+        purchaseBillSn: this.paramsData.purchaseBillSn,
+        purchaseBillNo: this.paramsData.purchaseBillNo,
+        purchaseBillDetailEntityList: this.rowSelectionInfo && this.rowSelectionInfo.selectedRows
+      }
+      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)
+          } else if (res.data.productSizeRepeat == res.data.productSize) {
+            content = `抱歉,您选择的 ${res.data.productSize} 个产品,采购单中已经全部存在,无需加入!`
+            this.$info({
+              title: '提示',
+              content: content,
+              okText: '好的',
+              centered: true,
+              onOk () {
+                _this.$refs.table.clearSelected() // 清空表格选中项
+              }
+            })
+          } else {
+            content = `您已经选择 ${res.data.productSize} 个产品,上次缺货数量将作为本次采购数量。确认加入本次采购吗?`
+            this.confirmFun(content)
+          }
+        }
+      })
+    },
+    confirmFun (content) {
+      const _this = this
+      this.$confirm({
+        title: '提示',
+        content: content,
+        okText: '确认加入',
+        cancelText: '重新选择',
+        centered: true,
+        closable: true,
+        onOk () {
+          _this.spinning = true
+          const params = {
+            confirm: true,
+            purchaseBillSn: _this.paramsData.purchaseBillSn,
+            purchaseBillNo: _this.paramsData.purchaseBillNo,
+            purchaseBillDetailEntityList: _this.rowSelectionInfo && _this.rowSelectionInfo.selectedRows
+          }
+          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() // 清空表格选中项
+        }
+      })
+    }
+  },
+  watch: {
+    //  父页面传过来的弹框状态
+    openModal (newValue, oldValue) {
+      this.isShow = newValue
+    },
+    //  重定义的弹框状态
+    isShow (newValue, oldValue) {
+      if (!newValue) {
+        this.$emit('close')
+        this.$refs.table.clearSelected() // 清空表格选中项
+      }
+    }
+  }
+}
+</script>
+
+<style lang="less" scoped>
+  .outStock-modal{
+    .outStock-con{
+      .btn-con{
+        text-align: center;
+        margin: 30px 0 20px;
+        .button-cancel{
+          font-size: 12px;
+        }
+      }
+    }
+  }
+</style>