chenrui пре 3 година
родитељ
комит
d5793381cc

+ 29 - 0
src/api/sales.js

@@ -129,3 +129,32 @@ export const salesPromoCount = (params) => {
     method: 'post'
   })
 }
+// 销售  详情  该销售单的产品二级分类
+export const salesDetailProductType = (params) => {
+  return axios({
+    url: `/sales/detail/queryProductType/${params.sn}`,
+    method: 'get'
+  })
+}
+// 销售 详情  打印
+export const salesDetailPrint = params => {
+  const url = `/sales/print/${params.priceType}`
+  delete params.priceType
+  return axios.request({
+    url: url,
+    data: params,
+    method: 'post',
+    responseType: 'blob'
+  })
+}
+// 销售 详情  导出
+export const salesDetailExcel = params => {
+  const url = `/sales/excel/${params.priceType}`
+  delete params.priceType
+  return axios.request({
+    url: url,
+    data: params,
+    method: 'post',
+    responseType: 'blob'
+  })
+}

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

@@ -6,7 +6,7 @@
           <a href="javascript:;" @click="handleBack"><a-icon type="left"></a-icon> 返回列表</a>
         </template>
         <template slot="extra" v-if="$hasPermissions('B_dispatchPrint')">
-          <a-button
+          <!-- <a-button
             key="4"
             type="primary"
             class="button-error"
@@ -19,7 +19,7 @@
             class="button-info"
             id="salesDetail-xsfl-print-btn"
             :disabled="localDataSource.length==0"
-            @click="handlePrint('SALES_BILL_TYPE')">销售分类打印</a-button>
+            @click="handlePrint('SALES_BILL_TYPE')">销售分类打印</a-button> -->
           <a-button
             key="2"
             type="primary"

+ 99 - 29
src/views/salesManagement/salesQuery/detail.vue

@@ -4,19 +4,29 @@
       <template slot="subTitle">
         <a href="javascript:;" @click="handleBack"><a-icon type="left"></a-icon> 返回列表</a>
       </template>
-      <!-- <template slot="extra">
-        <span>打印字段:</span>
-        <a-select key="1" style="width:150px" id="salesDetail-pritKey" placeholder="请选择打印字段" allowClear>
-          <a-select-option v-for="item in pritKey" :key="item.id" :value="item.id">{{ item.name }}</a-select-option>
-        </a-select>
-        <span><i style="color: red;">*</i>打印模板:</span>
-        <a-select key="2" style="width:150px" id="salesDetail-pritKey" placeholder="请选择打印模板" allowClear>
-          <a-select-option v-for="item in pritModal" :key="item.id" :value="item.id">{{ item.name }}</a-select-option>
-        </a-select>
-        <a-button key="3" id="salesDetail-preview-btn">打印预览</a-button>
-        <a-button key="4" type="primary" id="salesDetail-print-btn">快速打印</a-button>
-        <a-button key="5" id="salesDetail-export-btn">导出</a-button>
-      </template> -->
+      <template slot="extra">
+        <a-button
+          key="3"
+          type="primary"
+          class="button-error"
+          id="salesDetail-xs-print-btn"
+          :disabled="localDataSource.length==0"
+          @click="handlePrint('SALES_BILL')">销售打印</a-button>
+        <a-button
+          key="2"
+          type="primary"
+          class="button-info"
+          id="salesDetail-xsfl-print-btn"
+          :disabled="localDataSource.length==0"
+          @click="handlePrint('SALES_BILL_TYPE')">销售分类打印</a-button>
+        <a-button
+          key="1"
+          type="primary"
+          class="button-warning"
+          id="salesDetail-export-btn"
+          :disabled="localDataSource.length==0"
+          @click="handlePrint('export')">导出Excel</a-button>
+      </template>
     </a-page-header>
     <!-- 基础信息 -->
     <a-card size="small" :bordered="false" class="salesDetail-cont">
@@ -101,37 +111,33 @@
         改单
       </a-button>
     </a-card>
+    <!-- 打印导出 -->
+    <print-modal :openModal="openModal" :itemData="detailData" :nowType="nowType" @ok="handleOk" @close="openModal=false" />
+    <!-- 打印 -->
+    <div id="print"></div>
   </div>
 </template>
 
 <script>
+import moment from 'moment'
 import { STable, VSelect } from '@/components'
-import { salesDetailBySn } from '@/api/sales'
+import printModal from './printModal.vue'
+import { salesDetailBySn, salesDetailPrint, salesDetailExcel } from '@/api/sales'
 import { salesDetailList } from '@/api/salesDetail'
 export default {
   name: 'SalesDetail',
-  components: { STable, VSelect },
+  components: { STable, VSelect, printModal },
   data () {
     return {
       disabled: false,
-      pritKey: [
-        { id: 0, name: '打印促销' },
-        { id: 1, name: '打印支付方式' },
-        { id: 2, name: '打印收款方式' }
-      ],
-      pritModal: [
-        { id: 0, name: '普通模板一' },
-        { id: 1, name: '普通模板二' },
-        { id: 2, name: '仓库模板一' }
-      ],
       // 表头
       columns: [
         { title: '序号', dataIndex: 'no', width: 80, align: 'center', fixed: 'left' },
         { title: '产品编码', dataIndex: 'productCode', width: 220, scopedSlots: { customRender: 'productCode' }, align: 'center' },
         { title: '产品名称', dataIndex: 'productName', align: 'center', customRender: function (text) { return text || '--' }, ellipsis: true },
         { title: '原厂编码', dataIndex: 'productOrigCode', width: 220, align: 'center', customRender: function (text) { return text || '--' } },
-        { title: '成本价', dataIndex: 'showCost', width: 100, align: 'center', customRender: function (text) { return ((text || text == 0) ? ('¥' + text) : '--') } },
-        { title: '销售价', dataIndex: 'price', width: 100, align: 'center', customRender: function (text) { return ((text || text == 0) ? ('¥' + text) : '--') } },
+        { title: '成本价', dataIndex: 'showCost', width: 100, align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+        { title: '销售价', dataIndex: 'price', width: 100, align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
         { title: '单位', dataIndex: 'productOrigUnit', width: 100, align: 'center', customRender: function (text) { return text || '--' } },
         { title: '销售数量', dataIndex: 'qty', width: 100, align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
         { title: '已取消数', dataIndex: 'cancelQty', width: 100, align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
@@ -155,11 +161,15 @@ export default {
             data.list[i].productOrigCode = productOrigCode == ' ' ? '--' : productOrigCode
             data.list[i].productOrigUnit = productOrigUnit || '--'
           }
+          this.localDataSource = data.list
           this.disabled = false
           return data
         })
       },
-      detailData: null //  详情数据
+      localDataSource: [],
+      openModal: false,
+      detailData: null, //  详情数据
+      nowType: null
     }
   },
   computed: {
@@ -189,11 +199,71 @@ export default {
     getDetail () {
       salesDetailBySn({ salesBillSn: this.$route.params.sn }).then(res => {
         if (res.status == 200) {
-          this.detailData = res.data
+          this.detailData = res.data || null
         } else {
           this.detailData = null
         }
       })
+    },
+    // 打印导出
+    handlePrint (type) {
+      this.nowType = type
+      this.openModal = true
+    },
+    handleOk (objs) {
+      const _this = this
+      let url = salesDetailPrint //  打印
+      if (this.nowType == 'export') { //  导出
+        url = salesDetailExcel
+      }
+      const params = JSON.parse(JSON.stringify(objs))
+      delete params.type
+      _this.spinning = true
+      url(params).then(res => {
+        _this.spinning = false
+        if (res.type == 'application/json') {
+          var reader = new FileReader()
+          reader.addEventListener('loadend', function () {
+            const obj = JSON.parse(reader.result)
+            _this.$notification.error({
+              message: '提示',
+              description: obj.message
+            })
+          })
+          reader.readAsText(res)
+        } else {
+          if (this.nowType == 'export') {
+            this.download(res)
+          } else {
+            this.print(res, objs.type)
+          }
+        }
+      })
+    },
+    print (data, type) {
+      if (!data) {
+        return
+      }
+      const url = window.URL.createObjectURL(new Blob([data], { type: 'application/pdf' }))
+      document.getElementById('print').innerHTML = '<iframe id="printf" name="printf" src="' + url + '" hidden></iframe>'
+      if (type == 'preview') { //  预览
+        window.open(url)
+      } else if (type == 'print') { //  打印
+        window.frames['printf'].focus()
+        window.frames['printf'].print()
+      }
+    },
+    download (data) {
+      if (!data) { return }
+      const url = window.URL.createObjectURL(new Blob([data]))
+      const link = document.createElement('a')
+      link.style.display = 'none'
+      link.href = url
+      const a = moment().format('YYYYMMDDHHmmss')
+      const fname = '销售' + a
+      link.setAttribute('download', fname + '.xlsx')
+      document.body.appendChild(link)
+      link.click()
     }
   },
   mounted () {

+ 174 - 0
src/views/salesManagement/salesQuery/printModal.vue

@@ -0,0 +1,174 @@
+<template>
+  <a-modal
+    centered
+    :footer="null"
+    :maskClosable="false"
+    class="sales-print-type-modal"
+    :title="modalTit"
+    v-model="isShow"
+    @cancle="isShow=false"
+    :width="600">
+    <a-spin :spinning="spinning" tip="Loading...">
+      <a-form-model
+        id="sales-print-form"
+        ref="ruleForm"
+        :model="form"
+        :rules="rules"
+        :label-col="formItemLayout.labelCol"
+        :wrapper-col="formItemLayout.wrapperCol"
+      >
+        <a-form-model-item label="销售单号">{{ itemData&&itemData.salesBillNo || '' }}</a-form-model-item>
+        <a-form-model-item label="客户名称">{{ itemData&&itemData.buyerName || '' }}</a-form-model-item>
+        <a-form-model-item label="产品分类" prop="id" v-if="nowType=='SALES_BILL_TYPE'">
+          <a-select id="sales-print-form" v-model="form.id" placeholder="请选择产品分类">
+            <a-select-option v-for="item in typeList" :value="item.id" :key="item.id">
+              <span v-if="item.id != 'all'">{{ item.productBrandName }} - {{ item.productTypeName3 }}</span>
+              <span v-else>全部</span>
+            </a-select-option>
+          </a-select>
+        </a-form-model-item>
+        <a-form-model-item label="产品售价" prop="priceType">
+          <a-radio-group v-model="form.priceType">
+            <a-radio :value="nowType=='SALES_BILL_TYPE' ? 'SALES_BILL_TYPE_COST' : 'SALES_BILL_COST'">{{ nowType=='export' ? '导出' : '打印' }}</a-radio>
+            <a-radio :value="nowType=='SALES_BILL_TYPE' ? 'SALES_BILL_TYPE' : 'SALES_BILL'">不{{ nowType=='export' ? '导出' : '打印' }}</a-radio>
+          </a-radio-group>
+        </a-form-model-item>
+      </a-form-model>
+      <div class="btn-cont">
+        <a-button type="primary" id="sales-print-save" @click="handleSave()">{{ nowType=='export' ? '导出' : '打印预览' }}</a-button>
+        <a-button id="sales-print-back" @click="handleCancel" style="margin-left: 15px;">{{ nowType=='export' ? '取消' : '快捷打印' }}</a-button>
+      </div>
+    </a-spin>
+  </a-modal>
+</template>
+
+<script>
+import { salesDetailProductType } from '@/api/sales'
+export default {
+  props: {
+    openModal: { //  弹框显示状态
+      type: Boolean,
+      default: false
+    },
+    itemData: {
+      type: Object,
+      default: () => {
+        return null
+      }
+    },
+    nowType: {
+      type: String,
+      default: ''
+    }
+  },
+  data () {
+    return {
+      isShow: this.openModal, //  是否打开弹框
+      form: {
+        id: undefined,
+        priceType: undefined
+      },
+      rules: {
+        id: [{ required: true, message: '请选择产品分类', trigger: 'change' }],
+        priceType: [{ required: true, message: '请选择产品售价', trigger: 'change' }]
+      },
+      formItemLayout: {
+        labelCol: { span: 6 },
+        wrapperCol: { span: 18 }
+      },
+      spinning: false,
+      typeList: []
+    }
+  },
+  computed: {
+    modalTit () {
+      let title = ''
+      if (this.nowType == 'SALES_BILL') {
+        title = '销售打印'
+      } else if (this.nowType == 'SALES_BILL_TYPE') {
+        title = '销售分类打印'
+      } else if (this.nowType == 'export') {
+        title = '导出Excel'
+      }
+      return title
+    }
+  },
+  methods: {
+    // 确认
+    handleSave (isPrint) {
+      const _this = this
+      this.$refs.ruleForm.validate(valid => {
+        if (valid) {
+          if (_this.nowType == 'SALES_BILL_TYPE') {
+            const item = _this.typeList.find(item => item.id == _this.form.id)
+            if (item) {
+              const obj = {
+                salesBillSn: _this.itemData.salesBillSn,
+                productBrandSn: item.productBrandSn,
+                productTypeSn3: item.productTypeSn3,
+                priceType: _this.form.priceType,
+                type: isPrint || 'preview'
+              }
+              _this.$emit('ok', obj)
+            }
+          } else {
+            const obj = {
+              salesBillSn: _this.itemData.salesBillSn,
+              priceType: _this.form.priceType,
+              type: isPrint || 'preview'
+            }
+            _this.$emit('ok', obj)
+          }
+          _this.isShow = false
+        } else {
+          console.log('error submit!!')
+          return false
+        }
+      })
+    },
+    // 取消选择分类
+    handleCancel () {
+      if (this.nowType == 'export') {
+        this.isShow = false
+      } else {
+        this.handleSave('print')
+      }
+    },
+    // 获取该销售单产品二级分类
+    getTypeData () {
+      this.typeList = [{ id: 'all' }]
+      salesDetailProductType({ sn: this.itemData.salesBillSn || null }).then(res => {
+        if (res.status == 200) {
+          if (res.data && res.data.length > 0) {
+            this.typeList = [...this.typeList, ...res.data]
+          }
+        }
+      })
+    }
+  },
+  watch: {
+    //  父页面传过来的弹框状态
+    openModal (newValue, oldValue) {
+      this.isShow = newValue
+    },
+    //  重定义的弹框状态
+    isShow (newValue, oldValue) {
+      if (!newValue) {
+        this.$emit('close')
+        this.$refs.ruleForm.resetFields()
+      } else {
+        this.getTypeData()
+      }
+    }
+  }
+}
+</script>
+
+<style lang="less">
+  .sales-print-type-modal{
+    .btn-cont {
+      text-align: center;
+      margin: 35px 0 10px;
+    }
+  }
+</style>