Bläddra i källkod

货位编号管理

lilei 2 år sedan
förälder
incheckning
b40448f400

+ 73 - 0
src/api/product.js

@@ -329,4 +329,77 @@ export const queryNewProductPage = (params) => {
     data: params,
     method: 'post'
   })
+}
+
+// 导出产品及货位信息
+export const stackPlaceExport = (params) => {
+  return axios({
+    url: '/product/stackPlace/export',
+    data: params,
+    method: 'post',
+    responseType: 'blob'
+  })
+}
+
+// 导入产品货位-导出错误
+export const stackPlaceExportError = (params) => {
+  return axios({
+    url: '/product/stackPlace/exportImportError',
+    data: params,
+    method: 'post',
+    responseType: 'blob'
+  })
+}
+
+// 导入产品货位
+export const stackPlaceImport = (params) => {
+  return axios({
+    url: '/product/stackPlace/import',
+    data: params,
+    method: 'post'
+  })
+}
+// 下载导入模板
+export const stackPlaceImportTemplate= (params) => {
+  return axios({
+    url: '/product/stackPlace/importTemplate',
+    data: params,
+    method: 'post',
+    responseType: 'blob'
+  })
+}
+// 导入产品货位-入库数据
+export const stackPlaceInsertImport = (params) => {
+  return axios({
+    url: '/product/stackPlace/insertImport',
+    data: params,
+    method: 'post'
+  })
+}
+// 查询产品货位历史变更记录
+export const stackPlaceListHistory = (params) => {
+  return axios({
+    url: '/product/stackPlace/listHistoryByProductSn',
+    data: params,
+    method: 'post'
+  })
+}
+// 分页查询产品及货位信息
+export const queryStackPlaceQueryPage = (params) => {
+  const url = `/product/stackPlace/queryPage/${params.pageNo}/${params.pageSize}`
+  delete params.pageNo
+  delete params.pageSize
+  return axios({
+    url: url,
+    data: params,
+    method: 'post'
+  })
+}
+// 保存产品货位信息
+export const stackPlaceSave = (params) => {
+  return axios({
+    url: '/product/stackPlace/save',
+    data: params,
+    method: 'post'
+  })
 }

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

@@ -2401,6 +2401,31 @@ export const asyncRouterMap = [
                 }
               }
             ]
+          },
+          {
+            path: '/productManagement/shelfNoManage',
+            redirect: '/productManagement/shelfNoManage/list',
+            name: 'shelfNoManage',
+            component: BlankLayout,
+            meta: {
+              title: '货位编号管理',
+              icon: 'radar-chart',
+              // permission: 'M_shelfNoManageList'
+            },
+            hideChildrenInMenu: true,
+            children: [
+              {
+                path: 'list',
+                name: 'shelfNoManageList',
+                component: () => import(/* webpackChunkName: "productManagement" */ '@/views/productManagement/shelfNoManage/list.vue'),
+                meta: {
+                  title: '货位编号管理',
+                  icon: 'radar-chart',
+                  hidden: true,
+                  // permission: 'M_shelfNoManageList'
+                }
+              }
+            ]
           }
         ]
       },

+ 3 - 3
src/views/financialManagement/financialCollection/list.vue

@@ -33,7 +33,7 @@
               </a-col>
               <a-col :md="4" :sm="24">
                 <a-form-item label="付款方">
-                  <a-input id="financialCollectionList-payerNames" v-model.trim="queryParam.payerNames" allowClear placeholder="请输入付款方"/>
+                  <a-input id="financialCollectionList-payerNames" v-model.trim="queryParam.payerName" allowClear placeholder="请输入付款方"/>
                 </a-form-item>
               </a-col>
               <a-col :md="6" :sm="24">
@@ -179,7 +179,7 @@ export default {
         applyPersonSn: undefined,
         bookReason: '',
         status: undefined,
-        payerNames: ''
+        payerName: ''
       },
       disabled: false, //  查询、重置按钮是否可操作
       creatDate: [], //  创建时间
@@ -253,7 +253,7 @@ export default {
       if (this.advanced) {
         this.$refs.rangeAuditDate.resetDate(this.auditDate)
       }
-      this.queryParam.payerNames = ''
+      this.queryParam.payerName = ''
       this.queryParam.auditBeginDate = ''
       this.queryParam.auditEndDate = ''
       this.queryParam.bookNo = ''

+ 104 - 0
src/views/productManagement/shelfNoManage/changeRecordModal.vue

@@ -0,0 +1,104 @@
+<template>
+  <a-modal
+    centered
+    :footer="null"
+    :maskClosable="false"
+    title="变更记录"
+    v-model="isShow"
+    @cancel="isShow=false"
+    width="50%">
+    <a-descriptions size="small" :column="2">
+      <a-descriptions-item label="产品编码">
+        {{ detailData&&detailData.productVO.code || '--' }}
+      </a-descriptions-item>
+      <a-descriptions-item label="产品名称">
+        {{ detailData&&detailData.productVO.name || '--' }}
+      </a-descriptions-item>
+    </a-descriptions>
+    <a-spin :spinning="spinning" tip="Loading...">
+      <s-table
+        class="sTable fixPagination"
+        ref="table"
+        size="small"
+        :rowKey="(record) => record.id"
+        :columns="columns"
+        :data="loadData"
+        :scroll="{ y: 500 }"
+        :showPagination="false"
+        :defaultLoadData="false"
+        bordered>
+      </s-table>
+    </a-spin>
+  </a-modal>
+</template>
+
+<script>
+import { STable } from '@/components'
+import { stackPlaceListHistory } from '@/api/product'
+export default {
+  name: 'ChangeRecordModal',
+  components: { STable },
+  props: {
+    openModal: {
+      type: Boolean,
+      default: false
+    },
+    detailData: {
+      type: Object,
+      default: function () {
+        return null
+      }
+    }
+  },
+  data () {
+    return {
+      spinning: false,
+      isShow: this.openModal,
+      columns: [
+        { title: '序号', dataIndex: 'no', width: '10%', align: 'center' },
+        { title: '变更时间', dataIndex: 'updateDate', width: '25%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '变更人', dataIndex: 'creatorId', width: '25%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '货位编号-变更前', dataIndex: 'oldStackPlaceCode', width: '20%', align: 'left', customRender: function (text) { return text || '--' } },
+        { title: '货位编号-变更后', dataIndex: 'newStackPlaceCode', width: '20%', align: 'left', customRender: function (text) { return text || '--' } }
+      ],
+      // 加载数据方法 必须为 Promise 对象
+      loadData: parameter => {
+        this.spinning = true
+        delete parameter.tableId
+        delete parameter.index
+        return stackPlaceListHistory({ productSn: this.detailData.productVO.productSn }).then(res => {
+          let data
+          if (res.status == 200) {
+            data = res.data
+            const no = 0
+            for (var i = 0; i < data.length; i++) {
+              data[i].no = no + i + 1
+            }
+            this.disabled = false
+          }
+          this.spinning = false
+          return data
+        })
+      }
+    }
+  },
+  watch: {
+    openModal (nVal, oVal) {
+      this.isShow = nVal
+    },
+    isShow (nVal, oVal) {
+      if (!nVal) {
+        this.$emit('close')
+        this.$refs.table.clearTable()
+      } else {
+        this.$nextTick(() => {
+          this.$refs.table.refresh()
+        })
+      }
+    }
+  }
+}
+</script>
+
+<style>
+</style>

+ 189 - 0
src/views/productManagement/shelfNoManage/chooseImportModal.vue

@@ -0,0 +1,189 @@
+<template>
+  <a-modal
+    centered
+    class="chooseImport-modal"
+    :footer="null"
+    :maskClosable="false"
+    title="导入"
+    v-model="isShow"
+    @cancel="isShow=false"
+    :width="900">
+    <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 { stackPlaceImport, stackPlaceExportError } from '@/api/product'
+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: '10%', align: 'center' },
+        { title: '产品编码', dataIndex: 'code', width: '25%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '产品名称', dataIndex: 'name', width: '25%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '货位编号-变更前', dataIndex: 'stackPlaceCode', width: '20%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '货位编号-变更后', dataIndex: 'newStackPlaceCode', width: '20%', align: 'center', customRender: function (text) { return text || '--' } }
+      ],
+      loadData: [],
+      nowUnColumns: [
+        { title: '序号', dataIndex: 'no', width: '10%', 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 || '--' } },
+        { title: '货位编号-变更前', dataIndex: 'stackPlaceCode', width: '20%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '货位编号-变更后', dataIndex: 'newStackPlaceCode', width: '20%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '备注', dataIndex: 'errorMsg', width: '15%', align: 'center', customRender: function (text) { return text || '--' } }
+      ],
+      unLoadData: [],
+      loading: false
+    }
+  },
+  methods: {
+    getData () {
+      const _this = this
+      this.loading = true
+      const params = {
+        path: this.paramsData.path
+      }
+      stackPlaceImport(params).then(res => {
+        this.loading = false
+        if (res.status == 200) {
+          if (res.data.rightList && res.data.rightList.length > 0) {
+            res.data.rightList.map((item, index) => {
+              item.no = index + 1
+            })
+          }
+          if (res.data.errorList && res.data.errorList.length > 0) {
+            res.data.errorList.map((item, index) => {
+              item.no = index + 1
+            })
+          }
+          _this.loadData = res.data.rightList || []
+          _this.unLoadData = res.data.errorList || []
+        }
+      })
+    },
+    // 确认导入
+    handleSubmit () {
+      if (this.loadData.length == 0) {
+        this.$message.warning('无可导入货位编号!')
+      } else {
+        this.$emit('ok', this.loadData)
+        this.isShow = false
+      }
+    },
+    // 导出
+    handleError () {
+      const _this = this
+      if (_this.unLoadData.length < 1) {
+        _this.$message.info('暂无可导出的错误项~')
+        return
+      }
+      _this.spinning = true
+      hdExportExcel(stackPlaceExportError, _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>

+ 147 - 0
src/views/productManagement/shelfNoManage/editHwModal.vue

@@ -0,0 +1,147 @@
+<template>
+  <a-modal
+    centered
+    class="shelfSet-newHw-modal"
+    :footer="null"
+    :maskClosable="false"
+    title="编辑"
+    v-model="isShow"
+    @cancel="isShow=false"
+    :width="600">
+    <a-spin :spinning="spinning" tip="Loading...">
+      <a-form-model
+        id="shelfSet-newHw-form"
+        ref="ruleForm"
+        :model="form"
+        :rules="rules"
+        :label-col="formItemLayout.labelCol"
+        :wrapper-col="formItemLayout.wrapperCol">
+        <a-form-model-item label="产品编码">{{ nowData&&nowData.productVO.code || '--' }}</a-form-model-item>
+        <a-form-model-item label="产品名称">{{ nowData&&nowData.productVO.name || '--' }}</a-form-model-item>
+        <a-form-model-item label="货位编号" prop="stackPlaceCode">
+          <a-input v-model="form.stackPlaceCode" placeholder="请输入货位编号(最多10个字符)"></a-input>
+        </a-form-model-item>
+      </a-form-model>
+      <div class="btn-cont">
+        <a-button type="primary" id="shelfSet-newHw-modal-save" @click="handleSave">保存</a-button>
+        <a-button id="shelfSet-newHw-modal-back" @click="isShow=false" style="margin-left: 15px;">取消</a-button>
+      </div>
+    </a-spin>
+  </a-modal>
+</template>
+
+<script>
+import { commonMixin } from '@/utils/mixin'
+import { stackPlaceSave } from '@/api/product'
+export default {
+  name: 'EditHwModal',
+  mixins: [commonMixin],
+  props: {
+    openModal: { //  弹框显示状态
+      type: Boolean,
+      default: false
+    },
+    type: {
+      type: String,
+      default: 'edit'
+    },
+    nowData: {
+      type: Object,
+      default: () => {
+        return {}
+      }
+    }
+  },
+  data () {
+    return {
+      spinning: false,
+      isShow: this.openModal, //  是否打开弹框
+      formItemLayout: {
+        labelCol: { span: 4 },
+        wrapperCol: { span: 18 }
+      },
+      form: {
+        shelfPlaceCode: '',
+        productSn: undefined,
+        productCode: undefined,
+        price: '',
+        cost: '',
+        maxQty: ''
+      },
+      rules: {
+        shelfPlaceCode: [
+          { required: true, message: '请输入货位编号', trigger: 'blur' }
+        ]
+      },
+      productName: ''
+    }
+  },
+  methods: {
+    //  保存
+    handleSave () {
+      const _this = this
+      this.$refs.ruleForm.validate(valid => {
+        if (valid) {
+          const form = JSON.parse(JSON.stringify(_this.form))
+          const params = {
+            'stackPlaceCode': form.stackPlaceCode,
+            'product': {
+              'productSn': _this.nowData.productVO.productSn
+            }
+          }
+          // 开始提交数据
+          _this.spinning = true
+          stackPlaceSave(params).then(res => {
+            if (res.status == 200) {
+              _this.$message.success(res.message)
+              _this.isShow = false
+              _this.$emit('ok', res.data)
+              _this.spinning = false
+            } else {
+              _this.spinning = false
+            }
+          })
+        } else {
+          return false
+        }
+      })
+    },
+    resetData () {
+      this.form.stackPlaceCode = undefined
+      this.$refs.ruleForm.resetFields()
+    }
+  },
+  watch: {
+    //  父页面传过来的弹框状态
+    openModal (newValue, oldValue) {
+      this.isShow = newValue
+    },
+    //  重定义的弹框状态
+    isShow (newValue, oldValue) {
+      if (!newValue) {
+        this.$emit('close')
+        this.resetData()
+      } else {
+        if (this.type == 'edit') {
+          this.form.stackPlaceCode = this.nowData.stackPlaceCode
+        }
+      }
+    }
+  }
+}
+</script>
+
+<style lang="less">
+.shelfSet-newHw-modal {
+	.ant-modal-body {
+		padding: 40px 40px 24px;
+	}
+  .ant-form-item{
+    margin-bottom: 15px;
+  }
+	.btn-cont {
+		text-align: center;
+		margin: 35px 0 10px;
+	}
+}
+</style>

+ 195 - 0
src/views/productManagement/shelfNoManage/importGuideModal.vue

@@ -0,0 +1,195 @@
+<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 ChooseImportModal from './chooseImportModal.vue'
+import { Upload } from '@/components'
+import { hdExportExcel } from '@/libs/exportExcel'
+import { stackPlaceImportTemplate } from '@/api/product'
+export default {
+  name: 'ImportGuideModal',
+  components: { ChooseImportModal, Upload },
+  props: {
+    openModal: { //  弹框显示状态
+      type: Boolean,
+      default: false
+    },
+    params: {
+      type: Object,
+      default: null
+    }
+  },
+  data () {
+    return {
+      isShow: this.openModal, //  是否打开弹框
+      openImportModal: false, //  导入
+      attachAction: process.env.VUE_APP_API_BASE_URL + '/upload',
+      paramsData: null,
+      uploadParams: {
+        savePathType: 'local'
+      }
+    }
+  },
+  methods: {
+    // 下一步
+    handlerNextStep () {
+      if (this.paramsData) {
+        this.openImportModal = true
+      } else {
+        this.$message.warning('添加文件后再进行下一步操作!')
+      }
+    },
+    // 上传文件  change
+    changeImport (file) {
+      if (file) {
+        this.paramsData = {
+          path: file
+        }
+      }
+    },
+    // 导入
+    hanldeOk (obj) {
+      if (obj && obj.length > 0) {
+        this.$emit('ok', obj)
+        this.isShow = false
+      }
+    },
+    // 关闭
+    handleClose () {
+      this.openImportModal = false
+      this.isShow = false
+    },
+    //  位编号管理导入模板
+    handleExport () {
+      const _this = this
+      this.spinning = true
+      hdExportExcel(stackPlaceImportTemplate, {}, '货位编号管理导入模板', function () {
+        _this.spinning = false
+      })
+    }
+  },
+  watch: {
+    //  父页面传过来的弹框状态
+    openModal (newValue, oldValue) {
+      this.isShow = newValue
+    },
+    //  重定义的弹框状态
+    isShow (newValue, oldValue) {
+      if (!newValue) {
+        this.$emit('close')
+        this.paramsData = null
+        this.$refs.importUpload.setFileList('')
+      }
+    }
+  }
+}
+</script>
+
+<style lang="less" scoped>
+  .importGuide-modal{
+    .importGuide-con{
+      .explain-con{
+        .explain-item{
+          margin-bottom: 10px;
+          .explain-tit{
+            font-weight: bold;
+            span{
+              display: inline-block;
+              width: 18px;
+              height: 18px;
+              line-height: 16px;
+              text-align: center;
+              margin-right: 5px;
+              border-radius: 50%;
+              border: 1px solid rgba(0, 0, 0, 0.3);
+            }
+          }
+          p{
+            margin: 8px 0;
+            padding-left: 23px;
+          }
+          ul{
+            list-style: none;
+            padding: 0;
+            padding-left: 23px;
+            margin: 0;
+            li{
+              line-height: 26px;
+            }
+          }
+        }
+        #importGuide-attachList{
+          width: 100%;
+        }
+      }
+      .btn-con{
+        margin: 10px 0 20px;
+        text-align: center;
+        .button-cancel{
+          font-size: 12px;
+        }
+      }
+    }
+  }
+</style>

+ 311 - 0
src/views/productManagement/shelfNoManage/list.vue

@@ -0,0 +1,311 @@
+<template>
+  <a-card size="small" :bordered="false" class="shelfNoMan-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="4" :sm="24">
+              <a-form-item label="产品编码">
+                <a-input id="shelfNoMan-code" v-model.trim="queryParam.product.code" allowClear placeholder="请输入产品编码"/>
+              </a-form-item>
+            </a-col>
+            <a-col :md="4" :sm="24">
+              <a-form-item label="产品名称">
+                <a-input id="shelfNoMan-name" v-model.trim="queryParam.product.name" allowClear placeholder="请输入产品名称"/>
+              </a-form-item>
+            </a-col>
+            <a-col :md="4" :sm="24">
+              <a-form-item label="原厂编码">
+                <a-input id="shelfNoMan-origCode" v-model.trim="queryParam.product.origCode" allowClear placeholder="请输入原厂编码"/>
+              </a-form-item>
+            </a-col>
+            <a-col :md="4" :sm="24">
+              <a-form-item label="产品品牌">
+                <ProductBrand id="shelfNoMan-productBrandSn" v-model="queryParam.product.productBrandSn"></ProductBrand>
+              </a-form-item>
+            </a-col>
+            <template v-if="advanced">
+              <a-col :md="4" :sm="24">
+                <a-form-item label="产品分类">
+                  <productTypeAll placeholder="请选择产品分类" @change="changeProductType" v-model="productType" id="shelfNoMan-productType"></productTypeAll>
+                </a-form-item>
+              </a-col>
+              <a-col :md="4" :sm="24">
+                <a-form-item label="产品状态">
+                  <v-select code="PRODUCT_STATUS" id="shelfNoMan-state" v-model="queryParam.product.state" allowClear placeholder="请选择产品状态"></v-select>
+                </a-form-item>
+              </a-col>
+              <a-col :md="4" :sm="24">
+                <a-form-item label="货位编号">
+                  <a-input id="shelfNoMan-stackPlaceCode" v-model.trim="queryParam.stackPlaceCode" allowClear placeholder="请输入货位编号"/>
+                </a-form-item>
+              </a-col>
+              <a-col :md="4" :sm="24">
+                <a-form-item label="是否有货位编号">
+                  <a-select id="shelfNoMan-haveStackCode" v-model="queryParam.haveStackCode" allowClear placeholder="请选择">
+                    <a-select-option value="1">
+                      有编号
+                    </a-select-option>
+                    <a-select-option value="0">
+                      无编号
+                    </a-select-option>
+                  </a-select>
+                </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="shelfNoMan-refresh">查询</a-button>
+              <a-button style="margin-left: 5px" @click="resetSearchForm" :disabled="disabled" id="shelfNoMan-reset">重置</a-button>
+              <a-button
+                v-if="$hasPermissions('B_productInfo_export')"
+                style="margin-left: 5px"
+                type="primary"
+                class="button-warning"
+                @click="handleExport"
+                :disabled="disabled"
+                :loading="exportLoading"
+                id="shelfNoMan-export">导出</a-button>
+              <a @click="advanced=!advanced" style="margin-left: 5px">
+                {{ advanced ? '收起' : '展开' }}
+                <a-icon :type="advanced ? 'up' : 'down'"/>
+              </a>
+            </a-col>
+          </a-row>
+        </a-form>
+      </div>
+      <!-- 操作按钮 -->
+      <div class="table-operator">
+        <a-button
+          id="shelfNoMan-batchAudit"
+          type="primary"
+          @click="openGuideModal = true"
+        >批量导入</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="productType" slot-scope="text, record">
+          <span v-if="record.productVO.productTypeName2 || record.productVO.productTypeName3">{{ record.productVO.productTypeName2 }} {{ record.productVO.productTypeName3 ? '>' : '' }} {{ record.productVO.productTypeName3 }}</span>
+          <span v-else>--</span>
+        </template>
+        <!-- 操作 -->
+        <template slot="action" slot-scope="text, record">
+          <div>
+            <a-button
+              size="small"
+              type="link"
+              v-if="$hasPermissions('B_productInfo_edit')"
+              class="button-info"
+              @click="handleEdit(record)"
+              id="shelfNoMan-edit-btn">编辑</a-button>
+            <a-button
+              size="small"
+              type="link"
+              v-if="$hasPermissions('B_productInfo_detail')"
+              class="button-success"
+              @click="handleDetail(record)"
+              id="shelfNoMan-detail-btn">变更记录</a-button>
+          </div>
+        </template>
+      </s-table>
+    </a-spin>
+    <!-- 导入产品 -->
+    <importGuideModal :openModal="openGuideModal" @close="openGuideModal=false" @ok="hanldeOk" />
+    <!-- 编辑 -->
+    <editHwModal :openModal="openModal" :nowData="nowData" @ok="editOk" @close="closeModal" />
+    <!-- 变更记录 -->
+    <changeRecordModal :openModal="recordModal" :detailData="nowData" @close="closeModal"></changeRecordModal>
+  </a-card>
+</template>
+
+<script>
+import { commonMixin } from '@/utils/mixin'
+import { STable, VSelect } from '@/components'
+import editHwModal from './editHwModal.vue'
+import ProductBrand from '@/views/common/productBrand.js'
+import productTypeAll from '@/views/common/productTypeAll.js'
+import { exportExcel } from '@/libs/JGPrint.js'
+import ImportGuideModal from './importGuideModal.vue'
+import changeRecordModal from './changeRecordModal.vue'
+import { queryStackPlaceQueryPage, stackPlaceExport, stackPlaceInsertImport } from '@/api/product'
+export default {
+  name: 'ProductInfoList',
+  mixins: [commonMixin],
+  components: { STable, VSelect, editHwModal, ProductBrand, productTypeAll, ImportGuideModal, changeRecordModal },
+  data () {
+    return {
+      spinning: false,
+      openGuideModal: false,
+      advanced: true, // 高级搜索 展开/关闭
+      tableHeight: 0,
+      queryParam: { //  查询条件
+        stackPlaceCode: undefined, // 货位编号
+        haveStackCode: undefined,
+        product: {
+          name: '', //  产品名称
+          code: '', // 产品编码
+          origCode: '', // 原厂编码
+          productBrandSn: undefined, //  产品品牌
+          productTypeSn1: '', //  产品一级分类
+          productTypeSn2: '', //  产品二级分类
+          productTypeSn3: '', //  产品三级分类
+          state: undefined //  产品状态
+        }
+      },
+      productType: [],
+      disabled: false, //  查询、重置按钮是否可操作
+      exportLoading: false,
+      columns: [
+        { title: '序号', dataIndex: 'no', width: '5%', align: 'center' },
+        { title: '产品编码', dataIndex: 'productVO.code', width: '8%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '产品名称', dataIndex: 'productVO.name', align: 'center', width: '30%', ellipsis: true, customRender: function (text) { return text || '--' } },
+        { title: '原厂编码', dataIndex: 'productVO.origCode', width: '8%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '产品品牌', dataIndex: 'productVO.productBrandName', width: '8%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '产品分类', scopedSlots: { customRender: 'productType' }, width: '10%', align: 'center' },
+        { title: '产品状态', dataIndex: 'productVO.stateDictValue', width: '8%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '货位编号', dataIndex: 'stackPlaceCode', width: '8%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '操作', scopedSlots: { customRender: 'action' }, width: '15%', align: 'center' }
+      ],
+      loadingAudit: false,
+      loadingLaunch: false,
+      loadingDownline: false,
+      // 加载数据方法 必须为 Promise 对象
+      loadData: parameter => {
+        this.disabled = true
+        this.spinning = true
+        return queryStackPlaceQueryPage(Object.assign(parameter, this.queryParam)).then(res => {
+          let data
+          if (res.status == 200) {
+            data = res.data
+            const no = (data.pageNo - 1) * data.pageSize
+            for (var i = 0; i < data.list.length; i++) {
+              data.list[i].no = no + i + 1
+            }
+            this.disabled = false
+          }
+          this.spinning = false
+          return data
+        })
+      },
+      openModal: false, //  编辑弹框
+      recordModal: false, // 变更记录弹框
+      nowData: null, //  当前sn
+      pageFromInfo: null
+    }
+  },
+  methods: {
+    // 导入产品
+    hanldeOk (obj) {
+      stackPlaceInsertImport(obj).then(res => {
+        if (res.status == 200) {
+          this.resetSearchForm()
+        }
+      })
+    },
+    //  重置
+    resetSearchForm () {
+      this.queryParam = {
+        stackPlaceCode: undefined, // 货位编号
+        haveStackCode: undefined,
+        product: {
+          name: '', //  产品名称
+          code: '', // 产品编码
+          origCode: '', // 原厂编码
+          productBrandSn: undefined, //  产品品牌
+          productTypeSn1: '', //  产品一级分类
+          productTypeSn2: '', //  产品二级分类
+          productTypeSn3: '', //  产品三级分类
+          state: undefined //  产品状态
+        }
+      }
+      this.productType = []
+      this.$refs.table.refresh(true)
+    },
+    // 编辑
+    handleEdit (row) {
+      this.nowData = row
+      this.openModal = true
+    },
+    // 编辑成功
+    editOk () {
+      this.closeModal()
+      this.$refs.table.refresh()
+    },
+    //  关闭编辑弹框
+    closeModal () {
+      this.nowData = null
+      this.openModal = false
+      this.recordModal = false
+    },
+    // 变更记录
+    handleDetail (row) {
+      this.nowData = row
+      this.recordModal = true
+    },
+    //  导出
+    handleExport () {
+      const _this = this
+      const params = this.queryParam
+      this.spinning = true
+      exportExcel(stackPlaceExport, params, '货位编号导出', function () {
+        _this.spinning = false
+      })
+    },
+    //  产品分类  change
+    changeProductType (val, opt) {
+      this.queryParam.product.productTypeSn1 = val[0] ? val[0] : ''
+      this.queryParam.product.productTypeSn2 = val[1] ? val[1] : ''
+      this.queryParam.product.productTypeSn3 = val[2] ? val[2] : ''
+    },
+    pageInit () {
+      const _this = this
+      this.$nextTick(() => { // 页面渲染完成后的回调
+        _this.setTableH()
+      })
+    },
+    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 () {
+    if (!this.$store.state.app.isNewTab) { // 页签刷新时调用
+      this.pageInit()
+      this.resetSearchForm()
+    }
+  },
+  activated () {
+    // 如果是新页签打开,则重置当前页面
+    if (this.$store.state.app.isNewTab) {
+      this.pageInit()
+      this.resetSearchForm()
+    }
+  },
+  beforeRouteEnter (to, from, next) {
+    next(vm => {
+      vm.pageFromInfo = from
+    })
+  }
+}
+</script>

+ 2 - 2
src/views/salesManagement/salesQuery/stockOutDetailModal.vue

@@ -7,8 +7,8 @@
     v-model="isShow"
     @cancel="isShow=false"
     width="50%">
-    <a-descriptions size="small" :column="3">
-      <a-descriptions-item label="销售单号" :span="2">
+    <a-descriptions size="small" :column="2">
+      <a-descriptions-item label="销售单号">
         {{ detailData&&detailData.salesBillNo || '--' }}
         <span v-if="detailData&&detailData.salesBillNoSource">(原:{{ detailData&&detailData.salesBillNoSource || '--' }})</span>
       </a-descriptions-item>