Sfoglia il codice sorgente

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

lilei 2 anni fa
parent
commit
e353720c96

+ 1 - 1
public/version.json

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

+ 184 - 0
src/api/purchaseReturnApply.js

@@ -0,0 +1,184 @@
+import { axios } from '@/utils/request'
+//  采购退货申请单列表  分页
+export const purchaseReturnList = (params) => {
+  const url = `/purchaseReturnApply/queryPage/${params.pageNo}/${params.pageSize}`
+  delete params.pageNo
+  delete params.pageSize
+  return axios({
+    url: url,
+    data: params,
+    method: 'post'
+  })
+}
+// 申请单新增
+export const purchaseReturnSave = (params) => {
+  return axios({
+    url: '/purchaseReturnApply/create',
+    data: params,
+    method: 'post'
+  })
+}
+//  采购退货申请单 删除
+export const purchaseReturnDel = (params) => {
+  return axios({
+    url: `/purchaseReturnApply/delete`,
+    data: params,
+    method: 'post'
+  })
+}
+// 生成采购退货单
+export const createPurchaseReturnBill = (params) => {
+  return axios({
+    url: `/purchaseReturnApply/createPurchaseReturnBill`,
+    data: params,
+    method: 'post'
+  })
+}
+// 选择产品列表
+export const queryDealerScopeProductPage = (params) => {
+  const url = `/purchaseReturnApply/queryDealerScopeProductPage/${params.pageNo}/${params.pageSize}`
+  delete params.pageNo
+  delete params.pageSize
+  return axios({
+    url: url,
+    data: params,
+    method: 'post'
+  })
+}
+//  采购退货 详情 添加产品
+export const purchaseReturnDetailSave = (params) => {
+  return axios({
+    url: '/purchaseReturnApply/detail/create',
+    data: params,
+    method: 'post'
+  })
+}
+//  采购退货申请单 详情 删除
+export const purchaseReturnDetailDel = (params) => {
+  return axios({
+    url: `/purchaseReturnApply/detail/delete`,
+    data: params,
+    method: 'post'
+  })
+}
+//  采购退货 详情 全部删除
+export const purchaseReturnDetailDelAll = (params) => {
+  return axios({
+    url: `/purchaseReturnApply/detail/deleteAll`,
+    data: params,
+    method: 'post'
+  })
+}
+// 申请单详情修改数量
+export const purchaseReturnModifyQty = (params) => {
+  return axios({
+    url: `/purchaseReturnApply/detail/modifyQty`,
+    data: params,
+    method: 'post'
+  })
+}
+// 申请单详情修改退货原因
+export const modifyReturnReason = (params) => {
+  return axios({
+    url: `/purchaseReturnApply/detail/modifyReturnReason`,
+    data: params,
+    method: 'post'
+  })
+}
+// 批量修改退货原因
+export const modifyReturnReasonList = (params) => {
+  return axios({
+    url: `/purchaseReturnApply/detail/modifyReturnReasonList`,
+    data: params,
+    method: 'post'
+  })
+}
+//  申请单详情列表  分页
+export const purchaseReturnDetailList = (params) => {
+  const url = `/purchaseReturnApply/detail/queryPage/${params.pageNo}/${params.pageSize}`
+  delete params.pageNo
+  delete params.pageSize
+  return axios({
+    url: url,
+    data: params,
+    method: 'post'
+  })
+}
+//  获取采购退货申请单 详情
+export const purchaseReturnDetail = (params) => {
+  return axios({
+    url: `/purchaseReturnApply/findBySn/${params.sn}`,
+    method: 'get'
+  })
+}
+// 采购退货申请单提交
+export const purchaseReturnSubmit = (params) => {
+  return axios({
+    url: `/purchaseReturnApply/submit/${params.sn}`,
+    method: 'get'
+  })
+}
+// 采购退货申请单再次编辑
+export const purchaseReturnAgainCreate = (params) => {
+ return axios({
+   url: `/purchaseReturnApply/againCreate/${params.sn}`,
+   method: 'get'
+ })
+}
+
+// 导出删除项
+export const exportDeleteExcel = (params) => {
+  return axios({
+    url: `/purchaseReturnApply/detail/downloadDeleteFailExcel/${params.sn}`,
+    data: params,
+    method: 'post',
+    responseType: 'blob'
+  })
+}
+// 导出错误项
+export const exportErrorExcel = (params) => {
+  return axios({
+    url: `/purchaseReturnApply/detail/downloadFailExcel`,
+    data: params,
+    method: 'post',
+    responseType: 'blob'
+  })
+}
+
+// 解析产品的导入模板
+export const purchaseReturnApplyReadExcel = (params) => {
+  return axios({
+    url: `/purchaseReturnApply/detail/readExcel`,
+    data: params,
+    method: 'post'
+  })
+}
+
+// 批量导入产品
+export const purchaseReturnApplyCreateList = (params) => {
+  return axios({
+    url: `/purchaseReturnApply/detail/createList`,
+    data: params,
+    method: 'post'
+  })
+}
+// 导出明细
+export const purchaseReturnApplyExport = (params) => {
+ return axios({
+   url: `/purchaseReturnApply/excel/${params.sn}`,
+   method: 'get',
+   responseType: 'blob'
+ })
+}
+// 详情  打印
+export const purchaseReturnApplyPrint = params => {
+  const data = {
+    url: `/purchaseReturnApply/print/${params.sn}/${params.type}`,
+    method: 'get'
+  }
+  // 喷墨打印
+  if (params.type == 'INK') {
+    data.responseType = 'blob'
+  }
+  return axios(data)
+}

+ 25 - 0
src/components/index.less

@@ -394,6 +394,26 @@
       color: #d62a00;
     }
   }
+  .ant-table-row{
+    td{
+      > div:empty::after{
+        content: '--';
+      }
+      .ant-select-search__field__mirror{
+        white-space: pre-wrap;
+      }
+    }
+  }
+  .ant-table-small > .ant-table-content .ant-table-body,.ant-table-fixed-right{
+    margin: 0;
+    tr:hover{
+      td{
+        > div:empty::after{
+          content: '--';
+        }
+      }
+    }
+  }
 }
 .sTable.fixPagination{
   >.ant-table-wrapper{
@@ -410,6 +430,11 @@
         }
       }
     }
+    td > div:empty{
+      &::after{
+        content:'--'
+      }
+    }
   }
 }
 .ant-collapse{

+ 19 - 32
src/config/router.config.js

@@ -754,59 +754,46 @@ export const asyncRouterMap = [
             ]
           },
           {
-            path: '/purchasingManagement/purchaseReturn',
-            redirect: '/purchasingManagement/purchaseReturn/list',
-            name: 'purchaseReturn',
+            path: '/purchasingManagement/purchaseReturnApplyForm',
+            redirect: '/purchasingManagement/purchaseReturnApplyForm/list',
+            name: 'purchaseReturnApplyForm',
             component: BlankLayout,
             meta: {
-              title: '采购退货',
+              title: '采购退货申请单',
               icon: 'money-collect',
-              permission: 'M_purchaseReturnList'
+              // permission: 'M_purchaseReturnApplyFormList'
             },
             hideChildrenInMenu: true,
             children: [
               {
                 path: 'list',
-                name: 'purchaseReturnList',
-                component: () => import(/* webpackChunkName: "purchasingManagement" */ '@/views/purchasingManagement/purchaseReturn/list.vue'),
+                name: 'purchaseReturnApplyFormList',
+                component: () => import(/* webpackChunkName: "purchasingManagement" */ '@/views/purchasingManagement/purchaseReturnApplyForm/list.vue'),
                 meta: {
-                  title: '采购退货列表',
+                  title: '采购退货申请单列表',
                   icon: 'money-collect',
                   hidden: true,
-                  permission: 'M_purchaseReturnList'
+                  // permission: 'M_purchaseReturnApplyFormList'
                 }
               },
               {
-                path: 'add/:id/:sn/:name',
-                name: 'purchaseReturnAdd',
-                component: () => import(/* webpackChunkName: "purchasingManagement" */ '@/views/purchasingManagement/purchaseReturn/edit.vue'),
-                meta: {
-                  title: '新增采购退货单',
-                  icon: 'money-collect',
-                  hidden: true,
-                  permission: 'B_purchaseReturnNew'
-                }
-              },
-              {
-                path: 'edit/:id/:sn/:name',
-                name: 'purchaseReturnEdit',
-                component: () => import(/* webpackChunkName: "purchasingManagement" */ '@/views/purchasingManagement/purchaseReturn/edit.vue'),
+                path: 'edit/:sn',
+                name: 'purchaseReturnApplyFormEdit',
+                component: () => import(/* webpackChunkName: "purchasingManagement" */ '@/views/purchasingManagement/purchaseReturnApplyForm/edit.vue'),
                 meta: {
-                  title: '编辑采购退货单',
+                  title: '编辑采购退货申请单',
                   icon: 'money-collect',
                   hidden: true,
-                  permission: 'B_purchaseReturnEdit'
                 }
               },
               {
                 path: 'detail/:sn',
-                name: 'purchaseReturnDetail',
-                component: () => import(/* webpackChunkName: "purchasingManagement" */ '@/views/purchasingManagement/purchaseReturn/detail.vue'),
+                name: 'purchaseReturnApplyFormDetail',
+                component: () => import(/* webpackChunkName: "purchasingManagement" */ '@/views/purchasingManagement/purchaseReturnApplyForm/detail.vue'),
                 meta: {
-                  title: '采购退货详情',
+                  title: '采购退货申请单详情',
                   icon: 'money-collect',
                   hidden: true,
-                  permission: 'B_purchaseReturnDetail'
                 }
               }
             ]
@@ -818,7 +805,7 @@ export const asyncRouterMap = [
             name: 'purchaseReturnOutSync',
             component: BlankLayout,
             meta: {
-              title: '采购退货',
+              title: '采购退货',
               icon: 'money-collect',
               permission: 'M_purchaseReturn_outSnycList'
             },
@@ -829,7 +816,7 @@ export const asyncRouterMap = [
                 name: 'purchaseReturnOutSyncList',
                 component: () => import(/* webpackChunkName: "purchasingManagement" */ '@/views/purchasingManagement/purchaseReturnOutSync/list.vue'),
                 meta: {
-                  title: '采购退货列表',
+                  title: '采购退货列表',
                   icon: 'money-collect',
                   hidden: true,
                   permission: 'M_purchaseReturn_outSnycList'
@@ -848,7 +835,7 @@ export const asyncRouterMap = [
                 }
               },
               {
-                path: 'grapEdit/:sn/:returnTargetType',
+                path: 'grapEdit/:sn/:returnTargetType/:purchaseTargetSn',
                 name: 'purchaseReturnOutSyncGrapEdit',
                 component: () => import(/* webpackChunkName: "purchasingManagement" */ '@/views/purchasingManagement/purchaseReturnOutSync/grapEdit.vue'),
                 meta: {

+ 20 - 1
src/store/modules/app.js

@@ -1,4 +1,5 @@
 import Vue from 'vue'
+import { getLookUpData, listLookUp } from '@/api/data'
 import {
   SIDEBAR_TYPE,
   DEFAULT_THEME,
@@ -46,6 +47,7 @@ const app = {
     printSettingType: '', // 设置打印机类型,0 针式,1 喷墨
     printDefNeedle: undefined,// 默认针式打印机
     printDefInk: undefined, // 默认喷墨打印机
+    returnReason: [], // 申请退货列表
   },
   mutations: {
     SET_SIDEBAR_TYPE: (state, type) => {
@@ -148,6 +150,9 @@ const app = {
     SET_printSettingType: (state, val) => {
       state.printSettingType = val
     },
+    SET_returnReason:(state, val) => {
+      state.returnReason = val
+    },
   },
   actions: {
     setSidebar ({
@@ -240,7 +245,21 @@ const app = {
     },
     SetWinHeight ({ commit }, val) {
       commit('SET_WIN_HEIGHT', val)
-    }
+    },
+    getLookUpData({ commit }, code, isEnable) {
+      getLookUpData({
+        pageNo: 1,
+        pageSize: 1000,
+        lookupCode: code,
+        isEnable: isEnable ? 1 : undefined
+      }).then(res => {
+        if (res.status == 200) {
+          commit('SET_returnReason', res.data.list)
+        }else{
+          commit('SET_returnReason', [])
+        }
+      })
+    },
   }
 }
 

+ 3 - 1
src/views/Home.vue

@@ -347,7 +347,7 @@
 <script>
 import { mixin, commonMixin } from '@/utils/mixin'
 import getDate from '@/libs/getDate.js'
-import { mapGetters } from 'vuex'
+import { mapGetters, mapActions } from 'vuex'
 import ResetPwd from '@/views/user/ResetPwd.vue'
 import newProduct from '@/views/productManagement/newProduct/modal.vue'
 import { queryNewProductPage } from '@/api/product'
@@ -787,7 +787,9 @@ export default {
     }
   },
   methods: {
+    ...mapActions(['getLookUpData']),
     hasNewProduct () {
+      this.getLookUpData('RETURN_REASON')
       queryNewProductPage({ pageNo: 1, pageSize: 20, onlineFalg: this.onlineFalg }).then(res => {
         if (res.status == 200) {
           if (res.data.count > 0) {

+ 42 - 8
src/views/chainReportData/chainSalesDetailsCountReport/list.vue

@@ -91,14 +91,48 @@ export default {
       exportLoading: false,
       columns: [
         { title: '门店', dataIndex: 'salesTargetName', width: '16%', align: 'left', customRender: function (text) { return text || '--' }, ellipsis: true },
-        { title: '滤清器', dataIndex: 'lqqAmount', width: '8.4%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
-        { title: '雨刮片', dataIndex: 'ygpAmount', width: '8.4%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
-        { title: '刹车片', dataIndex: 'scpAmount', width: '8.4%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
-        { title: '蓄电池', dataIndex: 'xdcAmount', width: '8.4%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
-        { title: '润滑油', dataIndex: 'rhyAmount', width: '8.4%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
-        { title: '火花塞', dataIndex: 'hhsAmount', width: '8.4%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
-        { title: '点火线圈', dataIndex: 'dhxqAmount', width: '8.4%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
-        { title: 'LED灯', dataIndex: 'ledAmount', width: '8.4%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+        { title: '箭牌、冠牌',
+          children: [
+            { title: '滤清器', dataIndex: 'lqqAmount', width: '8.4%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } }
+          ]
+        },
+        {
+          title: '所有品牌',
+          children: [
+            { title: '雨刮片', dataIndex: 'ygpAmount', width: '8.4%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } }
+          ]
+        },
+        {
+          title: 'TBU',
+          children: [
+            { title: '刹车制动系统', dataIndex: 'scpAmount', width: '8.4%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } }
+          ]
+        },
+        {
+          title: '汇箭、布瑞斯',
+          children: [
+            { title: '蓄电池', dataIndex: 'xdcAmount', width: '8.4%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } }
+          ]
+        },
+        {
+          title: '德路斯',
+          children: [
+            { title: '润滑油', dataIndex: 'rhyAmount', width: '8.4%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } }
+          ]
+        },
+        {
+          title: '所有品牌',
+          children: [
+            { title: '火花塞', dataIndex: 'hhsAmount', width: '8.4%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } }
+          ]
+        },
+        {
+          title: '稳升',
+          children: [
+            { title: '点火线圈', dataIndex: 'dhxqAmount', width: '8.4%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+            { title: 'LED灯', dataIndex: 'ledAmount', width: '8.4%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } }
+          ]
+        },
         { title: '其他', dataIndex: 'otherAmount', width: '8.4%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
         { title: '合计', dataIndex: 'totalAmount', width: '8.4%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } }
       ],

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

@@ -11,6 +11,7 @@
     :width="416">
     <a-spin :spinning="spinning" tip="Loading...">
       <div class="common-main" v-html="modalHtml"></div>
+      <slot></slot>
       <div class="btn-box">
         <a-button type="primary" class="button-warning" @click="handleCommonCancel" v-if="isCancel">{{ cancelText }}</a-button>
         <a-button type="primary" class="button-info" @click="handleCommonOk">{{ okText }}</a-button>
@@ -65,6 +66,7 @@ export default {
     // 取消
     handleCommonCancel () {
       this.$emit('cancel')
+      this.$emit('close')
     }
   },
   watch: {

+ 108 - 0
src/views/common/returnReason.js

@@ -0,0 +1,108 @@
+const ReturnReason = {
+  template: `
+        <a-select
+            allowClear
+            :size="size"
+            mode="combobox"
+            :value="defaultVal"
+            show-search
+            :placeholder="placeholder"
+            option-filter-prop="children"
+            style="width: 100%"
+            :filter-option="filterOption"
+            :dropdownMatchSelectWidth="false"
+            @change="onChange"
+            @blur="onBlur"
+            @focus="open=true"
+            @select="open=false"
+            :open="open"
+          >
+            <a-select-option v-for="item in list" :key="item" :value="item">
+              {{item}}
+            </a-select-option>
+          </a-select>
+    `,
+  props: {
+    value: {
+      type: String,
+      defatut: ''
+    },
+    id: {
+      type: String,
+      default: ''
+    },
+    placeholder: {
+      type: String,
+      default: '请输入退货原因'
+    },
+    size: {
+      type: String,
+      default: 'small'
+    }
+  },
+  data() {
+    return {
+      defaultVal: this.value,
+      open: false,
+      list: [
+        '漏油或者不上油',
+        '外观不良:脏污、破损、脱胶、变形等',
+        '尺寸问题',
+        '泄压',
+        '无法安装',
+        '无法或不便安装',
+        '抖动或跳动',
+        '噪音',
+        '刮雨不干净',
+        '胶条断裂、脱落',
+        '喇叭无声',
+        '声音嘶哑或者变音',
+        '浸水',
+        '伤盘',
+        '摩擦块掉渣,脱落或有残渣',
+        '制动不足,刹车不灵敏',
+        '不耐磨',
+        '冒烟',
+        '缺少感应线',
+        '尺寸不标准',
+        '不点火,间歇式失火',
+        '漏电',
+        '击穿',
+        '烧蚀',
+        '包装型号不符',
+        '整体不亮/部分能亮',
+        '灯珠脱落',
+        '漏电短路',
+        '包装型号不符/包装破损',
+        '召回'
+        ]
+    };
+  },
+  mounted() {
+  },
+  watch: {
+    value(newValue, oldValue) {
+      this.defaultVal = newValue
+    },
+  },
+  methods: {
+    filterOption(input, option) {
+      return (
+        option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
+      );
+    },
+    onChange(value) {
+      console.log('onChange', value);
+      this.open = true;
+      this.defaultVal = value;
+      this.$emit('change', value);
+      this.$emit('input', value);
+    },
+    onBlur(value){
+      this.open = false;
+      this.$emit('blur', value);
+    }
+  },
+};
+
+export default ReturnReason

+ 196 - 0
src/views/purchasingManagement/purchaseReturnApplyForm/chooseImportModal.vue

@@ -0,0 +1,196 @@
+<template>
+  <a-modal
+    centered
+    class="chooseImport-modal"
+    :footer="null"
+    :maskClosable="false"
+    title="确认导入"
+    v-model="isShow"
+    @cancel="isShow=false"
+    width="80%">
+    <div class="chooseImport-con">
+      <!-- 可导入数据 -->
+      <p class="">可导入数据{{ loadData.length }}条</p>
+      <a-table
+        class="sTable"
+        ref="table"
+        size="small"
+        :rowKey="(record) => record.allocateSn"
+        :columns="nowColumns"
+        :dataSource="loadData"
+        :loading="loading"
+        :scroll="{ y: 200 }"
+        :pagination="false"
+        bordered>
+      </a-table>
+      <a-divider />
+      <!-- 不可导入数据 -->
+      <p class="red">不可导入数据{{ unLoadData.length }}条</p>
+      <a-table
+        class="unTable"
+        ref="unTable"
+        size="small"
+        :rowKey="(record) => record.errorDesc"
+        :columns="nowUnColumns"
+        :dataSource="unLoadData"
+        :loading="loading"
+        :scroll="{ y: 200 }"
+        :pagination="false"
+        bordered>
+      </a-table>
+      <!-- 按钮 -->
+      <div class="btn-con">
+        <a-button
+          type="primary"
+          id="chooseImport-submit"
+          size="large"
+          :class="loadData.length==0?'button-grey':'button-primary'"
+          @click="handleSubmit"
+          style="padding: 0 40px;">确认导入</a-button>
+        <a-button
+          id="chooseImport-cancel"
+          size="large"
+          class="button-cancel"
+          @click="isShow=false"
+          style="padding: 0 40px;margin-left: 15px;">取消</a-button>
+        <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-modal>
+</template>
+
+<script>
+import { hdExportExcel } from '@/libs/exportExcel'
+import { exportErrorExcel, purchaseReturnApplyReadExcel } from '@/api/purchaseReturnApply'
+export default {
+  name: 'ChooseImportModal',
+  props: {
+    openModal: { //  弹框显示状态
+      type: Boolean,
+      default: false
+    },
+    paramsData: {
+      type: Object,
+      default: () => {
+        return {}
+      }
+    }
+  },
+  data () {
+    return {
+      isShow: this.openModal, //  是否打开弹框
+      nowColumns: [
+        { title: '序号', dataIndex: 'no', width: '8%', align: 'center' },
+        { title: '产品编码', dataIndex: 'productCode', width: '25%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '产品名称', dataIndex: 'product.name', width: '25%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '单位', dataIndex: 'product.unit', align: 'center', width: '15%', customRender: function (text) { return text || '--' } },
+        { title: '申请退货数量', dataIndex: 'exprotQty', width: '14%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '退货原因', dataIndex: 'returnReason', width: '14%', align: 'center', customRender: function (text) { return text || '--' } }
+      ],
+      loadData: [],
+      nowUnColumns: [
+        { title: '序号', dataIndex: 'no', width: '9%', align: 'center' },
+        { title: '产品编码', dataIndex: 'productCode', width: '25%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '产品名称', dataIndex: 'product.name', width: '25%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '单位', dataIndex: 'product.unit', align: 'center', width: '10%', customRender: function (text) { return text || '--' } },
+        { title: '申请退货数量', dataIndex: 'exprotQty', width: '14%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '退货原因', dataIndex: 'returnReason', width: '14%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '错误说明', dataIndex: 'remarks', width: '15%', align: 'center', customRender: function (text) { return text || '--' } }
+      ],
+      unLoadData: [],
+      loading: false
+    }
+  },
+  methods: {
+    getData () {
+      const _this = this
+      this.loading = true
+      purchaseReturnApplyReadExcel(this.paramsData).then(res => {
+        this.loading = false
+        if (res.status == 200) {
+          if (res.data.successList && res.data.successList.length > 0) {
+            res.data.successList.map((item, index) => {
+              item.no = index + 1
+              item.purchaseReturnApplyNo = this.paramsData.purchaseReturnApplyNo
+              item.purchaseReturnApplySn = this.paramsData.purchaseReturnApplySn
+            })
+          }
+          if (res.data.failList && res.data.failList.length > 0) {
+            res.data.failList.map((item, index) => {
+              item.no = index + 1
+              item.purchaseReturnApplyNo = this.paramsData.purchaseReturnApplyNo
+              item.purchaseReturnApplySn = this.paramsData.purchaseReturnApplySn
+            })
+          }
+          _this.loadData = res.data.successList || []
+          _this.unLoadData = res.data.failList || []
+        }
+      })
+    },
+    // 确认导入
+    handleSubmit () {
+      if (this.loadData.length == 0) {
+        this.$message.warning('无可导入的产品!')
+      } else {
+        const data = {
+          purchaseReturnApplySn: this.paramsData.purchaseReturnApplySn,
+          detailList: this.loadData
+        }
+        this.$emit('ok', data)
+        this.isShow = false
+      }
+    },
+    // 导出
+    handleError () {
+      const _this = this
+      if (_this.unLoadData.length < 1) {
+        _this.$message.info('暂无可导出错误项~')
+        return
+      }
+      _this.spinning = true
+      hdExportExcel(exportErrorExcel, _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" scoped>
+  .chooseImport-modal{
+    .chooseImport-con{
+      .red{
+        color: #f30;
+      }
+      .btn-con{
+        text-align: center;
+        margin: 30px 0 20px;
+        .button-cancel,.button-error{
+          font-size: 12px;
+        }
+      }
+    }
+  }
+</style>

+ 176 - 0
src/views/purchasingManagement/purchaseReturnApplyForm/creatPurchaseReutn.vue

@@ -0,0 +1,176 @@
+<template>
+  <a-modal
+    centered
+    class="creatPurchaseReutn-modal"
+    :footer="null"
+    :maskClosable="false"
+    title="生成采购退货单"
+    v-model="isShow"
+    @cancel="isShow=false"
+    :width="600">
+    <a-spin :spinning="spinning" tip="Loading...">
+      <div class="creatPurchaseReutn-con" v-if="isShow">
+        <div class="row-flex" v-if="detail">
+          <div>供应商:{{ detail.returnTargetName }}</div>
+          <div><div class="col">总公司实收数量:{{ detail.totalReceiveQty||'--' }} </div><div class="col">退货金额:{{ detail.totalAmount||'--' }}</div></div>
+          <div>
+            <div>采购退货单:</div>
+            <div style="width:80%;padding-top:5px;">
+              <a-row>
+                <a-col :span="6">
+                  <a-checkbox :value="1" @change="onChange" :checked="syncStep.indexOf(1)>=0">
+                    同步提交 >
+                  </a-checkbox>
+                </a-col>
+                <a-col :span="6">
+                  <a-checkbox :value="2" @change="onChange" :checked="syncStep.indexOf(2)>=0">
+                    同步审核 >
+                  </a-checkbox>
+                </a-col>
+                <a-col :span="6">
+                  <a-checkbox :value="3" @change="onChange" :checked="syncStep.indexOf(3)>=0">
+                    同步出库 >
+                  </a-checkbox>
+                </a-col>
+                <a-col :span="6">
+                  <a-checkbox :value="4" @change="onChange" :checked="syncStep.indexOf(4)>=0">
+                    同步收款
+                  </a-checkbox>
+                </a-col>
+              </a-row>
+            </div>
+          </div>
+        </div>
+        <!-- 按钮 -->
+        <div class="btn-con">
+          <a-button
+            id="creatPurchaseReutn-cancel"
+            size="large"
+            class="button-cancel"
+            @click="isShow=false"
+            style="padding: 0 36px;">取消</a-button>
+          <a-button
+            type="primary"
+            id="creatPurchaseReutn-save"
+            size="large"
+            :loading="spinning"
+            class="button-primary"
+            @click="handleSave"
+            style="padding: 0 36px;margin-left: 15px;">确定</a-button>
+        </div>
+      </div>
+    </a-spin>
+  </a-modal>
+</template>
+
+<script>
+import { commonMixin } from '@/utils/mixin'
+import { STable } from '@/components'
+import { createPurchaseReturnBill } from '@/api/purchaseReturnApply'
+export default {
+  name: 'CreatPurchaseReutnModal',
+  components: { STable },
+  mixins: [commonMixin],
+  props: {
+    openModal: { //  弹框显示状态
+      type: Boolean,
+      default: false
+    },
+    paramsData: {
+      type: Object,
+      default: () => {
+        return {}
+      }
+    }
+  },
+  data () {
+    return {
+      isShow: this.openModal, //  是否打开弹框
+      disabled: false, //  查询、重置按钮是否可操作
+      spinning: false,
+      detail: null,
+      syncStep: []
+    }
+  },
+  methods: {
+    onChange (e) {
+      this.syncStep = []
+      const checked = e.target.checked
+      const len = checked ? e.target.value : e.target.value - 1
+      for (let i = 1; i <= len; i++) {
+        this.syncStep.push(i)
+      }
+    },
+    setData (data) {
+      this.detail = data
+    },
+    // 保存
+    handleSave () {
+      const params = {
+        purchaseReturnApplySn: this.detail.purchaseReturnApplySn,
+        syncStep: this.syncStep.length ? this.syncStep[this.syncStep.length - 1] : 0
+      }
+      this.spinning = true
+      createPurchaseReturnBill(params).then(res => {
+        if (res.status == 200) {
+          if (res.data && res.data.length) {
+            this.$info({
+              title: '以下产品库存不足',
+              centered: true,
+              content: res.data.toString()
+            })
+          } else {
+            this.$emit('creatOk')
+            this.$message.success(res.message)
+          }
+        }
+        this.$emit('close')
+        this.spinning = false
+      })
+    }
+  },
+  watch: {
+    //  父页面传过来的弹框状态
+    openModal (newValue, oldValue) {
+      this.isShow = newValue
+    },
+    //  重定义的弹框状态
+    isShow (newValue, oldValue) {
+      if (!newValue) {
+        this.$emit('close')
+        this.detail = null
+        this.syncStep = []
+      }
+    }
+  }
+}
+</script>
+
+<style lang="less" scoped>
+  .creatPurchaseReutn-modal{
+    .creatPurchaseReutn-con{
+      padding: 0 20px;
+      .row-flex{
+        > div{
+          display:flex;
+          align-items:center;
+          padding: 10px 0;
+          width:100%;
+          &:last-child{
+            flex-grow:1;
+          }
+          .col{
+            width:50%;
+          }
+        }
+      }
+      .btn-con{
+        text-align: center;
+        margin: 30px 0 20px;
+        .button-cancel{
+          font-size: 12px;
+        }
+      }
+    }
+  }
+</style>

+ 197 - 0
src/views/purchasingManagement/purchaseReturnApplyForm/detail.vue

@@ -0,0 +1,197 @@
+<template>
+  <div class="purchaseReturnDetail-wrap">
+    <a-spin :spinning="spinning" tip="Loading...">
+      <a-page-header :ghost="false" :backIcon="false" class="purchaseReturnDetail-cont" :style="{ padding: !outBizSn ? '16px 24px' : '0px 24px' }" >
+        <!-- 自定义的二级文字标题 -->
+        <template slot="subTitle" v-if="!outBizSn">
+          <a id="purchaseReturnDetail-back-btn" href="javascript:;" @click="handleBack"><a-icon type="left" /> 返回列表</a>
+          <span style="margin: 0 15px;color: #666;">供应商名称:箭冠营销中心</span>
+        </template>
+        <!-- 操作区,位于 title 行的行尾 -->
+        <template slot="extra" v-if="$hasPermissions('B_purchaseReturnApplyPrint')">
+          <Print :disabled="dataSource.length==0" @handlePrint="handlePrint"></Print>
+        </template>
+      </a-page-header>
+      <!-- 基础信息 -->
+      <a-card size="small" :bordered="false" class="purchaseReturnDetail-cont">
+        <a-collapse :activeKey="['1']">
+          <a-collapse-panel key="1" header="基础信息">
+            <a-descriptions :column="3">
+              <a-descriptions-item label="单据来源">{{ basicInfoData&&basicInfoData.billSourceDictValue || '--' }}</a-descriptions-item>
+              <a-descriptions-item label="采购退货申请单号">{{ basicInfoData&&basicInfoData.purchaseReturnApplyNo || '--' }}</a-descriptions-item>
+              <a-descriptions-item label="供应商">{{ basicInfoData&&basicInfoData.returnTargetName || '--' }}</a-descriptions-item>
+              <a-descriptions-item label="业务状态">{{ basicInfoData&&basicInfoData.billStatusDictValue || '--' }}</a-descriptions-item>
+              <a-descriptions-item label="创建时间">{{ basicInfoData&&basicInfoData.createDate || '--' }}</a-descriptions-item>
+              <a-descriptions-item label="客服审核时间">{{ basicInfoData&&basicInfoData.auditTime || '--' }}</a-descriptions-item>
+            </a-descriptions>
+          </a-collapse-panel>
+        </a-collapse>
+      </a-card>
+      <!-- 产品详情 -->
+      <a-card size="small" :bordered="false" class="purchaseReturnDetail-cont">
+        <a-collapse :activeKey="['1']">
+          <a-collapse-panel key="1" header="产品详情">
+            <!-- 总计 -->
+            <a-alert type="info" style="margin-bottom:10px">
+              <div slot="message">
+                申请退货数量:<strong>{{ (basicInfoData&&(basicInfoData.totalInitialQty || basicInfoData.totalInitialQty==0)) ? basicInfoData.totalInitialQty : '--' }}</strong>;
+                总公司实收数量:<strong>{{ (basicInfoData&&(basicInfoData.totalReceiveQty || basicInfoData.totalReceiveQty==0)) ? basicInfoData.totalReceiveQty : '--' }}</strong>;
+                坏件数量:<strong>{{ (basicInfoData&&(basicInfoData.totalBadQty || basicInfoData.totalBadQty==0)) ? basicInfoData.totalBadQty : '--' }}</strong>;
+                良品数量:<strong>{{ (basicInfoData&&(basicInfoData.totalGoodQty || basicInfoData.totalGoodQty==0)) ? basicInfoData.totalGoodQty : '--' }}</strong>;
+                返库数量:<strong>{{ (basicInfoData&&(basicInfoData.totalBackStockQty || basicInfoData.totalBackStockQty==0)) ? basicInfoData.totalBackStockQty : '--' }}</strong>;
+                退货金额:<strong>{{ (basicInfoData&&(basicInfoData.totalAmount || basicInfoData.totalAmount==0)) ? basicInfoData.totalAmount : '--' }}</strong>;
+              </div>
+            </a-alert>
+            <div v-if="basicInfoData&&basicInfoData.removeQty" style="margin-bottom:10px;display:flex;align-items:center;">
+              <div>总公司删除产品明细:共 {{ basicInfoData.removeQty||'--' }} 款产品,{{ basicInfoData.removeCode&&basicInfoData.removeCode.replace(',','、') }}。</div>
+              <a-button @click="exportDelProduct" type="link">导出删除产品明细</a-button>
+            </div>
+            <!-- 列表 -->
+            <s-table
+              class="sTable"
+              ref="table"
+              size="small"
+              :rowKey="(record) => record.id"
+              :columns="columns"
+              :data="loadData"
+              :defaultLoadData="false"
+              bordered>
+            </s-table>
+          </a-collapse-panel>
+        </a-collapse>
+      </a-card>
+    </a-spin>
+  </div>
+</template>
+
+<script>
+import { commonMixin } from '@/utils/mixin'
+import { STable, VSelect } from '@/components'
+import Print from '@/views/common/print.vue'
+import { hdPrint } from '@/libs/JGPrint'
+import { purchaseReturnDetail, purchaseReturnDetailList, purchaseReturnApplyPrint, purchaseReturnApplyExport, exportDeleteExcel } from '@/api/purchaseReturnApply'
+export default {
+  name: 'PurchaseReturnDetail',
+  components: { STable, VSelect, Print },
+  mixins: [commonMixin],
+  props: {
+    outBizSn: { //  有值则为弹框,无值则为页面
+      type: [Number, String],
+      default: ''
+    }
+  },
+  data () {
+    return {
+      spinning: false,
+      dataSource: [],
+      // 加载数据方法 必须为 Promise 对象
+      loadData: parameter => {
+        this.disabled = true
+        return purchaseReturnDetailList(Object.assign(parameter, { purchaseReturnApplySn: this.outBizSn || this.$route.params.sn })).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.dataSource = data.list
+          }
+          return data
+        })
+      },
+      basicInfoData: null //  基本信息
+    }
+  },
+  computed: {
+    columns () {
+      const arr = [
+        { title: '序号', dataIndex: 'no', width: '4%', align: 'center' },
+        { title: '产品编码', dataIndex: 'product.code', width: '8%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '产品名称', dataIndex: 'product.name', width: '14%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '申请退货数量', dataIndex: 'initQty', width: '8%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+        { title: '总公司实收数量', dataIndex: 'receiveQty', width: '8%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+        { title: '坏件数量', dataIndex: 'badQty', width: '6%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+        { title: '良品数量', dataIndex: 'goodQty', width: '6%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+        { title: '返库数量', dataIndex: 'backStockQty', width: '6%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+        { title: '单位', dataIndex: 'product.unit', width: '5%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '退货原因', dataIndex: 'returnReason', width: '8%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '总公司变更详情', dataIndex: 'modifyInfo', width: '15%', align: 'center', customRender: function (text) { return text || '--' } }
+      ]
+      if (this.$hasPermissions('M_ShowAllCost')) {
+        arr.splice(9, 0, { title: '退货单价', dataIndex: 'price', width: '6%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } })
+        arr.splice(10, 0, { title: '退货金额', dataIndex: 'totalAmount', width: '6%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } })
+      }
+      return arr
+    }
+  },
+  methods: {
+    //  返回列表
+    handleBack () {
+      this.$router.push({ name: 'purchaseReturnApplyFormList' })
+    },
+    // 打印预览/快捷打印
+    handlePrint (type, printerType) {
+      const _this = this
+      _this.spinning = true
+      let url = purchaseReturnApplyPrint
+      const params = { sn: this.$route.params.sn || this.outBizSn }
+      if (type == 'export') { //  导出
+        url = purchaseReturnApplyExport
+      }
+      // 打印或导出
+      hdPrint(printerType, type, url, params, '采购退货申请单', function () {
+        _this.spinning = false
+      })
+    },
+    // 导出删除的产品
+    exportDelProduct () {
+      const _this = this
+      _this.spinning = true
+      const params = { sn: this.$route.params.sn || this.outBizSn }
+      hdPrint('', 'export', exportDeleteExcel, params, '采购退货申请单删除产品明细', function () {
+        _this.spinning = false
+      })
+    },
+    // 基本信息
+    getDetail () {
+      purchaseReturnDetail({ sn: this.outBizSn || this.$route.params.sn }).then(res => {
+        if (res.status == 200) {
+          this.basicInfoData = res.data
+        } else {
+          this.basicInfoData = null
+        }
+      })
+    }
+  },
+  mounted () {
+    if (!this.$store.state.app.isNewTab || this.outBizSn) { // 页签刷新 或 为弹框时调用
+      this.$refs.table.refresh(true)
+      this.getDetail()
+    }
+  },
+  activated () {
+    // 如果是新页签打开或者进入新的子页(例:存在列表第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">
+  .purchaseReturnDetail-cont{
+    margin-bottom: 10px;
+    .timeline-box{
+      margin-top: 30px;
+      .auxiliary-txt{
+        color: #808695;
+      }
+    }
+  }
+</style>

+ 610 - 0
src/views/purchasingManagement/purchaseReturnApplyForm/edit.vue

@@ -0,0 +1,610 @@
+<template>
+  <div class="purchaseReturnEdit-wrap">
+    <a-spin :spinning="spinning" tip="Loading...">
+      <a-page-header :ghost="false" :backIcon="false" class="purchaseReturnEdit-back" >
+        <!-- 自定义的二级文字标题 -->
+        <template slot="subTitle">
+          <a id="purchaseReturnEdit-back-btn" href="javascript:;" @click="handleBack"><a-icon type="left" /> 返回列表</a>
+          <span style="margin: 0 15px;color: #666;">供应商名称:箭冠营销中心</span>
+        </template>
+        <!-- 操作区,位于 title 行的行尾 -->
+        <template slot="extra" v-if="$hasPermissions('B_purchaseReturnApplyPrint')">
+          <Print :disabled="dataSource.length==0" @handlePrint="handlePrint"></Print>
+        </template>
+      </a-page-header>
+      <!-- 选择产品 -->
+      <div class="purchaseReturnEdit-cont">
+        <a-collapse :activeKey="['1']">
+          <a-collapse-panel key="1" header="选择产品">
+            <!-- 筛选条件 -->
+            <div class="table-page-search-wrapper">
+              <a-form layout="inline" @keyup.enter.native="$refs.table.refresh(true)">
+                <a-row :gutter="15">
+                  <a-col :md="6" :sm="24">
+                    <a-form-item label="产品编码" prop="productCode">
+                      <a-input id="purchaseReturnEdit-productCode" v-model.trim="queryParam.code" placeholder="请输入产品编码" allowClear />
+                    </a-form-item>
+                  </a-col>
+                  <a-col :md="6" :sm="24">
+                    <a-form-item label="产品名称" prop="productName">
+                      <a-input id="purchaseReturnEdit-productName" v-model.trim="queryParam.name" placeholder="请输入产品名称" allowClear />
+                    </a-form-item>
+                  </a-col>
+                  <a-col :md="6" :sm="24">
+                    <a-form-model-item label="产品分类">
+                      <ProductType id="purchaseReturnEdit-productType" placeholder="请选择产品分类" :isDealer="true" @change="changeProductType" v-model="productType"></ProductType>
+                    </a-form-model-item>
+                  </a-col>
+                  <a-col :md="6" :sm="24" style="margin-bottom: 10px;">
+                    <a-button type="primary" @click="$refs.table.refresh(true)" :disabled="disabled" id="purchaseReturnList-refresh">查询</a-button>
+                    <a-button style="margin-left: 8px" @click="resetSearchForm" :disabled="disabled" id="purchaseReturnList-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"
+              :pageSize="10"
+              :scroll="{ y: 149 }"
+              bordered>
+              <!-- 产品分类 -->
+              <template slot="productType" slot-scope="text, record">
+                <span v-if="record.productTypeName2 || record.productTypeName3">{{ record.productTypeName2 }} {{ record.productTypeName3 ? '>' : '' }} {{ record.productTypeName3 }}</span>
+                <span v-else>--</span>
+              </template>
+              <!-- 数量 -->
+              <template slot="returnQty" slot-scope="text, record">
+                <a-input-number
+                  size="small"
+                  id="purchaseReturnEdit-returnQty"
+                  v-model="record.returnQty"
+                  :precision="0"
+                  :min="1"
+                  :max="record.refundableQty"
+                  placeholder="请输入"
+                  style="width: 100%;" />
+              </template>
+              <!-- 退货原因 -->
+              <template slot="returnReason" slot-scope="text, record">
+                <returnReason v-model="record.returnReason"></returnReason>
+              </template>
+              <!-- 操作 -->
+              <template slot="action" slot-scope="text, record">
+                <span v-if="record.refundableQty==0">--</span>
+                <a-button
+                  v-else
+                  size="small"
+                  type="link"
+                  class="button-primary"
+                  @click="handleAdd(record)"
+                  id="purchaseReturnEdit-add-btn">添加</a-button>
+              </template>
+            </s-table>
+          </a-collapse-panel>
+        </a-collapse>
+      </div>
+      <!-- 已选产品 -->
+      <a-card size="small" :bordered="false" class="purchaseReturnEdit-cont">
+        <a-collapse :activeKey="['1']">
+          <a-collapse-panel key="1">
+            <template slot="header">
+              已选产品
+            </template>
+            <!-- 总计 -->
+            <a-alert type="info" style="margin-bottom:10px">
+              <div slot="message">
+                申请退货数量:<strong>{{ (detailData&&(detailData.totalInitialQty || detailData.totalInitialQty==0)) ? detailData.totalInitialQty : '--' }}</strong> ;
+              </div>
+            </a-alert>
+            <!-- 筛选条件 -->
+            <div class="table-page-search-wrapper" style="display:flex;width:100%;">
+              <div style="flex-grow:1;">
+                <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="产品编码" prop="productCode">
+                        <a-input id="purchaseReturnEdit-productCode" v-model.trim="chooseParam.productCode" placeholder="请输入产品编码" allowClear />
+                      </a-form-item>
+                    </a-col>
+                    <a-col :md="6" :sm="24">
+                      <a-form-item label="产品名称" prop="productName">
+                        <a-input id="purchaseReturnEdit-productName" v-model.trim="chooseParam.productName" placeholder="请输入产品名称" allowClear />
+                      </a-form-item>
+                    </a-col>
+                    <a-col :md="6" :sm="24" style="margin-bottom: 10px;">
+                      <a-button type="primary" @click="$refs.chooseTable.refresh(true)" :disabled="disabled" id="purchaseReturnList-refresh">查询</a-button>
+                      <a-button style="margin-left: 8px" @click="resetChooseForm" :disabled="disabled" id="purchaseReturnList-reset">重置</a-button>
+                    </a-col>
+                  </a-row>
+                </a-form>
+              </div>
+              <div>
+                <span style="margin-right: 10px;" v-if="selNums">已选{{ selNums }}项</span>
+                <a-button type="default" style="margin-right: 10px;" class="button-info" @click="openPlSetReason">批量设置退货原因</a-button>
+                <a-button
+                  type="primary"
+                  id="purchaseReturnEdit-import-btn"
+                  class="button-info"
+                  @click="openGuideModal = true"
+                >产品导入</a-button>
+                <a-button
+                  type="primary"
+                  class="button-error"
+                  id="purchaseReturnEdit-delAll-btn"
+                  @click.stop="handleDel('', 'all')"
+                >整单删除</a-button>
+              </div>
+            </div>
+            <!-- 列表 -->
+            <s-table
+              class="sTable"
+              ref="chooseTable"
+              size="small"
+              :rowKey="(record) => record.id"
+              :row-selection="{ columnWidth: 40 }"
+              @rowSelection="rowSelectionFun"
+              :columns="chooseColumns"
+              :data="chooseLoadData"
+              :defaultLoadData="false"
+              :pageSize="10"
+              :scroll="{ y: 149 }"
+              bordered>
+              <!-- 产品分类 -->
+              <template slot="productType" slot-scope="text, record">
+                <span v-if="record.product.productTypeName2 || record.product.productTypeName3">{{ record.product.productTypeName2 }} {{ record.product.productTypeName3 ? '>' : '' }} {{ record.product.productTypeName3 }}</span>
+                <span v-else>--</span>
+              </template>
+              <!-- 退货数量 -->
+              <template slot="qty" slot-scope="text, record">
+                <a-input-number
+                  size="small"
+                  id="purchaseReturnEdit-qty"
+                  v-model="record.initQty"
+                  :precision="0"
+                  :min="1"
+                  placeholder="请输入"
+                  @blur="e => qtyBlur(e.target.value, record)"
+                  style="width: 100%;" />
+              </template>
+              <!-- 退货原因 -->
+              <template slot="returnReason" slot-scope="text, record">
+                <returnReason v-model="record.returnReason" @blur="e => remarksBlur(e, record)"></returnReason>
+              </template>
+              <!-- 操作 -->
+              <template slot="action" slot-scope="text, record">
+                <a-button size="small" type="link" class="button-error" @click="handleDel(record)" id="purchaseReturnEdit-del-btn">删除</a-button>
+              </template>
+            </s-table>
+          </a-collapse-panel>
+        </a-collapse>
+      </a-card>
+    </a-spin>
+    <a-card size="small" :bordered="false" class="affix-cont">
+      <a-button
+        type="primary"
+        id="purchaseReturnEdit-submit"
+        size="large"
+        :disabled="spinning"
+        class="button-primary"
+        @click="handleSubmit"
+        style="padding: 0 60px;">提交</a-button>
+    </a-card>
+
+    <!-- 导入明细 -->
+    <importGuideModal
+      :openModal="openGuideModal"
+      :params="{purchaseReturnApplySn: $route.params.sn, purchaseReturnApplyNo:detailData?detailData.purchaseReturnApplyNo:''}"
+      @close="openGuideModal=false"
+      @ok="hanldeImprotOk" />
+
+    <!-- 批量设置退货原因 -->
+    <commonModal modalTit="批量设置退货原因" :openModal="showPlModal" @close="showPlModal=false" @ok="setPlReturnReason">
+      <div style="text-align: center;">
+        <div style="margin-bottom: 15px;font-size: 14px;"><strong>请输入退货原因</strong></div>
+        <div style="line-height: 24px;">
+          <div><returnReason size="large" v-model="plReturnReason"></returnReason></div>
+        </div>
+      </div>
+    </commonModal>
+  </div>
+</template>
+
+<script>
+import { commonMixin } from '@/utils/mixin'
+import { STable, VSelect } from '@/components'
+import Print from '@/views/common/print.vue'
+import { hdPrint } from '@/libs/JGPrint'
+import returnReason from '@/views/common/returnReason'
+import commonModal from '@/views/common/commonModal.vue'
+import ProductType from '../../common/productType.js'
+import importGuideModal from './importGuideModal.vue'
+import {
+  purchaseReturnDetailList,
+  purchaseReturnDetail,
+  purchaseReturnDetailSave,
+  purchaseReturnDetailDel,
+  purchaseReturnDetailDelAll,
+  purchaseReturnModifyQty,
+  modifyReturnReason,
+  purchaseReturnSubmit,
+  purchaseReturnApplyPrint,
+  purchaseReturnApplyExport,
+  purchaseReturnApplyCreateList,
+  queryDealerScopeProductPage,
+  modifyReturnReasonList } from '@/api/purchaseReturnApply'
+export default {
+  name: 'PurchaseReturnEdit',
+  components: { STable, VSelect, Print, ProductType, importGuideModal, returnReason, commonModal },
+  mixins: [commonMixin],
+  data () {
+    return {
+      spinning: false,
+      queryParam: {
+        code: '',
+        name: '',
+        productTypeSn1: undefined,
+        productTypeSn2: undefined,
+        productTypeSn3: undefined
+      },
+      productType: [],
+      dataSource: [],
+      returnReasonList: [], // 退货原因列表
+      disabled: false, //  查询、重置按钮是否可操作
+      advanced: false, // 高级搜索 展开/关闭
+      openGuideModal: false, // 导入产品弹框
+      // 加载数据方法 必须为 Promise 对象
+      loadData: parameter => {
+        this.disabled = true
+        this.queryParam.sysFlag = '1' // 剪冠产品
+        return queryDealerScopeProductPage(Object.assign(parameter, this.queryParam)).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].returnQty = 1
+          }
+          this.disabled = false
+          return data
+        })
+      },
+      chooseParam: {
+        productCode: '',
+        productName: ''
+      },
+      // 加载数据方法 必须为 Promise 对象
+      chooseLoadData: parameter => {
+        return purchaseReturnDetailList(Object.assign(parameter, { purchaseReturnApplySn: this.$route.params.sn }, this.chooseParam)).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].initQty
+            data.list[i].returnReasonBackups = data.list[i].returnReason
+          }
+          this.dataSource = data.list
+          return data
+        })
+      },
+      detailData: null,
+      rowSelectionInfo: null,
+      plReturnReason: '',
+      showPlModal: false
+    }
+  },
+  watch: {
+    showPlModal (newValue, oldValue) {
+      if (!newValue) {
+        this.plReturnReason = ''
+      }
+    }
+  },
+  computed: {
+    selNums () {
+      return this.rowSelectionInfo && this.rowSelectionInfo.selectedRowKeys.length || 0
+    },
+    columns () {
+      const arr = [
+        { title: '序号', dataIndex: 'no', width: '5%', align: 'center' },
+        { title: '产品编码', dataIndex: 'code', width: '15%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '产品名称', dataIndex: 'name', width: '20%', align: 'center', customRender: function (text) { return text || '--' }, ellipsis: true },
+        { title: '产品分类', scopedSlots: { customRender: 'productType' }, width: '20%', align: 'center' },
+        { title: '单位', dataIndex: 'unit', width: '10%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '申请退货数量', scopedSlots: { customRender: 'returnQty' }, width: '10%', align: 'center' },
+        { title: '退货原因', scopedSlots: { customRender: 'returnReason' }, width: '10%', align: 'center' },
+        { title: '操作', scopedSlots: { customRender: 'action' }, width: '10%', align: 'center' }
+      ]
+      return arr
+    },
+    chooseColumns () {
+      const arr = [
+        { title: '序号', dataIndex: 'no', width: '5%', align: 'center' },
+        { title: '产品编码', dataIndex: 'product.code', width: '15%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '产品名称', dataIndex: 'product.name', width: '20%', align: 'center', customRender: function (text) { return text || '--' }, ellipsis: true },
+        { title: '产品分类', scopedSlots: { customRender: 'productType' }, width: '20%', align: 'center' },
+        { title: '单位', dataIndex: 'product.unit', width: '10%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '申请退货数量', scopedSlots: { customRender: 'qty' }, width: '10%', align: 'center' },
+        { title: '退货原因', scopedSlots: { customRender: 'returnReason' }, width: '10%', align: 'center' },
+        { title: '操作', scopedSlots: { customRender: 'action' }, width: '10%', align: 'center' }
+      ]
+      return arr
+    }
+  },
+  methods: {
+    //  返回列表
+    handleBack () {
+      this.$router.push({ name: 'purchaseReturnApplyFormList' })
+    },
+    // 表格选中项
+    rowSelectionFun (obj) {
+      this.rowSelectionInfo = obj || null
+    },
+    // 打印预览/快捷打印
+    handlePrint (type, printerType) {
+      const _this = this
+      _this.spinning = true
+      let url = purchaseReturnApplyPrint
+      const params = { sn: this.$route.params.sn }
+      if (type == 'export') { //  导出
+        url = purchaseReturnApplyExport
+      }
+      // 打印或导出
+      hdPrint(printerType, type, url, params, '采购退货申请单', function () {
+        _this.spinning = false
+      })
+    },
+    // 确认导入明细
+    hanldeImprotOk (obj) {
+      this.spinning = true
+      purchaseReturnApplyCreateList(obj).then(res => {
+        if (res.status == 200) {
+          this.$refs.chooseTable.refresh(true)
+          this.getDetail()
+          this.openGuideModal = false
+        }
+        this.spinning = false
+      })
+    },
+    //  产品分类  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.code = ''
+      this.queryParam.name = ''
+      this.queryParam.productTypeSn1 = undefined
+      this.queryParam.productTypeSn2 = undefined
+      this.queryParam.productTypeSn3 = undefined
+      this.productType = []
+      this.$refs.table.refresh(true)
+    },
+    //  添加/编辑
+    handleAdd (row) {
+      // 添加时退货数量字段名为returnQty,编辑时退货数量字段名为qty
+      if (!row.returnQty) {
+        this.$message.warning('请输入退货数量')
+        return
+      }
+      const params = {
+        purchaseReturnApplySn: this.$route.params.sn,
+        initQty: row.returnQty, //  退货数量
+        productSn: row.productSn,
+        returnReason: row.returnReason
+      }
+      this.spinning = true
+      purchaseReturnDetailSave(params).then(res => {
+        if (res.status == 200) {
+          this.$message.success(res.message)
+          this.$refs.chooseTable.refresh()
+          this.getDetail()
+          this.spinning = false
+        } else {
+          this.spinning = false
+        }
+      })
+    },
+    // 双击快速添加
+    handleClickRow (record) {
+      return {
+        on: {
+          dblclick: (event) => {
+            event.stopPropagation()
+            this.handleAdd(record)
+          }
+        }
+      }
+    },
+    // 导入明细
+    handleImport () {},
+    // 重置已选产品列表
+    resetChooseForm () {
+      this.chooseParam.productCode = ''
+      this.chooseParam.productName = ''
+      this.$refs.chooseTable.refresh(true)
+    },
+    //  删除
+    handleDel (row, isAll) {
+      const _this = this
+      if (this.dataSource.length == 0) {
+        this.$message.info('没有可删除的产品')
+        return
+      }
+      const content = isAll ? '删除后不可恢复,确定要进行整单删除吗?' : '删除后不可恢复,确定要进行删除吗?'
+      this.$confirm({
+        title: '提示',
+        content: content,
+        centered: true,
+        onOk () {
+          const fun = isAll ? purchaseReturnDetailDelAll : purchaseReturnDetailDel
+          const params = isAll ? { purchaseReturnApplySn: _this.$route.params.sn } : { purchaseReturnApplySn: _this.$route.params.sn, purchaseReturnApplyDetailSn: row.purchaseReturnApplyDetailSn }
+          _this.spinning = true
+          fun(params).then(res => {
+            if (res.status == 200) {
+              _this.$message.success(res.message)
+              // _this.$refs.table.refresh()
+              _this.$refs.chooseTable.refresh()
+              _this.spinning = false
+              _this.getDetail()
+            } else {
+              _this.spinning = false
+            }
+          })
+        }
+      })
+    },
+    //  提交
+    handleSubmit () {
+      const _this = this
+      if (this.dataSource.length == 0) {
+        this.$message.info('请添加产品')
+        return
+      }
+      _this.spinning = true
+      purchaseReturnSubmit({ sn: _this.$route.params.sn }).then(res => {
+        if (res.status == 200) {
+          if (res.data.length) {
+            _this.$warning({
+              title: '以下产品请输入退货原因',
+              centered: true,
+              content: res.data.toString()
+            })
+          } else {
+            _this.$message.success(res.message)
+            _this.handleBack()
+          }
+        }
+        _this.spinning = false
+      })
+    },
+    // 已选产品 退货数量修改
+    qtyBlur (val, record) {
+      //  光标移出,值发生改变再调用编辑接口
+      if (val != record.qtyBackups) {
+        this.spinning = true
+        purchaseReturnModifyQty({
+          initQty: record.initQty,
+          purchaseReturnApplyDetailSn: record.purchaseReturnApplyDetailSn,
+          purchaseReturnApplySn: this.$route.params.sn
+        }).then(res => {
+          if (res.status == 200) {
+            this.$message.success(res.message)
+            this.$refs.chooseTable.refresh()
+            record.qtyBackups = record.initQty
+            this.getDetail()
+          } else {
+            record.initQty = record.qtyBackups
+          }
+          this.spinning = false
+        })
+      }
+    },
+    // 已选产品 退货原因修改
+    remarksBlur (val, record) {
+      // 空或没有改变时不保存数据
+      if (!record.returnReason || record.returnReason == record.returnReasonBackups) {
+        record.returnReason = record.returnReasonBackups
+        return
+      }
+      this.spinning = true
+      modifyReturnReason({
+        returnReason: record.returnReason,
+        purchaseReturnApplyDetailSn: record.purchaseReturnApplyDetailSn,
+        purchaseReturnApplySn: this.$route.params.sn
+      }).then(res => {
+        if (res.status == 200) {
+          this.$message.success(res.message)
+          this.$refs.chooseTable.refresh()
+        } else {
+          record.returnReason = record.returnReasonBackups
+        }
+        this.spinning = false
+      })
+    },
+    // 批量设置退货原因
+    openPlSetReason () {
+      if (this.selNums) {
+        this.showPlModal = true
+      } else {
+        this.$message.warning('请先选择产品!')
+      }
+    },
+    setPlReturnReason () {
+      if (this.plReturnReason == '') {
+        this.$message.warning('请输入退货原因!')
+      } else {
+        this.spinning = true
+        const snList = []
+        const arr = this.rowSelectionInfo && this.rowSelectionInfo.selectedRows || []
+        arr.map(item => {
+          snList.push({
+            purchaseReturnApplyDetailSn: item.purchaseReturnApplyDetailSn,
+            returnReason: this.plReturnReason
+          })
+        })
+        modifyReturnReasonList({
+          purchaseReturnApplySn: this.$route.params.sn,
+          detailList: snList
+        }).then(res => {
+          if (res.status == 200) {
+            this.showPlModal = false
+            this.$refs.chooseTable.refresh()
+            this.$refs.chooseTable.clearSelected()
+          }
+          this.spinning = false
+        })
+      }
+    },
+    // 获取单据详情
+    getDetail () {
+      purchaseReturnDetail({ sn: this.$route.params.sn }).then(res => {
+        this.detailData = res.data ? res.data : null
+      })
+    },
+    pageInit () {
+      this.returnReasonList = this.$store.state.app.returnReason
+      this.$refs.chooseTable.refresh(true)
+      this.resetSearchForm()
+      this.getDetail()
+    }
+  },
+  mounted () {
+    if (!this.$store.state.app.isNewTab) { // 页签刷新时调用
+      this.pageInit()
+    }
+  },
+  activated () {
+    // 如果是新页签打开或者进入新的子页(例:存在列表第2条数据编辑页页签时再打开第4条数据的编辑页),则重置当前页面
+    if (this.$store.state.app.isNewTab || !this.$store.state.app.isNewSubTab) {
+      this.pageInit()
+    }
+  },
+  beforeRouteEnter (to, from, next) {
+    next(vm => {})
+  }
+}
+</script>
+
+<style lang="less">
+  .purchaseReturnEdit-wrap{
+    position: relative;
+    height: 100%;
+    padding-bottom: 51px;
+    box-sizing: border-box;
+    >.ant-spin-nested-loading{
+      overflow-y: auto;
+      height: 100%;
+    }
+    .purchaseReturnEdit-back, .purchaseReturnEdit-cont{
+      margin-bottom: 10px;
+    }
+  }
+</style>

+ 201 - 0
src/views/purchasingManagement/purchaseReturnApplyForm/importGuideModal.vue

@@ -0,0 +1,201 @@
+<template>
+  <a-modal
+    centered
+    class="importGuide-modal"
+    :footer="null"
+    :maskClosable="false"
+    title="导入产品"
+    v-model="isShow"
+    @cancel="isShow=false"
+    :width="800">
+    <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>
+          </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="选择导入文件"
+              @remove="resetSearchForm"
+              @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 ChooseImportModal from './chooseImportModal.vue'
+import { Upload } from '@/components'
+export default {
+  name: 'ImportGuideModal',
+  components: { ChooseImportModal, Upload },
+  props: {
+    openModal: { //  弹框显示状态
+      type: Boolean,
+      default: false
+    },
+    params: {
+      type: Object,
+      default: null
+    }
+  },
+  data () {
+    return {
+      isShow: this.openModal, //  是否打开弹框
+      openImportModal: false, //  导入
+      attachAction: process.env.VUE_APP_API_BASE_URL + '/upload',
+      paramsData: null,
+      uploadParams: {
+        savePathType: 'local'
+      }
+    }
+  },
+  methods: {
+    // 清空数据
+    resetSearchForm () {
+      this.$refs.importUpload.setFileList() //  清空导入文件
+      this.paramsData = null //  清空上传数据
+    },
+    // 下一步
+    handlerNextStep () {
+      if (this.paramsData && this.paramsData.path) {
+        this.openImportModal = true
+      } else {
+        this.$message.warning('添加文件后再进行下一步操作!')
+      }
+    },
+    // 上传文件  change
+    changeImport (file) {
+      console.log(file)
+      if (file) {
+        this.paramsData = {
+          purchaseReturnApplySn: this.params.purchaseReturnApplySn || '',
+          purchaseReturnApplyNo: this.params.purchaseReturnApplyNo || '',
+          path: file
+        }
+      }
+    },
+    // 导入
+    hanldeOk (obj) {
+      if (obj && obj.detailList.length > 0) {
+        this.$emit('ok', obj)
+      }
+    },
+    // 关闭
+    handleClose () {
+      this.openImportModal = false
+      this.isShow = false
+    },
+    // 下载模板
+    handleExport () {
+      const link = document.createElement('a')
+      link.style.display = 'none'
+      link.href = 'https://jianguan-images.oss-cn-beijing.aliyuncs.com/template/purchaseReturnApplyImport.xlsx'
+      link.setAttribute('download', '采购退货申请单产品明细模板' + '.xlsx')
+      document.body.appendChild(link)
+      link.click()
+      document.body.removeChild(link)
+    }
+  },
+  watch: {
+    //  父页面传过来的弹框状态
+    openModal (newValue, oldValue) {
+      this.isShow = newValue
+    },
+    //  重定义的弹框状态
+    isShow (newValue, oldValue) {
+      if (!newValue) {
+        this.$emit('close')
+        this.resetSearchForm()
+      }
+    }
+  }
+}
+</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>

+ 365 - 0
src/views/purchasingManagement/purchaseReturnApplyForm/list.vue

@@ -0,0 +1,365 @@
+<template>
+  <a-card size="small" :bordered="false" class="purchaseReturnList-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="单据来源">
+                <v-select
+                  v-model="queryParam.billSource"
+                  ref="billSource"
+                  id="purchaseReturnList-billSource"
+                  code="RETURN_APPLY_BILL_SOURCE"
+                  placeholder="请选择单据来源"
+                  allowClear></v-select>
+              </a-form-item>
+            </a-col>
+            <a-col :md="6" :sm="24">
+              <a-form-item label="采购退货申请单号">
+                <a-input id="purchaseReturnList-purchaseReturnApplyNo" v-model.trim="queryParam.purchaseReturnApplyNo" allowClear placeholder="请输入采购退货申请单号"/>
+              </a-form-item>
+            </a-col>
+            <a-col :md="6" :sm="24">
+              <a-form-item label="业务状态">
+                <v-select
+                  v-model="queryParam.billStatus"
+                  ref="billStatus"
+                  id="purchaseReturnList-billStatus"
+                  code="RETURN_APPLY_BILL_STATUS"
+                  placeholder="请选择业务状态"
+                  allowClear
+                ></v-select>
+              </a-form-item>
+            </a-col>
+            <template v-if="advanced">
+              <a-col :md="6" :sm="24">
+                <a-form-item label="客服审核时间">
+                  <rangeDate ref="auditDate" :value="auditTime" @change="auditDateChange" />
+                </a-form-item>
+              </a-col>
+            </template>
+            <a-col :md="6" :sm="24" style="margin-bottom: 10px;">
+              <a-button type="primary" @click="$refs.table.refresh(true)" :disabled="disabled" id="purchaseReturnList-refresh">查询</a-button>
+              <a-button style="margin-left: 8px" @click="resetSearchForm" :disabled="disabled" id="purchaseReturnList-reset">重置</a-button>
+              <a @click="advanced=!advanced" style="margin-left: 8px">
+                {{ advanced ? '收起' : '展开' }}
+                <a-icon :type="advanced ? 'up' : 'down'"/>
+              </a>
+            </a-col>
+          </a-row>
+        </a-form>
+      </div>
+      <!-- 操作按钮 -->
+      <div class="table-operator" v-if="$hasPermissions('B_purchaseReturnApplyNew')">
+        <a-button id="purchaseReturnList-add" type="primary" class="button-error" @click="handleEdit()">新增</a-button>
+      </div>
+      <!-- 列表 -->
+      <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="purchaseReturnApplyNo" slot-scope="text, record">
+          <span class="table-td-link" v-if="$hasPermissions('B_purchaseReturnApplyDetail')" @click="handleDetail(record)">{{ record.purchaseReturnApplyNo }}</span>
+          <span v-else>{{ record.purchaseReturnApplyNo }}</span>
+          <a-badge count="改" :offset="[10,0]" v-if="record.changeFlag=='1'"></a-badge>
+        </template>
+        <!-- 操作 -->
+        <template slot="action" slot-scope="text, record">
+          <div>
+            <a-button
+              size="small"
+              type="link"
+              class="button-primary"
+              v-if="record.billStatus == 'WAIT_SUBMIT'&&$hasPermissions('B_purchaseReturnApplyEdit')"
+              @click="handleEdit(record)"
+            >编辑</a-button>
+            <a-button
+              size="small"
+              type="link"
+              class="button-error"
+              v-if="record.billStatus == 'WAIT_SUBMIT'&&$hasPermissions('B_purchaseReturnApplyDel')"
+              @click="handleDel(record)"
+            >删除</a-button>
+            <a-button
+              size="small"
+              type="link"
+              v-if="record.billStatus == 'FINISH'&&$hasPermissions('B_purchaseReturnApplyCreat')"
+              @click="handleWarehouse(record)"
+              class="button-primary"
+            >生成采购退货单</a-button>
+            <a-button
+              size="small"
+              type="link"
+              v-if="(record.billStatus == 'CANCEL'||record.billStatus == 'AUDIT_REJECT')&&$hasPermissions('B_purchaseReturnApplyAsignEdit')"
+              @click="handleFinishBill(record)"
+              class="button-primary"
+            >再次编辑</a-button>
+          </div>
+        </template>
+      </s-table>
+    </a-spin>
+
+    <!-- 生成采购退货单 -->
+    <creatPurchaseReutn ref="creatPurchaseReutn" :openModal="openCpModal" @close="openCpModal=false" @creatOk="$refs.table.refresh()"></creatPurchaseReutn>
+  </a-card>
+</template>
+
+<script>
+import { commonMixin } from '@/utils/mixin'
+import { STable, VSelect } from '@/components'
+import rangeDate from '@/views/common/rangeDate.vue'
+import getDate from '@/libs/getDate.js'
+import creatPurchaseReutn from './creatPurchaseReutn.vue'
+import { purchaseReturnList, purchaseReturnSave, purchaseReturnDel, purchaseReturnAgainCreate } from '@/api/purchaseReturnApply'
+export default {
+  name: 'PurchaseReturnList',
+  components: { STable, VSelect, rangeDate, creatPurchaseReutn },
+  mixins: [commonMixin],
+  data () {
+    return {
+      spinning: false,
+      advanced: true, // 高级搜索 展开/关闭
+      openCpModal: false,
+      time: [
+        getDate.getCurrMonthDays().starttime,
+        getDate.getCurrMonthDays().endtime
+      ],
+      auditTime: [],
+      queryParam: { //  查询条件
+        beginDate: getDate.getCurrMonthDays().starttime,
+        endDate: getDate.getCurrMonthDays().endtime,
+        purchaseReturnApplyNo: '', //  退货申请单号
+        billStatus: undefined, //  业务状态
+        billSource: undefined, // 单据来源
+        beginAuditDate: '', // 审核时间
+        endAuditDate: ''
+      },
+      disabled: false, //  查询、重置按钮是否可操作
+      tableHeight: 0,
+      // 加载数据方法 必须为 Promise 对象
+      loadData: parameter => {
+        this.disabled = true
+        this.spinning = true
+        delete parameter.index
+        delete parameter.tableId
+        return purchaseReturnList(Object.assign(parameter, this.queryParam)).then(res => {
+          let data
+          if (res.status == 200) {
+            data = res.data
+            const no = (data.pageNo - 1) * data.pageSize
+            for (var i = 0; i < data.list.length; i++) {
+              data.list[i].no = no + i + 1
+            }
+            this.disabled = false
+          }
+          this.spinning = false
+          return data
+        })
+      }
+    }
+  },
+  computed: {
+    columns () {
+      const arr = [
+        { title: '序号', dataIndex: 'no', width: '5%', align: 'center' },
+        { title: '单据来源', dataIndex: 'billSourceDictValue', width: '6%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '采购退货申请单号', scopedSlots: { customRender: 'purchaseReturnApplyNo' }, width: '14%', align: 'center' },
+        { title: '供应商', dataIndex: 'returnTargetName', width: '15%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '申请退货数量', dataIndex: 'totalInitialQty', width: '8%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+        { title: '总公司实收数量', dataIndex: 'totalReceiveQty', width: '8%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+        { title: '业务状态', dataIndex: 'billStatusDictValue', width: '8%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '创建时间', dataIndex: 'createDate', width: '12%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '客服审核时间', dataIndex: 'auditTime', width: '12%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '操作', scopedSlots: { customRender: 'action' }, width: '12%', align: 'center' }
+      ]
+      return arr
+    }
+  },
+  methods: {
+    //  时间  change
+    dateChange (date) {
+      this.queryParam.beginDate = date[0]
+      this.queryParam.endDate = date[1]
+    },
+    // 审核时间
+    auditDateChange (date) {
+      this.queryParam.beginAuditDate = date[0]
+      this.queryParam.endAuditDate = date[1]
+    },
+    //  重置
+    resetSearchForm () {
+      this.resetData()
+      this.$refs.table.refresh(true)
+    },
+    // 重置数据
+    resetData (flag) {
+      this.$refs.rangeDate.resetDate(flag ? '' : this.time)
+      this.queryParam.beginDate = flag ? '' : getDate.getCurrMonthDays().starttime
+      this.queryParam.endDate = flag ? '' : getDate.getCurrMonthDays().endtime
+      this.queryParam.purchaseReturnApplyNo = ''
+      this.queryParam.billStatus = undefined
+      this.queryParam.billSource = undefined
+      this.auditTime = []
+      this.$refs.auditDate.resetDate(this.auditTime)
+      this.queryParam.beginAuditDate = ''
+      this.queryParam.endAuditDate = ''
+      if (!flag) {
+        this.setIsHomeNav(this.$route.name, null)
+      }
+    },
+    //  删除
+    handleDel (row) {
+      const _this = this
+      this.$confirm({
+        title: '提示',
+        content: '删除后不可恢复,确定要进行删除吗?',
+        centered: true,
+        onOk () {
+          _this.spinning = true
+          purchaseReturnDel({ purchaseReturnApplySn: row.purchaseReturnApplySn }).then(res => {
+            if (res.status == 200) {
+              _this.$message.success(res.message)
+              _this.$refs.table.refresh()
+              _this.spinning = false
+            } else {
+              _this.spinning = false
+            }
+          })
+        }
+      })
+    },
+    //  详情
+    handleDetail (row) {
+      this.$router.push({ name: 'purchaseReturnApplyFormDetail', params: { sn: row.purchaseReturnApplySn } })
+    },
+    //  新增/编辑
+    handleEdit (row) {
+      const _this = this
+      if (row) { //  编辑
+        _this.$router.push({ name: 'purchaseReturnApplyFormEdit', params: { sn: row.purchaseReturnApplySn } })
+      } else { //  新增
+        this.$confirm({
+          title: '提示',
+          content: <div><div style="padding:10px 0;">供应商:箭冠营销中心</div><div style='color:#999;'><div>说明:</div><div>1、采购退货申请单提交后,箭冠营销中心系统将能查看到此单并进行后续处理。</div><div>2、采购退货申请单中的产品,不会占用库存。</div></div></div>,
+          centered: true,
+          onOk () {
+            _this.spinning = true
+            purchaseReturnSave({}).then(res => {
+              if (res.status == 200) {
+                const data = res.data
+                _this.spinning = false
+                // 重置查询条件
+                _this.resetData()
+                _this.$router.push({ name: 'purchaseReturnApplyFormEdit', params: { sn: data.purchaseReturnApplySn } })
+              } else {
+                _this.spinning = false
+              }
+            })
+          }
+        })
+      }
+    },
+    // 再次编辑
+    handleFinishBill (row) {
+      const _this = this
+      this.$confirm({
+        title: '提示',
+        content: '系统将自动生成一个新的采购退货申请单,与原单据内容相同。确认再次编辑吗?',
+        centered: true,
+        onOk () {
+          _this.spinning = true
+          purchaseReturnAgainCreate({ sn: row.purchaseReturnApplySn }).then(res => {
+            if (res.status == 200) {
+              _this.$message.success(res.message)
+              _this.$refs.table.refresh()
+              _this.spinning = false
+            } else {
+              _this.spinning = false
+            }
+          })
+        }
+      })
+    },
+    // 生成采购单
+    handleWarehouse (row) {
+      this.openCpModal = true
+      this.$refs.creatPurchaseReutn.setData(row)
+    },
+    pageInit () {
+      const _this = this
+      this.$nextTick(() => { // 页面渲染完成后的回调
+        _this.setTableH()
+      })
+      // 是否打开的页签
+      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.resetData(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 - 235
+    }
+  },
+  watch: {
+    advanced (newValue, oldValue) {
+      const _this = this
+      this.$nextTick(() => { // 页面渲染完成后的回调
+        _this.setTableH()
+      })
+    },
+    '$store.state.app.winHeight' (newValue, oldValue) { //  窗口变更时,需同时更改表格高度
+      this.setTableH()
+    }
+  },
+  mounted () {},
+  activated () {
+    this.pageInit()
+  },
+  beforeRouteEnter (to, from, next) {
+    next(vm => {})
+  }
+}
+</script>

+ 2 - 1
src/views/purchasingManagement/purchaseReturnOutSync/grapEdit.vue

@@ -240,7 +240,8 @@ export default {
       // 加载数据方法 必须为 Promise 对象
       loadData: parameter => {
         this.disabled = true
-        this.queryParam.returnTargetType = this.$route.params.returnTargetType
+        this.queryParam.purchaseTargetType = this.$route.params.returnTargetType
+        this.queryParam.purchaseTargetSn = this.$route.params.purchaseTargetSn
         return purchaseReturnPurchaseBillNoSyncList(Object.assign(parameter, this.queryParam)).then(res => {
           const data = res.data
           const no = (data.pageNo - 1) * data.pageSize

+ 32 - 30
src/views/purchasingManagement/purchaseReturnOutSync/list.vue

@@ -107,35 +107,37 @@
         </template>
         <!-- 操作 -->
         <template slot="action" slot-scope="text, record">
-          <a-button
-            size="small"
-            type="link"
-            class="button-primary"
-            v-if="(record.state == 'WAIT_SUBMIT' || record.state == 'AUDIT_REJECT') && $hasPermissions('B_purchaseReturn_outSnycEdit')"
-            @click="handleEdit(record,1)"
-            id="purchaseReturnList-edit-btn">编辑</a-button>
-          <a-button
-            size="small"
-            type="link"
-            v-if="record.state == 'WAIT_AUDIT' && $hasPermissions('B_purchaseReturn_outSnycAudit')"
-            @click="handleAudit(record)"
-            class="button-primary"
-            id="bulkReturnGoodsList-audit-btn">审核</a-button>
-          <a-button
-            size="small"
-            type="link"
-            v-if="record.state == 'WAIT_OUT_WAREHOUSE' && $hasPermissions('B_purchaseReturn_outSnycOut')"
-            @click="handleWarehouse(record)"
-            class="button-primary"
-            id="bulkReturnGoodsList-out-btn">出库</a-button>
-          <a-button
-            size="small"
-            type="link"
-            class="button-error"
-            v-if="(record.state == 'WAIT_SUBMIT' || record.state == 'AUDIT_REJECT') && $hasPermissions('B_purchaseReturn_outSnycDel')"
-            @click="handleDel(record)"
-            id="purchaseReturnList-del-btn">删除</a-button>
-          <span v-if="record.state == 'FINISH'||!($hasPermissions('B_purchaseReturn_outSnycEdit') || $hasPermissions('B_purchaseReturn_outSnycDel')||$hasPermissions('B_purchaseReturn_outSnycOut')||$hasPermissions('B_purchaseReturn_outSnycAudit'))">--</span>
+          <div v-if="record.synchronizationType == '0'">
+            <a-button
+              size="small"
+              type="link"
+              class="button-primary"
+              v-if="(record.state == 'WAIT_SUBMIT' || record.state == 'AUDIT_REJECT') && $hasPermissions('B_purchaseReturn_outSnycEdit')"
+              @click="handleEdit(record,1)"
+              id="purchaseReturnList-edit-btn">编辑</a-button>
+            <a-button
+              size="small"
+              type="link"
+              v-if="record.state == 'WAIT_AUDIT' && $hasPermissions('B_purchaseReturn_outSnycAudit')"
+              @click="handleAudit(record)"
+              class="button-primary"
+              id="bulkReturnGoodsList-audit-btn">审核</a-button>
+            <a-button
+              size="small"
+              type="link"
+              v-if="record.state == 'WAIT_OUT_WAREHOUSE' && $hasPermissions('B_purchaseReturn_outSnycOut')"
+              @click="handleWarehouse(record)"
+              class="button-primary"
+              id="bulkReturnGoodsList-out-btn">出库</a-button>
+            <a-button
+              size="small"
+              type="link"
+              class="button-error"
+              v-if="(record.state == 'WAIT_SUBMIT' || record.state == 'AUDIT_REJECT') && $hasPermissions('B_purchaseReturn_outSnycDel')"
+              @click="handleDel(record)"
+              id="purchaseReturnList-del-btn">删除</a-button>
+          </div>
+          <div v-else></div>
         </template>
       </s-table>
     </a-spin>
@@ -280,7 +282,7 @@ export default {
       if (!flag) {
         this.resetData()
       }
-      this.$router.push({ name: row.grabFlag == 1 ? 'purchaseReturnOutSyncGrapEdit' : 'purchaseReturnOutSyncEdit', params: { sn: row.purchaseReturnSn, returnTargetType: row.returnTargetType } })
+      this.$router.push({ name: row.grabFlag == 1 ? 'purchaseReturnOutSyncGrapEdit' : 'purchaseReturnOutSyncEdit', params: { sn: row.purchaseReturnSn, returnTargetType: row.returnTargetType, purchaseTargetSn: row.returnTargetSn } })
     },
     // 详情
     handleDetail (row) {

+ 1 - 1
src/views/salesManagement/salesQuery/edit.vue

@@ -196,7 +196,7 @@
     <!-- <div class="affix-cont"></div> -->
     <!-- 选择客户弹框 -->
     <choose-custom-modal ref="custModal" :show="openModal" @updateData="updateData" @cancel="openModal=false" />
-    <!-- 导入费用明细 -->
+    <!-- 导入明细 -->
     <importGuideModal :openModal="openGuideModal" :params="{salesBillSn: $route.params.sn, salesBillNo:detailData?detailData.salesBillNo:''}" @close="openGuideModal=false" @ok="hanldeImprotOk" />
     <!-- 收付款弹框 -->
     <settleModal ref="settleModal" @ok="settleAcountPay" :openModal="openSettleModal" @close="openSettleModal=false"></settleModal>

+ 2 - 2
vue.config.js

@@ -211,8 +211,8 @@ const vueConfig = {
     // If you want to turn on the proxy, please remove the mockjs /src/main.jsL11
     proxy: {
       '/api': {
-        // target: 'http://192.168.0.102/qpls-md',
-        target: 'http://p.iscm.360arrow.com/qpls-md',
+        target: 'http://192.168.0.182:8503/qpls-md',
+        // target: 'http://p.iscm.360arrow.com/qpls-md',
         // ws: false,
         ws: true,
         changeOrigin: true,