Browse Source

Merge commit '35a2070f0a9cb7ac6ed6630d126caa192d1aea7d' into HEAD

gitadmin 3 tuần trước cách đây
mục cha
commit
e5789cf42d

+ 1 - 1
public/version.json

@@ -1,4 +1,4 @@
 {
-    "version": "2.2.58",
+    "version": "2.2.59",
     "message": "发现有新版本发布,确定更新系统?"
 }

+ 212 - 1
src/api/reportData.js

@@ -1580,4 +1580,215 @@ export const manageAnalysisReportExport = (params) => {
       'module': encodeURIComponent('各品类经营分析报表导出')
     }
   })
-}
+}
+
+/*
+***  促销费用报表
+*/
+
+// 促销费用报表   省份   有分页
+export const promoProvinceList = (params) => {
+  const url = `/report/promoExpenseProvince/reportList`
+  return axios({
+    url: url,
+    data: params,
+    method: 'post',
+    headers: {
+      'module': encodeURIComponent('列表查询')
+    }
+  })
+}
+
+// 促销费用报表 省份  表头
+export const promoProvinceTableTitle = (params) => {
+  return axios({
+    url: '/report/promoExpenseProvince/reportTitle',
+    data: params,
+    method: 'get',
+    headers: {
+      'module': encodeURIComponent('获取表头')
+    }
+  })
+}
+
+// 促销费用报表 省份  合计
+export const promoProvinceCount = (params) => {
+  return axios({
+    url: '/report/promoExpenseProvince/reportCount',
+    data: params,
+    method: 'post',
+    headers: {
+      'module': encodeURIComponent('合计')
+    }
+  })
+}
+
+// 促销费用报表 省份 导出
+export const promoProvinceExport = (params) => {
+  return axios({
+    url: '/report/promoExpenseProvince/reportExport',
+    data: params,
+    method: 'post',
+    responseType: 'blob',
+    headers: {
+      'module': encodeURIComponent('导出')
+    }
+  })
+}
+
+// 促销费用报表(客户) 、促销费用报表  有分页
+export const promoSalesExpenseList = (params) => {
+  const url = `/report/promoSalesExpense/reportPage/${params.pageNo}/${params.pageSize}`
+  delete params.pageNo
+  delete params.pageSize
+  return axios({
+    url: url,
+    data: params,
+    method: 'post',
+    headers: {
+      'module': encodeURIComponent('列表查询')
+    }
+  })
+}
+
+// 促销费用报表(客户) 、促销费用报表  表头
+export const promoSalesExpenseTitle = (params) => {
+  return axios({
+    url: '/report/promoSalesExpense/reportTitle',
+    data: params,
+    method: 'get',
+    headers: {
+      'module': encodeURIComponent('获取表头')
+    }
+  })
+}
+
+// 促销费用报表(客户) 、促销费用报表  合计
+export const promoSalesExpenseCount = (params) => {
+  return axios({
+    url: '/report/promoSalesExpense/reportCount',
+    data: params,
+    method: 'post',
+    headers: {
+      'module': encodeURIComponent('合计')
+    }
+  })
+}
+
+// 促销费用报表(客户) 、促销费用报表  导出
+export const promoSalesExpenseExport = (params) => {
+  return axios({
+    url: '/report/promoSalesExpense/reportExport',
+    data: params,
+    method: 'post',
+    responseType: 'blob',
+    headers: {
+      'module': encodeURIComponent('导出')
+    }
+  })
+}
+
+/*
+***** 开单统计报表
+*/
+
+// 开单统计报表(客户)   列表   有分页
+export const salesStatsDealerList = (params) => {
+  const url = `/report/salesStatsDealer/reportPage/${params.pageNo}/${params.pageSize}`
+  delete params.pageNo
+  delete params.pageSize
+  return axios({
+    url: url,
+    data: params,
+    method: 'post',
+    headers: {
+      'module': encodeURIComponent('列表查询')
+    }
+  })
+}
+
+// 开单统计报表(客户)  表头
+export const salesStatsDealerTitle = (params) => {
+  return axios({
+    url: '/report/salesStatsDealer/reportTitle',
+    data: params,
+    method: 'post',
+    headers: {
+      'module': encodeURIComponent('获取表头')
+    }
+  })
+}
+
+// 开单统计报表(客户)  合计
+export const salesStatsDealerCount = (params) => {
+  return axios({
+    url: '/report/salesStatsDealer/reportCount',
+    data: params,
+    method: 'post',
+    headers: {
+      'module': encodeURIComponent('合计')
+    }
+  })
+}
+
+// 开单统计报表(客户)  导出
+export const salesStatsDealerExport = (params) => {
+  return axios({
+    url: '/report/salesStatsDealer/reportExport',
+    data: params,
+    method: 'post',
+    responseType: 'blob',
+    headers: {
+      'module': encodeURIComponent('导出')
+    }
+  })
+}
+
+// 开单统计报表(省份)   列表   无分页
+export const salesStatsProvinceList = (params) => {
+  return axios({
+    url: '/report/salesStatsProvince/reportList',
+    data: params,
+    method: 'post',
+    headers: {
+      'module': encodeURIComponent('列表查询')
+    }
+  })
+}
+
+// 开单统计报表(省份)  表头
+export const salesStatsProvinceTit = (params) => {
+  return axios({
+    url: '/report/salesStatsProvince/reportTitle',
+    data: params,
+    method: 'post',
+    headers: {
+      'module': encodeURIComponent('获取表头')
+    }
+  })
+}
+
+// 开单统计报表(省份)  合计
+export const salesStatsProvinceCount = (params) => {
+  return axios({
+    url: '/report/salesStatsProvince/reportCount',
+    data: params,
+    method: 'post',
+    headers: {
+      'module': encodeURIComponent('合计')
+    }
+  })
+}
+
+// 开单统计报表(省份)  导出
+export const salesStatsProvinceExport = (params) => {
+  return axios({
+    url: '/report/salesStatsProvince/reportExport',
+    data: params,
+    method: 'post',
+    responseType: 'blob',
+    headers: {
+      'module': encodeURIComponent('导出')
+    }
+  })
+}

+ 50 - 0
src/config/report/salesReport.js

@@ -235,6 +235,31 @@ export default {
         }
       }]
     },
+    {
+      path: '/reportData/promotionFeeReport',
+      redirect: '/reportData/promotionFeeReport/index',
+      name: 'promotionFeeReport',
+      component: BlankLayout,
+      meta: {
+        title: '促销费用报表',
+        icon: 'profile',
+        permission: 'M_promotionFeeReportList'
+      },
+      hideChildrenInMenu: true,
+      children: [
+        {
+          path: 'index',
+          name: 'promotionFeeReportIndex',
+          component: () => import(/* webpackChunkName: "reportData" */ '@/views/reportData/promotionFeeReport/index.vue'),
+          meta: {
+            title: '促销费用报表',
+            icon: 'profile',
+            hidden: true,
+            permission: 'M_promotionFeeReportList'
+          }
+        }
+      ]
+    },
     {
       path: '/reportData/salesReturnsReport',
       redirect: '/reportData/salesReturnsReport/list',
@@ -408,6 +433,31 @@ export default {
         }
       ]
     },
+    {
+      path: '/reportData/billingStatistics',
+      redirect: '/reportData/billingStatistics/index',
+      name: 'billingStatistics',
+      component: BlankLayout,
+      meta: {
+        title: '开单统计报表',
+        icon: 'profile',
+        permission: 'M_billingStatisticsList'
+      },
+      hideChildrenInMenu: true,
+      children: [
+        {
+          path: 'index',
+          name: 'billingStatisticsIndex',
+          component: () => import(/* webpackChunkName: "reportData" */ '@/views/reportData/billingStatistics/index.vue'),
+          meta: {
+            title: '开单统计报表',
+            icon: 'profile',
+            hidden: true,
+            permission: 'M_billingStatisticsList'
+          }
+        }
+      ]
+    },
     {
       path: '/reportData/returnGoodsPresentation',
       redirect: '/reportData/returnGoodsPresentation/list',

+ 26 - 16
src/views/dealerManagement/dealerZoneSearch/list.vue

@@ -5,22 +5,27 @@
       <div ref="tableSearch" class="table-page-search-wrapper newTableSearchName">
         <a-form layout="inline" @keyup.enter.native="$refs.table.refresh(true)">
           <a-row :gutter="15">
-            <a-col :md="6" :sm="24">
+            <a-col :md="4" :sm="24">
+              <a-form-model-item label="地区">
+                <Area id="dealerZoneSearch-dealerProvinceSn" v-model="queryParam.dealer.provinceSn" placeholder="请选择省"></Area>
+              </a-form-model-item>
+            </a-col>
+            <a-col :md="5" :sm="24">
               <a-form-item label="所属区域/分区">
                 <subarea id="dealerZoneSearch-subareaSn" ref="subarea" @change="subareaChange"></subarea>
               </a-form-item>
             </a-col>
-            <a-col :md="6" :sm="24">
+            <a-col :md="5" :sm="24">
               <a-form-item label="经销商">
                 <custList id="dealerZoneSearch-dealerName" placeholder="请输入经销商名称搜索" ref="indirectDealer" @change="dealerChange" />
               </a-form-item>
             </a-col>
-            <a-col :md="7" :sm="24">
-              <a-form-item label="客服/区域负责人/销售总监">
-                <a-input id="dealerZoneSearch-bizUserName" v-model.trim="queryParam.bizUserName" allowClear placeholder="请输入客服/区域负责人/销售总监"/>
+            <a-col :md="6" :sm="24">
+              <a-form-item label="客服/品类经理/区域负责人/销售总监">
+                <a-input id="dealerZoneSearch-bizUserName" v-model.trim="queryParam.bizUserName" allowClear placeholder="请输入客服/品类经理/区域负责人/销售总监"/>
               </a-form-item>
             </a-col>
-            <a-col :md="5" :sm="24">
+            <a-col :md="4" :sm="24">
               <a-button type="primary" @click="$refs.table.refresh(true)" :disabled="disabled" id="dealerZoneSearch-refresh">查询</a-button>
               <a-button style="margin-left: 5px" @click="resetSearchForm" :disabled="disabled" id="dealerZoneSearch-reset">重置</a-button>
               <a-button
@@ -90,12 +95,13 @@ import { exportExcel } from '@/libs/JGPrint.js'
 import { STable } from '@/components'
 import subarea from '@/views/common/subarea.js'
 import custList from '@/views/common/custList.vue'
+import Area from '@/views/common/area.js'
 // 接口
 import { queryDealerWithBizuser, exportDealerWithBizuser } from '@/api/dealerRelation'
 export default {
   name: 'DealerZoneSearch',
   mixins: [commonMixin],
-  components: { STable, subarea, custList },
+  components: { STable, subarea, custList, Area },
   data () {
     return {
       spinning: false,
@@ -108,17 +114,20 @@ export default {
         subareaAreaSn: undefined, // 分区
         dealer: {
           dealerSn: '', // 经销商sn
-          dealerName: ''// 经销商名称
+          dealerName: '', // 经销商名称
+          provinceSn: undefined// 地区
         },
-        bizUserName: ''// 客服/区域负责人/销售总监
+        bizUserName: '' // 客服/品类经理/区域负责人/销售总监
       },
       columns: [
-        { title: '经销商名称', dataIndex: 'dealer.dealerName', width: '15%', align: 'center', customRender: function (text) { return text || '--' }, ellipsis: true },
-        { title: '所属区域', dataIndex: 'subareaName', width: '10%', align: 'center', customRender: function (text) { return text || '--' } },
-        { title: '所属分区', dataIndex: 'subareaAreaName', width: '10%', align: 'center', customRender: function (text) { return text || '--' } },
-        { title: '客服', scopedSlots: { customRender: 'kf' }, dataIndex: 'userNameKfs', width: '40%', align: 'center' },
-        { title: '区域负责人', scopedSlots: { customRender: 'qyfzr' }, dataIndex: 'userNameQyfzrs', width: '10%', align: 'center' },
-        { title: '销售总监', scopedSlots: { customRender: 'xszj' }, dataIndex: 'userNameXszjs', width: '10%', align: 'center' }
+        { title: '经销商名称', dataIndex: 'dealer.dealerName', width: '12%', align: 'center', customRender: function (text) { return text || '--' }, ellipsis: true },
+        { title: '省份', dataIndex: 'dealer.provinceName', width: '7%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '所属区域', dataIndex: 'subareaName', width: '7%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '所属分区', dataIndex: 'subareaAreaName', width: '7%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '客服', scopedSlots: { customRender: 'kf' }, dataIndex: 'userNameKfs', width: '30%', align: 'center' },
+        { title: '品类经理', dataIndex: 'userNamePljls', width: '14%', align: 'center', customRender: function (text) { return text || '--' }, ellipsis: true },
+        { title: '区域负责人', scopedSlots: { customRender: 'qyfzr' }, dataIndex: 'userNameQyfzrs', width: '11%', align: 'center' },
+        { title: '销售总监', scopedSlots: { customRender: 'xszj' }, dataIndex: 'userNameXszjs', width: '7%', align: 'center' }
       ],
       // 加载数据方法 必须为 Promise 对象
       loadData: parameter => {
@@ -160,6 +169,7 @@ export default {
       this.queryParam.subareaAreaSn = undefined
       this.queryParam.dealer.dealerSn = ''
       this.queryParam.dealer.dealerName = ''
+      this.queryParam.dealer.provinceSn = undefined
       this.queryParam.bizUserName = ''
       this.$refs.indirectDealer.resetForm()
       this.$refs.subarea.clearData()
@@ -181,7 +191,7 @@ export default {
     // 计算表格高度
     setTableH () {
       const tableSearchH = this.$refs.tableSearch.offsetHeight
-      this.tableHeight = window.innerHeight - tableSearchH - 200
+      this.tableHeight = window.innerHeight - tableSearchH - 197
     }
   },
   watch: {

+ 385 - 0
src/views/reportData/billingStatistics/customerCountList.vue

@@ -0,0 +1,385 @@
+<template>
+  <div>
+    <a-card size="small" :bordered="false" class="customerCountList-wrap searchBoxNormal">
+      <!-- 搜索条件 -->
+      <div class="table-page-search-wrapper" ref="tableSearch">
+        <a-form-model
+          id="customerCountList-form"
+          ref="ruleForm"
+          class="form-model-con"
+          layout="inline"
+          :rules="rules"
+          :model="queryParam">
+          <a-row :gutter="15">
+            <a-col :md="6" :sm="24">
+              <a-form-model-item label="月份" prop="beginDate">
+                <a-month-picker
+                  id="customerCountList-monthBox"
+                  class="monthBox"
+                  :disabled-date="disabledDate"
+                  v-model="monthVal"
+                  placeholder="请选择月份"
+                  @change="onChangeMonth" />
+              </a-form-model-item>
+            </a-col>
+            <a-col :md="6" :sm="24">
+              <a-form-model-item label="客户名称">
+                <dealerSubareaScopeList ref="dealerSubareaScopeList" id="customerCountList-dealerName" @change="custChange" />
+              </a-form-model-item>
+            </a-col>
+            <a-col :md="6" :sm="24">
+              <a-form-model-item label="客户级别">
+                <v-select
+                  v-model="queryParam.dealerLevel"
+                  ref="dealerLevel"
+                  id="customerCountList-dealerLevel"
+                  code="DEALER_LEVEL"
+                  placeholder="请选择客户级别"
+                  allowClear></v-select>
+              </a-form-model-item>
+            </a-col>
+            <template v-if="advanced">
+              <a-col :md="6" :sm="24">
+                <a-form-item label="所在区域">
+                  <subarea id="customerCountList-subarea" ref="subarea" @change="subareaChange"></subarea>
+                </a-form-item>
+              </a-col>
+              <a-col :md="6" :sm="24">
+                <a-form-model-item label="区域负责人">
+                  <BizUser id="customerCountList-bizUserSn" v-model="queryParam.subareaArea.bizUserSn"></BizUser>
+                </a-form-model-item>
+              </a-col>
+              <a-col :md="6" :sm="24">
+                <a-form-model-item label="地区">
+                  <AreaList id="customerCountList-areaList" changeOnSelect ref="areaList" @change="areaChange" defValKey="id"></AreaList>
+                </a-form-model-item>
+              </a-col>
+              <a-col :md="6" :sm="24">
+                <a-form-model-item label="客服">
+                  <customerService ref="customerName" id="customerCountList-customerName" v-model="queryParam.kfSn"></customerService>
+                </a-form-model-item>
+              </a-col>
+            </template>
+            <a-col :md="6" :sm="24">
+              <a-button
+                type="primary"
+                @click="handleSearch"
+                :disabled="disabled"
+                id="customerCountList-refresh">查询</a-button>
+              <a-button
+                style="margin-left: 8px"
+                @click="resetSearchForm"
+                :disabled="disabled"
+                id="customerCountList-reset">重置</a-button>
+              <a-button
+                style="margin-left: 10px"
+                type="primary"
+                class="button-warning"
+                @click="handleExport"
+                :disabled="disabled"
+                :loading="exportLoading"
+                v-if="$hasPermissions('B_billingStatisticsExport')"
+                id="customerCountList-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-model>
+      </div>
+    </a-card>
+    <a-card size="small" :bordered="false">
+      <a-spin :spinning="spinning" tip="Loading...">
+        <!-- 列表 -->
+        <s-table
+          class="sTable fixPagination"
+          ref="table"
+          size="small"
+          :rowKey="(record) => record.no"
+          rowKeyName="no"
+          :style="{ height: tableHeight+70+'px' }"
+          :columns="columns"
+          :data="loadData"
+          :scroll="{x:2200, y: tableHeight-130}"
+          :defaultLoadData="false"
+          bordered>
+          <template slot="footer" v-if="totalData&&totalData.length">
+            <a-row :gutter="15">
+              <a-col span="24">合计:</a-col>
+              <a-col span="24">
+                <a-col span="4" v-for="item in totalData" :key="item.key">
+                  {{ item.title }}:{{ item[item.key] ||item[item.key] ==0?toThousands(item[item.key]) :'--' }}
+                </a-col>
+              </a-col>
+            </a-row>
+          </template>
+        </s-table>
+      </a-spin>
+    </a-card>
+  </div>
+</template>
+
+<script>
+import { commonMixin } from '@/utils/mixin'
+import { hdExportExcel } from '@/libs/exportExcel'
+import moment from 'moment'
+// 组件
+import { STable, VSelect } from '@/components'
+import subarea from '@/views/common/subarea.js'
+import AreaList from '@/views/common/areaList.js'
+import dealerSubareaScopeList from '@/views/common/dealerSubareaScopeList.vue'
+import BizUser from '@/views/common/bizUser.js'
+import customerService from '@/views/common/customerService.vue'
+// 接口
+import { salesStatsDealerList, salesStatsDealerTitle, salesStatsDealerCount, salesStatsDealerExport } from '@/api/reportData'
+export default {
+  name: 'CustomerCountList',
+  mixins: [commonMixin],
+  components: { STable, VSelect, subarea, AreaList, dealerSubareaScopeList, BizUser, customerService },
+  data () {
+    return {
+      spinning: false,
+      disabled: false, //  查询、重置按钮是否可操作
+      advanced: true, // 高级搜索 展开/关闭
+      tableHeight: 0, // 表格高度
+      exportLoading: false, // 导出按钮加载状态
+      monthVal: moment().format('YYYY-MM'), // 初始化月份值
+      //  查询条件
+      queryParam: {
+        beginDate: moment().startOf('month').format('YYYY-MM-DD') + ' 00:00:00', // 月份开始时间
+        endDate: moment().endOf('month').format('YYYY-MM-DD') + ' 23:59:59', // 月份结束时间
+        dealerLevel: undefined, // 客户等级
+        dealerSn: undefined, // 客户sn
+        dealerName: undefined, // 客户名称
+        provinceSn: undefined, // 省
+        citySn: undefined, // 市
+        districtSn: undefined, // 区
+        subareaArea: {
+          subareaSn: '', // 区域
+          subareaAreaSn: '', // 分区
+          bizUserSn: undefined// 区域负责人
+        },
+        kfSn: undefined// 客服
+      },
+      columns: [], // 表格  列数据
+      totalData: null, // 合计
+      rules: {
+        'beginDate': [{ required: true, message: '请选择查询月份', trigger: 'change' }]
+      },
+      // 加载数据方法 必须为 Promise 对象
+      loadData: parameter => {
+        this.disabled = true
+        this.spinning = true
+        const params = Object.assign(parameter, this.queryParam)
+        // 获取列表数据  有分页
+        return salesStatsDealerList(params).then(res => {
+          let data
+          if (res.status == 200) {
+            data = res.data
+            // 计算表格序号
+            const no = (data.pageNo - 1) * data.pageSize
+            for (var i = 0; i < data.list.length; i++) {
+              data.list[i].no = no + i + 1
+            }
+            this.disabled = false
+            this.getCount(params)
+          }
+          this.spinning = false
+          return data
+        })
+      }
+    }
+  },
+  watch: {
+    advanced (newValue, oldValue) {
+      const _this = this
+      this.$nextTick(() => { // 页面渲染完成后的回调
+        _this.setTableH()
+      })
+    },
+    '$store.state.app.winHeight' (newValue, oldValue) { //  窗口变更时,需同时更改表格高度
+      this.setTableH()
+    }
+  },
+  methods: {
+    // 选择月份  禁用选择当月以后日期
+    disabledDate (current) {
+      return current && current >= moment().endOf('day')
+    },
+    // 选择月份 change
+    onChangeMonth (date, dateString) {
+      this.monthVal = dateString
+      if (date && dateString != '') {
+        this.queryParam.beginDate = this.getMonthRange(dateString).firstDay
+        this.queryParam.endDate = this.getMonthRange(dateString).lastDay
+      } else {
+        this.queryParam.beginDate = undefined
+        this.queryParam.endDate = undefined
+      }
+    },
+    // 获取指定月份   第一天和最后一天
+    getMonthRange (targetMonth) {
+      // 获取指定月第一天(格式化为 YYYY-MM-DD)
+      const firstDay = moment(targetMonth).startOf('month').format('YYYY-MM-DD') + ' 00:00:00'
+      // 获取指定月最后一天(格式化为 YYYY-MM-DD)
+      const lastDay = moment(targetMonth).endOf('month').format('YYYY-MM-DD') + ' 23:59:59'
+      return { firstDay, lastDay }
+    },
+    // 获取表头
+    async getTableTitle () {
+      const _this = this
+      const tableTitle = await salesStatsDealerTitle().then(res => res.data)
+      this.columns = tableTitle.list
+      this.countLabel = tableTitle.count
+      this.columns.map(item => {
+        item.titleNum = item.title
+        let mw = 20
+        if (item.customRender == 'amount') {
+          mw = 15
+          if (item.colour && item.colour === 'red') {
+            item.title = <span style="color:red;">{item.titleNum}</span>
+            item.customRender = (text) => { return <span style="color:red;">{(text || text == 0) ? _this.toThousands(text) : '--'}</span> }
+          } else {
+            item.customRender = function (text) { return (text || text == 0) ? _this.toThousands(text) : '--' }
+          }
+        } else {
+          item.customRender = function (text) { return text || '--' }
+        }
+        const w = item.titleNum.length * mw
+        const tw = w <= 80 ? mw * 5 : w
+        item.width = tw + 'px'
+        this.tableWidth = this.tableWidth + tw
+      })
+      this.resetSearchForm()
+    },
+    // 查询
+    handleSearch () {
+      const _this = this
+      this.$refs.ruleForm.validate(valid => {
+        if (valid) {
+          _this.$refs.table.refresh(true)
+        } else {
+          _this.$message.error('请选择查询月份')
+          return false
+        }
+      })
+    },
+    // 客户名称 change
+    custChange (val) {
+      this.queryParam.dealerName = val.name
+      this.queryParam.dealerSn = val.key
+    },
+    // 统计
+    getCount (params) {
+      salesStatsDealerCount(params).then(res => {
+        if (res.status == 200 && res.data) {
+          const mergedList = this.countLabel.map(item => {
+            const key = item.key
+            return key in res.data
+              ? { ...item, [key]: res.data[key] }
+              : item
+          })
+          this.totalData = mergedList
+        } else {
+          this.totalData = null
+        }
+      })
+    },
+    // 地区
+    areaChange (val) {
+      this.queryParam.provinceSn = val[0] ? val[0] : undefined
+      this.queryParam.citySn = val[1] ? val[1] : undefined
+      this.queryParam.districtSn = val[2] ? val[2] : undefined
+    },
+    // 区域分区  change
+    subareaChange (val) {
+      this.queryParam.subareaArea.subareaSn = val[0] ? val[0] : ''
+      this.queryParam.subareaArea.subareaAreaSn = val[1] ? val[1] : ''
+    },
+    //  重置
+    resetSearchForm () {
+      this.queryParam.beginDate = moment().startOf('month').format('YYYY-MM-DD') + ' 00:00:00'
+      this.queryParam.endDate = moment().endOf('month').format('YYYY-MM-DD') + ' 23:59:59'
+      this.monthVal = moment().format('YYYY-MM')
+      this.queryParam.provinceSn = undefined
+      this.queryParam.citySn = undefined
+      this.queryParam.districtSn = undefined
+      this.queryParam.dealerName = undefined
+      this.queryParam.dealerSn = undefined
+      this.queryParam.bizUserSn = undefined
+      this.queryParam.subareaArea.subareaSn = ''
+      this.queryParam.subareaArea.subareaAreaSn = ''
+      this.queryParam.subareaArea.bizUserSn = undefined
+      this.queryParam.dealerLevel = undefined
+      if (this.advanced) {
+        this.$refs.subarea.clearData()
+        this.$refs.dealerSubareaScopeList.resetForm()
+        this.$refs.areaList.clearData()
+      }
+      this.totalData = null
+      this.$refs.table.clearTable()
+      this.$refs.ruleForm.resetFields()
+    },
+    //  导出  必填判断
+    handleExport () {
+      const _this = this
+      this.$refs.ruleForm.validate(valid => {
+        if (valid) {
+          _this.exportList()
+        } else {
+          _this.$message.error('请选择查询月份')
+          return false
+        }
+      })
+    },
+    // 导出
+    exportList () {
+      const _this = this
+      const params = JSON.parse(JSON.stringify(_this.queryParam))
+      _this.exportLoading = true
+      _this.spinning = true
+      hdExportExcel(salesStatsDealerExport, params, '开单统计报表(客户)', function () {
+        _this.exportLoading = false
+        _this.spinning = false
+      })
+    },
+    // 初始化
+    pageInit () {
+      this.$nextTick(() => { // 页面渲染完成后的回调
+        this.setTableH()
+        this.resetSearchForm()
+      })
+    },
+    // 计算表格高度
+    setTableH () {
+      const tableSearchH = this.$refs.tableSearch.offsetHeight
+      this.tableHeight = window.innerHeight - tableSearchH - 280
+    }
+  },
+  mounted () {
+    if (!this.$store.state.app.isNewTab) { // 页签刷新时调用
+      this.pageInit()
+      this.getTableTitle()
+    }
+  },
+  activated () {
+    // 如果是新页签打开,则重置当前页面
+    if (this.$store.state.app.isNewTab) {
+      this.pageInit()
+      this.getTableTitle()
+    }
+  }
+}
+</script>
+<style lang="less" scoped>
+  .monthBox{
+    width: 100%;
+    /deep/.ant-calendar-picker-icon{
+      display:none !important;
+    }
+    /deep/.ant-calendar-picker input{
+      text-align:center;
+    }
+  }
+</style>

+ 54 - 0
src/views/reportData/billingStatistics/index.vue

@@ -0,0 +1,54 @@
+<template>
+  <div>
+    <a-card size="small" :bordered="false">
+      <a-tabs default-active-key="1" @change="handleChange">
+        <a-tab-pane key="1" tab="开单统计报表(客户)">
+          <customerCountList ref="customerList"></customerCountList>
+        </a-tab-pane>
+        <a-tab-pane key="2" tab="开单统计报表(省份)" force-render>
+          <provinceCountList ref="provinceList"></provinceCountList>
+        </a-tab-pane>
+      </a-tabs>
+    </a-card>
+  </div>
+</template>
+<script>
+import { commonMixin } from '@/utils/mixin'
+// 组件
+import customerCountList from './customerCountList.vue'
+import provinceCountList from './provinceCountList.vue'
+export default {
+  name: 'BillingStatisticsIndex',
+  mixins: [commonMixin],
+  components: { customerCountList, provinceCountList },
+  data () {
+    return {
+      tabVal: 1 // tab值  1轮胎月度费用报表 2轮胎季度费用报表 3轮胎年度费用报表 4轮胎费用明细报表
+    }
+  },
+  methods: {
+    // 切换tab值  change
+    handleChange (val) {
+      this.tabVal = val
+    },
+    // 初始化
+    pageInit () {
+      if (this.tabVal == 1) {
+        this.$refs.customerList.pageInit()
+      }
+    }
+  },
+  mounted () {
+    if (!this.$store.state.app.isNewTab) { // 页签刷新时调用
+      this.pageInit()
+    }
+  },
+  activated () {
+    // 如果是新页签打开,则重置当前页面
+    if (this.$store.state.app.isNewTab) {
+      this.pageInit()
+    }
+  }
+}
+
+</script>

+ 324 - 0
src/views/reportData/billingStatistics/provinceCountList.vue

@@ -0,0 +1,324 @@
+<template>
+  <div>
+    <a-card size="small" :bordered="false" class="provinceCountList-wrap searchBoxNormal">
+      <!-- 搜索条件 -->
+      <div class="table-page-search-wrapper" ref="tableSearch">
+        <a-form-model
+          id="provinceCountList-form"
+          ref="ruleForm"
+          class="form-model-con"
+          layout="inline"
+          :rules="rules"
+          :model="queryParam">
+          <a-row :gutter="15">
+            <a-col :md="5" :sm="24">
+              <a-form-model-item label="月份" prop="beginDate">
+                <a-month-picker
+                  id="provinceCountList-monthBox"
+                  class="monthBox"
+                  :disabled-date="disabledDate"
+                  v-model="monthVal"
+                  placeholder="请选择月份"
+                  @change="onChangeMonth" />
+              </a-form-model-item>
+            </a-col>
+            <a-col :md="5" :sm="24">
+              <a-form-model-item label="地区">
+                <Area id="provinceCountList-areaList" v-model="queryParam.provinceSn" placeholder="请选择省份"></Area>
+              </a-form-model-item>
+            </a-col>
+            <a-col :md="5" :sm="24">
+              <a-form-item label="所在区域">
+                <subarea id="provinceCountList-subarea" ref="subarea" @change="subareaChange"></subarea>
+              </a-form-item>
+            </a-col>
+            <a-col :md="5" :sm="24">
+              <a-form-model-item label="区域负责人">
+                <BizUser id="provinceCountList-bizUserSn" v-model="queryParam.subareaArea.bizUserSn"></BizUser>
+              </a-form-model-item>
+            </a-col>
+            <a-col :md="4" :sm="24">
+              <a-button
+                type="primary"
+                @click="handleSearch"
+                :disabled="disabled"
+                id="provinceCountList-refresh">查询</a-button>
+              <a-button
+                style="margin-left: 8px"
+                @click="resetSearchForm"
+                :disabled="disabled"
+                id="provinceCountList-reset">重置</a-button>
+              <a-button
+                style="margin-left: 10px"
+                type="primary"
+                class="button-warning"
+                @click="handleExport"
+                :disabled="disabled"
+                :loading="exportLoading"
+                v-if="$hasPermissions('B_billingStatisticsExport')"
+                id="provinceCountList-export">导出</a-button>
+            </a-col>
+          </a-row>
+        </a-form-model>
+      </div>
+    </a-card>
+    <a-card size="small" :bordered="false">
+      <a-spin :spinning="spinning" tip="Loading...">
+        <!-- 列表 -->
+        <s-table
+          class="sTable fixPagination"
+          ref="table"
+          size="small"
+          :rowKey="(record) => record.no"
+          rowKeyName="no"
+          :style="{ height: tableHeight+70+'px' }"
+          :columns="columns"
+          :data="loadData"
+          :scroll="{x:2200, y: tableHeight-130}"
+          :defaultLoadData="false"
+          :showPagination="false"
+          bordered>
+          <template slot="footer" v-if="totalData&&totalData.length">
+            <a-row :gutter="15">
+              <a-col span="24">合计:</a-col>
+              <a-col span="24">
+                <a-col span="4" v-for="item in totalData" :key="item.key">
+                  {{ item.title }}:{{ item[item.key] ||item[item.key] ==0?toThousands(item[item.key]) :'--' }}
+                </a-col>
+              </a-col>
+            </a-row>
+          </template>
+        </s-table>
+      </a-spin>
+    </a-card>
+  </div>
+</template>
+
+<script>
+import { commonMixin } from '@/utils/mixin'
+import { hdExportExcel } from '@/libs/exportExcel'
+import moment from 'moment'
+// 组件
+import { STable, VSelect } from '@/components'
+import subarea from '@/views/common/subarea.js'
+import Area from '@/views/common/area.js'
+import BizUser from '@/views/common/bizUser.js'
+// 接口
+import { salesStatsProvinceList, salesStatsProvinceTit, salesStatsProvinceCount, salesStatsProvinceExport } from '@/api/reportData'
+export default {
+  name: 'ProvinceCountList',
+  mixins: [commonMixin],
+  components: { STable, VSelect, subarea, Area, BizUser },
+  data () {
+    return {
+      spinning: false,
+      disabled: false, //  查询、重置按钮是否可操作
+      tableHeight: 0, // 表格高度
+      exportLoading: false, // 导出按钮加载状态
+      monthVal: moment().format('YYYY-MM'), // 初始化月份值
+      //  查询条件
+      queryParam: {
+        beginDate: moment().startOf('month').format('YYYY-MM-DD') + ' 00:00:00', // 月份开始时间
+        endDate: moment().endOf('month').format('YYYY-MM-DD') + ' 23:59:59', // 月份结束时间
+        provinceSn: undefined, // 地区
+        subareaArea: {
+          subareaSn: '', // 区域
+          subareaAreaSn: '', // 分区
+          bizUserSn: undefined// 区域负责人
+        }
+      },
+      columns: [], // 表格列
+      countLabel: null, // 统计名称合集
+      totalData: null, // 合计
+      rules: {
+        'beginDate': [{ required: true, message: '请选择查询月份', trigger: 'change' }]
+      },
+      // 加载数据方法 必须为 Promise 对象
+      loadData: parameter => {
+        this.disabled = true
+        this.spinning = true
+        const params = Object.assign(parameter, this.queryParam)
+        // 获取列表数据  无分页
+        return salesStatsProvinceList(params).then(res => {
+          let data
+          if (res.status == 200) {
+            data = res.data
+            // 计算表格序号
+            for (var i = 0; i < data.length; i++) {
+              data[i].no = i + 1
+            }
+            this.disabled = false
+            // 统计
+            this.getCount(params)
+          }
+          this.spinning = false
+          return data
+        })
+      }
+    }
+  },
+  watch: {
+    '$store.state.app.winHeight' (newValue, oldValue) { //  窗口变更时,需同时更改表格高度
+      this.setTableH()
+    }
+  },
+  methods: {
+    // 选择月份  禁用选择当月以后日期
+    disabledDate (current) {
+      return current && current >= moment().endOf('day')
+    },
+    // 选择月份 change
+    onChangeMonth (date, dateString) {
+      this.monthVal = dateString
+      if (date && dateString != '') {
+        this.queryParam.beginDate = this.getMonthRange(dateString).firstDay
+        this.queryParam.endDate = this.getMonthRange(dateString).lastDay
+      } else {
+        this.queryParam.beginDate = undefined
+        this.queryParam.endDate = undefined
+      }
+    },
+    // 获取指定月份   第一天和最后一天
+    getMonthRange (targetMonth) {
+      // 获取指定月第一天(格式化为 YYYY-MM-DD)
+      const firstDay = moment(targetMonth).startOf('month').format('YYYY-MM-DD') + ' 00:00:00'
+      // 获取指定月最后一天(格式化为 YYYY-MM-DD)
+      const lastDay = moment(targetMonth).endOf('month').format('YYYY-MM-DD') + ' 23:59:59'
+      return { firstDay, lastDay }
+    },
+    // 获取表头
+    async getTableTitle () {
+      const _this = this
+      const tableTitle = await salesStatsProvinceTit().then(res => res.data)
+      this.columns = tableTitle.list
+      this.countLabel = tableTitle.count
+      this.columns.map(item => {
+        item.titleNum = item.title
+        let mw = 20
+        if (item.customRender == 'amount') {
+          mw = 15
+          if (item.colour && item.colour === 'red') {
+            item.title = <span style="color:red;">{item.titleNum}</span>
+            item.customRender = (text) => { return <span style="color:red;">{(text || text == 0) ? _this.toThousands(text) : '--'}</span> }
+          } else {
+            item.customRender = function (text) { return (text || text == 0) ? _this.toThousands(text) : '--' }
+          }
+        } else {
+          item.customRender = function (text) { return text || '--' }
+        }
+        const w = item.titleNum.length * mw
+        const tw = w <= 80 ? mw * 5 : w
+        item.width = tw + 'px'
+        this.tableWidth = this.tableWidth + tw
+      })
+      this.resetSearchForm()
+    },
+    // 查询
+    handleSearch () {
+      const _this = this
+      this.$refs.ruleForm.validate(valid => {
+        if (valid) {
+          _this.$refs.table.refresh(true)
+        } else {
+          _this.$message.error('请选择查询月份')
+          return false
+        }
+      })
+    },
+    // 统计
+    getCount (params) {
+      salesStatsProvinceCount(params).then(res => {
+        if (res.status == 200 && res.data) {
+          const mergedList = this.countLabel.map(item => {
+            const key = item.key
+            return key in res.data
+              ? { ...item, [key]: res.data[key] }
+              : item
+          })
+          this.totalData = mergedList
+        } else {
+          this.totalData = null
+        }
+      })
+    },
+    // 区域分区  change
+    subareaChange (val) {
+      this.queryParam.subareaArea.subareaSn = val[0] ? val[0] : ''
+      this.queryParam.subareaArea.subareaAreaSn = val[1] ? val[1] : ''
+    },
+    //  重置
+    resetSearchForm () {
+      this.queryParam.beginDate = moment().startOf('month').format('YYYY-MM-DD') + ' 00:00:00'
+      this.queryParam.endDate = moment().endOf('month').format('YYYY-MM-DD') + ' 23:59:59'
+      this.monthVal = moment().format('YYYY-MM')
+      this.queryParam.provinceSn = undefined
+      this.queryParam.subareaArea.subareaSn = ''
+      this.queryParam.subareaArea.subareaAreaSn = ''
+      this.queryParam.subareaArea.bizUserSn = undefined
+      this.$refs.subarea.clearData()
+      this.totalData = null
+      this.$refs.table.clearTable()
+      this.$refs.ruleForm.resetFields()
+    },
+    //  导出  必填判断
+    handleExport () {
+      const _this = this
+      this.$refs.ruleForm.validate(valid => {
+        if (valid) {
+          _this.exportList()
+        } else {
+          _this.$message.error('请选择查询月份')
+          return false
+        }
+      })
+    },
+    // 导出
+    exportList () {
+      const _this = this
+      const params = JSON.parse(JSON.stringify(_this.queryParam))
+      _this.exportLoading = true
+      _this.spinning = true
+      hdExportExcel(salesStatsProvinceExport, params, '开单统计报表(省份)', function () {
+        _this.exportLoading = false
+        _this.spinning = false
+      })
+    },
+    // 初始化
+    pageInit () {
+      this.$nextTick(() => { // 页面渲染完成后的回调
+        this.setTableH()
+        this.resetSearchForm()
+      })
+    },
+    // 计算表格高度
+    setTableH () {
+      const tableSearchH = this.$refs.tableSearch.offsetHeight
+      this.tableHeight = window.innerHeight - tableSearchH - 280
+    }
+  },
+  mounted () {
+    if (!this.$store.state.app.isNewTab) { // 页签刷新时调用
+      this.pageInit()
+      this.getTableTitle()
+    }
+  },
+  activated () {
+    // 如果是新页签打开,则重置当前页面
+    if (this.$store.state.app.isNewTab) {
+      this.pageInit()
+      this.getTableTitle()
+    }
+  }
+}
+</script>
+<style lang="less" scoped>
+  .monthBox{
+    width: 100%;
+    /deep/.ant-calendar-picker-icon{
+      display:none !important;
+    }
+    /deep/.ant-calendar-picker input{
+      text-align:center;
+    }
+  }
+</style>

+ 359 - 0
src/views/reportData/promotionFeeReport/customerFeeList.vue

@@ -0,0 +1,359 @@
+<template>
+  <div>
+    <a-card size="small" :bordered="false" class="customerFeeList-wrap searchBoxNormal">
+      <!-- 搜索条件 -->
+      <div class="table-page-search-wrapper" ref="tableSearch">
+        <a-form-model
+          id="customerFeeList-form"
+          ref="ruleForm"
+          class="form-model-con"
+          layout="inline"
+          :rules="rules"
+          :model="queryParam">
+          <a-row :gutter="15">
+            <a-col :md="6" :sm="24">
+              <a-form-model-item label="月份" prop="beginDate">
+                <a-month-picker
+                  id="customerFeeList-monthBox"
+                  class="monthBox"
+                  :disabled-date="disabledDate"
+                  v-model="monthVal"
+                  placeholder="请选择月份"
+                  @change="onChangeMonth" />
+              </a-form-model-item>
+            </a-col>
+            <a-col :md="6" :sm="24">
+              <a-form-model-item label="客户名称">
+                <dealerSubareaScopeList ref="dealerSubareaScopeList" id="customerFeeList-dealerName" @change="custChange" />
+              </a-form-model-item>
+            </a-col>
+            <a-col :md="6" :sm="24">
+              <a-form-model-item label="客户级别">
+                <v-select
+                  v-model="queryParam.dealerLevel"
+                  ref="dealerLevel"
+                  id="customerFeeList-dealerLevel"
+                  code="DEALER_LEVEL"
+                  placeholder="请选择客户级别"
+                  allowClear></v-select>
+              </a-form-model-item>
+            </a-col>
+            <template v-if="advanced">
+              <a-col :md="6" :sm="24">
+                <a-form-item label="所在区域">
+                  <subarea id="customerFeeList-subarea" ref="subarea" @change="subareaChange"></subarea>
+                </a-form-item>
+              </a-col>
+              <a-col :md="6" :sm="24">
+                <a-form-model-item label="区域负责人">
+                  <BizUser id="customerFeeList-bizUserSn" v-model="queryParam.subareaArea.bizUserSn"></BizUser>
+                </a-form-model-item>
+              </a-col>
+              <a-col :md="6" :sm="24">
+                <a-form-model-item label="地区">
+                  <AreaList id="customerFeeList-areaList" changeOnSelect ref="areaList" @change="areaChange" defValKey="id"></AreaList>
+                </a-form-model-item>
+              </a-col>
+              <a-col :md="6" :sm="24">
+                <a-form-model-item label="客服">
+                  <customerService ref="customerName" id="customerFeeList-customerName" v-model="queryParam.kfSn"></customerService>
+                </a-form-model-item>
+              </a-col>
+            </template>
+            <a-col :md="6" :sm="24">
+              <a-button
+                type="primary"
+                @click="handleSearch"
+                :disabled="disabled"
+                id="customerFeeList-refresh">查询</a-button>
+              <a-button
+                style="margin-left: 8px"
+                @click="resetSearchForm"
+                :disabled="disabled"
+                id="customerFeeList-reset">重置</a-button>
+              <a-button
+                style="margin-left: 10px"
+                type="primary"
+                class="button-warning"
+                @click="handleExport"
+                :disabled="disabled"
+                :loading="exportLoading"
+                v-if="$hasPermissions('B_promotionFeeExport')"
+                id="customerFeeList-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-model>
+      </div>
+    </a-card>
+    <a-card size="small" :bordered="false">
+      <a-spin :spinning="spinning" tip="Loading...">
+        <!-- 列表 -->
+        <s-table
+          class="sTable fixPagination"
+          ref="table"
+          size="small"
+          :rowKey="(record) => record.id"
+          :style="{ height: tableHeight+70+'px' }"
+          :columns="columns"
+          :data="loadData"
+          :scroll="{x:2200, y: tableHeight}"
+          :defaultLoadData="false"
+          bordered>
+        </s-table>
+      </a-spin>
+    </a-card>
+  </div>
+</template>
+
+<script>
+import { commonMixin } from '@/utils/mixin'
+import { hdExportExcel } from '@/libs/exportExcel'
+import moment from 'moment'
+// 组件
+import { STable, VSelect } from '@/components'
+import subarea from '@/views/common/subarea.js'
+import AreaList from '@/views/common/areaList.js'
+import dealerSubareaScopeList from '@/views/common/dealerSubareaScopeList.vue'
+import BizUser from '@/views/common/bizUser.js'
+import customerService from '@/views/common/customerService.vue'
+// 接口
+import { promoSalesExpenseList, promoSalesExpenseTitle, promoSalesExpenseCount, promoSalesExpenseExport } from '@/api/reportData'
+export default {
+  name: 'CustomerFeeList',
+  mixins: [commonMixin],
+  components: { STable, VSelect, subarea, AreaList, dealerSubareaScopeList, BizUser, customerService },
+  data () {
+    return {
+      spinning: false,
+      disabled: false, //  查询、重置按钮是否可操作
+      advanced: true, // 高级搜索 展开/关闭
+      tableHeight: 0, // 表格高度
+      exportLoading: false, // 导出按钮加载状态
+      monthVal: moment().format('YYYY-MM'), // 初始化月份值
+      //  查询条件
+      queryParam: {
+        amountType: 'promo',
+        beginDate: moment().startOf('month').format('YYYY-MM-DD') + ' 00:00:00', // 月份开始时间
+        endDate: moment().endOf('month').format('YYYY-MM-DD') + ' 23:59:59', // 月份结束时间
+        dealerLevel: undefined, // 客户级别
+        dealerSn: undefined, // 客户sn
+        dealerEntity: {
+          dealerName: undefined, // 客户名称
+          provinceSn: undefined, // 省
+          citySn: undefined, // 市
+          districtSn: undefined // 区
+        },
+        subareaArea: {
+          subareaSn: '', // 区域
+          subareaAreaSn: '', // 分区
+          bizUserSn: undefined// 区域负责人
+        },
+        kfSn: undefined// 客服
+      },
+      columns: [], // 表头
+      countLabel: null, // 合计名称
+      rules: {
+        'beginDate': [{ required: true, message: '请选择查询月份', trigger: 'change' }]
+      },
+      // 加载数据方法 必须为 Promise 对象
+      loadData: parameter => {
+        this.disabled = true
+        this.spinning = true
+        const params = Object.assign(parameter, this.queryParam)
+        // 获取列表数据  有分页
+        return promoSalesExpenseList(params).then(res => {
+          let data
+          if (res.status == 200) {
+            data = res.data
+            // 计算表格序号
+            const id = (data.pageNo - 1) * data.pageSize
+            for (var i = 0; i < data.list.length; i++) {
+              data.list[i].id = id + i + 1
+            }
+            this.disabled = false
+          }
+          this.spinning = false
+          return data
+        })
+      }
+    }
+  },
+  watch: {
+    advanced (newValue, oldValue) {
+      const _this = this
+      this.$nextTick(() => { // 页面渲染完成后的回调
+        _this.setTableH()
+      })
+    },
+    '$store.state.app.winHeight' (newValue, oldValue) { //  窗口变更时,需同时更改表格高度
+      this.setTableH()
+    }
+  },
+  methods: {
+    // 选择月份  禁用选择当月以后日期
+    disabledDate (current) {
+      return current && current >= moment().endOf('day')
+    },
+    // 选择月份 change
+    onChangeMonth (date, dateString) {
+      this.monthVal = dateString
+      if (date && dateString != '') {
+        this.queryParam.beginDate = this.getMonthRange(dateString).firstDay
+        this.queryParam.endDate = this.getMonthRange(dateString).lastDay
+      } else {
+        this.queryParam.beginDate = undefined
+        this.queryParam.endDate = undefined
+      }
+    },
+    // 获取指定月份   第一天和最后一天
+    getMonthRange (targetMonth) {
+      // 获取指定月第一天(格式化为 YYYY-MM-DD)
+      const firstDay = moment(targetMonth).startOf('month').format('YYYY-MM-DD') + ' 00:00:00'
+      // 获取指定月最后一天(格式化为 YYYY-MM-DD)
+      const lastDay = moment(targetMonth).endOf('month').format('YYYY-MM-DD') + ' 23:59:59'
+      return { firstDay, lastDay }
+    },
+    // 获取表头
+    async getTableTitle () {
+      const _this = this
+      const tableTitle = await promoSalesExpenseTitle().then(res => res.data)
+      this.columns = tableTitle.list
+      this.countLabel = tableTitle.count
+      this.columns.map(item => {
+        item.titleNum = item.title
+        let mw = 20
+        if (item.customRender == 'amount') {
+          mw = 15
+          if (item.colour && item.colour === 'red') {
+            item.title = <span style="color:red;">{item.titleNum}</span>
+            item.customRender = (text) => { return <span style="color:red;">{(text || text == 0) ? _this.toThousands(text) : '--'}</span> }
+          } else {
+            item.customRender = function (text) { return (text || text == 0) ? _this.toThousands(text) : '--' }
+          }
+        } else {
+          item.customRender = function (text) { return text || '--' }
+        }
+        const w = item.titleNum.length * mw
+        const tw = w <= 80 ? mw * 5 : w
+        item.width = tw + 'px'
+        this.tableWidth = this.tableWidth + tw
+      })
+      this.resetSearchForm()
+    },
+    // 查询
+    handleSearch () {
+      const _this = this
+      this.$refs.ruleForm.validate(valid => {
+        if (valid) {
+          _this.$refs.table.refresh(true)
+        } else {
+          _this.$message.error('请选择查询月份')
+          return false
+        }
+      })
+    },
+    // 客户名称 change
+    custChange (val) {
+      this.queryParam.dealerEntity.dealerName = val.name
+      this.queryParam.dealerSn = val.key
+    },
+    // 地区
+    areaChange (val) {
+      this.queryParam.provinceSn = val[0] ? val[0] : undefined
+      this.queryParam.citySn = val[1] ? val[1] : undefined
+      this.queryParam.districtSn = val[2] ? val[2] : undefined
+    },
+    // 区域分区  change
+    subareaChange (val) {
+      this.queryParam.subareaArea.subareaSn = val[0] ? val[0] : ''
+      this.queryParam.subareaArea.subareaAreaSn = val[1] ? val[1] : ''
+    },
+    //  重置
+    resetSearchForm () {
+      this.queryParam.beginDate = moment().startOf('month').format('YYYY-MM-DD') + ' 00:00:00'
+      this.queryParam.endDate = moment().endOf('month').format('YYYY-MM-DD') + ' 23:59:59'
+      this.monthVal = moment().format('YYYY-MM')
+      this.queryParam.provinceSn = undefined
+      this.queryParam.citySn = undefined
+      this.queryParam.districtSn = undefined
+      this.queryParam.dealerEntity.dealerName = undefined
+      this.queryParam.dealerSn = undefined
+      this.queryParam.subareaArea.subareaSn = ''
+      this.queryParam.subareaArea.subareaAreaSn = ''
+      this.queryParam.subareaArea.bizUserSn = undefined
+      this.queryParam.dealerLevel = undefined
+      this.queryParam.kfSn = undefined
+      this.$refs.dealerSubareaScopeList.resetForm()
+      if (this.advanced) {
+        this.$refs.subarea && this.$refs.subarea.clearData()
+        this.$refs.areaList && this.$refs.areaList.clearData()
+      }
+      this.$refs.table.clearTable()
+      this.$refs.ruleForm.resetFields()
+    },
+    //  导出  必填判断
+    handleExport () {
+      const _this = this
+      this.$refs.ruleForm.validate(valid => {
+        if (valid) {
+          _this.exportList()
+        } else {
+          _this.$message.error('请选择查询月份')
+          return false
+        }
+      })
+    },
+    // 导出
+    exportList () {
+      const _this = this
+      const params = JSON.parse(JSON.stringify(_this.queryParam))
+      _this.exportLoading = true
+      _this.spinning = true
+      hdExportExcel(promoSalesExpenseExport, params, '促销费用报表(客户)', function () {
+        _this.exportLoading = false
+        _this.spinning = false
+      })
+    },
+    // 初始化
+    pageInit () {
+      this.$nextTick(() => { // 页面渲染完成后的回调
+        this.setTableH()
+        this.resetSearchForm()
+      })
+    },
+    // 计算表格高度
+    setTableH () {
+      const tableSearchH = this.$refs.tableSearch.offsetHeight
+      this.tableHeight = window.innerHeight - tableSearchH - 280
+    }
+  },
+  mounted () {
+    if (!this.$store.state.app.isNewTab) { // 页签刷新时调用
+      this.pageInit()
+      this.getTableTitle()
+    }
+  },
+  activated () {
+    // 如果是新页签打开,则重置当前页面
+    if (this.$store.state.app.isNewTab) {
+      this.pageInit()
+      this.getTableTitle()
+    }
+  }
+}
+</script>
+<style lang="less" scoped>
+  .monthBox{
+    width: 100%;
+    /deep/.ant-calendar-picker-icon{
+      display:none !important;
+    }
+    /deep/.ant-calendar-picker input{
+      text-align:center;
+    }
+  }
+</style>

+ 41 - 0
src/views/reportData/promotionFeeReport/index.vue

@@ -0,0 +1,41 @@
+<template>
+  <div>
+    <a-card size="small" :bordered="false">
+      <a-tabs default-active-key="1" @change="handleChange">
+        <a-tab-pane key="1" tab="促销费用报表(客户)">
+          <customerFeeList ref="customerFeeList"></customerFeeList>
+        </a-tab-pane>
+        <a-tab-pane key="2" tab="促销费用报表(省份)" force-render>
+          <provinceFeeList ref="provinceFeeList"></provinceFeeList>
+        </a-tab-pane>
+        <a-tab-pane key="3" tab="促销销售费用报表" force-render>
+          <promotionFeeList ref="promotionFeeList"></promotionFeeList>
+        </a-tab-pane>
+      </a-tabs>
+    </a-card>
+  </div>
+</template>
+<script>
+import { commonMixin } from '@/utils/mixin'
+// 组件
+import customerFeeList from './customerFeeList.vue'
+import provinceFeeList from './provinceFeeList.vue'
+import promotionFeeList from './promoFeeList.vue'
+export default {
+  name: 'PromotionFeeReportIndex',
+  mixins: [commonMixin],
+  components: { customerFeeList, provinceFeeList, promotionFeeList },
+  data () {
+    return {
+      tabVal: 1 // tab值  1轮胎月度费用报表 2轮胎季度费用报表 3轮胎年度费用报表 4轮胎费用明细报表
+    }
+  },
+  methods: {
+    // 切换tab值  change
+    handleChange (val) {
+      this.tabVal = val
+    }
+  }
+}
+
+</script>

+ 382 - 0
src/views/reportData/promotionFeeReport/promoFeeList.vue

@@ -0,0 +1,382 @@
+<template>
+  <div>
+    <a-card size="small" :bordered="false" class="promotionFeeList-wrap searchBoxNormal">
+      <!-- 搜索条件 -->
+      <div class="table-page-search-wrapper" ref="tableSearch">
+        <a-form-model
+          id="promotionFeeList-form"
+          ref="ruleForm"
+          class="form-model-con"
+          layout="inline"
+          :rules="rules"
+          :model="queryParam">
+          <a-row :gutter="15">
+            <a-col :md="6" :sm="24">
+              <a-form-model-item label="月份" prop="beginDate">
+                <a-month-picker
+                  id="promotionFeeList-monthBox"
+                  class="monthBox"
+                  :disabled-date="disabledDate"
+                  v-model="monthVal"
+                  placeholder="请选择月份"
+                  @change="onChangeMonth" />
+              </a-form-model-item>
+            </a-col>
+            <a-col :md="6" :sm="24">
+              <a-form-model-item label="客户名称">
+                <dealerSubareaScopeList ref="dealerSubareaScopeList" id="promotionFeeList-dealerName" @change="custChange" />
+              </a-form-model-item>
+            </a-col>
+            <a-col :md="6" :sm="24">
+              <a-form-model-item label="客户级别">
+                <v-select
+                  v-model="queryParam.dealerLevel"
+                  ref="dealerLevel"
+                  id="promotionFeeList-dealerLevel"
+                  code="DEALER_LEVEL"
+                  placeholder="请选择客户级别"
+                  allowClear></v-select>
+              </a-form-model-item>
+            </a-col>
+            <template v-if="advanced">
+              <a-col :md="6" :sm="24">
+                <a-form-item label="所在区域">
+                  <subarea id="promotionFeeList-subarea" ref="subarea" @change="subareaChange"></subarea>
+                </a-form-item>
+              </a-col>
+              <a-col :md="6" :sm="24">
+                <a-form-model-item label="区域负责人">
+                  <BizUser id="promotionFeeList-bizUserSn" v-model="queryParam.subareaArea.bizUserSn"></BizUser>
+                </a-form-model-item>
+              </a-col>
+              <a-col :md="6" :sm="24">
+                <a-form-model-item label="地区">
+                  <AreaList id="promotionFeeList-areaList" changeOnSelect ref="areaList" @change="areaChange" defValKey="id"></AreaList>
+                </a-form-model-item>
+              </a-col>
+            </template>
+            <a-col :md="6" :sm="24">
+              <a-button
+                type="primary"
+                @click="handleSearch"
+                :disabled="disabled"
+                id="promotionFeeList-refresh">查询</a-button>
+              <a-button
+                style="margin-left: 8px"
+                @click="resetSearchForm"
+                :disabled="disabled"
+                id="promotionFeeList-reset">重置</a-button>
+              <a-button
+                style="margin-left: 10px"
+                type="primary"
+                class="button-warning"
+                @click="handleExport"
+                :disabled="disabled"
+                :loading="exportLoading"
+                v-if="$hasPermissions('B_promotionFeeExport')"
+                id="promotionFeeList-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-model>
+      </div>
+    </a-card>
+    <a-card size="small" :bordered="false">
+      <a-spin :spinning="spinning" tip="Loading...">
+        <!-- 列表 -->
+        <s-table
+          class="sTable fixPagination"
+          ref="table"
+          size="small"
+          :rowKey="(record) => record.no"
+          rowKeyName="no"
+          :style="{ height: tableHeight+90+'px' }"
+          :columns="columns"
+          :data="loadData"
+          :scroll="{x:2200, y: tableHeight-120}"
+          :defaultLoadData="false"
+          bordered>
+          <template slot="footer" v-if="totalData&&totalData.length">
+            <a-row :gutter="15">
+              <a-col span="24">合计:</a-col>
+              <a-col span="24">
+                <a-col span="4" v-for="item in totalData" :key="item.key">
+                  {{ item.title }}:{{ item[item.key] ||item[item.key] ==0?toThousands(item[item.key]) :'--' }}
+                </a-col>
+              </a-col>
+            </a-row>
+          </template>
+        </s-table>
+      </a-spin>
+    </a-card>
+  </div>
+</template>
+
+<script>
+import { commonMixin } from '@/utils/mixin'
+import { hdExportExcel } from '@/libs/exportExcel'
+import moment from 'moment'
+// 组件
+import { STable, VSelect } from '@/components'
+import subarea from '@/views/common/subarea.js'
+import AreaList from '@/views/common/areaList.js'
+import dealerSubareaScopeList from '@/views/common/dealerSubareaScopeList.vue'
+import BizUser from '@/views/common/bizUser.js'
+// 接口
+import { promoSalesExpenseList, promoSalesExpenseTitle, promoSalesExpenseCount, promoSalesExpenseExport } from '@/api/reportData'
+export default {
+  name: 'PromotionFeeList',
+  mixins: [commonMixin],
+  components: { STable, VSelect, subarea, AreaList, dealerSubareaScopeList, BizUser },
+  data () {
+    return {
+      spinning: false,
+      disabled: false, //  查询、重置按钮是否可操作
+      advanced: true, // 高级搜索 展开/关闭
+      tableHeight: 0, // 表格高度
+      exportLoading: false, // 导出按钮加载状态
+      monthVal: moment().format('YYYY-MM'), // 初始化月份值
+      //  查询条件
+      queryParam: {
+        amountType: 'sales_promo',
+        beginDate: moment().startOf('month').format('YYYY-MM-DD') + ' 00:00:00', // 月份开始时间
+        endDate: moment().endOf('month').format('YYYY-MM-DD') + ' 23:59:59', // 月份结束时间
+        dealerLevel: undefined, // 客户级别
+        dealerSn: undefined, // 客户sn
+        dealerEntity: {
+          dealerName: undefined, // 客户名称
+          provinceSn: undefined, // 省
+          citySn: undefined, // 市
+          districtSn: undefined // 区
+        },
+        subareaArea: {
+          subareaSn: '', // 区域
+          subareaAreaSn: '', // 分区
+          bizUserSn: undefined// 区域负责人
+        }
+      },
+      columns: [], // 表头
+      countLabel: null, // 合计名称
+      totalData: null, // 合计
+      rules: {
+        'beginDate': [{ required: true, message: '请选择查询月份', trigger: 'change' }]
+      },
+      // 加载数据方法 必须为 Promise 对象
+      loadData: parameter => {
+        this.disabled = true
+        this.spinning = true
+        const params = Object.assign(parameter, this.queryParam)
+        // 获取列表数据  有分页
+        return promoSalesExpenseList(params).then(res => {
+          let data
+          if (res.status == 200) {
+            data = res.data
+            // 计算表格序号
+            const no = (data.pageNo - 1) * data.pageSize
+            for (var i = 0; i < data.list.length; i++) {
+              data.list[i].no = no + i + 1
+            }
+            this.disabled = false
+            // 统计
+            this.getCount(params)
+          }
+          this.spinning = false
+          return data
+        })
+      }
+    }
+  },
+  watch: {
+    advanced (newValue, oldValue) {
+      const _this = this
+      this.$nextTick(() => { // 页面渲染完成后的回调
+        _this.setTableH()
+      })
+    },
+    '$store.state.app.winHeight' (newValue, oldValue) { //  窗口变更时,需同时更改表格高度
+      this.setTableH()
+    }
+  },
+  methods: {
+    // 选择月份  禁用选择当月以后日期
+    disabledDate (current) {
+      return current && current >= moment().endOf('day')
+    },
+    // 选择月份 change
+    onChangeMonth (date, dateString) {
+      this.monthVal = dateString
+      if (date && dateString != '') {
+        this.queryParam.beginDate = this.getMonthRange(dateString).firstDay
+        this.queryParam.endDate = this.getMonthRange(dateString).lastDay
+      } else {
+        this.queryParam.beginDate = undefined
+        this.queryParam.endDate = undefined
+      }
+    },
+    // 获取指定月份   第一天和最后一天
+    getMonthRange (targetMonth) {
+      // 获取指定月第一天(格式化为 YYYY-MM-DD)
+      const firstDay = moment(targetMonth).startOf('month').format('YYYY-MM-DD') + ' 00:00:00'
+      // 获取指定月最后一天(格式化为 YYYY-MM-DD)
+      const lastDay = moment(targetMonth).endOf('month').format('YYYY-MM-DD') + ' 23:59:59'
+      return { firstDay, lastDay }
+    },
+    // 获取表头
+    async getTableTitle () {
+      const _this = this
+      const tableTitle = await promoSalesExpenseTitle().then(res => res.data)
+      this.columns = tableTitle.list
+      this.countLabel = tableTitle.count
+      this.columns.map(item => {
+        item.titleNum = item.title
+        let mw = 20
+        if (item.customRender == 'amount') {
+          mw = 15
+          if (item.colour && item.colour === 'red') {
+            item.title = <span style="color:red;">{item.titleNum}</span>
+            item.customRender = (text) => { return <span style="color:red;">{(text || text == 0) ? _this.toThousands(text) : '--'}</span> }
+          } else {
+            item.customRender = function (text) { return (text || text == 0) ? _this.toThousands(text) : '--' }
+          }
+        } else {
+          item.customRender = function (text) { return text || '--' }
+        }
+        const w = item.titleNum.length * mw
+        const tw = w <= 80 ? mw * 5 : w
+        item.width = tw + 'px'
+        this.tableWidth = this.tableWidth + tw
+      })
+      this.resetSearchForm()
+    },
+    // 查询
+    handleSearch () {
+      const _this = this
+      this.$refs.ruleForm.validate(valid => {
+        if (valid) {
+          _this.$refs.table.refresh(true)
+        } else {
+          _this.$message.error('请选择查询月份')
+          return false
+        }
+      })
+    },
+    // 客户名称 change
+    custChange (val) {
+      this.queryParam.dealerEntity.dealerName = val.name
+      this.queryParam.dealerSn = val.key
+    },
+    // 统计
+    getCount (params) {
+      promoSalesExpenseCount(params).then(res => {
+        if (res.status == 200 && res.data) {
+          const mergedList = this.countLabel.map(item => {
+            const key = item.key
+            return key in res.data
+              ? { ...item, [key]: res.data[key] }
+              : item
+          })
+          this.totalData = mergedList
+        } else {
+          this.totalData = null
+        }
+      })
+    },
+    // 地区
+    areaChange (val) {
+      this.queryParam.provinceSn = val[0] ? val[0] : undefined
+      this.queryParam.citySn = val[1] ? val[1] : undefined
+      this.queryParam.districtSn = val[2] ? val[2] : undefined
+    },
+    // 区域分区  change
+    subareaChange (val) {
+      this.queryParam.subareaArea.subareaSn = val[0] ? val[0] : ''
+      this.queryParam.subareaArea.subareaAreaSn = val[1] ? val[1] : ''
+    },
+    //  重置
+    resetSearchForm () {
+      this.queryParam.beginDate = moment().startOf('month').format('YYYY-MM-DD') + ' 00:00:00'
+      this.queryParam.endDate = moment().endOf('month').format('YYYY-MM-DD') + ' 23:59:59'
+      this.monthVal = moment().format('YYYY-MM')
+      this.queryParam.provinceSn = undefined
+      this.queryParam.citySn = undefined
+      this.queryParam.districtSn = undefined
+      this.queryParam.dealerEntity.dealerName = undefined
+      this.queryParam.dealerSn = undefined
+      this.queryParam.subareaArea.subareaSn = ''
+      this.queryParam.subareaArea.subareaAreaSn = ''
+      this.queryParam.subareaArea.bizUserSn = undefined
+      this.queryParam.dealerLevel = undefined
+      this.$refs.dealerSubareaScopeList.resetForm()
+      if (this.advanced) {
+        this.$refs.subarea && this.$refs.subarea.clearData()
+        this.$refs.areaList && this.$refs.areaList.clearData()
+      }
+      this.totalData = null
+      this.$refs.table.clearTable()
+      this.$refs.ruleForm.resetFields()
+    },
+    //  导出  必填判断
+    handleExport () {
+      const _this = this
+      this.$refs.ruleForm.validate(valid => {
+        if (valid) {
+          _this.exportList()
+        } else {
+          _this.$message.error('请选择查询月份')
+          return false
+        }
+      })
+    },
+    // 导出
+    exportList () {
+      const _this = this
+      const params = JSON.parse(JSON.stringify(_this.queryParam))
+      _this.exportLoading = true
+      _this.spinning = true
+      hdExportExcel(promoSalesExpenseExport, params, '促销费用报表', function () {
+        _this.exportLoading = false
+        _this.spinning = false
+      })
+    },
+    // 初始化
+    pageInit () {
+      this.$nextTick(() => { // 页面渲染完成后的回调
+        this.setTableH()
+        this.resetSearchForm()
+      })
+    },
+    // 计算表格高度
+    setTableH () {
+      const tableSearchH = this.$refs.tableSearch.offsetHeight
+      this.tableHeight = window.innerHeight - tableSearchH - 300
+    }
+  },
+  mounted () {
+    if (!this.$store.state.app.isNewTab) { // 页签刷新时调用
+      this.pageInit()
+      this.getTableTitle()
+    }
+  },
+  activated () {
+    // 如果是新页签打开,则重置当前页面
+    if (this.$store.state.app.isNewTab) {
+      this.getTableTitle()
+      this.pageInit()
+    }
+  }
+}
+</script>
+<style lang="less" scoped>
+  .monthBox{
+    width: 100%;
+    /deep/.ant-calendar-picker-icon{
+      display:none !important;
+    }
+    /deep/.ant-calendar-picker input{
+      text-align:center;
+    }
+  }
+</style>

+ 298 - 0
src/views/reportData/promotionFeeReport/provinceFeeList.vue

@@ -0,0 +1,298 @@
+<template>
+  <div>
+    <a-card size="small" :bordered="false" class="provinceFeeList-wrap searchBoxNormal">
+      <!-- 搜索条件 -->
+      <div class="table-page-search-wrapper" ref="tableSearch">
+        <a-form-model
+          id="provinceFeeList-form"
+          ref="ruleForm"
+          class="form-model-con"
+          layout="inline"
+          :rules="rules"
+          :model="queryParam">
+          <a-row :gutter="15">
+            <a-col :md="5" :sm="24">
+              <a-form-model-item label="月份" prop="beginDate">
+                <a-month-picker
+                  id="provinceFeeList-monthBox"
+                  class="monthBox"
+                  :disabled-date="disabledDate"
+                  v-model="monthVal"
+                  placeholder="请选择月份"
+                  @change="onChangeMonth" />
+              </a-form-model-item>
+            </a-col>
+            <a-col :md="5" :sm="24">
+              <a-form-model-item label="地区">
+                <Area id="provinceFeeList-areaList" v-model="queryParam.provinceSn" placeholder="请选择省份"></Area>
+              </a-form-model-item>
+            </a-col>
+            <a-col :md="5" :sm="24">
+              <a-form-item label="所在区域">
+                <subarea id="provinceFeeList-subarea" ref="subarea" @change="subareaChange"></subarea>
+              </a-form-item>
+            </a-col>
+            <a-col :md="5" :sm="24">
+              <a-form-model-item label="区域负责人">
+                <BizUser id="provinceFeeList-bizUserSn" v-model="queryParam.subareaArea.bizUserSn"></BizUser>
+              </a-form-model-item>
+            </a-col>
+            <a-col :md="4" :sm="24">
+              <a-button
+                type="primary"
+                @click="handleSearch"
+                :disabled="disabled"
+                id="provinceFeeList-refresh">查询</a-button>
+              <a-button
+                style="margin-left: 8px"
+                @click="resetSearchForm"
+                :disabled="disabled"
+                id="provinceFeeList-reset">重置</a-button>
+              <a-button
+                style="margin-left: 10px"
+                type="primary"
+                class="button-warning"
+                @click="handleExport"
+                :disabled="disabled"
+                :loading="exportLoading"
+                v-if="$hasPermissions('B_promotionFeeExport')"
+                id="provinceFeeList-export">导出</a-button>
+            </a-col>
+          </a-row>
+        </a-form-model>
+      </div>
+    </a-card>
+    <a-card size="small" :bordered="false">
+      <a-spin :spinning="spinning" tip="Loading...">
+        <!-- 列表 -->
+        <s-table
+          class="sTable fixPagination"
+          ref="table"
+          size="small"
+          :rowKey="(record) => record.id"
+          :style="{ height: tableHeight+70+'px' }"
+          :columns="columns"
+          :data="loadData"
+          :scroll="{x:2200, y: tableHeight}"
+          :defaultLoadData="false"
+          :showPagination="false"
+          bordered>
+        </s-table>
+      </a-spin>
+    </a-card>
+  </div>
+</template>
+
+<script>
+import { commonMixin } from '@/utils/mixin'
+import { hdExportExcel } from '@/libs/exportExcel'
+import moment from 'moment'
+// 组件
+import { STable, VSelect } from '@/components'
+import subarea from '@/views/common/subarea.js'
+import Area from '@/views/common/area.js'
+import BizUser from '@/views/common/bizUser.js'
+import customerService from '@/views/common/customerService.vue'
+// 接口
+import { promoProvinceList, promoProvinceTableTitle, promoProvinceExport } from '@/api/reportData'
+export default {
+  name: 'ProvinceFeeList',
+  mixins: [commonMixin],
+  components: { STable, VSelect, subarea, Area, BizUser, customerService },
+  data () {
+    return {
+      spinning: false,
+      disabled: false, //  查询、重置按钮是否可操作
+      tableHeight: 0, // 表格高度
+      exportLoading: false, // 导出按钮加载状态
+      //  查询条件
+      monthVal: moment().format('YYYY-MM'), // 初始化月份值
+      queryParam: {
+        beginDate: moment().startOf('month').format('YYYY-MM-DD') + ' 00:00:00', // 月份开始时间
+        endDate: moment().endOf('month').format('YYYY-MM-DD') + ' 23:59:59', // 月份结束时间
+        provinceSn: undefined, // 省
+        subareaArea: {
+          subareaSn: '', // 区域
+          subareaAreaSn: '', // 分区
+          bizUserSn: undefined// 区域负责人
+        }
+      },
+      countLabel: null, // 统计名称合集
+      totalData: null, // 统计数据
+      columns: [], // 表格列
+      rules: {
+        'beginDate': [{ required: true, message: '请选择查询月份', trigger: 'change' }]
+      },
+      // 加载数据方法 必须为 Promise 对象
+      loadData: parameter => {
+        this.disabled = true
+        this.spinning = true
+        const params = Object.assign(parameter, this.queryParam)
+        // 获取列表数据  有分页
+        return promoProvinceList(params).then(res => {
+          let data
+          if (res.status == 200) {
+            data = res.data
+            // 计算表格序号
+            for (var i = 0; i < data.length; i++) {
+              data[i].id = i + 1
+            }
+            this.disabled = false
+          }
+          this.spinning = false
+          return data
+        })
+      }
+    }
+  },
+  methods: {
+    // 选择月份  禁用选择当月以后日期
+    disabledDate (current) {
+      return current && current >= moment().endOf('day')
+    },
+    // 选择月份 change
+    onChangeMonth (date, dateString) {
+      this.monthVal = dateString
+      if (date && dateString != '') {
+        this.queryParam.beginDate = this.getMonthRange(dateString).firstDay
+        this.queryParam.endDate = this.getMonthRange(dateString).lastDay
+      } else {
+        this.queryParam.beginDate = undefined
+        this.queryParam.endDate = undefined
+      }
+    },
+    // 获取指定月份   第一天和最后一天
+    getMonthRange (targetMonth) {
+      // 获取指定月第一天(格式化为 YYYY-MM-DD)
+      const firstDay = moment(targetMonth).startOf('month').format('YYYY-MM-DD') + ' 00:00:00'
+      // 获取指定月最后一天(格式化为 YYYY-MM-DD)
+      const lastDay = moment(targetMonth).endOf('month').format('YYYY-MM-DD') + ' 23:59:59'
+      return { firstDay, lastDay }
+    },
+    // 获取表头
+    async getTableTitle () {
+      const _this = this
+      const tableTitle = await promoProvinceTableTitle().then(res => res.data)
+      this.columns = tableTitle.list
+      this.countLabel = tableTitle.count
+      this.columns.map(item => {
+        item.titleNum = item.title
+        let mw = 20
+        if (item.customRender == 'amount') {
+          mw = 15
+          if (item.colour && item.colour === 'red') {
+            item.title = <span style="color:red;">{item.titleNum}</span>
+            item.customRender = (text) => { return <span style="color:red;">{(text || text == 0) ? _this.toThousands(text) : '--'}</span> }
+          } else {
+            item.customRender = function (text) { return (text || text == 0) ? _this.toThousands(text) : '--' }
+          }
+        } else {
+          item.customRender = function (text) { return text || '--' }
+        }
+        const w = item.titleNum.length * mw
+        const tw = w <= 80 ? mw * 5 : w
+        item.width = tw + 'px'
+        this.tableWidth = this.tableWidth + tw
+      })
+      this.resetSearchForm()
+    },
+    // 查询
+    handleSearch () {
+      const _this = this
+      this.$refs.ruleForm.validate(valid => {
+        if (valid) {
+          _this.$refs.table.refresh(true)
+        } else {
+          _this.$message.error('请选择查询月份')
+          return false
+        }
+      })
+    },
+    // 地区
+    areaChange (val) {
+      this.queryParam.dealerEntity.provinceSn = val[0] ? val[0] : undefined
+      this.queryParam.dealerEntity.citySn = val[1] ? val[1] : undefined
+      this.queryParam.dealerEntity.districtSn = val[2] ? val[2] : undefined
+    },
+    // 区域分区  change
+    subareaChange (val) {
+      this.queryParam.subareaArea.subareaSn = val[0] ? val[0] : ''
+      this.queryParam.subareaArea.subareaAreaSn = val[1] ? val[1] : ''
+    },
+    //  重置
+    resetSearchForm () {
+      this.queryParam.beginDate = moment().startOf('month').format('YYYY-MM-DD') + ' 00:00:00'
+      this.queryParam.endDate = moment().endOf('month').format('YYYY-MM-DD') + ' 23:59:59'
+      this.monthVal = moment().format('YYYY-MM')
+      this.queryParam.provinceSn = undefined
+      this.queryParam.subareaArea.subareaSn = ''
+      this.queryParam.subareaArea.subareaAreaSn = ''
+      this.queryParam.subareaArea.bizUserSn = undefined
+      this.totalData = null
+      this.$refs.subarea && this.$refs.subarea.clearData()
+      this.$refs.areaList && this.$refs.areaList.clearData()
+      this.$refs.table.clearTable()
+      this.$refs.ruleForm.resetFields()
+    },
+    //  导出  必填判断
+    handleExport () {
+      const _this = this
+      this.$refs.ruleForm.validate(valid => {
+        if (valid) {
+          _this.exportList()
+        } else {
+          _this.$message.error('请选择查询月份')
+          return false
+        }
+      })
+    },
+    // 导出
+    exportList () {
+      const _this = this
+      const params = JSON.parse(JSON.stringify(_this.queryParam))
+      _this.exportLoading = true
+      _this.spinning = true
+      hdExportExcel(promoProvinceExport, params, '促销费用报表(省份)', function () {
+        _this.exportLoading = false
+        _this.spinning = false
+      })
+    },
+    // 初始化
+    pageInit () {
+      this.$nextTick(() => { // 页面渲染完成后的回调
+        this.setTableH()
+        this.resetSearchForm()
+      })
+    },
+    // 计算表格高度
+    setTableH () {
+      const tableSearchH = this.$refs.tableSearch.offsetHeight
+      this.tableHeight = window.innerHeight - tableSearchH - 280
+    }
+  },
+  mounted () {
+    if (!this.$store.state.app.isNewTab) { // 页签刷新时调用
+      this.pageInit()
+      this.getTableTitle()
+    }
+  },
+  activated () {
+    // 如果是新页签打开,则重置当前页面
+    if (this.$store.state.app.isNewTab) {
+      this.pageInit()
+      this.getTableTitle()
+    }
+  }
+}
+</script>
+<style lang="less" scoped>
+  .monthBox{
+    width: 100%;
+    /deep/.ant-calendar-picker-icon{
+      display:none !important;
+    }
+    /deep/.ant-calendar-picker input{
+      text-align:center;
+    }
+  }
+</style>

+ 2 - 2
src/views/reportData/regionTypeBusinessReport/list.vue

@@ -70,7 +70,7 @@
           :style="{ height: tableHeight+'px' }"
           :columns="columns"
           :data="loadData"
-          :scroll="{ y: tableHeight}"
+          :scroll="{ y: tableHeight-40}"
           :defaultLoadData="false"
           :showPagination="false"
           bordered>
@@ -297,7 +297,7 @@ export default {
     // 计算表格高度
     setTableH () {
       const tableSearchH = this.$refs.tableSearch.offsetHeight
-      this.tableHeight = window.innerHeight - tableSearchH - 160
+      this.tableHeight = window.innerHeight - tableSearchH - 130
     }
   },
   mounted () {