Procházet zdrojové kódy

Merge branch 'master' of http://120.26.64.82:10880/BFFE/dz2.1

zhaoke před 1 rokem
rodič
revize
3d9794681a
65 změnil soubory, kde provedl 12477 přidání a 0 odebrání
  1. 422 0
      src/views/statisticsCharts/components/TableDialog.vue
  2. 580 0
      src/views/statisticsCharts/components/commonBarStatisticsCharts.vue
  3. 632 0
      src/views/statisticsCharts/components/commonPieStatisticsCharts.vue
  4. 596 0
      src/views/statisticsCharts/components/newBarStatisticsCharts.vue
  5. 588 0
      src/views/statisticsCharts/components/newPieStatisticsCharts.vue
  6. 595 0
      src/views/statisticsCharts/components/newPieStatisticsChartscpsy.vue
  7. 687 0
      src/views/statisticsCharts/components/statisticsHeader.vue
  8. 452 0
      src/views/statisticsCharts/components/statisticsTabs.vue
  9. 1517 0
      src/views/statisticsCharts/components/tableformbrs.vue
  10. 371 0
      src/views/statisticsCharts/components/tableformcp.vue
  11. 186 0
      src/views/statisticsCharts/components/tableforms.vue
  12. 22 0
      src/views/statisticsCharts/index.vue
  13. 55 0
      src/views/statisticsCharts/mixins/noTerminal.js
  14. 65 0
      src/views/statisticsCharts/mixins/onlyAirline.js
  15. 67 0
      src/views/statisticsCharts/mixins/passengerType.js
  16. 64 0
      src/views/statisticsCharts/views/abnormalBaggageClassificationStatisticsCharts.vue
  17. 26 0
      src/views/statisticsCharts/views/airlineCompany/abnormalBaggageStatisticsCharts.vue
  18. 22 0
      src/views/statisticsCharts/views/airlineCompany/baggageAverageStatisticsCharts.vue
  19. 22 0
      src/views/statisticsCharts/views/airlineCompany/baggagePassengerStatisticsCharts.vue
  20. 44 0
      src/views/statisticsCharts/views/airlineCompany/baggageStatisticsCharts.vue
  21. 26 0
      src/views/statisticsCharts/views/airlineCompany/compensationBaggageStatisticsCharts.vue
  22. 26 0
      src/views/statisticsCharts/views/airlineCompany/compensationStatisticsCharts.vue
  23. 26 0
      src/views/statisticsCharts/views/airlineCompany/complaintBaggageStatisticsCharts.vue
  24. 44 0
      src/views/statisticsCharts/views/airlineCompany/flightStatisticsCharts.vue
  25. 22 0
      src/views/statisticsCharts/views/airlineCompany/specialBaggageStatisticsCharts.vue
  26. 177 0
      src/views/statisticsCharts/views/averagepassengers/averagepassairlineStatisticsCharts.vue
  27. 177 0
      src/views/statisticsCharts/views/averagepassengers/averagepassrouteStatisticsCharts.vue
  28. 195 0
      src/views/statisticsCharts/views/averagepassengers/averagepassterminalStatisticsCharts.vue
  29. 181 0
      src/views/statisticsCharts/views/baggage/airlineStatisticsCharts.vue
  30. 185 0
      src/views/statisticsCharts/views/baggage/baggageAllStatisticsCharts.vue
  31. 183 0
      src/views/statisticsCharts/views/baggage/companyStatisticsCharts.vue
  32. 74 0
      src/views/statisticsCharts/views/baggage/hourStatisticsCharts.vue
  33. 244 0
      src/views/statisticsCharts/views/flight/flightvolumeStatisticsCharts.vue
  34. 227 0
      src/views/statisticsCharts/views/flight/numberairStatisticsCharts.vue
  35. 227 0
      src/views/statisticsCharts/views/flight/volumeofStatisticsCharts.vue
  36. 26 0
      src/views/statisticsCharts/views/flightClassification/baggageClassificationStatisticsCharts.vue
  37. 27 0
      src/views/statisticsCharts/views/flightClassification/flightClassificationStatisticsCharts.vue
  38. 27 0
      src/views/statisticsCharts/views/flightClassification/passengerClassificationStatisticsCharts.vue
  39. 774 0
      src/views/statisticsCharts/views/nodeStatisticsCharts.vue
  40. 177 0
      src/views/statisticsCharts/views/passenger/passengerairlineStatisticsCharts.vue
  41. 177 0
      src/views/statisticsCharts/views/passenger/passengerrouteStatisticsCharts.vue
  42. 195 0
      src/views/statisticsCharts/views/passenger/terminalpassengersStatisticsCharts.vue
  43. 30 0
      src/views/statisticsCharts/views/passengerClassification/abnormalBaggageStatisticsCharts.vue
  44. 29 0
      src/views/statisticsCharts/views/passengerClassification/baggagePassengerStatisticsCharts.vue
  45. 29 0
      src/views/statisticsCharts/views/passengerClassification/baggageStatisticsCharts.vue
  46. 30 0
      src/views/statisticsCharts/views/passengerClassification/compensationBaggageStatisticsCharts.vue
  47. 30 0
      src/views/statisticsCharts/views/passengerClassification/compensationStatisticsCharts.vue
  48. 30 0
      src/views/statisticsCharts/views/passengerClassification/complaintBaggageStatisticsCharts.vue
  49. 30 0
      src/views/statisticsCharts/views/passengerClassification/specialBaggageStatisticsCharts.vue
  50. 110 0
      src/views/statisticsCharts/views/report/Percentageofbaggage.vue
  51. 161 0
      src/views/statisticsCharts/views/report/baggageProportionTable.vue
  52. 68 0
      src/views/statisticsCharts/views/report/reportStatistics.vue
  53. 124 0
      src/views/statisticsCharts/views/report/rfldTable.vue
  54. 124 0
      src/views/statisticsCharts/views/report/scanDataTable.vue
  55. 119 0
      src/views/statisticsCharts/views/report/scanningStatistics.vue
  56. 167 0
      src/views/statisticsCharts/views/report/transferBaggageTable.vue
  57. 268 0
      src/views/statisticsCharts/views/report/transferDirectionTable.vue
  58. 206 0
      src/views/statisticsCharts/views/report/transitTables.vue
  59. 34 0
      src/views/statisticsCharts/views/special/abnormalBaggageClassificationStatisticsCharts.vue
  60. 34 0
      src/views/statisticsCharts/views/special/compensationBaggageClassificationStatisticsCharts.vue
  61. 35 0
      src/views/statisticsCharts/views/special/compensationClassificationStatisticsCharts.vue
  62. 26 0
      src/views/statisticsCharts/views/special/specialBaggageClassificationStatisticsCharts.vue
  63. 51 0
      src/views/statisticsCharts/views/specialbaggageanalysisStatisticsCharts.vue
  64. 142 0
      src/views/statisticsCharts/views/transitTables.vue
  65. 170 0
      src/views/statisticsCharts/views/workloadStatisticsCharts.vue

+ 422 - 0
src/views/statisticsCharts/components/TableDialog.vue

@@ -0,0 +1,422 @@
+<template>
+  <Dialog :flag="flag" width="90%">
+    <div ref="dialog" class="dialog-wrapper" :tabindex="0" @keyup.esc="dialogHide">
+      <div class="title">
+        <span class="title-text">{{ title }}</span>
+        <span class="right">
+          <img class="btn-square btn-shadow" style="position: relative;top:-8px;margin-right: 15px;" src="@/assets/baggage/ic_export.png" title="导出" @click="exportClickHandler" />
+          <i class="icon el-icon-close" style="top: -12px;position: relative;" @click="dialogHide" />
+        </span>
+      </div>
+      <div class="content">
+        <div v-loading="loading" element-loading-text="拼命加载中" element-loading-spinner="el-icon-loading" element-loading-background="rgba(0, 0, 0, 0.8)" class="table-wrapper">
+          <el-table ref="table" height="calc(100vh - 100px - 60px - 10px)" class="table" :data="dealedTableData" border stripe fit show-summary :summary-method="summaryRow" :header-cell-class-name="headerCellClass" :row-class-name="rowClass" :cell-class-name="cellClass" :span-method="spanMethod" @cell-click="cellClickHandler">
+            <el-table-column v-for="column in tableColumns" :key="column.prop" :prop="column.prop" :label="column.label" :width="column.width" :fixed="column.fixed" :formatter="formatter">
+              <template #header>
+                <el-tooltip :content="column.desc || column.label" placement="top">
+                  <TableHeaderCell :label="column.label" :filter-options="tableDataFilters[column.prop]" :filter-values.sync="filterValues[column.prop]" :sortable="column.sortable" :sort-rule.sync="tableDataSortRules[column.prop]" />
+                </el-tooltip>
+              </template>
+            </el-table-column>
+          </el-table>
+        </div>
+      </div>
+    </div>
+  </Dialog>
+</template>
+
+<script>
+import Dialog from '@/layout/components/Dialog/index.vue'
+import TableHeaderCell from '@/components/TableHeaderCell/index.vue'
+import { setTableFilters, exportToExcel } from '@/utils/table'
+import { TempQuery } from '@/api/temp'
+export default {
+  name: 'TableDialog',
+  components: { Dialog, TableHeaderCell },
+  props: {
+    flag: {
+      type: Boolean,
+      require: true,
+    },
+    queryParams: {
+      type: Array,
+      default: () => [],
+    },
+    title: {
+      type: String,
+      default: '标题',
+    },
+    withExport: {
+      type: Boolean,
+      default: true
+    },
+  },
+  data () {
+    return {
+      tableColumns: [
+        {
+          prop: 'flightNO',
+          label: '航班号',
+          desc: '指航班编号',
+          fixed: 'left',
+          filterable: true,
+          sortable: true,
+        },
+        {
+          prop: 'flightDate',
+          label: '航班日期',
+          desc: '指航班计划起飞日期(机票上的静态数据)',
+          fixed: 'left',
+          width: 110,
+          filterable: true,
+          sortable: true,
+        },
+        {
+          prop: 'departureTime',
+          label: '起飞时间',
+          desc: '指航班预计起飞时间,动态数据,仅显示最新结果',
+          width: 150,
+        },
+        {
+          prop: 'sourceAirport',
+          label: '起飞站',
+          desc: '指航班执飞航段的起飞航站,以航站英文三字码显示',
+          filterable: true,
+          sortable: true,
+        },
+        {
+          prop: 'targetAirport',
+          label: '目的地',
+          desc: '指航班执飞航段的目的航站,以航站英文三字码显示',
+          filterable: true,
+          sortable: true,
+        },
+        {
+          prop: 'passengerNameUpcase',
+          label: '旅客姓名',
+          desc: '指旅客姓名的拼音大写',
+          width: 150,
+          filterable: true,
+          sortable: true,
+        },
+        {
+          prop: 'bagSN',
+          label: '行李牌号',
+          desc: '指行李的10位数字行李牌号码',
+          width: 110,
+          filterable: true,
+          sortable: true,
+        },
+        {
+          prop: 'specialType',
+          label: '特殊行李类型',
+          desc: '指有别于普通托运行李的特殊行李分类,包括(装笼动物、机组行李、易碎行李、VIP行李等),参考BSM报文.E项说明',
+          width: 115,
+          filterable: true,
+          sortable: true,
+        },
+        {
+          prop: 'deleted',
+          label: '删除',
+          desc: '指旅客是否取消值机托运,根据BSM报文状态是否有DEL判断,已删除的行李记录为斜体灰色字体',
+          filterable: true,
+          sortable: true,
+        },
+        {
+          prop: 'activated',
+          label: '激活',
+          desc: '指托运行李是否被激活,参照BSM报文.S项说明',
+          filterable: true,
+          sortable: true,
+        },
+        {
+          prop: 'bagWeight',
+          label: '重量',
+          desc: '指托运行李的重量,参照BSM报文.W项说明',
+        },
+        {
+          prop: 'latestStatus',
+          label: '最新状态',
+          desc: '指托运行李的当前查询时间所在的节点状态',
+          width: 110,
+          filterable: true,
+          sortable: true,
+        },
+        {
+          prop: 'bagLocation',
+          label: '最新位置',
+          desc: '指托运行李的当前查询时间所在的节点状态的识读位置代号',
+          width: 110,
+          filterable: true,
+          sortable: true,
+        },
+        {
+          prop: 'U_Device_ID',
+          label: '容器编号',
+          desc: '指集装器ID信息',
+          width: 110,
+          filterable: true,
+          sortable: true,
+        },
+        {
+          prop: 'preFlightNO',
+          label: '中转进航班',
+          desc: '指有中转行李转出的进港航班号',
+          width: 110,
+          filterable: true,
+          sortable: true,
+        },
+        {
+          prop: 'transferFlightNO',
+          label: '中转出航班',
+          desc: '指有中转行李转入的离港航班号',
+          width: 110,
+          filterable: true,
+          sortable: true,
+        },
+      ],
+      tableData: [],
+      tableDataFilters: {},
+      filterValues: {},
+      tableDataSortRules: {},
+      spanArr: [],
+      loading: false,
+    }
+  },
+  computed: {
+    dealedTableData () {
+      const filtered = this.tableData.filter(item => {
+        let flag = true
+        Object.entries(this.filterValues).forEach(([key, arr]) => {
+          if (arr.length && !arr.includes(String(item[key]))) {
+            flag = false
+          }
+        })
+        return flag
+      })
+      const sortRules = Object.entries(this.tableDataSortRules).reduce(
+        (pre, [key, value]) => {
+          if (value) {
+            pre[0].push(key)
+            value = value === 'ascending' ? 'asc' : 'desc'
+            pre[1].push(value)
+          }
+          return pre
+        },
+        [[], []]
+      )
+      return this._.orderBy(filtered, sortRules[0], sortRules[1])
+    },
+  },
+  watch: {
+    flag (val) {
+      if (val) {
+        this.tableData = []
+        this.getTableData()
+        this.$nextTick(() => {
+          this.$refs['dialog']?.focus()
+        })
+      }
+    },
+    dealedTableData: {
+      handler (val) {
+        this.spanArr = []
+        let contactDot = 0
+        val.forEach((item, index, arr) => {
+          if (index === 0) {
+            this.spanArr.push(1)
+          } else {
+            if (
+              item['flightNO'] === arr[index - 1]['flightNO'] &&
+              item['flightDate'] === arr[index - 1]['flightDate'] &&
+              item['passengerNameUpcase'] ===
+              arr[index - 1]['passengerNameUpcase'] &&
+              item['checkInNO'] === arr[index - 1]['checkInNO'] &&
+              item['bagWeight'] === arr[index - 1]['bagWeight']
+            ) {
+              this.spanArr[contactDot] += 1
+              this.spanArr.push(0)
+            } else {
+              this.spanArr.push(1)
+              contactDot = index
+            }
+          }
+        })
+      },
+      deep: true,
+    },
+  },
+  created () {
+    Object.values(this.tableColumns).forEach(
+      ({ prop, filterable, sortable }) => {
+        if (filterable) {
+          this.$set(this.tableDataFilters, prop, [])
+          this.$set(this.filterValues, prop, [])
+        }
+        if (sortable) {
+          this.$set(this.tableDataSortRules, prop, '')
+        }
+      }
+    )
+  },
+  updated () {
+    // table数据更新
+    this.$nextTick(() => {
+      this.$refs.table?.doLayout()
+    })
+  },
+  methods: {
+    dialogHide () {
+      this.$emit('update:flag', false)
+    },
+    spanMethod ({ row, column, rowIndex, columnIndex }) {
+      if (['passengerNameUpcase', 'bagWeight'].includes(column.property)) {
+        const _row = this.spanArr[rowIndex]
+        const _col = _row > 0 ? 1 : 0
+        return {
+          rowspan: _row,
+          colspan: _col,
+        }
+      }
+    },
+    // 给表头单元格加上 ascending 或 descending 使用 element 自带的排序箭头变色
+    headerCellClass ({ row, column, rowIndex, columnIndex }) {
+      const classes = []
+      const rule = this.tableDataSortRules[column.property]
+      if (rule) {
+        classes.push(rule)
+      }
+      return classes.join(' ')
+    },
+    rowClass ({ row, rowIndex }) {
+      const classes = []
+      if (row.deleted === 'DEL') {
+        classes.push('bgl-deleted')
+      }
+      return classes.join(' ')
+    },
+    cellClass ({ row, column, rowIndex, columnIndex }) {
+      const classes = []
+      return classes.join(' ')
+    },
+    cellClickHandler (row, column, cell, event) { },
+    formatter (row, column, cellValue) {
+      switch (column.property) {
+        case 'departureTime':
+          return (cellValue ?? '').replace('T', ' ')
+        case 'deleted':
+          return cellValue == 'DEL' ? cellValue : ''
+        case 'activated':
+          return cellValue == 1 ? '激活' : '未激活'
+        default:
+          return cellValue ?? ''
+      }
+    },
+    // 统计行数
+    summaryRow () {
+      const rowNum = this.dealedTableData.length
+      return ['合计', `共${rowNum}件`]
+    },
+    async getTableData () {
+      this.loading = true
+      try {
+        const {
+          code,
+          returnData: { listValues },
+          message,
+        } = await TempQuery({
+          id: 1844,
+          dataContent: this.queryParams,
+        })
+        if (String(code) !== '0') {
+          throw new Error(message || '获取数据失败')
+        }
+        this.tableData = this._.cloneDeep(listValues)
+        this.tableData = this.tableData.sort((a, b) => Date.parse(a.departureTime) - Date.parse(b.departureTime))
+        setTableFilters(this.tableData, this.tableDataFilters)
+      } catch (error) {
+        this.$message.error(error.message || '失败')
+      }
+      this.loading = false
+    },
+    //导出
+    exportClickHandler () {
+      const table = this.$refs['table'].$el.cloneNode(true)
+      const fileName = `${this.title}.xlsx`
+      exportToExcel(table, `${this.title}`, fileName)
+    }
+  },
+}
+</script>
+
+<style lang="scss" scoped>
+.dialog-wrapper {
+  width: 100%;
+  height: calc(100vh - 100px);
+  .title {
+    display: flex;
+    justify-content: space-between;
+    .icon {
+      margin-right: 10px;
+      font-size: 20px;
+      cursor: pointer;
+      &:hover {
+        background-color: #0003;
+      }
+    }
+  }
+  .content {
+    margin: 0 20px;
+  }
+  ::v-deep .table {
+    width: 100%;
+    .cell {
+      padding: 0;
+      text-align: center;
+      font-size: 14px;
+      font-family: Helvetica, "Microsoft YaHei";
+      letter-spacing: 0;
+    }
+    .cell-click {
+      cursor: pointer;
+      color: #2d7cff;
+      &.cell-clicked {
+        color: purple;
+      }
+    }
+    .el-table__header-wrapper,
+    .el-table__fixed-header-wrapper {
+      .cell {
+        font-weight: bold;
+        color: #101116;
+      }
+
+      .has-gutter {
+        tr {
+          .bgl-huang {
+            background: #fcf0b1;
+          }
+        }
+      }
+    }
+
+    .el-table__body-wrapper,
+    .el-table__fixed-body-wrapper {
+      tr.bgl-deleted {
+        background: #d2d6df;
+        td {
+          background: #d2d6df;
+          font-style: italic;
+        }
+      }
+    }
+
+    .el-table__body tr.hover-row.current-row > td,
+    .el-table__body tr.hover-row.el-table__row--striped.current-row > td,
+    .el-table__body tr.hover-row.el-table__row--striped > td,
+    .el-table__body tr.hover-row > td {
+      background-color: red;
+    }
+  }
+}
+</style>

+ 580 - 0
src/views/statisticsCharts/components/commonBarStatisticsCharts.vue

@@ -0,0 +1,580 @@
+<template>
+  <div class="statstics-wrapper">
+    <div
+      ref="headerWrapper"
+      class="statstics-header"
+    >
+      <StatisticsHeader
+        :title="`${chartsTitle}统计`"
+        :custom-items="customFormItems"
+        @getFormData="getFormData"
+        @export="exportHandler"
+      />
+    </div>
+    <div class="statstics-content">
+      <div
+        id="chart"
+        class="statistics-chart"
+        :style="{ height: chartHeight }"
+      />
+    </div>
+  </div>
+</template>
+
+<script>
+import StatisticsHeader from './statisticsHeader.vue'
+import { TempQuery } from '@/api/temp'
+import { mapGetters } from 'vuex'
+import * as XLSX from 'xlsx'
+import XLSX_STYLE from 'xlsx-style'
+import FileSaver from 'file-saver'
+
+export default {
+  name: 'CommonBarStatisticsCharts',
+  components: { StatisticsHeader },
+  props: {
+    chartsTitle: {
+      type: String,
+      required: true
+    },
+    querySettings: {
+      type: Object,
+      required: true
+    },
+    customFormItems: {
+      type: Array,
+      default: () => []
+    }
+  },
+  data() {
+    return {
+      myChart: null,
+      debounceTime: 300,
+      chartHeight: '70vh',
+      hasChartData: false,
+      seriesKey: 'seriesData',
+      filters: [],
+      tableData: [],
+      params: [],
+      options: {
+        backgroundColor: '#fff',
+        tooltip: {
+          trigger: 'axis',
+          axisPointer: {
+            type: 'cross',
+            crossStyle: {
+              color: '#999'
+            }
+          }
+        },
+        legend: {
+          top: '5%',
+          right: '5%',
+          icon: 'rect',
+          height: 14,
+          itemWidth: 14,
+          itemHeight: 14,
+          itemGap: 30,
+          data: [
+            this.chartsTitle.replace('量', '数量'),
+            // `${this.chartsTitle}量同比`,
+            `${this.chartsTitle}环比`
+          ],
+          textStyle: {
+            fontFamily: 'Helvetica, "Microsoft YaHei"',
+            color: '#101116'
+          }
+        },
+        grid: {
+          top: '15%',
+          left: '5%',
+          right: '5%',
+          bottom: '5%'
+        },
+        xAxis: {
+          data: [],
+          axisLine: {
+            show: true,
+            lineStyle: {
+              color: '#000000'
+            }
+          },
+          axisTick: {
+            show: false // 隐藏X轴刻度
+          },
+          axisLabel: {
+            fontFamily: 'Helvetica, "Microsoft YaHei"',
+            color: '#101116'
+          },
+          axisPointer: {
+            type: 'shadow'
+          }
+        },
+        yAxis: [
+          {
+            min: 0,
+            max: 60000,
+            splitLine: {
+              lineStyle: {
+                type: 'dashed',
+                color: '#B0B3C3',
+                opacity: 0.5
+              }
+            },
+            axisPointer: {
+              label: {
+                formatter: ({ value }) => value.toFixed()
+              }
+            },
+            axisLabel: {
+              fontFamily: 'Helvetica, "Microsoft YaHei"',
+              color: '#101116'
+            }
+          },
+          {
+            min: -0.3,
+            max: 0.5,
+            axisLabel: {
+              formatter: value => (value * 100).toFixed(2) + '%',
+              fontFamily: 'Helvetica, "Microsoft YaHei"',
+              color: '#101116'
+            },
+            axisPointer: {
+              label: {
+                formatter: ({ value }) => (value * 100).toFixed(2) + '%'
+              }
+            },
+            splitLine: {
+              show: false
+            }
+          }
+        ],
+        series: [
+          {
+            name: this.chartsTitle.replace('量', '数量'),
+            type: 'bar',
+            z: 2,
+            itemStyle: {
+              color: '#6682B5'
+            },
+            barWidth: 40,
+            label: {
+              show: true,
+              position: 'top'
+            },
+            data: []
+          },
+          {
+            name: `${this.chartsTitle}同比`,
+            type: 'line',
+            z: 4,
+            yAxisIndex: 1,
+            symbol: 'circle',
+            itemStyle: {
+              color: '#F2B849',
+              borderColor: '#ffffff',
+              borderWidth: 4
+            },
+            lineStyle: {
+              width: 4,
+              color: '#F2B849'
+            },
+            symbolSize: 32,
+            tooltip: {
+              valueFormatter: value => (value * 100).toFixed(2) + '%'
+            },
+            data: []
+          },
+          {
+            name: `${this.chartsTitle}环比`,
+            type: 'line',
+            z: 3,
+            yAxisIndex: 1,
+            symbol: 'circle',
+            itemStyle: {
+              color: '#E33D3D',
+              borderColor: '#ffffff',
+              borderWidth: 4
+            },
+            lineStyle: {
+              width: 4,
+              color: '#E33D3D'
+            },
+            symbolSize: 32,
+            tooltip: {
+              valueFormatter: value => (value * 100).toFixed(2) + '%'
+            },
+            data: []
+          }
+        ]
+      }
+    }
+  },
+  computed: {
+    ...mapGetters(['sidebar'])
+  },
+  watch: {
+    // 监听数据变化 重绘图形
+    options: {
+      handler(obj) {
+        this.myChart.setOption(obj)
+        this.resizeHandler()
+      },
+      deep: true
+    },
+    'sidebar.expand'() {
+      this.setChartHeight()
+    },
+    querySettings: {
+      handler({ seriesKey, filters }) {
+        if (seriesKey) {
+          this.seriesKey = seriesKey
+        }
+        if (filters?.length) {
+          this.filters = filters
+        }
+      },
+      deep: true,
+      immediate: true
+    }
+  },
+  mounted() {
+    this.setChartHeight()
+    this.myChart = this.$echarts.init(document.getElementById('chart'))
+    this.myChart.setOption(this.options)
+    // 监听页面缩放
+    this.debouncedChartHeightSetter = this._.debounce(this.setChartHeight, this.debounceTime)
+    window.addEventListener('resize', this.debouncedChartHeightSetter)
+  },
+  beforeDestroy() {
+    // 销毁实例和移除监听
+    window.removeEventListener('resize', this.debouncedChartHeightSetter)
+    if (this.myChart) {
+      this.myChart.dispose()
+      this.myChart = null
+    }
+  },
+  methods: {
+    resetDatas() {
+      this.hasChartData = false
+      this.options.yAxis[0].max = 60000
+      this.options.xAxis.data = []
+      this.options.series[0].data = []
+      this.options.series[2].data = []
+      this.options.yAxis[1].min = -0.3
+      this.options.yAxis[1].max = 0.5
+    },
+    getFormData(formData) {
+      this.resetDatas()
+
+      let id
+      let params = []
+      if (formData.range === '基地分公司') {
+        if (formData.flightType === '有行李') {
+          id = this.querySettings.withBaggageByArea
+        } else if (formData.baggageType === '不包含DEL') {
+          id = this.querySettings.notDelByArea
+        } else if (formData.passengerType[0] === '要客类型') {
+          id = this.querySettings.importantByArea
+        } else {
+          id = this.querySettings.byArea
+        }
+        params = [formData.interval, formData.area, formData.inOrOut, formData.dateTime[0], formData.dateTime[1]]
+      } else {
+        if (formData.flightType === '有行李') {
+          id = this.querySettings.withBaggageByOther
+        } else if (formData.baggageType === '不包含DEL') {
+          id = this.querySettings.notDelByOther
+        } else if (formData.passengerType[0] === '要客类型') {
+          id = this.querySettings.importantByOther
+        } else {
+          id = this.querySettings.byOther
+        }
+        params = [formData.interval, formData.range, formData.inOrOut, formData.dateTime[0], formData.dateTime[1]]
+        if (formData.airline.length) {
+          params.splice(2, 0, formData.airline)
+        } else if (formData.airport.length) {
+          params.splice(2, 0, formData.airport)
+        } else if (formData.terminal !== '') {
+          params.splice(2, 0, formData.terminal)
+        } else {
+          params.splice(2, 0, '全部')
+        }
+      }
+      if (formData.passengerType.length) {
+        this.filters = [
+          {
+            key: formData.passengerType[0],
+            value: formData.passengerType[1]
+          }
+        ]
+      }
+      this.params = [...params, ...this.filters.map(({ value }) => value)]
+      if (params[2] instanceof Array) {
+        const paramsList = params[2].map(param => [...params.slice(0, 2), param, ...params.slice(3)])
+        this.getMultipleChartsData(id, paramsList)
+      } else {
+        this.getSingleChartsData(id, params)
+      }
+    },
+    async getMultipleChartsData(id, paramsList) {
+      try {
+        const listValuesArray = await Promise.all(paramsList.map(params => this.getChartsData(id, params)))
+        const listValues = listValuesArray.reduce((preValues, currentValues) => {
+          currentValues.forEach(value => {
+            const preValue = preValues.find(preValue => preValue.A === value.A)
+            if (preValue) {
+              preValue[this.seriesKey] += value[this.seriesKey]
+            } else {
+              preValues.push({
+                A: value.A,
+                [this.seriesKey]: value[this.seriesKey]
+              })
+            }
+          })
+          return preValues
+        }, [])
+        this.setChartsData(this._.sortBy(listValues, 'A'))
+      } catch (error) {
+        this.$message.error(error.message)
+      }
+    },
+    async getSingleChartsData(id, params) {
+      try {
+        const listValues = await this.getChartsData(id, params)
+        this.setChartsData(listValues)
+      } catch (error) {
+        this.$message.error(error.message)
+      }
+    },
+    async getChartsData(id, params) {
+      try {
+        const {
+          code,
+          returnData: { listValues },
+          message
+        } = await TempQuery({
+          id,
+          dataContent: params
+        })
+        if (Number(code) === 0) {
+          return listValues
+        } else {
+          return Promise.reject(message || '失败')
+        }
+      } catch (error) {
+        return Promise.reject(error.message || '失败')
+      }
+    },
+    setChartsData(listValues) {
+      const xAxisData = []
+      const yAxisData = [0]
+      const seriesDatas = []
+      const filteredList = listValues.filter(element =>
+        this.filters.every((key, value) => {
+          if (key && value && element[key] !== value) {
+            return false
+          } else {
+            return true
+          }
+        })
+      )
+      if (filteredList.length === 0) {
+        this.$message.info('未查询到对应数据')
+        return
+      }
+      for (let i = 0; i < filteredList.length; i++) {
+        xAxisData.push(filteredList[i].A)
+        seriesDatas.push(filteredList[i][this.seriesKey])
+        if (i > 0) {
+          if (filteredList[i - 1][this.seriesKey] > 0) {
+            yAxisData.push(
+              (filteredList[i][this.seriesKey] - filteredList[i - 1][this.seriesKey]) /
+                filteredList[i - 1][this.seriesKey]
+            )
+          } else {
+            yAxisData.push(0)
+          }
+        }
+      }
+      let max = Math.max(...seriesDatas)
+      max = Math.ceil(max / 10) * 10
+      this.options.yAxis[0].max = max
+      this.options.xAxis.data = xAxisData
+      this.options.series[0].data = seriesDatas
+      this.options.series[2].data = yAxisData
+      this.options.yAxis[1].min = (Math.min(...yAxisData) - 0.1).toFixed(2)
+      this.options.yAxis[1].max = (Math.max(...yAxisData) + 0.1).toFixed(2)
+      this.tableData = [xAxisData, seriesDatas, yAxisData]
+      this.hasChartData = true
+    },
+    setChartHeight() {
+      const topBarHeight = 80
+      const headerBlankHeight = 24
+      const tabsWrapperHeight = 62
+      const headerHeight = this.$refs['headerWrapper'].offsetHeight
+      const footerBlankHeight = 24
+      this.chartHeight = `calc(100vh - ${
+        topBarHeight + headerBlankHeight + tabsWrapperHeight + headerHeight + footerBlankHeight
+      }px)`
+      this.$nextTick(() => {
+        this.resizeHandler()
+      })
+    },
+    resizeHandler() {
+      if (this.myChart) {
+        this.myChart.resize()
+      }
+    },
+    exportHandler() {
+      if (!this.hasChartData) {
+        this.$message.warning('请查询后再进行导出')
+        return
+      }
+      // const myCanvas = this.myChart._dom.querySelectorAll('canvas')[0]
+      // const image = myCanvas.toDataURL('image/png')
+      // const $a = document.createElement('a')
+      // $a.setAttribute('href', image)
+      // $a.setAttribute('download', `${this.chartsTitle}统计.png`)
+      // $a.click()
+
+      // 生成表格数据
+      const xlsxDatas = [['时间', this.chartsTitle.replace('量', '数量'), `${this.chartsTitle}环比`]]
+      const transposition = this.tableData[0].map((col, colIndex) => {
+        return this.tableData.map((row, rowIndex) => {
+          return rowIndex === 2 ? (row[colIndex] * 100).toFixed(2) + '%' : row[colIndex]
+        })
+      })
+      xlsxDatas.push(...transposition)
+      // 添加合计行
+      if (xlsxDatas.length > 2) {
+        const summaryRow = ['合计']
+        const colNum = xlsxDatas[0].length
+        for (let colIndex = 1; colIndex < colNum; colIndex++) {
+          summaryRow[colIndex] = xlsxDatas.reduce((pre, currentRow, rowIndex) => {
+            if (colIndex === 1) {
+              if (rowIndex === 0) {
+                return 0
+              } else {
+                return pre + currentRow[colIndex]
+              }
+            } else {
+              return pre
+            }
+          }, '')
+        }
+        xlsxDatas.push(summaryRow)
+      }
+      // 计算列宽
+      const columnWidths = []
+      xlsxDatas.forEach((row, rowIndex) => {
+        // 计算每一列宽度,考虑换行
+        row.forEach((cell, columnIndex) => {
+          const cellWidth = Math.max(
+            ...cell
+              .toString()
+              .split('\n')
+              .map(cellRow =>
+                cellRow.split('').reduce((pre, curr) => {
+                  const letterSize = curr.charCodeAt(0) > 255 ? 2 : 1
+                  return pre + letterSize
+                }, 0)
+              )
+          )
+          if ((!columnWidths[columnIndex] && cellWidth > 0) || cellWidth > columnWidths[columnIndex]) {
+            columnWidths[columnIndex] = cellWidth
+          }
+        })
+      })
+      // 生成表格
+      const sheet = XLSX.utils.aoa_to_sheet(xlsxDatas)
+      // 添加列宽度
+      sheet['!cols'] = columnWidths.map(width => ({
+        wch: width + 2
+      }))
+      // 样式
+      const borderStyle = {
+        style: 'medium',
+        color: {
+          rgb: 'FFFFFF'
+        }
+      }
+      const reg = /^[A-Z]+([\d]+$)/
+      for (const key in sheet) {
+        const match = key.match(reg)
+        if (match) {
+          const rowIndex = match[1]
+          let cellStyle = {
+            alignment: {
+              horizontal: 'center',
+              vertical: 'center',
+              wrapText: true
+            }
+          }
+          if (Number(rowIndex) === 1) {
+            cellStyle = {
+              ...cellStyle,
+              border: {
+                top: borderStyle,
+                right: borderStyle,
+                bottom: borderStyle,
+                left: borderStyle
+              },
+              font: {
+                color: {
+                  rgb: 'FFFFFF'
+                }
+              },
+              fill: {
+                fgColor: {
+                  rgb: '3366FF'
+                }
+              }
+            }
+          } else {
+            cellStyle.alignment.horizontal = 'left'
+          }
+          const cellValue = sheet[key].v
+          const isNumber = /^[^0]/.test(cellValue) && !isNaN(parseFloat(cellValue)) && isFinite(cellValue)
+          const isPercentage = /^[0-9]+(\.[0-9]+){0,1}\%$/.test(cellValue)
+          if (isNumber) {
+            sheet[key] = {
+              ...sheet[key],
+              t: 'n',
+              z: '0',
+              v: Number(cellValue)
+            }
+          }
+          if (isPercentage) {
+            sheet[key] = {
+              ...sheet[key],
+              t: 'n',
+              z: '0.00%',
+              v: parseFloat(cellValue)
+            }
+          }
+          sheet[key].s = cellStyle
+        }
+      }
+      // 表格数据转换
+      const workBook = XLSX.utils.book_new()
+      XLSX.utils.book_append_sheet(workBook, sheet, this.chartsTitle)
+      const tableWrite = XLSX_STYLE.write(workBook, {
+        bookType: 'xlsx',
+        bookSST: true,
+        type: 'buffer',
+        cellStyles: true
+      })
+      // 下载表格
+      const fileName = `${this.chartsTitle}统计-${this.params.join('-')}.xlsx`
+      FileSaver.saveAs(new Blob([tableWrite], { type: 'application/octet-stream' }), fileName)
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.statistics-chart {
+  width: 100%;
+}
+</style>

+ 632 - 0
src/views/statisticsCharts/components/commonPieStatisticsCharts.vue

@@ -0,0 +1,632 @@
+<template>
+  <div
+    v-loading="loading"
+    element-loading-text="拼命加载中"
+    element-loading-spinner="el-icon-loading"
+    element-loading-background="rgba(0, 0, 0, 0.8)"
+    class="statstics-wrapper"
+  >
+    <div
+      ref="headerWrapper"
+      class="statstics-header"
+    >
+      <StatisticsHeader
+        :title="`${chartsTitle}统计`"
+        :custom-items="customFormItems"
+        @getFormData="getFormData"
+        @export="exportHandler"
+      />
+    </div>
+    <div class="statstics-content">
+      <div
+        id="chart"
+        class="statistics-chart"
+        :style="{ height: chartHeight }"
+      />
+    </div>
+  </div>
+</template>
+
+<script>
+import StatisticsHeader from './statisticsHeader.vue'
+import { TempQuery } from '@/api/temp'
+import { mapGetters } from 'vuex'
+import * as XLSX from 'xlsx'
+import XLSX_STYLE from 'xlsx-style'
+import FileSaver from 'file-saver'
+
+export default {
+  name: 'CommonBarStatisticsCharts',
+  components: { StatisticsHeader },
+  props: {
+    chartsTitle: {
+      type: String,
+      required: true,
+    },
+    querySettings: {
+      type: Object,
+      required: true,
+    },
+    categories: {
+      type: Array,
+      required: true,
+    },
+    customFormItems: {
+      type: Array,
+      default: () => [],
+    },
+    pieTitle: {
+      type: String,
+      default: '总件数',
+    },
+    onlyAirline: {
+      type: Boolean,
+    },
+  },
+  data() {
+    return {
+      loading: false,
+      myChart: null,
+      debounceTime: 300,
+      chartHeight: '70vh',
+      hasChartData: false,
+      tableData: [],
+      params: [],
+      options: {
+        backgroundColor: '#ffffff',
+        tooltip: {
+          trigger: 'item',
+        },
+        title: {
+          text: '',
+          // 副标题
+          subtext: '0',
+          // 主副标题间距
+          itemGap: 24,
+          x: 'left',
+          y: 'center',
+          left: '30%',
+          top: '40%',
+          textAlign: 'center',
+          // 主标题样式
+          textStyle: {
+            fontSize: '48',
+            color: '#ffffff',
+            fontWeight: 'bold',
+            fontFamily: 'Microsoft YaHei',
+          },
+          // 副标题样式
+          subtextStyle: {
+            fontSize: '80',
+            color: '#ffffff',
+            fontWeight: 'bold',
+          },
+        },
+        legend: {
+          show: true,
+          left: '60%',
+          x: 'right',
+          y: 'center',
+          icon: 'rect',
+          itemWidth: 20,
+          itemHeight: 20,
+          formatter: name => this.legendFormatter(name),
+          textStyle: {
+            backgroundColor: 'transparent',
+            lineHeight: 0,
+            rich: {
+              chartsTitle: {
+                width: 200,
+                lineHeight: 100,
+                fontSize: 32,
+                fontFamily: 'Microsoft YaHei',
+                fontWeight: 'bold',
+                color: '#101116',
+                padding: [0, 1000, 0, -20],
+              },
+              name: {
+                fontSize: 20,
+                fontFamily: 'Microsoft YaHei',
+                fontWeight: 'bold',
+                color: '#101116',
+                lineHeight: 100,
+              },
+              label: {
+                fontSize: 16,
+                fontFamily: 'Microsoft YaHei',
+                color: '#101116',
+              },
+              value: {
+                width: 96,
+                fontSize: 16,
+                fontFamily: 'Helvetica',
+                fontWeight: 'bold',
+                color: '#101116',
+              },
+              ratio: {
+                width: 80,
+                fontSize: 16,
+                fontFamily: 'Helvetica',
+                fontWeight: 'bold',
+                color: '#101116',
+              },
+              wrap: {
+                padding: [0, 40, 0, 0],
+              },
+            },
+          },
+          selected: {
+            [this.chartsTitle]: false,
+          },
+        },
+        series: [
+          {
+            name: '',
+            type: 'pie',
+            left: '30%',
+            width: 560,
+            height: 560,
+            center: [0, '60%'],
+            radius: ['60%', '90%'],
+            avoidLabelOverlap: false,
+            label: {
+              show: false,
+              position: 'center',
+            },
+            emphasis: {
+              label: {
+                show: false,
+                fontSize: '40',
+                fontWeight: 'bold',
+              },
+            },
+            labelLine: {
+              show: false,
+            },
+            data: [],
+          },
+          {
+            name: '总数',
+            type: 'pie',
+            left: '30%',
+            width: 560,
+            height: 560,
+            center: [0, '60%'],
+            radius: ['0%', '50%'],
+            avoidLabelOverlap: false,
+            itemStyle: {
+              normal: {
+                color: '#101116',
+              },
+            },
+            label: {
+              show: false,
+              position: 'center',
+            },
+            // 自定义中心内容的话需要把这个关闭
+            emphasis: {
+              label: {
+                show: false,
+              },
+            },
+            labelLine: {
+              show: false,
+            },
+            data: [],
+          },
+        ],
+      },
+      totalCount: [{ value: 0 }],
+      categoryDatas: [],
+      categoryKey: 'specialnum',
+      seriesKey: 'special',
+    }
+  },
+  computed: {
+    ...mapGetters(['sidebar']),
+  },
+  watch: {
+    pieTitle: {
+      handler(val) {
+        this.options.title.text = val
+      },
+      immediate: true,
+    },
+    // 监听数据变化 重绘图形
+    options: {
+      handler(obj) {
+        this.myChart.setOption(obj)
+        this.resizeHandler()
+      },
+      deep: true,
+    },
+    categories: {
+      handler(arr) {
+        this.categoryDatas = arr.map(categoryName => ({
+          name: categoryName,
+          value: 0,
+        }))
+        this.categoryDatas.unshift({
+          name: this.chartsTitle,
+          value: null,
+        })
+      },
+      deep: true,
+      immediate: true,
+    },
+    querySettings: {
+      handler({ categoryKey, seriesKey }) {
+        if (seriesKey) {
+          this.seriesKey = seriesKey
+        }
+        if (categoryKey) {
+          this.categoryKey = categoryKey
+        }
+      },
+      deep: true,
+      immediate: true,
+    },
+    'sidebar.expand'() {
+      this.setChartHeight()
+    },
+  },
+  mounted() {
+    this.setChartHeight()
+    this.myChart = this.$echarts.init(document.getElementById('chart'))
+    this.options.series[0].data = this.categoryDatas
+    this.options.legend.data = this.categoryDatas.map(({ name }, index) => {
+      if (index === 0) {
+        return {
+          name,
+          icon: 'none',
+        }
+      } else {
+        return {
+          name,
+        }
+      }
+    })
+    this.options.series[1].data = this.totalCount
+    this.myChart.setOption(this.options)
+    this.myChart.on('legendselectchanged', ({ name }) => {
+      if (name === this.chartsTitle) {
+        this.myChart.dispatchAction({
+          type: 'legendUnSelect',
+          name,
+        })
+      }
+    })
+    // 监听页面缩放
+    this.debouncedChartHeightSetter = this._.debounce(
+      this.setChartHeight,
+      this.debounceTime
+    )
+    window.addEventListener('resize', this.debouncedChartHeightSetter)
+  },
+  beforeDestroy() {
+    // 销毁实例和移除监听
+    window.removeEventListener('resize', this.debouncedChartHeightSetter)
+    if (this.myChart) {
+      this.myChart.dispose()
+      this.myChart = null
+    }
+  },
+  methods: {
+    legendFormatter(name) {
+      const index = this.categoryDatas.findIndex(
+        category => category.name === name
+      )
+      if (index === 0) {
+        return `{chartsTitle|${name}}`
+      } else {
+        const value = this.categoryDatas[index].value
+        const ratio =
+          value && this.totalCount.value
+            ? ((value / this.totalCount.value) * 100).toFixed(2) + '%'
+            : '0%'
+        const richString = `{name|${name}}\n{label|数量:}{value|${value}}{label|占比:}{ratio|${ratio}}`
+        return index % 2 ? richString + '{wrap| }' : richString
+      }
+    },
+    resetDatas() {
+      this.hasChartData = false
+      this.categoryDatas.forEach(category => {
+        category && (category.value = 0)
+      })
+      this.options.title.subtext = '0'
+      this.options.series[1].data[0].value = 0
+    },
+    getFormData(formData) {
+      this.resetDatas()
+
+      let id
+      let params = []
+
+      if (this.onlyAirline) {
+        if (formData.range === '航线') {
+          id = this.querySettings.byAirline
+          params = [
+            formData.airline,
+            formData.dateTime[0],
+            formData.dateTime[1],
+          ]
+        } else {
+          id = this.querySettings.all
+          params = [formData.dateTime[0], formData.dateTime[1]]
+        }
+      } else {
+        if (formData.range === '基地分公司') {
+          id = this.querySettings.byArea
+          params = [
+            formData.interval,
+            formData.area,
+            formData.inOrOut,
+            formData.dateTime[0],
+            formData.dateTime[1],
+          ]
+        } else {
+          id = this.querySettings.byOther
+          params = [
+            formData.interval,
+            formData.range,
+            formData.inOrOut,
+            formData.dateTime[0],
+            formData.dateTime[1],
+          ]
+          if (formData.airline.length) {
+            params.splice(2, 0, formData.airline)
+          } else if (formData.airport.length) {
+            params.splice(2, 0, formData.airport)
+          } else if (formData.terminal !== '') {
+            params.splice(2, 0, formData.terminal)
+          } else {
+            params.splice(2, 0, '全部')
+          }
+        }
+      }
+      this.params = params
+      if (params[0] instanceof Array) {
+        const paramsList = params[0].map(param => [param, ...params.slice(1)])
+        this.getMultipleChartsData(id, paramsList)
+      } else if (params[2] instanceof Array) {
+        const paramsList = params[2].map(param => [
+          ...params.slice(0, 2),
+          param,
+          ...params.slice(3),
+        ])
+        this.getMultipleChartsData(id, paramsList)
+      } else {
+        this.getSingleChartsData(id, params)
+      }
+    },
+    async getMultipleChartsData(id, paramsList) {
+      this.loading = true
+      try {
+        const listValuesArray = await Promise.all(
+          paramsList.map(params => this.getChartsData(id, params))
+        )
+        this.tableData = listValuesArray.flat()
+        const listValues = listValuesArray.reduce(
+          (preValues, currentValues) => {
+            currentValues.forEach(value => {
+              const preValue = preValues.find(
+                preValue =>
+                  preValue.A === value.A &&
+                  preValue[this.categoryKey] === value[this.categoryKey]
+              )
+              if (preValue) {
+                preValue[this.seriesKey] += value[this.seriesKey]
+              } else {
+                preValues.push({
+                  A: value.A,
+                  [this.categoryKey]: value[this.categoryKey],
+                  [this.seriesKey]: value[this.seriesKey],
+                })
+              }
+            })
+            return preValues
+          },
+          []
+        )
+        // console.log(listValues)
+
+        this.setChartsData(this._.sortBy(listValues, 'A'))
+      } catch (error) {
+        this.$message.error(error.message)
+      }
+      this.loading = false
+    },
+    async getSingleChartsData(id, params) {
+      this.loading = true
+      try {
+        const listValues = await this.getChartsData(id, params)
+        this.tableData = listValues
+        this.setChartsData(listValues)
+      } catch (error) {
+        this.$message.error(error.message)
+      }
+      this.loading = false
+    },
+    async getChartsData(id, params) {
+      try {
+        const {
+          code,
+          returnData: { listValues },
+          message,
+        } = await TempQuery({
+          id,
+          dataContent: params,
+        })
+        if (Number(code) === 0) {
+          return listValues
+        } else {
+          return Promise.reject(message || '失败')
+        }
+      } catch (error) {
+        return Promise.reject(error.message || '失败')
+      }
+    },
+    setChartsData(listValues) {
+      if (listValues.length === 0) {
+        this.$message.info('未查询到对应数据')
+        return
+      }
+      let totalCount = 0
+      listValues.forEach(element => {
+        this.categoryDatas.forEach(category => {
+          if (element[this.categoryKey]?.includes(category.name)) {
+            category.value += element[this.seriesKey]
+          }
+        })
+        totalCount += element[this.seriesKey]
+      })
+      this.options.title.subtext = totalCount.toString()
+      this.totalCount.value = totalCount
+      this.hasChartData = true
+    },
+    setChartHeight() {
+      const topBarHeight = 80
+      const headerBlankHeight = 24
+      const tabsWrapperHeight = 62
+      const headerHeight = this.$refs['headerWrapper'].offsetHeight
+      const footerBlankHeight = 24
+      this.chartHeight = `calc(100vh - ${
+        topBarHeight +
+        headerBlankHeight +
+        tabsWrapperHeight +
+        headerHeight +
+        footerBlankHeight
+      }px)`
+      this.$nextTick(() => {
+        this.resizeHandler()
+      })
+    },
+    resizeHandler() {
+      if (this.myChart) {
+        this.myChart.resize()
+      }
+    },
+    exportHandler() {
+      if (!this.hasChartData) {
+        this.$message.warning('请查询后再进行导出')
+        return
+      }
+      // const myCanvas = this.myChart._dom.querySelectorAll('canvas')[0]
+      // const image = myCanvas.toDataURL('image/png')
+      // const $a = document.createElement('a')
+      // $a.setAttribute('href', image)
+      // $a.setAttribute('download', `${this.chartsTitle}统计.png`)
+      // $a.click()
+
+      const xlsxDatas = [['时间', '位置', '分类', '数量', '占比']]
+      xlsxDatas.push(
+        ...this.tableData.map(element => [
+          element['A'],
+          element['location'],
+          element[this.categoryKey],
+          element[this.seriesKey],
+          ((element[this.seriesKey] / this.totalCount.value) * 100).toFixed(2) +
+            '%',
+        ])
+      )
+      xlsxDatas.push(['合计', '', '', this.totalCount.value, ''])
+      // 计算列宽
+      const columnWidths = []
+      xlsxDatas.forEach((row, rowIndex) => {
+        // 计算每一列宽度,考虑换行
+        row.forEach((cell, columnIndex) => {
+          const cellWidth = Math.max(
+            ...cell
+              .toString()
+              .split('\n')
+              .map(cellRow =>
+                cellRow.split('').reduce((pre, curr) => {
+                  const letterSize = curr.charCodeAt(0) > 255 ? 2 : 1
+                  return pre + letterSize
+                }, 0)
+              )
+          )
+          if (
+            (!columnWidths[columnIndex] && cellWidth > 0) ||
+            cellWidth > columnWidths[columnIndex]
+          ) {
+            columnWidths[columnIndex] = cellWidth
+          }
+        })
+      })
+      // 生成表格
+      const sheet = XLSX.utils.aoa_to_sheet(xlsxDatas)
+      // 添加列宽度
+      sheet['!cols'] = columnWidths.map(width => ({
+        wch: width + 2,
+      }))
+      // 样式
+      const borderStyle = {
+        style: 'medium',
+        color: {
+          rgb: 'FFFFFF',
+        },
+      }
+      const reg = /^[A-Z]+([\d]+$)/
+      for (const key in sheet) {
+        const match = reg.test(key)
+        if (match) {
+          const rowIndex = reg.exec(key)[1]
+          let cellStyle = {
+            alignment: {
+              horizontal: 'center',
+              vertical: 'center',
+              wrapText: true,
+            },
+          }
+          if (Number(rowIndex) === 1) {
+            cellStyle = {
+              ...cellStyle,
+              border: {
+                top: borderStyle,
+                right: borderStyle,
+                bottom: borderStyle,
+                left: borderStyle,
+              },
+              font: {
+                color: {
+                  rgb: 'FFFFFF',
+                },
+              },
+              fill: {
+                fgColor: {
+                  rgb: '3366FF',
+                },
+              },
+            }
+          } else {
+            cellStyle.alignment.horizontal = 'left'
+          }
+          sheet[key].s = cellStyle
+        }
+      }
+      // 表格数据转换
+      const workBook = XLSX.utils.book_new()
+      XLSX.utils.book_append_sheet(workBook, sheet, this.chartsTitle)
+      const tableWrite = XLSX_STYLE.write(workBook, {
+        bookType: 'xlsx',
+        bookSST: true,
+        type: 'buffer',
+        cellStyles: true,
+      })
+      // 下载表格
+      const fileName = `${this.chartsTitle}统计-${this.params.join('-')}.xlsx`
+      FileSaver.saveAs(
+        new Blob([tableWrite], { type: 'application/octet-stream' }),
+        fileName
+      )
+    },
+  },
+}
+</script>
+
+<style lang="scss" scoped>
+.statistics-chart {
+  width: 100%;
+}
+</style>

+ 596 - 0
src/views/statisticsCharts/components/newBarStatisticsCharts.vue

@@ -0,0 +1,596 @@
+<template>
+  <div
+    v-loading="loading"
+    element-loading-text="拼命加载中"
+    element-loading-spinner="el-icon-loading"
+    element-loading-background="rgba(0, 0, 0, 0.8)"
+    class="statstics-wrapper"
+  >
+    <div
+      ref="headerWrapper"
+      class="statstics-header"
+    >
+      <StatisticsHeader
+        :title="`${chartsTitle}统计`"
+        :custom-items="customFormItems"
+        :items="formItems"
+        :data="formData"
+        @getFormData="getFormData"
+        @export="exportHandler"
+      />
+    </div>
+    <div class="statstics-content">
+      <div
+        id="chart"
+        class="statistics-chart"
+        :style="{ height: chartHeight }"
+      />
+    </div>
+  </div>
+</template>
+
+<script>
+import StatisticsHeader from './statisticsHeader.vue'
+import { TempQuery } from '@/api/temp'
+import { mapGetters } from 'vuex'
+import * as XLSX from 'xlsx'
+import XLSX_STYLE from 'xlsx-style'
+import FileSaver from 'file-saver'
+
+export default {
+  name: 'CommonBarStatisticsCharts',
+  components: { StatisticsHeader },
+  props: {
+    chartsTitle: {
+      type: String,
+      required: true,
+    },
+    rol: {
+      type: String,
+      default: () => null,
+    },
+    querySettings: {
+      type: Object,
+      required: true,
+    },
+    customFormItems: {
+      type: Array,
+      default: () => [],
+    },
+    formItems: {
+      type: Array,
+    },
+    formData: {
+      type: Object,
+      required: true,
+    },
+  },
+  data() {
+    return {
+      loading: false,
+      myChart: null,
+      debounceTime: 300,
+      chartHeight: '70vh',
+      hasChartData: false,
+      seriesKey: 'seriesData',
+      xAxisKey: 'flight_date',
+      filters: [],
+      tableData: [],
+      params: [],
+      options: {
+        backgroundColor: '#fff',
+        tooltip: {
+          trigger: 'axis',
+          axisPointer: {
+            type: 'cross',
+            crossStyle: {
+              color: '#999',
+            },
+          },
+        },
+        legend: {
+          top: '5%',
+          right: '5%',
+          icon: 'rect',
+          height: 14,
+          itemWidth: 14,
+          itemHeight: 14,
+          itemGap: 30,
+          data: [
+            this.chartsTitle.replace('量', '数量'),
+            // `${this.chartsTitle}量同比`,
+            `${this.chartsTitle}环比`,
+          ],
+          textStyle: {
+            fontFamily: 'Helvetica, "Microsoft YaHei"',
+            color: '#101116',
+          },
+        },
+        grid: {
+          top: '15%',
+          left: '5%',
+          right: '5%',
+          bottom: '5%',
+        },
+        xAxis: {
+          data: [],
+          axisLine: {
+            show: true,
+            lineStyle: {
+              color: '#000000',
+            },
+          },
+          axisTick: {
+            show: false, // 隐藏X轴刻度
+          },
+          axisLabel: {
+            fontFamily: 'Helvetica, "Microsoft YaHei"',
+            color: '#101116',
+          },
+          axisPointer: {
+            type: 'shadow',
+          },
+        },
+        yAxis: [
+          {
+            min: 0,
+            max: 60000,
+            splitLine: {
+              lineStyle: {
+                type: 'dashed',
+                color: '#B0B3C3',
+                opacity: 0.5,
+              },
+            },
+            axisPointer: {
+              label: {
+                formatter: ({ value }) => value.toFixed(),
+              },
+            },
+            axisLabel: {
+              fontFamily: 'Helvetica, "Microsoft YaHei"',
+              color: '#101116',
+            },
+          },
+          {
+            min: -0.3,
+            max: 0.5,
+            axisLabel: {
+              formatter: value => (value * 100).toFixed(2) + '%',
+              fontFamily: 'Helvetica, "Microsoft YaHei"',
+              color: '#101116',
+            },
+            axisPointer: {
+              label: {
+                formatter: ({ value }) => (value * 100).toFixed(2) + '%',
+              },
+            },
+            splitLine: {
+              show: false,
+            },
+          },
+        ],
+        series: [
+          {
+            name: this.chartsTitle.replace('量', '数量'),
+            type: 'bar',
+            z: 2,
+            itemStyle: {
+              color: '#6682B5',
+            },
+            barWidth: 40,
+            label: {
+              show: true,
+              position: 'top',
+            },
+            data: [],
+          },
+          {
+            name: `${this.chartsTitle}同比`,
+            type: 'line',
+            z: 4,
+            yAxisIndex: 1,
+            symbol: 'circle',
+            itemStyle: {
+              color: '#F2B849',
+              borderColor: '#ffffff',
+              borderWidth: 4,
+            },
+            lineStyle: {
+              width: 4,
+              color: '#F2B849',
+            },
+            symbolSize: 32,
+            tooltip: {
+              valueFormatter: value => (value * 100).toFixed(2) + '%',
+            },
+            data: [],
+          },
+          {
+            name: `${this.chartsTitle}环比`,
+            type: 'line',
+            z: 3,
+            yAxisIndex: 1,
+            symbol: 'circle',
+            itemStyle: {
+              color: '#E33D3D',
+              borderColor: '#ffffff',
+              borderWidth: 4,
+            },
+            lineStyle: {
+              width: 4,
+              color: '#E33D3D',
+            },
+            symbolSize: 32,
+            tooltip: {
+              valueFormatter: value => (value * 100).toFixed(2) + '%',
+            },
+            data: [],
+          },
+        ],
+      },
+      admin: {},
+    }
+  },
+  computed: {
+    ...mapGetters(['sidebar']),
+  },
+  watch: {
+    // 监听数据变化 重绘图形
+    options: {
+      handler(obj) {
+        this.myChart.setOption(obj)
+        this.resizeHandler()
+      },
+      deep: true,
+    },
+    'sidebar.expand'() {
+      this.setChartHeight()
+    },
+    querySettings: {
+      handler({ seriesKey, filters, xAxisKey }) {
+        if (seriesKey) {
+          this.seriesKey = seriesKey
+        }
+        if (xAxisKey) {
+          this.xAxisKey = xAxisKey
+        }
+        if (filters?.length) {
+          this.filters = filters
+        }
+      },
+      deep: true,
+      immediate: true,
+    },
+  },
+  mounted() {
+    this.setChartHeight()
+    this.myChart = this.$echarts.init(document.getElementById('chart'))
+    this.myChart.setOption(this.options)
+    // 监听页面缩放
+    this.debouncedChartHeightSetter = this._.debounce(
+      this.setChartHeight,
+      this.debounceTime
+    )
+    window.addEventListener('resize', this.debouncedChartHeightSetter)
+  },
+  beforeDestroy() {
+    // 销毁实例和移除监听
+    window.removeEventListener('resize', this.debouncedChartHeightSetter)
+    if (this.myChart) {
+      this.myChart.dispose()
+      this.myChart = null
+    }
+  },
+  methods: {
+    resetDatas() {
+      this.hasChartData = false
+      this.options.yAxis[0].max = 60000
+      this.options.xAxis.data = []
+      this.options.series[0].data = []
+      this.options.series[2].data = []
+      this.options.yAxis[1].min = -0.3
+      this.options.yAxis[1].max = 0.5
+    },
+    getFormData(formData) {
+      this.resetDatas()
+      let params = {}
+      params = JSON.parse(JSON.stringify(formData))
+      params.fd1 = formData.dateTime[0]
+      params.fd2 = formData.dateTime[1]
+      delete params.dateTime
+      this.admin = JSON.parse(JSON.stringify(params))
+      delete params.baggageType
+      this.getSingleChartsData(this.querySettings.serviceid, params)
+    },
+    async getMultipleChartsData(id, paramsList) {
+      this.loading = true
+      try {
+        const listValuesArray = await Promise.all(
+          paramsList.map(params => this.getChartsData(id, params))
+        )
+        const listValues = listValuesArray.reduce(
+          (preValues, currentValues) => {
+            currentValues.forEach(value => {
+              const preValue = preValues.find(
+                preValue => preValue.A === value.A
+              )
+              if (preValue) {
+                preValue[this.seriesKey] += value[this.seriesKey]
+              } else {
+                preValues.push({
+                  A: value.A,
+                  [this.seriesKey]: value[this.seriesKey],
+                })
+              }
+            })
+            return preValues
+          },
+          []
+        )
+        this.setChartsData(this._.sortBy(listValues, 'A'))
+      } catch (error) {
+        this.$message.error(error.message)
+      }
+      this.loading = false
+    },
+    async getSingleChartsData(id, params) {
+      this.loading = true
+      try {
+        const listValues = await this.getChartsData(id, params)
+        this.setChartsData(JSON.parse(listValues))
+      } catch (error) {
+        this.$message.error(error.message)
+      }
+      this.loading = false
+    },
+    async getChartsData(serviceid, params) {
+      try {
+        const { code, returnData, message } = await TempQuery({
+          serviceid,
+          datacontent: [{filter:params}],
+          event: '0',
+        })
+        if (Number(code) === 0) {
+          return returnData.listValues || returnData
+        } else {
+          return Promise.reject(message || '失败')
+        }
+      } catch (error) {
+        return Promise.reject(error.message || '失败')
+      }
+    },
+    setChartsData(listValues) {
+      const xAxisData = []
+      const yAxisData = [0]
+      const seriesDatas = []
+      let filteredList = []
+      if (listValues && listValues.length) {
+        filteredList = listValues.filter(element =>
+          this.filters.every((key, value) => {
+            if (key && value && element[key] !== value) {
+              return false
+            } else {
+              return true
+            }
+          })
+        )
+      }
+      if (filteredList.length === 0) {
+        this.$message.info('未查询到对应数据')
+        return
+      }
+      if (this.admin.io === '进港') {
+        this.seriesKey = 'in_num'
+      } else if (this.admin.io === '离港') {
+        this.seriesKey = 'out_num'
+      } else if (this.admin.io === '中转') {
+        this.seriesKey = 'trans_num'
+      } else if (this.admin.baggageType === '正常') {
+        this.seriesKey = 'bag_num'
+      } else if (this.admin.baggageType === '异常') {
+        this.seriesKey = 'exception_num'
+      }else if (this.rol){
+        this.seriesKey = this.rol
+      }
+      for (let i = 0; i < filteredList.length; i++) {
+        xAxisData.push(filteredList[i][this.xAxisKey])
+        seriesDatas.push(filteredList[i][this.seriesKey])
+        if (i > 0) {
+          if (filteredList[i - 1][this.seriesKey] > 0) {
+            yAxisData.push(
+              (filteredList[i][this.seriesKey] -
+                filteredList[i - 1][this.seriesKey]) /
+                filteredList[i - 1][this.seriesKey]
+            )
+          } else {
+            yAxisData.push(0)
+          }
+        }
+      }
+      let max = Math.max(...seriesDatas)
+      max = Math.ceil(max / 10) * 10
+      this.options.yAxis[0].max = max
+      this.options.xAxis.data = xAxisData
+      this.options.series[0].data = seriesDatas
+      this.options.series[2].data = yAxisData
+      this.options.yAxis[1].min = (Math.min(...yAxisData) - 0.1).toFixed(2)
+      this.options.yAxis[1].max = (Math.max(...yAxisData) + 0.1).toFixed(2)
+      this.tableData = [xAxisData, seriesDatas, yAxisData]
+      this.hasChartData = true
+    },
+    setChartHeight() {
+      const topBarHeight = 80
+      const headerBlankHeight = 24
+      const tabsWrapperHeight = 62
+      const headerHeight = this.$refs['headerWrapper'].offsetHeight
+      const footerBlankHeight = 24
+      this.chartHeight = `calc(100vh - ${
+        topBarHeight +
+        headerBlankHeight +
+        tabsWrapperHeight +
+        headerHeight +
+        footerBlankHeight
+      }px)`
+      this.$nextTick(() => {
+        this.resizeHandler()
+      })
+    },
+    resizeHandler() {
+      if (this.myChart) {
+        this.myChart.resize()
+      }
+    },
+    exportHandler() {
+      if (!this.hasChartData) {
+        this.$message.warning('请查询后再进行导出')
+        return
+      }
+      // const myCanvas = this.myChart._dom.querySelectorAll('canvas')[0]
+      // const image = myCanvas.toDataURL('image/png')
+      // const $a = document.createElement('a')
+      // $a.setAttribute('href', image)
+      // $a.setAttribute('download', `${this.chartsTitle}统计.png`)
+      // $a.click()
+
+      // 生成表格数据
+      const xlsxDatas = [
+        [
+          '时间',
+          this.chartsTitle.replace('量', '数量'),
+          `${this.chartsTitle}环比`,
+        ],
+      ]
+      const transposition = this.tableData[0].map((col, colIndex) => {
+        return this.tableData.map((row, rowIndex) => {
+          return rowIndex === 2
+            ? (row[colIndex] * 100).toFixed(2) + '%'
+            : row[colIndex]
+        })
+      })
+      xlsxDatas.push(...transposition)
+      // 添加合计行
+      if (xlsxDatas.length > 2) {
+        const summaryRow = ['合计']
+        const colNum = xlsxDatas[0].length
+        for (let colIndex = 1; colIndex < colNum; colIndex++) {
+          summaryRow[colIndex] = xlsxDatas.reduce(
+            (pre, currentRow, rowIndex) => {
+              if (colIndex === 1) {
+                if (rowIndex === 0) {
+                  return 0
+                } else {
+                  return pre + currentRow[colIndex]
+                }
+              } else {
+                return pre
+              }
+            },
+            ''
+          )
+        }
+        xlsxDatas.push(summaryRow)
+      }
+      // 计算列宽
+      const columnWidths = []
+      xlsxDatas.forEach((row, rowIndex) => {
+        // 计算每一列宽度,考虑换行
+        row.forEach((cell, columnIndex) => {
+          const cellWidth = Math.max(
+            ...cell
+              .toString()
+              .split('\n')
+              .map(cellRow =>
+                cellRow.split('').reduce((pre, curr) => {
+                  const letterSize = curr.charCodeAt(0) > 255 ? 2 : 1
+                  return pre + letterSize
+                }, 0)
+              )
+          )
+          if (
+            (!columnWidths[columnIndex] && cellWidth > 0) ||
+            cellWidth > columnWidths[columnIndex]
+          ) {
+            columnWidths[columnIndex] = cellWidth
+          }
+        })
+      })
+      // 生成表格
+      const sheet = XLSX.utils.aoa_to_sheet(xlsxDatas)
+      // 添加列宽度
+      sheet['!cols'] = columnWidths.map(width => ({
+        wch: width + 2,
+      }))
+      // 样式
+      const borderStyle = {
+        style: 'medium',
+        color: {
+          rgb: 'FFFFFF',
+        },
+      }
+      const reg = /^[A-Z]+([\d]+$)/
+      for (const key in sheet) {
+        const match = reg.test(key)
+        if (match) {
+          const rowIndex = reg.exec(key)[1]
+          let cellStyle = {
+            alignment: {
+              horizontal: 'center',
+              vertical: 'center',
+              wrapText: true,
+            },
+          }
+          if (Number(rowIndex) === 1) {
+            cellStyle = {
+              ...cellStyle,
+              border: {
+                top: borderStyle,
+                right: borderStyle,
+                bottom: borderStyle,
+                left: borderStyle,
+              },
+              font: {
+                color: {
+                  rgb: 'FFFFFF',
+                },
+              },
+              fill: {
+                fgColor: {
+                  rgb: '3366FF',
+                },
+              },
+            }
+          } else {
+            cellStyle.alignment.horizontal = 'left'
+          }
+          sheet[key].s = cellStyle
+        }
+      }
+      // 表格数据转换
+      const workBook = XLSX.utils.book_new()
+      XLSX.utils.book_append_sheet(workBook, sheet, this.chartsTitle)
+      const tableWrite = XLSX_STYLE.write(workBook, {
+        bookType: 'xlsx',
+        bookSST: true,
+        type: 'buffer',
+        cellStyles: true,
+      })
+      // 下载表格
+      const fileName = `${this.chartsTitle}统计-${this.params.join('-')}.xlsx`
+      FileSaver.saveAs(
+        new Blob([tableWrite], { type: 'application/octet-stream' }),
+        fileName
+      )
+    },
+  },
+}
+</script>
+
+<style lang="scss" scoped>
+.statistics-chart {
+  width: 100%;
+}
+.statstics-wrapper{
+  padding: 24px;
+}
+</style>

+ 588 - 0
src/views/statisticsCharts/components/newPieStatisticsCharts.vue

@@ -0,0 +1,588 @@
+<template>
+  <div
+    v-loading="loading"
+    element-loading-text="拼命加载中"
+    element-loading-spinner="el-icon-loading"
+    element-loading-background="rgba(0, 0, 0, 0.8)"
+    class="statstics-wrapper"
+  >
+    <div
+      ref="headerWrapper"
+      class="statstics-header"
+    >
+      <StatisticsHeader
+        :title="`${chartsTitle}统计`"
+        :data="formData"
+        :items="formItems"
+        :custom-items="customFormItems"
+        @getFormData="getFormData"
+        @export="exportHandler"
+      />
+    </div>
+    <div class="statstics-content">
+      <div
+        id="chart"
+        class="statistics-chart"
+        :style="{ height: chartHeight }"
+      />
+    </div>
+  </div>
+</template>
+
+<script>
+import StatisticsHeader from './statisticsHeader.vue'
+import { TempQuery } from '@/api/temp'
+import { mapGetters } from 'vuex'
+import * as XLSX from 'xlsx'
+import XLSX_STYLE from 'xlsx-style'
+import FileSaver from 'file-saver'
+
+export default {
+  name: 'CommonBarStatisticsCharts',
+  components: { StatisticsHeader },
+  props: {
+    chartsTitle: {
+      type: String,
+      required: true,
+    },
+    querySettings: {
+      type: Object,
+      required: true,
+    },
+    categories: {
+      type: Array,
+      validator(arr) {
+        return (
+          arr &&
+          arr.every(
+            category =>
+              (category instanceof Object && 'name' in category) ||
+              typeof category === 'string'
+          )
+        )
+      },
+    },
+    formData: {
+      type: Object,
+      required: true,
+    },
+    formItems: {
+      type: Array,
+      default: () => [],
+    },
+    customFormItems: {
+      type: Array,
+      default: () => [],
+    },
+    pieTitle: {
+      type: String,
+      default: '总件数',
+    },
+  },
+  data() {
+    return {
+      loading: false,
+      myChart: null,
+      debounceTime: 300,
+      chartHeight: '70vh',
+      hasChartData: false,
+      tableData: [],
+      params: [],
+      options: {
+        backgroundColor: '#ffffff',
+        tooltip: {
+          trigger: 'item',
+        },
+        title: {
+          text: '',
+          // 副标题
+          subtext: '0',
+          // 主副标题间距
+          itemGap: 24,
+          x: 'left',
+          y: 'center',
+          left: '30%',
+          top: '40%',
+          textAlign: 'center',
+          // 主标题样式
+          textStyle: {
+            fontSize: '48',
+            color: '#ffffff',
+            fontWeight: 'bold',
+            fontFamily: 'Microsoft YaHei',
+          },
+          // 副标题样式
+          subtextStyle: {
+            fontSize: '80',
+            color: '#ffffff',
+            fontWeight: 'bold',
+          },
+        },
+        legend: {
+          show: true,
+          left: '60%',
+          x: 'right',
+          y: 'center',
+          icon: 'rect',
+          itemWidth: 20,
+          itemHeight: 20,
+          formatter: name => this.legendFormatter(name),
+          textStyle: {
+            backgroundColor: 'transparent',
+            lineHeight: 0,
+            rich: {
+              chartsTitle: {
+                width: 200,
+                lineHeight: 100,
+                fontSize: 32,
+                fontFamily: 'Microsoft YaHei',
+                fontWeight: 'bold',
+                color: '#101116',
+                padding: [0, 1000, 0, -20],
+              },
+              name: {
+                fontSize: 20,
+                fontFamily: 'Microsoft YaHei',
+                fontWeight: 'bold',
+                color: '#101116',
+                lineHeight: 100,
+              },
+              label: {
+                fontSize: 16,
+                fontFamily: 'Microsoft YaHei',
+                color: '#101116',
+              },
+              value: {
+                width: 96,
+                fontSize: 16,
+                fontFamily: 'Helvetica',
+                fontWeight: 'bold',
+                color: '#101116',
+              },
+              ratio: {
+                width: 80,
+                fontSize: 16,
+                fontFamily: 'Helvetica',
+                fontWeight: 'bold',
+                color: '#101116',
+              },
+              wrap: {
+                padding: [0, 40, 0, 0],
+              },
+            },
+          },
+          selected: {
+            [this.chartsTitle]: false,
+          },
+        },
+        series: [
+          {
+            name: '',
+            type: 'pie',
+            left: '30%',
+            width: 560,
+            height: 560,
+            center: [0, '60%'],
+            radius: ['60%', '90%'],
+            avoidLabelOverlap: false,
+            label: {
+              show: false,
+              position: 'center',
+            },
+            emphasis: {
+              label: {
+                show: false,
+                fontSize: '40',
+                fontWeight: 'bold',
+              },
+            },
+            labelLine: {
+              show: false,
+            },
+            data: [],
+          },
+          {
+            name: '总数',
+            type: 'pie',
+            left: '30%',
+            width: 560,
+            height: 560,
+            center: [0, '60%'],
+            radius: ['0%', '50%'],
+            avoidLabelOverlap: false,
+            itemStyle: {
+              normal: {
+                color: '#101116',
+              },
+            },
+            label: {
+              show: false,
+              position: 'center',
+            },
+            // 自定义中心内容的话需要把这个关闭
+            emphasis: {
+              label: {
+                show: false,
+              },
+            },
+            labelLine: {
+              show: false,
+            },
+            data: [],
+          },
+        ],
+      },
+      totalCount: [{ value: 0 }],
+      categoryDatas: [],
+    }
+  },
+  computed: {
+    ...mapGetters(['sidebar']),
+  },
+  watch: {
+    pieTitle: {
+      handler(val) {
+        this.options.title.text = val
+      },
+      immediate: true,
+    },
+    // 监听数据变化 重绘图形
+    options: {
+      handler(obj) {
+        this.myChart.setOption(obj)
+        this.resizeHandler()
+      },
+      deep: true,
+    },
+    categories: {
+      handler(arr) {
+        this.categoryDatas = arr.map(category => {
+          if (category instanceof Object) {
+            return {
+              ...category,
+              value: 0,
+            }
+          } else {
+            return {
+              name: category,
+              key: category,
+              value: 0,
+            }
+          }
+        })
+      },
+      deep: true,
+      immediate: true,
+    },
+    'sidebar.expand'() {
+      this.setChartHeight()
+    },
+  },
+  mounted() {
+    this.setChartHeight()
+    this.myChart = this.$echarts.init(document.getElementById('chart'))
+    this.options.series[0].data = [
+      {
+        name: this.chartsTitle,
+        key: this.chartsTitle,
+        value: null,
+      },
+      ...this.categoryDatas,
+    ]
+    this.options.legend.data = [
+      {
+        name: this.chartsTitle,
+        icon: 'none',
+      },
+      ...this.categoryDatas.map(({ name }, index) => ({ name })),
+    ]
+    this.options.series[1].data = this.totalCount
+    this.myChart.setOption(this.options)
+    this.myChart.on('legendselectchanged', ({ name }) => {
+      if (name === this.chartsTitle) {
+        this.myChart.dispatchAction({
+          type: 'legendUnSelect',
+          name,
+        })
+      }
+    })
+    // 监听页面缩放
+    this.debouncedChartHeightSetter = this._.debounce(
+      this.setChartHeight,
+      this.debounceTime
+    )
+    window.addEventListener('resize', this.debouncedChartHeightSetter)
+  },
+  beforeDestroy() {
+    // 销毁实例和移除监听
+    window.removeEventListener('resize', this.debouncedChartHeightSetter)
+    if (this.myChart) {
+      this.myChart.dispose()
+      this.myChart = null
+    }
+  },
+  methods: {
+    legendFormatter(name) {
+      const index = this.categoryDatas.findIndex(
+        category => category.name === name
+      )
+      if (index === -1) {
+        return `{chartsTitle|${name}}`
+      } else {
+        const value = this.categoryDatas[index].value
+        const ratio =
+          value && this.totalCount.value
+            ? ((value / this.totalCount.value) * 100).toFixed(2) + '%'
+            : '0%'
+        const richString = `{name|${name}}\n{label|数量:}{value|${value}}{label|占比:}{ratio|${ratio}}`
+        return index % 2 ? richString + '{wrap| }' : richString
+      }
+    },
+    resetDatas() {
+      this.hasChartData = false
+      this.categoryDatas.forEach(category => {
+        category && (category.value = 0)
+      })
+      this.options.title.subtext = '0'
+      this.options.series[1].data[0].value = 0
+    },
+    getFormData(formData) {
+      this.resetDatas()
+      const params = JSON.parse(JSON.stringify(formData))
+      ;[params.fd1, params.fd2] = params.dateTime
+      delete params.dateTime
+      this.params = Object.values(params)
+      const paramsList = [params]
+      this.getMultipleChartsData(this.querySettings.serviceId, paramsList)
+    },
+    async getMultipleChartsData(serviceId, paramsList) {
+      this.loading = true
+      try {
+        const listValuesArray = await Promise.all(
+          paramsList.map(params => this.getChartsData(serviceId, params))
+        )
+        this.tableData = this._.sortBy(listValuesArray.flat(), 'fdt')
+        const categories = this.categoryDatas.map(category => category.key)
+        const listValues = listValuesArray.reduce(
+          (preValues, currentValues) => {
+            currentValues.forEach(value => {
+              const preValue = preValues.find(
+                preValue => preValue.fdt === value.fdt
+              )
+              if (preValue) {
+                categories.forEach(key => {
+                  preValue[key] += value[key] ?? 0
+                })
+              } else {
+                const valuesObj = {
+                  location: value.location,
+                  fdt: value.fdt,
+                }
+                categories.forEach(key => {
+                  valuesObj[key] = value[key] ?? 0
+                })
+                preValues.push(valuesObj)
+              }
+            })
+            return preValues
+          },
+          []
+        )
+        this.setChartsData(this._.sortBy(listValues, 'fdt'))
+      } catch (error) {
+        this.$message.error(error.message)
+      }
+      this.loading = false
+    },
+    async getChartsData(serviceId, params) {
+      try {
+        const {
+          code,
+          returnData: listValues,
+          message,
+        } = await TempQuery({
+          serviceId,
+          dataContent: params,
+        })
+        if (String(code) === '0') {
+          return listValues.map(obj => ({
+            ...obj,
+            location: params.air_line || params.airport || '',
+          }))
+        } else {
+          throw new Error(message)
+        }
+      } catch (error) {
+        return Promise.reject(error.message || '失败')
+      }
+    },
+    setChartsData(listValues) {
+      if (listValues.length === 0) {
+        this.$message.info('未查询到对应数据')
+        return
+      }
+      let totalCount = 0
+      listValues.forEach(element => {
+        this.categoryDatas.forEach(category => {
+          if (element[category.key]) {
+            category.value += element[category.key]
+            totalCount += element[category.key]
+          }
+        })
+      })
+      this.options.title.subtext = totalCount.toString()
+      this.totalCount.value = totalCount
+      this.hasChartData = true
+    },
+    setChartHeight() {
+      const topBarHeight = 80
+      const headerBlankHeight = 24
+      const tabsWrapperHeight = 62
+      const headerHeight = this.$refs['headerWrapper'].offsetHeight
+      const footerBlankHeight = 24
+      this.chartHeight = `calc(100vh - ${
+        topBarHeight +
+        headerBlankHeight +
+        tabsWrapperHeight +
+        headerHeight +
+        footerBlankHeight
+      }px)`
+      this.$nextTick(() => {
+        this.resizeHandler()
+      })
+    },
+    resizeHandler() {
+      if (this.myChart) {
+        this.myChart.resize()
+      }
+    },
+    exportHandler() {
+      if (!this.hasChartData) {
+        this.$message.warning('请查询后再进行导出')
+        return
+      }
+      // const myCanvas = this.myChart._dom.querySelectorAll('canvas')[0]
+      // const image = myCanvas.toDataURL('image/png')
+      // const $a = document.createElement('a')
+      // $a.setAttribute('href', image)
+      // $a.setAttribute('download', `${this.chartsTitle}统计.png`)
+      // $a.click()
+
+      const xlsxDatas = [['时间', '位置', '分类', '数量', '占比']]
+      xlsxDatas.push(
+        ...this.tableData
+          .map(element =>
+            this.categoryDatas.map(category => [
+              element['fdt'],
+              element['location'],
+              category.name,
+              element[category.key],
+              `${(
+                (element[category.key] / this.totalCount.value) *
+                100
+              ).toFixed(2)}%`,
+            ])
+          )
+          .flat(1)
+      )
+      xlsxDatas.push(['合计', '', '', this.totalCount.value, ''])
+      // 计算列宽
+      const columnWidths = []
+      xlsxDatas.forEach((row, rowIndex) => {
+        // 计算每一列宽度,考虑换行
+        row.forEach((cell, columnIndex) => {
+          const cellWidth = Math.max(
+            ...cell
+              .toString()
+              .split('\n')
+              .map(cellRow =>
+                cellRow.split('').reduce((pre, curr) => {
+                  const letterSize = curr.charCodeAt(0) > 255 ? 2 : 1
+                  return pre + letterSize
+                }, 0)
+              )
+          )
+          if (
+            (!columnWidths[columnIndex] && cellWidth > 0) ||
+            cellWidth > columnWidths[columnIndex]
+          ) {
+            columnWidths[columnIndex] = cellWidth
+          }
+        })
+      })
+      // 生成表格
+      const sheet = XLSX.utils.aoa_to_sheet(xlsxDatas)
+      // 添加列宽度
+      sheet['!cols'] = columnWidths.map(width => ({
+        wch: width + 2,
+      }))
+      // 样式
+      const borderStyle = {
+        style: 'medium',
+        color: {
+          rgb: 'FFFFFF',
+        },
+      }
+      const reg = /^[A-Z]+([\d]+$)/
+      for (const key in sheet) {
+        const match = reg.test(key)
+        if (match) {
+          const rowIndex = reg.exec(key)[1]
+          let cellStyle = {
+            alignment: {
+              horizontal: 'center',
+              vertical: 'center',
+              wrapText: true,
+            },
+          }
+          if (Number(rowIndex) === 1) {
+            cellStyle = {
+              ...cellStyle,
+              border: {
+                top: borderStyle,
+                right: borderStyle,
+                bottom: borderStyle,
+                left: borderStyle,
+              },
+              font: {
+                color: {
+                  rgb: 'FFFFFF',
+                },
+              },
+              fill: {
+                fgColor: {
+                  rgb: '3366FF',
+                },
+              },
+            }
+          } else {
+            cellStyle.alignment.horizontal = 'left'
+          }
+          sheet[key].s = cellStyle
+        }
+      }
+      // 表格数据转换
+      const workBook = XLSX.utils.book_new()
+      XLSX.utils.book_append_sheet(workBook, sheet, this.chartsTitle)
+      const tableWrite = XLSX_STYLE.write(workBook, {
+        bookType: 'xlsx',
+        bookSST: true,
+        type: 'buffer',
+        cellStyles: true,
+      })
+      // 下载表格
+      const fileName = `${this.chartsTitle}统计-${this.params.join('-')}.xlsx`
+      FileSaver.saveAs(
+        new Blob([tableWrite], { type: 'application/octet-stream' }),
+        fileName
+      )
+    },
+  },
+}
+</script>
+
+<style lang="scss" scoped>
+.statistics-chart {
+  width: 100%;
+}
+</style>

+ 595 - 0
src/views/statisticsCharts/components/newPieStatisticsChartscpsy.vue

@@ -0,0 +1,595 @@
+<template>
+  <div
+    v-loading="loading"
+    element-loading-text="拼命加载中"
+    element-loading-spinner="el-icon-loading"
+    element-loading-background="rgba(0, 0, 0, 0.8)"
+    class="statstics-wrapper"
+  >
+    <div
+      ref="headerWrapper"
+      class="statstics-header"
+    >
+      <StatisticsHeader
+        :title="`${chartsTitle}统计`"
+        :data="formData"
+        :items="formItems"
+        :custom-items="customFormItems"
+        @getFormData="getFormData"
+        @export="exportHandler"
+      />
+    </div>
+    <div class="statstics-content">
+      <div
+        id="chart"
+        class="statistics-chart"
+        :style="{ height: chartHeight }"
+      />
+    </div>
+  </div>
+</template>
+
+<script>
+import StatisticsHeader from './statisticsHeader.vue'
+import { TempQuery } from '@/api/temp'
+import { mapGetters } from 'vuex'
+import * as XLSX from 'xlsx'
+import XLSX_STYLE from 'xlsx-style'
+import FileSaver from 'file-saver'
+
+export default {
+  name: 'CommonBarStatisticsCharts',
+  components: { StatisticsHeader },
+  props: {
+    chartsTitle: {
+      type: String,
+      required: true,
+    },
+    querySettings: {
+      type: Object,
+      required: true,
+    },
+    categories: {
+      type: Array,
+      validator(arr) {
+        return (
+          arr &&
+          arr.every(
+            category =>
+              (category instanceof Object && 'name' in category) ||
+              typeof category === 'string'
+          )
+        )
+      },
+    },
+    formData: {
+      type: Object,
+      required: true,
+    },
+    formItems: {
+      type: Array,
+      default: () => [],
+    },
+    customFormItems: {
+      type: Array,
+      default: () => [],
+    },
+    pieTitle: {
+      type: String,
+      default: '总件数',
+    },
+  },
+  data() {
+    return {
+      loading: false,
+      myChart: null,
+      debounceTime: 300,
+      chartHeight: '70vh',
+      hasChartData: false,
+      tableData: [],
+      params: [],
+      options: {
+        backgroundColor: '#ffffff',
+        tooltip: {
+          trigger: 'item',
+        },
+        title: {
+          text: '',
+          // 副标题
+          subtext: '0',
+          // 主副标题间距
+          itemGap: 24,
+          x: 'left',
+          y: 'center',
+          left: '30%',
+          top: '40%',
+          textAlign: 'center',
+          // 主标题样式
+          textStyle: {
+            fontSize: '48',
+            color: '#ffffff',
+            fontWeight: 'bold',
+            fontFamily: 'Microsoft YaHei',
+          },
+          // 副标题样式
+          subtextStyle: {
+            fontSize: '80',
+            color: '#ffffff',
+            fontWeight: 'bold',
+          },
+        },
+        legend: {
+          show: true,
+          left: '60%',
+          x: 'right',
+          y: 'center',
+          icon: 'rect',
+          itemWidth: 20,
+          itemHeight: 20,
+          formatter: name => this.legendFormatter(name),
+          textStyle: {
+            backgroundColor: 'transparent',
+            lineHeight: 0,
+            rich: {
+              chartsTitle: {
+                width: 200,
+                lineHeight: 100,
+                fontSize: 32,
+                fontFamily: 'Microsoft YaHei',
+                fontWeight: 'bold',
+                color: '#101116',
+                padding: [0, 1000, 0, -20],
+              },
+              name: {
+                fontSize: 20,
+                fontFamily: 'Microsoft YaHei',
+                fontWeight: 'bold',
+                color: '#101116',
+                lineHeight: 100,
+              },
+              label: {
+                fontSize: 16,
+                fontFamily: 'Microsoft YaHei',
+                color: '#101116',
+              },
+              value: {
+                width: 96,
+                fontSize: 16,
+                fontFamily: 'Helvetica',
+                fontWeight: 'bold',
+                color: '#101116',
+              },
+              ratio: {
+                width: 80,
+                fontSize: 16,
+                fontFamily: 'Helvetica',
+                fontWeight: 'bold',
+                color: '#101116',
+              },
+              wrap: {
+                padding: [0, 40, 0, 0],
+              },
+            },
+          },
+          selected: {
+            [this.chartsTitle]: false,
+          },
+        },
+        series: [
+          {
+            name: '',
+            type: 'pie',
+            left: '30%',
+            width: 560,
+            height: 560,
+            center: [0, '60%'],
+            radius: ['60%', '90%'],
+            avoidLabelOverlap: false,
+            label: {
+              show: false,
+              position: 'center',
+            },
+            emphasis: {
+              label: {
+                show: false,
+                fontSize: '40',
+                fontWeight: 'bold',
+              },
+            },
+            labelLine: {
+              show: false,
+            },
+            data: [],
+          },
+          {
+            name: '总数',
+            type: 'pie',
+            left: '30%',
+            width: 560,
+            height: 560,
+            center: [0, '60%'],
+            radius: ['0%', '50%'],
+            avoidLabelOverlap: false,
+            itemStyle: {
+              normal: {
+                color: '#101116',
+              },
+            },
+            label: {
+              show: false,
+              position: 'center',
+            },
+            // 自定义中心内容的话需要把这个关闭
+            emphasis: {
+              label: {
+                show: false,
+              },
+            },
+            labelLine: {
+              show: false,
+            },
+            data: [],
+          },
+        ],
+      },
+      totalCount: [{ value: 0 }],
+      categoryDatas: [],
+    }
+  },
+  computed: {
+    ...mapGetters(['sidebar']),
+  },
+  watch: {
+    pieTitle: {
+      handler(val) {
+        this.options.title.text = val
+      },
+      immediate: true,
+    },
+    // 监听数据变化 重绘图形
+    options: {
+      handler(obj) {
+        this.myChart.setOption(obj)
+        this.resizeHandler()
+      },
+      deep: true,
+    },
+    categories: {
+      handler(arr) {
+        this.categoryDatas = arr.map(category => {
+          if (category instanceof Object) {
+            return {
+              ...category,
+              value: 0,
+            }
+          } else {
+            return {
+              name: category,
+              key: category,
+              value: 0,
+            }
+          }
+        })
+      },
+      deep: true,
+      immediate: true,
+    },
+    'sidebar.expand'() {
+      this.setChartHeight()
+    },
+  },
+  mounted() {
+    this.setChartHeight()
+    this.myChart = this.$echarts.init(document.getElementById('chart'))
+    this.options.series[0].data = [
+      {
+        name: this.chartsTitle,
+        key: this.chartsTitle,
+        value: null,
+      },
+      ...this.categoryDatas,
+    ]
+    this.options.legend.data = [
+      {
+        name: this.chartsTitle,
+        icon: 'none',
+      },
+      ...this.categoryDatas.map(({ name }, index) => ({ name })),
+    ]
+    this.options.series[1].data = this.totalCount
+    this.myChart.setOption(this.options)
+    this.myChart.on('legendselectchanged', ({ name }) => {
+      if (name === this.chartsTitle) {
+        this.myChart.dispatchAction({
+          type: 'legendUnSelect',
+          name,
+        })
+      }
+    })
+    // 监听页面缩放
+    this.debouncedChartHeightSetter = this._.debounce(
+      this.setChartHeight,
+      this.debounceTime
+    )
+    window.addEventListener('resize', this.debouncedChartHeightSetter)
+  },
+  beforeDestroy() {
+    // 销毁实例和移除监听
+    window.removeEventListener('resize', this.debouncedChartHeightSetter)
+    if (this.myChart) {
+      this.myChart.dispose()
+      this.myChart = null
+    }
+  },
+  methods: {
+    legendFormatter(name) {
+      const index = this.categoryDatas.findIndex(
+        category => category.name === name
+      )
+      if (index === -1) {
+        return `{chartsTitle|${name}}`
+      } else {
+        const value = this.categoryDatas[index].value
+        const ratio =
+          value && this.totalCount.value
+            ? ((value / this.totalCount.value) * 100).toFixed(2) + '%'
+            : '0%'
+        const richString = `{name|${name}}\n{label|数量:}{value|${value}}{label|占比:}{ratio|${ratio}}`
+        return index % 2 ? richString + '{wrap| }' : richString
+      }
+    },
+    resetDatas() {
+      this.hasChartData = false
+      this.categoryDatas.forEach(category => {
+        category && (category.value = 0)
+      })
+      this.options.title.subtext = '0'
+      this.options.series[1].data[0].value = 0
+    },
+    getFormData(formData) {
+      this.resetDatas()
+      const params = JSON.parse(JSON.stringify(formData))
+      ;[params.fd1, params.fd2] = params.dateTime
+      delete params.dateTime
+      this.params = Object.values(params)
+      const paramsList = [params]
+      this.getMultipleChartsData(this.querySettings.serviceId, paramsList)
+    },
+    async getMultipleChartsData(serviceId, paramsList) {
+      this.loading = true
+      try {
+        const listValuesArray = await Promise.all(
+          paramsList.map(params => this.getChartsData(serviceId, params))
+        )
+        this.tableData = this._.sortBy(listValuesArray.flat(), 'fdt')
+        const categories = this.categoryDatas.map(category => category.key)
+        const listValues = listValuesArray.reduce(
+          (preValues, currentValues) => {
+            currentValues.forEach(value => {
+              const preValue = preValues.find(
+                preValue => preValue.fdt === value.fdt
+              )
+              if (preValue) {
+                // console.log(value)
+                categories.forEach(key => {
+                  if (key == value.specialtype) {
+                    preValue[key] = value.bags ?? 0
+                  }
+                })
+              } else {
+                const valuesObj = {
+                  location: value.location,
+                  fdt: value.fdt,
+                }
+                categories.forEach(key => {
+                  if (key == value.specialtype) {
+                    valuesObj[key] = value.bags ?? 0
+                  }
+                })
+                console.log(valuesObj)
+                preValues.push(valuesObj)
+              }
+              // console.log(value)
+            })
+            return preValues
+          },
+          []
+        )
+        this.setChartsData(this._.sortBy(listValues, 'fdt'))
+      } catch (error) {
+        this.$message.error(error.message)
+      }
+      this.loading = false
+    },
+    async getChartsData(serviceId, params) {
+      try {
+        const {
+          code,
+          returnData: listValues,
+          message,
+        } = await TempQuery({
+          serviceId,
+          dataContent: params,
+        })
+        if (String(code) === '0') {
+          return listValues.map(obj => ({
+            ...obj,
+            location: params.air_line || params.airport || '',
+          }))
+        } else {
+          throw new Error(message)
+        }
+      } catch (error) {
+        return Promise.reject(error.message || '失败')
+      }
+    },
+    setChartsData(listValues) {
+      if (listValues.length === 0) {
+        this.$message.info('未查询到对应数据')
+        return
+      }
+      let totalCount = 0
+      listValues.forEach(element => {
+        this.categoryDatas.forEach(category => {
+          if (element[category.key]) {
+            category.value += element[category.key]
+            totalCount += element[category.key]
+          }
+        })
+      })
+      this.options.title.subtext = totalCount.toString()
+      this.totalCount.value = totalCount
+      this.hasChartData = true
+    },
+    setChartHeight() {
+      const topBarHeight = 80
+      const headerBlankHeight = 24
+      const tabsWrapperHeight = 62
+      const headerHeight = this.$refs['headerWrapper'].offsetHeight
+      const footerBlankHeight = 24
+      this.chartHeight = `calc(100vh - ${
+        topBarHeight +
+        headerBlankHeight +
+        tabsWrapperHeight +
+        headerHeight +
+        footerBlankHeight
+      }px)`
+      this.$nextTick(() => {
+        this.resizeHandler()
+      })
+    },
+    resizeHandler() {
+      if (this.myChart) {
+        this.myChart.resize()
+      }
+    },
+    exportHandler() {
+      if (!this.hasChartData) {
+        this.$message.warning('请查询后再进行导出')
+        return
+      }
+      // const myCanvas = this.myChart._dom.querySelectorAll('canvas')[0]
+      // const image = myCanvas.toDataURL('image/png')
+      // const $a = document.createElement('a')
+      // $a.setAttribute('href', image)
+      // $a.setAttribute('download', `${this.chartsTitle}统计.png`)
+      // $a.click()
+
+      const xlsxDatas = [['时间', '位置', '分类', '数量', '占比']]
+      xlsxDatas.push(
+        ...this.tableData
+          .map(element =>
+            this.categoryDatas.map(category => [
+              element['fdt'],
+              element['location'],
+              category.name,
+              element[category.key],
+              `${(
+                (element[category.key] / this.totalCount.value) *
+                100
+              ).toFixed(2)}%`,
+            ])
+          )
+          .flat(1)
+      )
+      xlsxDatas.push(['合计', '', '', this.totalCount.value, ''])
+      // 计算列宽
+      const columnWidths = []
+      xlsxDatas.forEach((row, rowIndex) => {
+        // 计算每一列宽度,考虑换行
+        row.forEach((cell, columnIndex) => {
+          const cellWidth = Math.max(
+            ...cell
+              .toString()
+              .split('\n')
+              .map(cellRow =>
+                cellRow.split('').reduce((pre, curr) => {
+                  const letterSize = curr.charCodeAt(0) > 255 ? 2 : 1
+                  return pre + letterSize
+                }, 0)
+              )
+          )
+          if (
+            (!columnWidths[columnIndex] && cellWidth > 0) ||
+            cellWidth > columnWidths[columnIndex]
+          ) {
+            columnWidths[columnIndex] = cellWidth
+          }
+        })
+      })
+      // 生成表格
+      const sheet = XLSX.utils.aoa_to_sheet(xlsxDatas)
+      // 添加列宽度
+      sheet['!cols'] = columnWidths.map(width => ({
+        wch: width + 2,
+      }))
+      // 样式
+      const borderStyle = {
+        style: 'medium',
+        color: {
+          rgb: 'FFFFFF',
+        },
+      }
+      const reg = /^[A-Z]+([\d]+$)/
+      for (const key in sheet) {
+        const match = reg.test(key)
+        if (match) {
+          const rowIndex = reg.exec(key)[1]
+          let cellStyle = {
+            alignment: {
+              horizontal: 'center',
+              vertical: 'center',
+              wrapText: true,
+            },
+          }
+          if (Number(rowIndex) === 1) {
+            cellStyle = {
+              ...cellStyle,
+              border: {
+                top: borderStyle,
+                right: borderStyle,
+                bottom: borderStyle,
+                left: borderStyle,
+              },
+              font: {
+                color: {
+                  rgb: 'FFFFFF',
+                },
+              },
+              fill: {
+                fgColor: {
+                  rgb: '3366FF',
+                },
+              },
+            }
+          } else {
+            cellStyle.alignment.horizontal = 'left'
+          }
+          sheet[key].s = cellStyle
+        }
+      }
+      // 表格数据转换
+      const workBook = XLSX.utils.book_new()
+      XLSX.utils.book_append_sheet(workBook, sheet, this.chartsTitle)
+      const tableWrite = XLSX_STYLE.write(workBook, {
+        bookType: 'xlsx',
+        bookSST: true,
+        type: 'buffer',
+        cellStyles: true,
+      })
+      // 下载表格
+      const fileName = `${this.chartsTitle}统计-${this.params.join('-')}.xlsx`
+      FileSaver.saveAs(
+        new Blob([tableWrite], { type: 'application/octet-stream' }),
+        fileName
+      )
+    },
+  },
+}
+</script>
+
+<style lang="scss" scoped>
+.statistics-chart {
+  width: 100%;
+}
+</style>

+ 687 - 0
src/views/statisticsCharts/components/statisticsHeader.vue

@@ -0,0 +1,687 @@
+<template>
+  <div class="flight-statistics-header">
+    <template v-if="title">
+      <div class="title">{{ title }}</div>
+    </template>
+    <el-form
+      ref="form"
+      class="form"
+      :model="formData"
+    >
+      <el-form-item
+        v-for="item in formItems"
+        :key="item.prop"
+        :prop="item.prop"
+        :label="item.label"
+        :style="{
+          width: item.width || '120px',
+        }"
+      >
+        <template v-if="item.inputType === 'input'">
+          <el-input
+            v-model="formData[item.prop]"
+            :size="item.size || 'small'"
+            :placeholder="item.placeholder || '请输入'"
+            :clearable="item.clearable"
+          />
+        </template>
+        <template v-if="item.inputType === 'select'">
+          <el-select
+            v-model="formData[item.prop]"
+            :filterable="item.filterable"
+            :default-first-option="item.filterable"
+            :size="item.size || 'small'"
+            :placeholder="item.placeholder || '请选择'"
+            :multiple="item.multiple"
+            :collapse-tags="item.multiple"
+            :clearable="item.clearable"
+            :disabled="item.disabled"
+          >
+            <el-option
+              v-for="option in item.options"
+              :key="option.value"
+              :value="option.value"
+              :label="option.label"
+            />
+          </el-select>
+        </template>
+        <template v-if="item.inputType === 'datePicker'">
+          <el-date-picker
+            v-model="formData[item.prop]"
+            :size="item.size || 'small'"
+            type="daterange"
+            format="yyyy-MM-dd"
+            value-format="yyyy-MM-dd"
+            unlink-panels
+            range-separator="至"
+            start-placeholder="开始日期"
+            end-placeholder="结束日期"
+          />
+        </template>
+        <template v-if="item.inputType === 'monthPicker'">
+          <el-date-picker
+            v-model="formData[item.prop]"
+            :size="item.size || 'small'"
+            type="monthrange"
+            format="yyyy-MM"
+            value-format="yyyy-MM"
+            unlink-panels
+            range-separator="至"
+            start-placeholder="开始月份"
+            end-placeholder="结束月份"
+          />
+        </template>
+        <template v-if="item.inputType === 'yearPicker'">
+          <year-range-picker
+            v-model="formData[item.prop]"
+            :size="item.size || 'small'"
+            range-separator="至"
+          />
+        </template>
+        <template v-if="item.inputType === 'cascader'">
+          <el-cascader
+            v-model="formData[item.prop]"
+            :size="item.size || 'small'"
+            :placeholder="item.placeholder || '请选择'"
+            :options="item.options"
+            :props="item.props"
+            :clearable="item.clearable"
+            :disabled="item.disabled"
+          />
+        </template>
+      </el-form-item>
+      <el-form-item v-if="formItems.length">
+        <el-button
+          type="primary"
+          size="small"
+          @click="getData"
+          >{{ buttonText }}</el-button
+        >
+      </el-form-item>
+      <el-form-item v-if="withExport">
+        <img
+          src="../../../assets/nav/ic_export.png"
+          title="导出"
+          class="btn-icon-only"
+          @click="exportClickHandler"
+        />
+      </el-form-item>
+      <el-form-item v-if="withSetting">
+        <img
+          src="../../../assets/nav/ic_setting.png"
+          title="节点设置"
+          class="btn-icon-only"
+          @click="settingClickHandler"
+        />
+      </el-form-item>
+    </el-form>
+  </div>
+</template>
+
+<script>
+import { TempQuery } from '@/api/temp'
+import { mapGetters } from 'vuex'
+// import YearRangePicker from '@/components/YearRangePicker'
+import { parseTime } from '@/utils'
+
+export default {
+  name: 'StatisticsHeader',
+  // components: { YearRangePicker },
+  props: {
+    title: {
+      type: String,
+      default: '',
+    },
+    items: {
+      type: Array,
+      default: undefined,
+    },
+    customItems: {
+      type: Array,
+      default: () => [],
+    },
+    data: {
+      type: Object,
+      default: undefined,
+    },
+    buttonText: {
+      type: String,
+      default: '查询',
+    },
+    withExport: {
+      type: Boolean,
+      default: true,
+    },
+    withSetting: {
+      type: Boolean,
+      default: false,
+    },
+  },
+  data() {
+    return {
+      formData: {
+        range: '',
+        inOrOut: '',
+        td: '',
+        air_line: [],
+        area: '',
+        airport: [],
+        terminal: '',
+        dateTime: [],
+        flightType: '',
+        baggageType: '',
+        passengerType: [],
+      },
+      formItems: [
+        {
+          prop: 'range',
+          inputType: 'select',
+          placeholder: '统计范围',
+          requiredWarning: '请先选择统计范围',
+          options: [
+            {
+              value: '全部',
+              label: '全部',
+            },
+            {
+              value: '航线',
+              label: '航线',
+            },
+            {
+              value: '基地分公司',
+              label: '基地分公司',
+            },
+            {
+              value: '航站',
+              label: '航站',
+            },
+            {
+              value: '航站楼',
+              label: '航站楼',
+            },
+          ],
+          changeHandler(value) {
+            this.setInOrOutOptions(value)
+            const rangeMap = {
+              航线: 'air_line',
+              基地分公司: 'area',
+              航站: 'airport',
+              航站楼: 'terminal',
+            }
+            Object.entries(rangeMap).forEach(([k, v]) => {
+              const theItem = this.formItems.find(item => item.prop === v)
+              if (value === k) {
+                theItem && (theItem.disabled = false)
+              } else {
+                this.formData[v] = ''
+                theItem && (theItem.disabled = true)
+              }
+            })
+          },
+        },
+        {
+          prop: 'inOrOut',
+          inputType: 'select',
+          placeholder: '进离港',
+          requiredWarning: '请先选择进离港',
+          // clearable: true,
+          options: [],
+        },
+        {
+          prop: 'td',
+          inputType: 'select',
+          placeholder: '时间维度',
+          requiredWarning: '请先选择统计时间维度',
+          options: [
+            {
+              value: '日',
+              label: '按日统计',
+            },
+            {
+              value: '月',
+              label: '按月统计',
+            },
+            {
+              value: '年',
+              label: '按年统计',
+            },
+          ],
+          changeHandler(value) {
+            const typeMap = {
+              日: 'datePicker',
+              月: 'monthPicker',
+              年: 'yearPicker',
+            }
+            const dateTimeItem = this.formItems.find(
+              item => item.prop === 'dateTime'
+            )
+            if (dateTimeItem) {
+              dateTimeItem.inputType = typeMap[value]
+              const dateTime = formData.dateTime
+              if (dateTime && dateTime[0] && dateTime[1]) {
+                if (value === '年') {
+                  this.formData.dateTime[0] = dateTime[0].split('-')[0]
+                  this.formData.dateTime[1] = dateTime[1].split('-')[0]
+                }
+                if (value === '月') {
+                  if (oldValue === '年') {
+                    this.formData.dateTime[0] = `${
+                      dateTime[0].split('-')[0]
+                    }-01`
+                    this.formData.dateTime[1] = `${
+                      dateTime[1].split('-')[0]
+                    }-12`
+                  }
+                  if (oldValue === '日') {
+                    this.formData.dateTime[0] = dateTime[0]
+                      .split('-')
+                      .slice(0, 2)
+                      .join('-')
+                    this.formData.dateTime[1] = dateTime[1]
+                      .split('-')
+                      .slice(0, 2)
+                      .join('-')
+                  }
+                }
+                if (value === '日') {
+                  if (oldValue === '年') {
+                    this.formData.dateTime[0] = `${
+                      dateTime[0].split('-')[0]
+                    }-01-01`
+                    this.formData.dateTime[1] = `${
+                      dateTime[1].split('-')[0]
+                    }-12-31`
+                  }
+                  if (oldValue === '月') {
+                    this.formData.dateTime[0] = `${dateTime[0]
+                      .split('-')
+                      .slice(0, 2)
+                      .join('-')}-01`
+                    let [year, month] = dateTime[1].split('-')
+                    if (month === '12') {
+                      year = Number(year) + 1
+                      month = 1
+                    } else {
+                      month = Number(month) + 1
+                    }
+                    const day = 24 * 60 * 60 * 1000
+                    this.formData.dateTime[1] = parseTime(
+                      new Date(`${year}-${month}-01`) - day * 1,
+                      '{y}-{m}-{d}'
+                    )
+                  }
+                }
+              }
+            }
+          },
+        },
+        {
+          prop: 'dateTime',
+          inputType: 'datePicker',
+          // clearable: true,
+          width: '240px',
+          requiredWarning: '请先选择统计时间范围',
+        },
+        {
+          prop: 'air_line',
+          inputType: 'select',
+          placeholder: '航线',
+          width: '180px',
+          filterable: true,
+          // clearable: true,
+          multiple: true,
+          disabled: true,
+          queryId: SERVICE_ID.airlineOptions,
+          setKey: 'air_line',
+          options: [],
+        },
+        {
+          prop: 'area',
+          inputType: 'select',
+          placeholder: '基地分公司',
+          filterable: true,
+          // clearable: true,
+          disabled: true,
+          queryId: SERVICE_ID.areaOptions,
+          setKey: 'a5',
+          options: [],
+        },
+        {
+          prop: 'airport',
+          inputType: 'select',
+          placeholder: '航站',
+          width: '150px',
+          filterable: true,
+          // clearable: true,
+          multiple: true,
+          disabled: true,
+          queryId: SERVICE_ID.AirportIds,
+          setKey: 'code3',
+          options: [],
+        },
+        {
+          prop: 'terminal',
+          inputType: 'select',
+          placeholder: '航站楼',
+          filterable: true,
+          // clearable: true,
+          disabled: true,
+          queryId: SERVICE_ID.TerminalId,
+          setKey: 'a2',
+          options: [],
+        },
+      ],
+    }
+  },
+  computed: {
+    // ...mapGetters(['savedFormDataMap']),
+    formDataObj() {
+      return JSON.parse(JSON.stringify(this.formData))
+    },
+  },
+  watch: {
+    items: {
+      handler(val) {
+        val && (this.formItems = val)
+      },
+      deep: true,
+      immediate: true,
+    },
+    data: {
+      handler(val) {
+        val && (this.formData = val)
+      },
+      deep: true,
+      immediate: true,
+    },
+    formDataObj: {
+      handler(val, oldVal) {
+        this.formItems.forEach(item => {
+          if (
+            item.changeHandler &&
+            String(val[item.prop]) !== String(oldVal[item.prop])
+          ) {
+            item.changeHandler.call(this, val[item.prop], oldVal[item.prop])
+          }
+        })
+      },
+      deep: true,
+    },
+  },
+  created() {
+    this.customItems.forEach(item => {
+      if (typeof item.itemIndex === 'number') {
+        if (item.prop) {
+          this.formItems.splice(item.itemIndex, item.replaceNum, item)
+        } else {
+          this.formItems.splice(item.itemIndex, item.replaceNum)
+        }
+      } else {
+        this.formItems.push(item)
+      }
+    })
+    // const savedFormData = this.savedFormDataMap[this.$route.name]
+    this.formItems.forEach(item => {
+      if (item.queryId && item.setKey) {
+        this.getOptions(
+          item.prop,
+          item.queryId,
+          item.setKey,
+          item.setLabel ?? item.setKey
+        )
+      }
+      // if (savedFormData?.[item.prop]) {
+      //   this.formData[item.prop] = savedFormData[item.prop]
+      // } else if (item.defaultOption) {
+      //   this.formData[item.prop] = item.defaultOption
+      // }
+    })
+  },
+  methods: {
+    getData() {
+      const formData = this._.cloneDeep(this.formData)
+      try {
+        this.formItems.forEach(item => {
+          if (
+            item.requiredWarning &&
+            (!formData[item.prop] || formData[item.prop].length === 0)
+          ) {
+            throw new Error(item.requiredWarning)
+          }
+        })
+      } catch (error) {
+        this.$message.warning(error.message)
+        return
+      }
+      if (formData.range === '航线' && !formData.air_line) {
+        this.$message.warning('请先选择航线')
+        return
+      } else if (formData.range === '航站' && !formData.airport) {
+        this.$message.warning('请先选择航站')
+        return
+      } else if (formData.range === '基地分公司' && !formData.area) {
+        this.$message.warning('请先选择基地分公司')
+        return
+      }
+      this.$store.dispatch('savedSettings/saveFormData', {
+        formData,
+      })
+      if (formData.td === '月') {
+        formData.dateTime[0] = `${formData.dateTime[0]}-01`
+        let [year, month] = formData.dateTime[1].split('-')
+        if (month === '12') {
+          year = Number(year) + 1
+          month = 1
+        } else {
+          month = Number(month) + 1
+        }
+        const day = 24 * 60 * 60 * 1000
+        formData.dateTime[1] = parseTime(
+          new Date(`${year}-${month}-01`) - day * 1,
+          '{y}-{m}-{d}'
+        )
+      } else if (formData.td === '年') {
+        formData.dateTime = [
+          `${formData.dateTime[0]}-01-01`,
+          `${formData.dateTime[1]}-12-31`,
+        ]
+      }
+      this.$emit('getFormData', formData)
+    },
+    exportClickHandler() {
+      this.$emit('export')
+    },
+    settingClickHandler() {
+      this.$emit('setting')
+    },
+    setInOrOutOptions(range) {
+      const theInOrOutItem = this.formItems.find(
+        item => item.prop === 'inOrOut'
+      )
+      switch (range) {
+        case '全部':
+        case '航线':
+          if (theInOrOutItem) {
+            theInOrOutItem.options = [
+              {
+                label: '全部',
+                value: '全部',
+              },
+            ]
+            theInOrOutItem.disabled = true
+          }
+          this.formData.inOrOut = '全部'
+          break
+        case '基地分公司':
+        case '航站':
+        case '航站楼':
+          if (theInOrOutItem) {
+            theInOrOutItem.options = [
+              {
+                value: '全部',
+                label: '全部',
+              },
+              {
+                value: '进港',
+                label: '进港',
+              },
+              {
+                value: '离港',
+                label: '离港',
+              },
+            ]
+            theInOrOutItem.disabled = false
+          }
+          break
+        default:
+          if (theInOrOutItem) {
+            theInOrOutItem.options = []
+            theInOrOutItem.disabled = false
+          }
+          break
+      }
+    },
+    async getOptions(prop, queryId, setKey, setLabel) {
+      try {
+        const { code, returnData, message } = await TempQuery({
+          serviceid: queryId,
+          datacontent: [{filter:{1:1}}],
+          event: '0',
+        })
+        if (String(code) === '0') {
+          const listValues = returnData.listValues || returnData
+          const arr = listValues.map(element => ({
+            label: element[setLabel],
+            value: element[setKey],
+          }))
+          const theItem = this.formItems.find(item => item.prop === prop)
+          theItem.options = arr
+        } else {
+          this.$message.error(message)
+        }
+      } catch (error) {
+        this.$message.error('失败')
+      }
+    },
+  },
+}
+</script>
+
+<style lang="scss" scoped>
+.flight-statistics-header {
+  padding-top: 24px;
+  min-height: 80px;
+  display: flex;
+  justify-content: space-between;
+  align-items: flex-start;
+  .title {
+    margin-right: 24px;
+    padding-left: 16px;
+    // min-width: 190px;
+    height: 32px;
+    line-height: 32px;
+    font-size: 18px;
+    font-family: Helvetica, 'Microsoft YaHei';
+    font-weight: bold;
+    white-space: nowrap;
+    position: relative;
+    &::before {
+      content: '';
+      width: 4px;
+      height: 20px;
+      background: #2d67e3;
+      position: absolute;
+      top: 0;
+      bottom: 0;
+      left: 0;
+      margin: auto;
+    }
+  }
+  ::v-deep .form {
+    display: flex;
+    flex-wrap: wrap;
+    > .el-form-item {
+      margin-bottom: 24px;
+      // width: 185px;
+      &:not(:last-child) {
+        margin-right: 8px;
+      }
+      &:nth-last-child(2),
+      &:nth-last-child(3) {
+        margin-right: 16px;
+      }
+      .el-form-item__content {
+        height: 32px;
+        line-height: 30px;
+        .el-input {
+          &.is-disabled .el-input__inner {
+            border: none;
+          }
+          .el-input__inner {
+            border-radius: 4px;
+            font-family: Helvetica, 'Microsoft YaHei';
+            color: #303133;
+            border-color: #ffffff;
+            &:hover {
+              border-color: #c0c4cc;
+            }
+            &:focus {
+              border-color: #409eff;
+            }
+          }
+        }
+        .el-date-editor--monthrange.el-input,
+        .el-date-editor--monthrange.el-input__inner,
+        .el-date-editor--daterange.el-input,
+        .el-date-editor--daterange.el-input__inner,
+        .el-date-editor--timerange.el-input,
+        .el-date-editor--timerange.el-input__inner {
+          width: 100%;
+          border-radius: 4px;
+          border-color: #ffffff;
+          color: #303133;
+          font-family: Helvetica, 'Microsoft YaHei';
+          &:hover {
+            border-color: #c0c4cc;
+          }
+          &.is-active {
+            border-color: #409eff;
+          }
+          .el-input__icon {
+            color: #303133;
+          }
+          .el-range-separator {
+            line-height: 28px;
+          }
+        }
+        .el-select,
+        .el-cascader {
+          .el-input {
+            .el-icon-arrow-up::before {
+              content: '\e78f';
+            }
+            .el-icon-arrow-down::before {
+              content: '\e790';
+            }
+            &:not(.is-disabled) {
+              .el-input__icon,
+              .el-input__inner::-webkit-input-placeholder {
+                color: #303133;
+              }
+            }
+          }
+        }
+        .el-button {
+          border-radius: 4px;
+          font-family: Helvetica, 'Microsoft YaHei';
+        }
+        .btn-icon-only {
+          width: 32px;
+          height: 32px;
+          cursor: pointer;
+        }
+      }
+    }
+  }
+}
+</style>

+ 452 - 0
src/views/statisticsCharts/components/statisticsTabs.vue

@@ -0,0 +1,452 @@
+<template>
+  <div class="statistics-tabs">
+    <el-row
+      :gutter="16"
+      type="flex"
+    >
+      <el-col
+        v-for="(tab, index) in newTabList"
+        :key="index"
+        :span="4"
+      >
+        <el-dropdown
+          v-if="tab.children && tab.children.length"
+          placement="bottom"
+          @command="commandHandler"
+        >
+          <div :class="['tab-bar', { 'tab-active': activeIndex === index }]">
+            <img
+              class="tab-icon"
+              :src="activeIndex === index ? activeIcon : defaultIcon"
+              :alt="tab.title"
+            />
+            <el-tooltip
+              :content="tab.title"
+              placement="top"
+            >
+              <span class="tab-title">{{ tab.title }}</span>
+            </el-tooltip>
+            <i class="icon-arrow el-icon-caret-bottom" />
+          </div>
+          <el-dropdown-menu slot="dropdown">
+            <el-dropdown-item
+              v-for="(childTab, childIndex) in tab.children"
+              :key="childIndex"
+              :command="[tab.path, childTab.path]"
+              >{{ childTab.title }}</el-dropdown-item
+            >
+          </el-dropdown-menu>
+        </el-dropdown>
+        <div
+          v-else
+          :class="[
+            'tab-bar tab-bar-single',
+            { 'tab-active': activeIndex === index },
+          ]"
+          @click="clickHandler(tab.path)"
+        >
+          <img
+            class="tab-icon"
+            :src="activeIndex === index ? activeIcon : defaultIcon"
+            :alt="tab.title"
+          />
+          <el-tooltip
+            :content="tab.title"
+            placement="top"
+          >
+            <span class="tab-title">{{ tab.title }}</span>
+          </el-tooltip>
+        </div>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'StatisticsTabs',
+  data() {
+    return {
+      defaultIcon: require('@/assets/nav/ic_statistical_top_default.png'),
+      activeIcon: require('@/assets/nav/ic_statistical_top_check.png'),
+      tabList: [
+        // {
+        //   title: '航司行李相关统计',
+        //   path: '/statisticsCharts/airlineCompany',
+        //   roles: ['airline_baggage_statistics'],
+        //   children: [
+        //     {
+        //       path: 'flight',
+        //       title: '航班量统计',
+        //     },
+        //     {
+        //       path: 'baggage',
+        //       title: '行李量统计',
+        //     },
+        //     {
+        //       path: 'baggagePassenger',
+        //       title: '行李旅客量统计',
+        //     },
+        //     {
+        //       path: 'specialBaggage',
+        //       title: '特殊行李量统计',
+        //     },
+        //     {
+        //       path: 'baggageAverage',
+        //       title: '平均行李量统计',
+        //     },
+        //     {
+        //       path: 'abnormalBaggage',
+        //       title: '异常行李量统计',
+        //     },
+        //     {
+        //       path: 'complaintBaggage',
+        //       title: '投诉行李量统计',
+        //     },
+        //     {
+        //       path: 'compensationBaggage',
+        //       title: '赔偿行李量统计',
+        //     },
+        //     {
+        //       path: 'compensation',
+        //       title: '赔偿金额统计',
+        //     },
+        //   ],
+        // },
+        // {
+        //   path: '/statisticsCharts/passengerClassification',
+        //   title: '旅客分类统计',
+        //   roles: ['passenger_luggage_classification_statistics'],
+        //   children: [
+        //     {
+        //       path: 'baggage',
+        //       title: '行李量统计',
+        //     },
+        //     {
+        //       path: 'baggagePassenger',
+        //       title: '行李旅客量统计',
+        //     },
+        //     {
+        //       path: 'specialBaggage',
+        //       title: '特殊行李量统计',
+        //     },
+        //     {
+        //       path: 'abnormalBaggage',
+        //       title: '异常行李量统计',
+        //     },
+        //     {
+        //       path: 'complaintBaggage',
+        //       title: '投诉行李量统计',
+        //     },
+        //     {
+        //       path: 'compensationBaggage',
+        //       title: '赔偿行李量统计',
+        //     },
+        //     {
+        //       path: 'compensation',
+        //       title: '赔偿金额统计',
+        //     },
+        //   ],
+        // },
+        // {
+        //   path: '/statisticsCharts/flightClassification',
+        //   title: '航班分类相关统计',
+        //   roles: ['statistics_related_to_flight_classification'],
+        //   children: [
+        //     {
+        //       path: 'flight',
+        //       title: '航班量统计',
+        //     },
+        //     {
+        //       path: 'baggage',
+        //       title: '行李量统计',
+        //     },
+        //     {
+        //       path: 'passenger',
+        //       title: '行李旅客量统计',
+        //     },
+        //   ],
+        // },
+        // {
+        //   title: '报表统计',
+        //   path: '/statisticsCharts/report',
+        //   roles: ['report_statistics'],
+        //   children: [
+        //     {
+        //       path: 'reportStatistics',
+        //       title: '运送效率报表统计',
+        //     },
+        //     {
+        //       path: 'transitTables',
+        //       title: '中转四个流向统计',
+        //     },
+        //     {
+        //       path: 'transferDirectionTable',
+        //       title: '中转流向明细统计',
+        //     },
+        //     {
+        //       path: 'transferBaggageTable',
+        //       title: '中转行李因素分析统计',
+        //     },
+        //     {
+        //       path: 'baggageProportionTable',
+        //       title: '中转行李比例明细统计',
+        //     },
+        //     {
+        //       path: 'ScanningStatistics',
+        //       title: '航站BRS扫描统计',
+        //     },
+        //     {
+        //       path: 'scanDataTable',
+        //       title: 'Mannual Load扫描数据统计表',
+        //     },
+        //     {
+        //       path: 'rfldTable',
+        //       title: '航易行RFID扫描数据统计表',
+        //     },
+        //     {
+        //       path: 'Percentageofbaggage',
+        //       title: '行李全流程服务水平百分比',
+        //     },
+        //   ],
+        // },
+        // {
+        //   title: '特殊赔偿异常分类统计',
+        //   path: '/statisticsCharts/specialClassification',
+        //   roles: ['special_compensation_exception_classification_statistics'],
+        //   children: [
+        //     {
+        //       path: 'special',
+        //       title: '特殊行李分类统计',
+        //     },
+        //     {
+        //       path: 'abnormal',
+        //       title: '异常行李分类统计',
+        //     },
+        //     {
+        //       path: 'compensationBaggage',
+        //       title: '赔偿行李分类统计',
+        //     },
+        //     {
+        //       path: 'compensation',
+        //       title: '赔偿金额分类统计',
+        //     },
+        //   ],
+        // },
+        // {
+        //   path: '/statisticsCharts/statisticalAnalysis',
+        //   title: '统计分析',
+        //   roles: ['statistical_analysis'],
+        // },
+        {
+          title: '行李量相关统计',
+          path: '/statisticsCharts/baggage',
+          children: [
+            {
+              path: 'all',
+              title: '行李数量统计',
+            },
+            {
+              path: 'company',
+              title: '航司行李量统计',
+            },
+            {
+              path: 'airline',
+              title: '航线行李量统计',
+            },
+            {
+              path: 'hour',
+              title: '行李小时量统计',
+            },
+          ],
+        },
+        {
+          path: '/statisticsCharts/node',
+          title: '扫描节点与位置分析',
+          roles: ['scanning_node_and_location_analysis'],
+        },
+        {
+          path: '/statisticsCharts/workload',
+          title: '工作量统计',
+          roles: ['scanning_node_and_location_analysis'],
+        },
+        {
+          path: '/statisticsCharts/abnormal',
+          title: '异常行李分析',
+          roles: ['scanning_node_and_location_analysis'],
+        },
+        {
+          path: '/statisticsCharts/flight',
+          title: '航班量',
+          children: [
+            {
+              path: 'flightvolume',
+              title: '航站航班量统计',
+            },
+            {
+                path: 'numberair',
+                title: '航司航班量统计',
+            },
+            {
+                path: 'volumeof',
+                title: '航线航班量统计',
+            }]
+        },
+        {
+          path: '/statisticsCharts/passenger',
+          title: '行李旅客量',
+          children: [
+            {
+              path: 'terminalpassengers',
+              title: '航站旅客量',
+            },
+            {
+              path: 'passengerair',
+              title: '航司旅客量',
+            },
+            {
+              path: 'passengerroute',
+              title: '航线旅客量',
+            },
+          ]
+        },
+        {
+          path: '/statisticsCharts/averagepassengers',
+          title: '平均旅客行李量',
+          children: [
+            {
+              path: 'averagepassterminal',
+              title: '航站平均旅客行李量',
+            },
+            {
+              path: 'averagepassairline',
+              title: '航司平均旅客行李量',
+            },
+            {
+              path: 'averagepassroute',
+              title: '航线平均旅客行李量',
+            },
+          ]
+        },
+        {
+          path: '/statisticsCharts/specialbaggageanalysis',
+          title: '特殊行李分析',
+        },
+        {
+          path: '/statisticsCharts/transitTables',
+          title: '中转专项统计',
+        },
+      ],
+      activeIndex: null,
+    }
+  },
+  computed: {
+    newTabList() {
+      // const auths = JSON.parse(sessionStorage.getItem('userAuthList'))
+      // return this.tabList.filter(
+      //   tab => !tab.roles || tab.roles.every(role => auths.includes(role))
+      // )
+      return this.tabList
+    },
+  },
+  watch: {
+    '$route.path': {
+      handler(path) {
+        let activeIndex = null
+        this.newTabList.some((tab, index) => {
+          if (path.includes(tab.path)) {
+            activeIndex = index
+            return true
+          }
+        })
+        this.activeIndex = activeIndex
+      },
+      immediate: true,
+    },
+  },
+  methods: {
+    commandHandler(pathArray) {
+      if (pathArray.some(path => !path)) {
+        this.$message.info('开发中')
+        return
+      }
+      this.$router.push({
+        path: pathArray.join('/'),
+      })
+    },
+    clickHandler(path) {
+      if (!path) {
+        this.$message.info('开发中')
+        return
+      }
+      this.$router.push({
+        path,
+      })
+    },
+  },
+}
+</script>
+
+<style lang="scss" scoped>
+.statistics-tabs {
+  > .el-row > .el-col {
+    max-width: 208px;
+    min-width: 175px;
+    .el-dropdown {
+      width: 100%;
+    }
+    .tab-bar {
+      width: 100%;
+      height: 56px;
+      background-color: #ffffff;
+      padding-left: 16px;
+      padding-right: 16px;
+      display: flex;
+      align-items: center;
+      box-shadow: 0px 6px 7px 0px rgba(0, 0, 0, 0.06);
+      border-radius: 4px;
+      &-single {
+        cursor: pointer;
+      }
+      &:not(:last-child) {
+        margin-right: 16px;
+      }
+      .tab-icon {
+        width: 14px;
+        height: 14px;
+      }
+      .tab-title {
+        padding-left: 12px;
+        padding-right: 8px;
+        font-size: 14px;
+        font-family: Helvetica, 'Microsoft YaHei';
+        font-weight: bold;
+        color: #101116;
+        letter-spacing: 0;
+        overflow: hidden;
+        white-space: nowrap;
+        text-overflow: ellipsis;
+      }
+      &.tab-active {
+        background-color: #2d67e3;
+        .tab-title {
+          color: #ffffff;
+        }
+      }
+      .icon-arrow {
+        position: absolute;
+        right: 16px;
+        color: #101116;
+        font-size: 14px;
+        transition: transform 0.3s;
+      }
+      &.tab-active .icon-arrow {
+        color: #ffffff;
+      }
+      &:hover .icon-arrow {
+        transform: rotate(180deg);
+      }
+    }
+  }
+}
+</style>

+ 1517 - 0
src/views/statisticsCharts/components/tableformbrs.vue

@@ -0,0 +1,1517 @@
+<template>
+  <div class="data-table">
+    <div
+      :style="dataTableContentStyle"
+      v-loading="loading"
+      element-loading-text="拼命加载中"
+      element-loading-spinner="el-icon-loading"
+      element-loading-background="rgba(0, 0, 0, 0.8)"
+      class="data-table-content"
+    >
+      <template v-if="tableData.length && upid == 1">
+        <el-table
+          :data="tableData"
+          style="width: 100%"
+          ref="userTableData"
+        >
+          <el-table-column
+            :label="dataContent[1] + '国航行李BRS扫描数据统计表'"
+          >
+            <el-table-column
+              prop="A"
+              label="日期"
+            >
+            </el-table-column>
+            <el-table-column label="离港数">
+              <el-table-column
+                prop="totalfly"
+                label="航班(架次)"
+                width="240"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="totalbag"
+                label="行李(件数)"
+                width="240"
+              >
+              </el-table-column>
+            </el-table-column>
+            <el-table-column label="扫描数">
+              <el-table-column
+                prop="brsfly"
+                label="航班(架次)"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="brsbag"
+                label="行李(件数)"
+              >
+              </el-table-column>
+            </el-table-column>
+            <el-table-column label="扫描率">
+              <el-table-column
+                prop="ra_brsfly"
+                label="航班"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="ra_brsbag"
+                label="行李"
+              >
+              </el-table-column>
+            </el-table-column>
+          </el-table-column>
+        </el-table>
+      </template>
+      <template v-else-if="tableData.length && upid == 2">
+        <el-table
+          :data="tableData"
+          style="width: 100%"
+          ref="userTableDatard"
+        >
+          <el-table-column label="Mannual Load扫描数据统计表">
+            <el-table-column
+              prop="A"
+              label="日期"
+            >
+            </el-table-column>
+            <el-table-column label="离港数">
+              <el-table-column
+                prop="totalfly"
+                label="航班(架次)"
+                width="240"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="totalbag"
+                label="行李(件数)"
+                width="240"
+              >
+              </el-table-column>
+            </el-table-column>
+            <el-table-column label="扫描数">
+              <el-table-column
+                prop="starfly"
+                label="航班(架次)"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="starbag"
+                label="行李(件数)"
+              >
+              </el-table-column>
+            </el-table-column>
+            <el-table-column label="扫描率">
+              <el-table-column
+                prop="ra_starfly"
+                label="航班"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="ra_starbag"
+                label="行李"
+              >
+              </el-table-column>
+            </el-table-column>
+          </el-table-column>
+        </el-table>
+      </template>
+      <template v-else-if="tableData.length && upid == 3">
+        <el-table
+          :data="tableData"
+          style="width: 100%"
+          ref="TableDatardrfid"
+        >
+          <el-table-column label="航易行RFID扫描数据统计表">
+            <el-table-column
+              prop="A"
+              label="日期"
+            >
+            </el-table-column>
+            <el-table-column label="离港数">
+              <el-table-column
+                prop="totalfly"
+                label="航班(架次)"
+                width="240"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="totalbag"
+                label="行李(件数)"
+                width="240"
+              >
+              </el-table-column>
+            </el-table-column>
+            <el-table-column label="扫描数">
+              <el-table-column
+                prop="hyxfly"
+                label="航班(架次)"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="hyxbag"
+                label="行李(件数)"
+              >
+              </el-table-column>
+            </el-table-column>
+            <el-table-column label="扫描率">
+              <el-table-column
+                prop="ra_hyxfly"
+                label="航班"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="ra_hyxbag"
+                label="行李"
+              >
+              </el-table-column>
+            </el-table-column>
+          </el-table-column>
+        </el-table>
+      </template>
+      <template v-else-if="tableData.length && upid == 4">
+        <el-table
+          ref="userTableDatas"
+          :data="tableData"
+          style="width: 100%"
+          :show-summary="true"
+          :summary-method="totalOutPrice"
+          :cell-class-name="cellClass"
+          @cell-click="cellClickHandler"
+        >
+          <el-table-column
+            prop="fd"
+            label="日期"
+          >
+          </el-table-column>
+          <el-table-column label="中转行李流向">
+            <el-table-column label="D-D" v-if="DD">
+              <el-table-column
+                prop="fly_dd_need_trans"
+                label="进港中转航班数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="fly_dd_trans"
+                label="中转出航班数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="bag_dd_need_trans"
+                label="须中转行李数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="bag_dd_trans"
+                label="完成中转行李数"
+              >
+              </el-table-column>
+              <!-- <el-table-column
+                prop="Transferout_dd"
+                label="转出成功率"
+              >
+              </el-table-column> -->
+            </el-table-column>
+            <el-table-column label="D-I"  v-if="DI">
+              <el-table-column
+                prop="fly_di_need_trans"
+                label="进港中转航班数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="fly_di_trans"
+                label="中转出航班数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="bag_di_need_trans"
+                label="须中转行李数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="bag_di_trans"
+                label="完成中转行李数"
+              >
+              </el-table-column>
+              <!-- <el-table-column
+                prop="Transferout_di"
+                label="转出成功率"
+              >
+              </el-table-column> -->
+            </el-table-column>
+            <el-table-column label="I-I"  v-if="II">
+              <el-table-column
+                prop="fly_ii_need_trans"
+                label="进港中转航班数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="fly_ii_trans"
+                label="中转出航班数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="bag_ii_need_trans"
+                label="须中转行李数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="bag_ii_trans"
+                label="完成中转行李数"
+              >
+              </el-table-column>
+              <!-- <el-table-column
+                prop="Transferout_ii"
+                label="转出成功率"
+              >
+              </el-table-column> -->
+            </el-table-column>
+            <el-table-column label="I-D"  v-if="ID">
+              <el-table-column
+                prop="fly_id_need_trans"
+                label="进港中转航班数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="fly_id_trans"
+                label="中转出航班数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="bag_id_need_trans"
+                label="须中转行李数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="bag_id_trans"
+                label="完成中转行李数"
+              >
+              </el-table-column>
+              <!-- <el-table-column
+                prop="Transferout_id"
+                label="转出成功率"
+              >
+              </el-table-column> -->
+            </el-table-column>
+          </el-table-column>
+        </el-table>
+      </template>
+      <template v-else-if="tableData.length && upid == 5">
+        <el-table
+          ref="transferTableData"
+          :data="tableData"
+          style="width: 100%"
+          :show-summary="true"
+          :summary-method="totalOutPrice"
+          :cell-class-name="cellClass"
+          @cell-click="cellClickHandler"
+        >
+          <el-table-column
+            prop="fd"
+            label="日期"
+          >
+          </el-table-column>
+          <el-table-column label="D-D"  v-if="DD">
+            <el-table-column label="T2-T2" v-if="t1">
+              <el-table-column
+                prop="need_trans_flight_dd_22"
+                label="进港中转航班数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="finish_trans_flight_dd_22"
+                label="中转出航班数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="need_trans_bag_dd_22"
+                label="须中转行李数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="finish_trans_bag_dd_22"
+                label="完成中转行李数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="not_trans_bag_dd_22"
+                label="未中转行李数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="Transferout_dd_22"
+                label="转出成功率"
+              >
+              </el-table-column>
+            </el-table-column>
+            <el-table-column label="T2-T3" v-if="t2">
+              <el-table-column
+                prop="need_trans_flight_dd_23"
+                label="进港中转航班数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="finish_trans_flight_dd_23"
+                label="中转出航班数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="need_trans_bag_dd_23"
+                label="须中转行李数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="finish_trans_bag_dd_23"
+                label="完成中转行李数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="not_trans_bag_dd_23"
+                label="未中转行李数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="Transferout_dd_23"
+                label="转出成功率"
+              >
+              </el-table-column>
+            </el-table-column>
+            <el-table-column label="T3-T3" v-if="t3">
+              <el-table-column
+                prop="need_trans_flight_dd_33"
+                label="进港中转航班数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="finish_trans_flight_dd_33"
+                label="中转出航班数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="need_trans_bag_dd_33"
+                label="须中转行李数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="finish_trans_bag_dd_33"
+                label="完成中转行李数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="not_trans_bag_dd_33"
+                label="未中转行李数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="Transferout_dd_33"
+                label="转出成功率"
+              >
+              </el-table-column>
+            </el-table-column>
+            <el-table-column label="T3-T2" v-if="t4">
+              <el-table-column
+                prop="need_trans_flight_dd_32"
+                label="进港中转航班数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="finish_trans_flight_dd_32"
+                label="中转出航班数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="need_trans_bag_dd_32"
+                label="须中转行李数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="finish_trans_bag_dd_32"
+                label="完成中转行李数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="not_trans_bag_dd_32"
+                label="未中转行李数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="Transferout_dd_32"
+                label="转出成功率"
+              >
+              </el-table-column>
+            </el-table-column>
+          </el-table-column>
+          <el-table-column label="D-I"  v-if="DI">
+            <el-table-column label="T2-T2" v-if="t1">
+              <el-table-column
+                prop="need_trans_flight_di_22"
+                label="进港中转航班数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="finish_trans_flight_di_22"
+                label="中转出航班数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="need_trans_bag_di_22"
+                label="须中转行李数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="finish_trans_bag_di_22"
+                label="完成中转行李数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="not_trans_bag_di_22"
+                label="未中转行李数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="Transferout_di_22"
+                label="转出成功率"
+              >
+              </el-table-column>
+            </el-table-column>
+            <el-table-column label="T2-T3" v-if="t2">
+              <el-table-column
+                prop="need_trans_flight_di_23"
+                label="进港中转航班数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="finish_trans_flight_di_23"
+                label="中转出航班数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="need_trans_bag_di_23"
+                label="须中转行李数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="finish_trans_bag_di_23"
+                label="完成中转行李数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="not_trans_bag_di_23"
+                label="未中转行李数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="Transferout_di_23"
+                label="转出成功率"
+              >
+              </el-table-column>
+            </el-table-column>
+            <el-table-column label="T3-T3" v-if="t3">
+              <el-table-column
+                prop="need_trans_flight_di_33"
+                label="进港中转航班数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="finish_trans_flight_di_33"
+                label="中转出航班数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="need_trans_bag_di_33"
+                label="须中转行李数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="finish_trans_bag_di_33"
+                label="完成中转行李数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="not_trans_bag_di_33"
+                label="未中转行李数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="Transferout_di_33"
+                label="转出成功率"
+              >
+              </el-table-column>
+            </el-table-column>
+            <el-table-column label="T3-T2" v-if="t4">
+              <el-table-column
+                prop="need_trans_flight_di_32"
+                label="进港中转航班数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="finish_trans_flight_di_32"
+                label="中转出航班数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="need_trans_bag_di_32"
+                label="须中转行李数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="finish_trans_bag_di_32"
+                label="完成中转行李数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="not_trans_bag_di_32"
+                label="未中转行李数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="Transferout_di_32"
+                label="转出成功率"
+              >
+              </el-table-column>
+            </el-table-column>
+          </el-table-column>
+          <el-table-column label="I-I" v-if="II">
+            <el-table-column label="T2-T2" v-if="t1">
+              <el-table-column
+                prop="need_trans_flight_ii_22"
+                label="进港中转航班数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="finish_trans_flight_ii_22"
+                label="中转出航班数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="need_trans_bag_ii_22"
+                label="须中转行李数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="finish_trans_bag_ii_22"
+                label="完成中转行李数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="not_trans_bag_ii_22"
+                label="未中转行李数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="Transferout_ii_22"
+                label="转出成功率"
+              >
+              </el-table-column>
+            </el-table-column>
+            <el-table-column label="T2-T3" v-if="t2">
+              <el-table-column
+                prop="need_trans_flight_ii_23"
+                label="进港中转航班数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="finish_trans_flight_ii_23"
+                label="中转出航班数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="need_trans_bag_ii_23"
+                label="须中转行李数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="finish_trans_bag_ii_23"
+                label="完成中转行李数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="not_trans_bag_ii_23"
+                label="未中转行李数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="Transferout_ii_23"
+                label="转出成功率"
+              >
+              </el-table-column>
+            </el-table-column>
+            <el-table-column label="T3-T3" v-if="t3">
+              <el-table-column
+                prop="need_trans_flight_ii_33"
+                label="进港中转航班数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="finish_trans_flight_ii_33"
+                label="中转出航班数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="need_trans_bag_ii_33"
+                label="须中转行李数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="finish_trans_bag_ii_33"
+                label="完成中转行李数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="not_trans_bag_ii_33"
+                label="未中转行李数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="Transferout_ii_33"
+                label="转出成功率"
+              >
+              </el-table-column>
+            </el-table-column>
+            <el-table-column label="T3-T2" v-if="t4">
+              <el-table-column
+                prop="need_trans_flight_ii_32"
+                label="进港中转航班数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="finish_trans_flight_ii_32"
+                label="中转出航班数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="need_trans_bag_ii_32"
+                label="须中转行李数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="finish_trans_bag_ii_32"
+                label="完成中转行李数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="not_trans_bag_ii_32"
+                label="未中转行李数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="Transferout_ii_32"
+                label="转出成功率"
+              >
+              </el-table-column>
+            </el-table-column>
+          </el-table-column>
+          <el-table-column label="I-D"  v-if="ID">
+            <el-table-column label="T2-T2" v-if="t1">
+              <el-table-column
+                prop="need_trans_flight_id_22"
+                label="进港中转航班数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="finish_trans_flight_id_22"
+                label="中转出航班数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="need_trans_bag_id_22"
+                label="须中转行李数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="finish_trans_bag_id_22"
+                label="完成中转行李数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="not_trans_bag_id_22"
+                label="未中转行李数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="Transferout_id_22"
+                label="转出成功率"
+              >
+              </el-table-column>
+            </el-table-column>
+            <el-table-column label="T2-T3" v-if="t2">
+              <el-table-column
+                prop="need_trans_flight_id_23"
+                label="进港中转航班数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="finish_trans_flight_id_23"
+                label="中转出航班数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="need_trans_bag_id_23"
+                label="须中转行李数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="finish_trans_bag_id_23"
+                label="完成中转行李数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="not_trans_bag_id_23"
+                label="未中转行李数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="Transferout_id_23"
+                label="转出成功率"
+              >
+              </el-table-column>
+            </el-table-column>
+            <el-table-column label="T3-T3" v-if="t3">
+              <el-table-column
+                prop="need_trans_flight_id_33"
+                label="进港中转航班数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="finish_trans_flight_id_33"
+                label="中转出航班数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="need_trans_bag_id_33"
+                label="须中转行李数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="finish_trans_bag_id_33"
+                label="完成中转行李数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="not_trans_bag_id_33"
+                label="未中转行李数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="Transferout_id_33"
+                label="转出成功率"
+              >
+              </el-table-column>
+            </el-table-column>
+            <el-table-column label="T3-T2" v-if="t4">
+              <el-table-column
+                prop="need_trans_flight_id_32"
+                label="进港中转航班数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="finish_trans_flight_id_32"
+                label="中转出航班数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="need_trans_bag_id_32"
+                label="须中转行李数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="finish_trans_bag_id_32"
+                label="完成中转行李数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="not_trans_bag_id_32"
+                label="未中转行李数"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="Transferout_id_32"
+                label="转出成功率"
+              >
+              </el-table-column>
+            </el-table-column>
+          </el-table-column>
+          <el-table-column
+            prop="a14"
+            label="中转出航班数总数"
+          >
+          </el-table-column>
+          <el-table-column
+            prop="a15"
+            label="中转出航班数总数"
+          >
+          </el-table-column>
+          <el-table-column
+            prop="a16"
+            label="须中转行李数总数"
+          >
+          </el-table-column>
+          <el-table-column
+            prop="a17"
+            label="完成中转行李数总数"
+          >
+          </el-table-column>
+          <el-table-column
+            prop="a19"
+            label="未中转行李数总数"
+          >
+          </el-table-column>
+          <el-table-column
+            prop="a18"
+            label="转出成功率"
+          >
+          </el-table-column>
+        </el-table>
+      </template>
+      <template v-else-if="tableData.length && upid == 6">
+        <el-table
+          ref="transferBaggageTableData"
+          :data="tableData"
+          style="width: 100%"
+          :show-summary="true"
+        >
+          <el-table-column
+            prop="a1"
+            label="日期"
+          >
+          </el-table-column>
+          <el-table-column
+            prop="a2"
+            label="进港中转航班量"
+          >
+          </el-table-column>
+          <el-table-column
+            prop="a3"
+            label="中转行李件数"
+          >
+          </el-table-column>
+          <el-table-column
+            prop="a4"
+            label="未转出件数"
+          >
+          </el-table-column>
+          <el-table-column label="未转出件数分项">
+            <el-table-column
+              prop="a5"
+              label="MCT时间紧"
+            >
+            </el-table-column>
+            <el-table-column
+              prop="a6"
+              label="过检设备原因"
+            >
+            </el-table-column>
+            <el-table-column
+              prop="a7"
+              label="混装"
+            >
+            </el-table-column>
+            <el-table-column
+              prop="a8"
+              label="布控"
+            >
+            </el-table-column>
+            <el-table-column
+              prop="a9"
+              label="等锥桶"
+            >
+            </el-table-column>
+            <el-table-column
+              prop="a10"
+              label="车辆故障"
+            >
+            </el-table-column>
+            <el-table-column
+              prop="a11"
+              label="货舱门/卡锁故障"
+            >
+            </el-table-column>
+            <el-table-column
+              prop="a12"
+              label="机位远"
+            >
+            </el-table-column>
+            <el-table-column
+              prop="a13"
+              label="未通过扫描"
+            >
+            </el-table-column>
+            <el-table-column
+              prop="a14"
+              label="BHS无记录"
+            >
+            </el-table-column>
+            <el-table-column
+              prop="a15"
+              label="分拣设备故障"
+            >
+            </el-table-column>
+            <el-table-column
+              prop="a16"
+              label="进港晚卸"
+            >
+            </el-table-column>
+            <el-table-column
+              prop="a17"
+              label="设备紧张"
+            >
+            </el-table-column>
+            <el-table-column
+              prop="a18"
+              label="导入晚"
+            >
+            </el-table-column>
+            <el-table-column
+              prop="a19"
+              label="正常传出未装机"
+            >
+            </el-table-column>
+            <el-table-column
+              prop="a20"
+              label="错传"
+            >
+            </el-table-column>
+            <el-table-column
+              prop="a21"
+              label="原因待定"
+            >
+            </el-table-column>
+          </el-table-column>
+        </el-table>
+      </template>
+      <template v-else-if="tableData.length && upid == 7">
+        <el-table
+          ref="baggageProportionTableData"
+          :data="tableData"
+          style="width: 100%"
+          :show-summary="true"
+        >
+          <el-table-column
+            prop="a1"
+            label="日期"
+          >
+          </el-table-column>
+          <el-table-column label="总">
+            <el-table-column
+              prop="a2"
+              label="中转行李百分比"
+            >
+            </el-table-column>
+            <el-table-column
+              prop="a3"
+              label="行李总件数"
+            >
+            </el-table-column>
+            <el-table-column
+              prop="a4"
+              label="中转行李件数"
+            >
+            </el-table-column>
+          </el-table-column>
+          <el-table-column label="国内">
+            <el-table-column
+              prop="a5"
+              label="中转行李百分比"
+            >
+            </el-table-column>
+            <el-table-column
+              prop="a6"
+              label="行李总件数"
+            >
+            </el-table-column>
+            <el-table-column
+              prop="a7"
+              label="中转行李件数"
+            >
+            </el-table-column>
+          </el-table-column>
+          <el-table-column label="国际">
+            <el-table-column
+              prop="a8"
+              label="中转行李百分比"
+            >
+            </el-table-column>
+            <el-table-column
+              prop="a9"
+              label="行李总件数"
+            >
+            </el-table-column>
+            <el-table-column
+              prop="a10"
+              label="中转行李件数"
+            >
+            </el-table-column>
+          </el-table-column>
+        </el-table>
+      </template>
+      <template v-else-if="tableData.length && upid == 8">
+        <el-table
+          :data="tableData"
+          style="width: 100%"
+          :show-summary="true"
+          ref="userTableDataelt"
+        >
+        <el-table-column
+            prop="time"
+            label="日期"
+          >
+          </el-table-column>
+          <el-table-column
+            prop="bpm"
+            label="有BPM行李数量"
+          >
+          </el-table-column>
+          <el-table-column
+            prop="bsm"
+            label="总数量"
+          >
+          </el-table-column>
+          <el-table-column
+            prop="lv"
+            label="行李全流程跟踪服务水平(%)"
+          >
+          </el-table-column>
+        </el-table>
+      </template>
+      <template v-else>
+        <NoData
+          image-width="auto"
+          image-height="100%"
+        />
+      </template>
+    </div>
+  </div>
+</template>
+<script>
+import NoData from '@/components/nodata'
+import { TempQuery } from '@/api/temp'
+import { exportToExcel } from '@/utils/table'
+import { Query } from '@/api/webApi'
+export default {
+  props: {
+    // 接口ID
+    dataId: {
+      type: [String, Number],
+      default: '',
+    },
+    isloadings: {
+      type: Number,
+    },
+    upid: {
+      type: [String, Number],
+    },
+    dataContent: {
+      type: Array,
+      default: () => [],
+    },
+    textShow: {
+      type: Array,
+      default: () => [],
+    },
+    textShowtp: {
+      type: Array,
+      default: () => [],
+    },
+  },
+  data() {
+    return {
+      loading: false,
+      page: 0,
+      serviceId: null,
+      rowTitle: '',
+      tableCols: [], //表头数据
+      tableData: [
+        // {
+        //   date: "wnz(7月)",
+        //   name: "409",
+        //   province: "18946",
+        //   city: "409",
+        //   address: "18294",
+        //   zip: "100%",
+        //   cp: "96.56%",
+        // },
+      ],
+      DD: true,
+      DI: true,
+      II: true,
+      ID: true,
+      t1: true,
+      t2: true,
+      t3: true,
+      t4: true,
+    }
+  },
+  components: {
+    NoData,
+  },
+  watch: {
+    dataContent: {
+      handler(val) {
+        if (val) {
+          this.getQuery()
+        }
+      },
+      deep: true,
+    },
+    isloadings: {
+      handler(val) {
+        this.downFile()
+      },
+    },
+    textShow: {
+      handler(val) {
+        if (val.length === 0) {
+          this.DD = true
+          this.DI = true
+          this.II = true
+          this.ID = true
+        } else {
+          this.DD = false
+          this.DI = false
+          this.II = false
+          this.ID = false
+          val.forEach(element => {
+            if (element === 'D-D') {
+              this.DD = true
+            } else if (element === 'D-I') {
+              this.DI = true
+            } else if (element === 'I-I') {
+              this.II = true
+            } else if (element === 'I-D') {
+              this.ID = true
+            }
+          });
+        }
+      },
+    },
+    textShowtp: {
+      handler(val) {
+        if (val.length === 0) {
+          this.t1 = true
+          this.t2 = true
+          this.t3 = true
+          this.t4 = true
+        } else {
+          this.t1 = false
+          this.t2 = false
+          this.t3 = false
+          this.t4 = false
+          val.forEach(element => {
+            if (element === 'T2-T2') {
+              this.t1 = true
+            } else if (element === 'T2-T3') {
+              this.t2 = true
+            } else if (element === 'T3-T3') {
+              this.t3 = true
+            } else if (element === 'T3-T2') {
+              this.t4 = true
+            }
+          });
+        }
+      },
+    },
+  },
+  computed: {
+    dataTableContentStyle() {
+      const style = {}
+      if (this.minHeight) {
+        style['min-height'] = this.minHeight
+      }
+      if (this.tableHeight) {
+        style['height'] = this.tableHeight
+      }
+      return style
+    },
+  },
+  mounted() {
+    // this.getQuery();
+  },
+  methods: {
+    totalOutPrice(param) {
+      const { columns, data } = param;
+      const sums = [];
+      columns.forEach((column, index) => {
+        if (index === 0) {
+          sums[index] = "合计";
+          return;
+        }
+        const values = data.map((item) => Number(item[column.property]));
+        if (
+          column.property != "stand" &&
+          column.property != "flightdate" &&
+          column.property != "indexs" &&
+          column.property != "flightNo" &&
+          column.property != "line" &&
+          column.property != "cargoCompany"
+        ) {
+          sums[index] = values.reduce((prev, curr) => {
+            const value = Number(curr);
+            if (!isNaN(value)) {
+              return prev + curr;
+            } else {
+              return "";
+            }
+          }, 0);
+          sums[index];
+        }
+        if (this.upid == 4) {
+          // sums[6] = (sums[4] * 100 / (sums[3] > 0 ? sums[3] : 1)).toFixed(2) + '%'
+          // sums[12] = (sums[10] * 100 / (sums[9] > 0 ? sums[9] : 1)).toFixed(2) + '%'
+          // sums[18] = (sums[16] * 100 / (sums[15] > 0 ? sums[15] : 1)).toFixed(2) + '%'
+          // sums[24] = (sums[22] * 100 / (sums[21]  > 0 ? sums[21] : 1)).toFixed(2) + '%'
+          // sums[30] = (sums[28] * 100 / (sums[27]  > 0 ? sums[27] : 1)).toFixed(2) + '%'
+        }
+        if (this.upid == 5) {
+          // sums[6] = (sums[4] * 100 / sums[3]).toFixed(2) + '%'
+          // sums[12] = (sums[10] * 100 / sums[9]).toFixed(2) + '%'
+          // sums[18] = (sums[16] * 100 / sums[15]).toFixed(2) + '%'
+          // sums[24] = (sums[22] * 100 / sums[21]).toFixed(2) + '%'
+          // sums[30] = (sums[28] * 100 / sums[27]).toFixed(2) + '%'
+          // sums[36] = (sums[34] * 100 / sums[33]).toFixed(2) + '%'
+          // sums[42] = (sums[40] * 100 / sums[39]).toFixed(2) + '%'
+          for(var i = 6; i < sums.length; i+=6) {
+            sums[i] = (sums[i-2] * 100 / (sums[i-3] > 0 ? sums[i-3] : 1)).toFixed(2) + '%'
+          }
+          // sums[6] = (sums[4] * 100 / (sums[3] > 0 ? sums[3] : 1)).toFixed(2) + '%'
+          // sums[12] = (sums[10] * 100 / (sums[9] > 0 ? sums[9] : 1)).toFixed(2) + '%'
+          // sums[18] = (sums[16] * 100 / (sums[15] > 0 ? sums[15] : 1)).toFixed(2) + '%'
+          // sums[24] = (sums[22] * 100 / (sums[21] > 0 ? sums[21] : 1)).toFixed(2) + '%'
+          // sums[30] = (sums[28] * 100 / (sums[27] > 0 ? sums[27] : 1)).toFixed(2) + '%'
+          // sums[36] = (sums[34] * 100 / (sums[33] > 0 ? sums[33] : 1)).toFixed(2) + '%'
+          // sums[42] = (sums[40] * 100 / (sums[39] > 0 ? sums[39] : 1)).toFixed(2) + '%'
+        }
+      });
+      return sums;
+    },
+    //获取表格数据
+    async getQuery() {
+      try {
+        this.loading = true
+        const { code, returnData } = await Query({
+          serviceId: Number(this.dataId),
+          dataContent: this.dataContent,
+        })
+        if (code == 0) {
+          this.tableData = returnData
+          if (returnData.length === 0) {
+            this.page--
+            this.noMore = true
+            this.loading = false
+          }
+          const titleColumn = returnData.columnSet.find(
+            item => item.needShow === 1
+          )
+          if (titleColumn) {
+            this.rowTitle = titleColumn.columnName
+          }
+          // returnData.listValues.forEach((res) => {
+          //   if (!res.A) {
+          //     res.A = 0;
+          //   }
+          //   if (!res.totalfly) {
+          //     res.totalfly = 0;
+          //   }
+          //   if (!res.totalbag) {
+          //     res.totalbag = 0;
+          //   }
+          //   if (!res.brsfly) {
+          //     res.brsfly = 0;
+          //   }
+          //   if (!res.brsbag) {
+          //     res.brsbag = 0;
+          //   }
+          //   if (!res.ra_brsfly) {
+          //     res.ra_brsfly = 0;
+          //   }
+          //   if (!res.ra_brsbag) {
+          //     res.ra_brsbag = 0;
+          //   }
+          //   if (!res.starfly) {
+          //     res.starfly = 0;
+          //   }
+          //   if (!res.starbag) {
+          //     res.starbag = 0;
+          //   }
+          //   if (!res.ra_starfly) {
+          //     res.ra_starfly = 0;
+          //   }
+          //   if (!res.ra_starfly) {
+          //     res.ra_starfly = 0;
+          //   }
+          //   if (!res.hyxfly) {
+          //     res.hyxfly = 0;
+          //   }
+          //   if (!res.hyxbag) {
+          //     res.hyxbag = 0;
+          //   }
+          //   if (!res.ra_hyxfly) {
+          //     res.ra_hyxfly = 0;
+          //   }
+          //   if (!res.ra_hyxbag) {
+          //     res.ra_hyxbag = 0;
+          //   }
+          // });
+          this.tableData = returnData
+          this.tableCols = returnData.columnSet
+          this.serviceId = returnData.submitID
+          this.loading = false
+          if(this.upid == 4){
+            // this.tableData.forEach(element => {
+            //   element.Transferout_dd = (element.finish_trans_bag_dd * 100 / (element.need_trans_bag_dd > 0  ? element.need_trans_bag_dd : 1)).toFixed(2) + '%'
+            //   element.Transferout_di = (element.finish_trans_bag_di * 100 / (element.need_trans_bag_di > 0  ?  element.need_trans_bag_di : 1)).toFixed(2) + '%'
+            //   element.Transferout_ii = (element.finish_trans_bag_ii * 100 / (element.need_trans_bag_ii > 0  ? element.need_trans_bag_ii : 1)).toFixed(2) + '%'
+            //   element.Transferout_id = (element.finish_trans_bag_id * 100 / (element.need_trans_bag_id > 0 ? element.need_trans_bag_id : 1)).toFixed(2) + '%'
+            //   element.a14 = (this.DD ? element.need_trans_flight_dd : 0) + (this.DI ? element.need_trans_flight_di : 0) + (this.II ? element.need_trans_flight_ii : 0) + (this.ID ? element.need_trans_flight_id : 0)
+            //   element.a15 =  (this.DD ? element.finish_trans_flight_dd : 0) + (this.DI ? element.finish_trans_flight_di : 0) + (this.II ? element.finish_trans_flight_ii : 0) + (this.ID ? element.finish_trans_flight_id : 0)
+            //   element.a16 =  (this.DD ? element.need_trans_bag_dd : 0) + (this.DI ? element.need_trans_bag_di : 0) + (this.II ? element.need_trans_bag_ii : 0) + (this.ID ? element.need_trans_bag_id : 0)
+            //   element.a17 =  (this.DD ? element.finish_trans_bag_dd : 0) + (this.DI ? element.finish_trans_bag_di : 0) + (this.II ? element.finish_trans_bag_ii : 0) + (this.ID ? element.finish_trans_bag_id : 0)
+            //   element.a19 = (this.DD ? element.not_trans_bag_dd : 0) + (this.DI ? element.not_trans_bag_di : 0) + (this.II ? element.not_trans_bag_ii : 0) + (this.ID ? element.not_trans_bag_id : 0)
+            //   element.a18 = (element.a17 * 100 /( element.a16 > 0 ?  element.a16 : 0)).toFixed(2) + '%'
+            // });
+          } else if (this.upid == 5) {
+            this.tableData.forEach(element => {
+              element.Transferout_dd_22 = (element.finish_trans_bag_dd_22 * 100 / (element.need_trans_bag_dd_22 > 0 ? element.need_trans_bag_dd_22 : 1)).toFixed(2) + '%'
+              element.Transferout_dd_23 = (element.finish_trans_bag_dd_23 * 100 / (element.need_trans_bag_dd_23 > 0 ? element.need_trans_bag_dd_23 : 1)).toFixed(2) + '%'
+              element.Transferout_dd_33 = (element.finish_trans_bag_dd_33 * 100 / (element.need_trans_bag_dd_33 > 0 ? element.need_trans_bag_dd_33 : 1)).toFixed(2) + '%'
+              element.Transferout_dd_32 = (element.finish_trans_bag_dd_32 * 100 / (element.need_trans_bag_dd_32 > 0 ? element.need_trans_bag_dd_32 : 1)).toFixed(2) + '%'
+
+              element.Transferout_di_22 = (element.finish_trans_bag_di_22 * 100 / (element.need_trans_bag_di_22 > 0 ? element.need_trans_bag_di_22 : 1)).toFixed(2) + '%'
+              element.Transferout_di_23 = (element.finish_trans_bag_di_23 * 100 / (element.need_trans_bag_di_23 > 0 ? element.need_trans_bag_di_23 : 1)).toFixed(2) + '%'
+              element.Transferout_di_33 = (element.finish_trans_bag_di_33 * 100 / (element.need_trans_bag_di_33 > 0 ? element.need_trans_bag_di_33 : 1)).toFixed(2) + '%'
+              element.Transferout_di_32 = (element.finish_trans_bag_di_32 * 100 / (element.need_trans_bag_di_32 > 0 ? element.need_trans_bag_di_32 : 1)).toFixed(2) + '%'
+
+              element.Transferout_ii_22 = (element.finish_trans_bag_ii_22 * 100 / (element.need_trans_bag_ii_22 > 0 ? element.need_trans_bag_ii_22 : 1)).toFixed(2) + '%'
+              element.Transferout_ii_23 = (element.finish_trans_bag_ii_23 * 100 / (element.need_trans_bag_ii_23 > 0 ? element.need_trans_bag_ii_23 : 1)).toFixed(2) + '%'
+              element.Transferout_ii_33 = (element.finish_trans_bag_ii_33 * 100 / (element.need_trans_bag_ii_33 > 0 ? element.need_trans_bag_ii_33 : 1)).toFixed(2) + '%'
+              element.Transferout_ii_32 = (element.finish_trans_bag_ii_32 * 100 / (element.need_trans_bag_ii_32 > 0 ? element.need_trans_bag_ii_32 : 1)).toFixed(2) + '%'
+
+              element.Transferout_id_22 = (element.finish_trans_bag_id_22 * 100 / (element.need_trans_bag_id_22 > 0 ? element.need_trans_bag_id_22 : 1)).toFixed(2) + '%'
+              element.Transferout_id_23 = (element.finish_trans_bag_id_23 * 100 / (element.need_trans_bag_id_23 > 0 ? element.need_trans_bag_id_23 : 1)).toFixed(2) + '%'
+              element.Transferout_id_33 = (element.finish_trans_bag_id_33 * 100 / (element.need_trans_bag_id_33 > 0 ? element.need_trans_bag_id_33 : 1)).toFixed(2) + '%'
+              element.Transferout_id_32 = (element.finish_trans_bag_id_32 * 100 / (element.need_trans_bag_id_32 > 0 ? element.need_trans_bag_id_32 : 1)).toFixed(2) + '%'
+              
+              let t1DD = (this.t1 ? element.need_trans_flight_dd_22 : 0) + (this.t2 ? element.need_trans_flight_dd_23 : 0) + (this.t3 ? element.need_trans_flight_dd_33 : 0) + (this.t4 ? element.need_trans_flight_dd_32 : 0)
+              let t1DI = (this.t1 ? element.need_trans_flight_di_22 : 0) + (this.t2 ? element.need_trans_flight_di_23 : 0) + (this.t3 ? element.need_trans_flight_di_23 : 0) + (this.t4 ? element.need_trans_flight_di_32 : 0)
+              let t1II = (this.t1 ? element.need_trans_flight_ii_22 : 0) + (this.t2 ? element.need_trans_flight_ii_23 : 0) + (this.t3 ? element.need_trans_flight_ii_33 : 0) + (this.t4 ? element.need_trans_flight_ii_32 : 0)
+              let t1ID = (this.t1 ? element.need_trans_flight_id_22 : 0) + (this.t2 ? element.need_trans_flight_id_23 : 0) + (this.t3 ? element.need_trans_flight_id_33 : 0) + (this.t4 ? element.need_trans_flight_id_32 : 0)
+              element.a14 = (this.DD ? t1DD : 0) + (this.DI ? t1DI : 0) + (this.II ? t1II : 0) + (this.II ? t1ID : 0)
+
+              let t2DD = (this.t1 ? element.finish_trans_flight_dd_22 : 0) + (this.t2 ? element.finish_trans_flight_dd_23 : 0) + (this.t3 ? element.finish_trans_flight_dd_33 : 0) + (this.t4 ? element.finish_trans_flight_dd_32 : 0)
+              let t2DI = (this.t1 ? element.finish_trans_flight_di_22 : 0) + (this.t2 ? element.finish_trans_flight_di_23 : 0) + (this.t3 ? element.finish_trans_flight_di_33 : 0) + (this.t4 ? element.finish_trans_flight_di_32 : 0)
+              let t2II = (this.t1 ? element.finish_trans_flight_ii_22 : 0) + (this.t2 ? element.finish_trans_flight_ii_23 : 0) + (this.t3 ? element.finish_trans_flight_ii_33 : 0) + (this.t4 ? element.finish_trans_flight_ii_32 : 0)
+              let t2ID = (this.t1 ? element.finish_trans_flight_id_22 : 0) + (this.t2 ? element.finish_trans_flight_id_23 : 0) + (this.t3 ? element.finish_trans_flight_id_33 : 0) + (this.t4 ? element.finish_trans_flight_id_32 : 0)
+              element.a15 = (this.DD ? t2DD : 0) + (this.DI ? t2DI : 0) + (this.II ? t2II : 0) + (this.II ? t2ID : 0)
+
+              let t3DD = (this.t1 ? element.need_trans_bag_dd_22 : 0) + (this.t2 ? element.need_trans_bag_dd_23 : 0) + (this.t3 ? element.need_trans_bag_dd_33 : 0) + (this.t4 ? element.need_trans_bag_dd_32 : 0)
+              let t3DI = (this.t1 ? element.need_trans_bag_di_22 : 0) + (this.t2 ? element.need_trans_bag_di_23 : 0) + (this.t3 ? element.need_trans_bag_di_33 : 0) + (this.t4 ? element.need_trans_bag_di_32 : 0)
+              let t3II = (this.t1 ? element.need_trans_bag_ii_22 : 0) + (this.t2 ? element.need_trans_bag_ii_23 : 0) + (this.t3 ? element.need_trans_bag_ii_33 : 0) + (this.t4 ? element.need_trans_bag_ii_32 : 0)
+              let t3ID = (this.t1 ? element.need_trans_bag_id_22 : 0) + (this.t2 ? element.need_trans_bag_id_23 : 0) + (this.t3 ? element.need_trans_bag_id_33 : 0) + (this.t4 ? element.need_trans_bag_id_32 : 0)
+              element.a16 = (this.DD ? t3DD : 0) + (this.DI ? t3DI : 0) + (this.II ? t3II : 0) + (this.II ? t3ID : 0)
+
+              let t4DD = (this.t1 ? element.finish_trans_bag_dd_22 : 0) + (this.t2 ? element.finish_trans_bag_dd_23 : 0) + (this.t3 ? element.finish_trans_bag_dd_33 : 0) + (this.t4 ? element.finish_trans_bag_dd_32 : 0)
+              let t4DI = (this.t1 ? element.finish_trans_bag_di_22 : 0) + (this.t2 ? element.finish_trans_bag_di_23 : 0) + (this.t3 ? element.finish_trans_bag_di_33 : 0) + (this.t4 ? element.finish_trans_bag_di_32 : 0)
+              let t4II = (this.t1 ? element.finish_trans_bag_ii_22 : 0) + (this.t2 ? element.finish_trans_bag_ii_23 : 0) + (this.t3 ? element.finish_trans_bag_ii_33 : 0) + (this.t4 ? element.finish_trans_bag_ii_32 : 0)
+              let t4ID = (this.t1 ? element.finish_trans_bag_id_22 : 0) + (this.t2 ? element.finish_trans_bag_id_23 : 0) + (this.t3 ? element.finish_trans_bag_id_33 : 0) + (this.t4 ? element.finish_trans_bag_id_32 : 0)
+              element.a17 = (this.DD ? t4DD : 0) + (this.DI ? t4DI : 0) + (this.II ? t4II : 0) + (this.II ? t4ID : 0)
+
+              let t5DD = (this.t1 ? element.not_trans_bag_dd_22 : 0) + (this.t2 ? element.not_trans_bag_dd_23 : 0) + (this.t3 ? element.not_trans_bag_dd_33 : 0) + (this.t4 ? element.not_trans_bag_dd_32 : 0)
+              let t5DI = (this.t1 ? element.not_trans_bag_di_22 : 0) + (this.t2 ? element.not_trans_bag_di_23 : 0) + (this.t3 ? element.not_trans_bag_di_33 : 0) + (this.t4 ? element.not_trans_bag_di_32 : 0)
+              let t5II = (this.t1 ? element.not_trans_bag_ii_22 : 0) + (this.t2 ? element.not_trans_bag_ii_23 : 0) + (this.t3 ? element.not_trans_bag_ii_33 : 0) + (this.t4 ? element.not_trans_bag_ii_32 : 0)
+              let t5ID = (this.t1 ? element.not_trans_bag_id_22 : 0) + (this.t2 ? element.not_trans_bag_id_23 : 0) + (this.t3 ? element.not_trans_bag_id_33 : 0) + (this.t4 ? element.not_trans_bag_id_32 : 0)
+              element.a19 = (this.DD ? t5DD : 0) + (this.DI ? t5DI : 0) + (this.II ? t5II : 0) + (this.II ? t5ID : 0)
+
+              element.a18 = (element.a17 * 100 /( element.a16 > 0 ?  element.a16 : 0)).toFixed(2) + '%'
+
+
+
+            });
+          } else if (this.upid == 8) {
+            this.tableData.forEach(element => {
+              element.lv = element.lv.toFixed(2)
+              element.time = this.dataContent[0] + '至' + this.dataContent[1]
+            });
+          }
+          // setTimeout(() => {
+          //   this.initTableData();
+          //   this.loading = false;
+          // }, 100);
+        } else {
+          this.page--
+          this.loading = false
+          this.$message.error('获取表格数据失败')
+        }
+      } catch (error) {
+        this.page--
+        this.loading = false
+      }
+    },
+    downFile() {
+      if (this.upid == 1) {
+        let tableName = this.dataContent[1] + '国航行李BRS扫描数据统计表'
+        const table = this.$refs['userTableData'].$el.cloneNode(true)
+        const fileName = `${tableName}.xlsx`
+        exportToExcel(table, tableName, fileName)
+      } else if (this.upid == 2) {
+        let tableName = 'Mannual Load扫描数据统计表'
+        const table = this.$refs['userTableDatard'].$el.cloneNode(true)
+        const fileName = `${tableName}.xlsx`
+        exportToExcel(table, tableName, fileName)
+      } else if (this.upid == 3) {
+        let tableName = '航易行RFID扫描数据统计表'
+        const table = this.$refs['TableDatardrfid'].$el.cloneNode(true)
+        const fileName = `${tableName}.xlsx`
+        exportToExcel(table, tableName, fileName)
+      } else if (this.upid == 4) {
+        let tableName = '中转四个流向统计表'
+        const table = this.$refs['userTableDatas'].$el.cloneNode(true)
+        const fileName = `${tableName}.xlsx`
+        exportToExcel(table, tableName, fileName)
+      } else if (this.upid == 5) {
+        let tableName = '中转流向明细统计表'
+        const table = this.$refs['transferTableData'].$el.cloneNode(true)
+        const fileName = `${tableName}.xlsx`
+        exportToExcel(table, tableName, fileName)
+      } else if (this.upid == 6) {
+        let tableName = '中转行李因素分析统计表'
+        const table = this.$refs['transferBaggageTableData'].$el.cloneNode(true)
+        const fileName = `${tableName}.xlsx`
+        exportToExcel(table, tableName, fileName)
+      } else if (this.upid == 7) {
+        let tableName = '中转行李比例明细统计表'
+        const table =
+          this.$refs['baggageProportionTableData'].$el.cloneNode(true)
+        const fileName = `${tableName}.xlsx`
+        exportToExcel(table, tableName, fileName)
+      }else if (this.upid == 8) {
+        let tableName = '行李全流程服务水平百分比表'
+        const table =
+          this.$refs['userTableDataelt'].$el.cloneNode(true)
+        const fileName = `${tableName}.xlsx`
+        exportToExcel(table, tableName, fileName)
+      }
+    },
+    cellClass({ row, column, rowIndex, columnIndex }) {
+      const classes = []
+      if (
+        column.property.includes('trans_bag') &&
+        row[column.property] &&
+        Number(row[column.property])
+      ) {
+        classes.push('cell-click')
+      }
+      return classes.join(' ')
+    },
+    cellClickHandler(...payload) {
+      this.$emit('cell-click', ...payload)
+    }
+  },
+}
+</script>
+<style lang="scss" scoped>
+::v-deep .el-table {
+  .cell-click {
+    cursor: pointer;
+    color: #2d7cff;
+  }
+}
+</style>

+ 371 - 0
src/views/statisticsCharts/components/tableformcp.vue

@@ -0,0 +1,371 @@
+<template>
+  <div class="data-table">
+    <div
+      :style="dataTableContentStyle"
+      v-loading="loading"
+      element-loading-text="拼命加载中"
+      element-loading-spinner="el-icon-loading"
+      element-loading-background="rgba(0, 0, 0, 0.8)"
+      class="data-table-content"
+    >
+      <template v-if="tableData.length">
+        <el-table
+          ref="userTableDatas"
+          :data="tableData"
+          style="width: 100%"
+          :show-summary="true"
+          :summary-method="getSummaries"
+        >
+          <el-table-column
+            prop="1"
+            label="日期"
+          >
+          </el-table-column>
+          <el-table-column label="中转行李流向">
+            <el-table-column label="D-D">
+              <el-table-column
+                prop="2"
+                label="转出"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="3"
+                label="未转出"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="4"
+                label="转出成功率"
+              >
+              </el-table-column>
+            </el-table-column>
+            <el-table-column label="D-I">
+              <el-table-column
+                prop="5"
+                label="转出"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="6"
+                label="未转出"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="7"
+                label="转出成功率"
+              >
+              </el-table-column>
+            </el-table-column>
+            <el-table-column label="I-I">
+              <el-table-column
+                prop="8"
+                label="转出"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="9"
+                label="未转出"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="10"
+                label="转出成功率"
+              >
+              </el-table-column>
+            </el-table-column>
+            <el-table-column label="I-D">
+              <el-table-column
+                prop="11"
+                label="转出"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="12"
+                label="未转出"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="13"
+                label="转出成功率"
+              >
+              </el-table-column>
+            </el-table-column>
+          </el-table-column>
+          <el-table-column
+            prop="14"
+            label="进港中转航班数"
+          >
+          </el-table-column>
+          <el-table-column
+            prop="15"
+            label="中转总件数"
+          >
+          </el-table-column>
+          <el-table-column
+            prop="16"
+            label="未转出总件数"
+          >
+          </el-table-column>
+          <el-table-column
+            prop="17"
+            label="转出成功率"
+          >
+          </el-table-column>
+        </el-table>
+      </template>
+      <template v-else>
+        <NoData
+          image-width="auto"
+          image-height="100%"
+        />
+      </template>
+    </div>
+  </div>
+</template>
+<script>
+import NoData from '@/components/nodata'
+import { exportToExcel } from '@/utils/table'
+export default {
+  props: {
+    isloadings: {
+      type: Number,
+    },
+  },
+  data() {
+    return {
+      loading: false,
+      tableData: [
+        {
+          1: '10月7日',
+          2: '161',
+          3: '2',
+          4: '98.77%',
+          5: '64',
+          6: '0',
+          7: '100%',
+          8: '0',
+          9: '0',
+          10: '#DV0.!',
+          11: '0',
+          12: '0',
+          13: '#DV0.!',
+          14: '55',
+          15: '227',
+          16: '2',
+          17: '92.12%',
+        },
+        {
+          1: '10月8日',
+          2: '254',
+          3: '1',
+          4: '99.61%',
+          5: '66',
+          6: '0',
+          7: '100%',
+          8: '0',
+          9: '0',
+          10: '#DV0.!',
+          11: '0',
+          12: '0',
+          13: '#DV0.!',
+          14: '41',
+          15: '321',
+          16: '1',
+          17: '99.69%',
+        },
+        {
+          1: '10月9日',
+          2: '176',
+          3: '0',
+          4: '100%',
+          5: '36',
+          6: '0',
+          7: '100%',
+          8: '0',
+          9: '0',
+          10: '#DV0.!',
+          11: '0',
+          12: '0',
+          13: '#DV0.!',
+          14: '45',
+          15: '213',
+          16: '0',
+          17: '100%',
+        },
+        {
+          1: '10月',
+          2: '199',
+          3: '0',
+          4: '100%',
+          5: '53',
+          6: '0',
+          7: '100%',
+          8: '0',
+          9: '0',
+          10: '#DV0.!',
+          11: '0',
+          12: '0',
+          13: '#DV0.!',
+          14: '42',
+          15: '252',
+          16: '0',
+          17: '100%',
+        },
+        {
+          1: '11月',
+          2: '159',
+          3: '0',
+          4: '100%',
+          5: '42',
+          6: '0',
+          7: '100%',
+          8: '0',
+          9: '0',
+          10: '#DV0.!',
+          11: '0',
+          12: '0',
+          13: '#DV0.!',
+          14: '40',
+          15: '201',
+          16: '0',
+          17: '100%',
+        },
+        {
+          1: '2020年',
+          2: '172',
+          3: '3',
+          4: '98.29%',
+          5: '181',
+          6: '0',
+          7: '100%',
+          8: '0',
+          9: '0',
+          10: '#DV0.!',
+          11: '0',
+          12: '0',
+          13: '#DV0.!',
+          14: '26',
+          15: '356',
+          16: '3',
+          17: '99.16%',
+        },
+        {
+          1: '2021年',
+          2: '194',
+          3: '0',
+          4: '100%',
+          5: '22',
+          6: '0',
+          7: '100%',
+          8: '0',
+          9: '0',
+          10: '#DV0.!',
+          11: '0',
+          12: '0',
+          13: '#DV0.!',
+          14: '26',
+          15: '216',
+          16: '0',
+          17: '100%',
+        },
+      ],
+    }
+  },
+  watch: {
+    isloadings: {
+      handler(val) {
+        this.downFile()
+      },
+    },
+  },
+  components: {
+    NoData,
+  },
+  computed: {
+    dataTableContentStyle() {
+      const style = {}
+      if (this.minHeight) {
+        style['min-height'] = this.minHeight
+      }
+      if (this.tableHeight) {
+        style['height'] = this.tableHeight
+      }
+      return style
+    },
+  },
+  methods: {
+    getSummaries() {
+      let arr = [
+        '合计',
+        '1315',
+        '6',
+        '99.55%',
+        '464',
+        '0',
+        '100%',
+        '0',
+        '0',
+        '#DV0.!',
+        '0',
+        '0',
+        '#DV0.!',
+        '275',
+        '1785',
+        '6',
+        '99.66%',
+      ]
+      // {
+      //   1: "合计",
+      //   2: "218",
+      //   3: "557",
+      //   4: "###",
+      //   5: "12",
+      //   6: "99.32%",
+      //   7: "1",
+      //   8: "1",
+      //   9: "3",
+      //   10: "0",
+      //   11: "######",
+      //   12: "0",
+      //   13: "0",
+      //   14: "0",
+      //   15: "0",
+      //   16: "#DV0.!",
+      //   17: "87",
+      //   18: "131",
+      //   19: "##",
+      //   20: "0",
+      //   21: "100%",
+      //   22: "15",
+      //   23: "17",
+      //   24: "33",
+      //   25: "0",
+      //   26: "100%",
+      //   27: "0",
+      //   28: "0",
+      //   29: "0",
+      //   30: "0",
+      //   31: "100%",
+      //   32: "59",
+      //   33: "147",
+      //   34: "311",
+      //   35: "5",
+      //   36: "98.42%",
+      //   37: "380",
+      //   38: "853",
+      //   39: "2426",
+      //   40: "17",
+      //   41: "99.30%",
+      // },
+      return arr
+    },
+    downFile() {
+      let tableName = '中转专项报表'
+      const table = this.$refs['userTableDatas'].$el.cloneNode(true)
+      const fileName = `${tableName}.xlsx`
+      exportToExcel(table, tableName, fileName)
+    },
+  },
+}
+</script>
+<style lang="scss" scoped></style>

+ 186 - 0
src/views/statisticsCharts/components/tableforms.vue

@@ -0,0 +1,186 @@
+<template>
+  <div class="data-table">
+    <div
+      :style="dataTableContentStyle"
+      v-loading="loading"
+      element-loading-text="拼命加载中"
+      element-loading-spinner="el-icon-loading"
+      element-loading-background="rgba(0, 0, 0, 0.8)"
+      class="data-table-content"
+    >
+      <template v-if="tableData.length">
+        <el-table
+          :data="tableData"
+          style="width: 100%"
+          ref="userTableDatasr"
+        >
+          <el-table-column
+            prop="date"
+            label="时间"
+          >
+          </el-table-column>
+          <el-table-column label="行李平均运输时间">
+            <el-table-column
+              prop="name"
+              label="到达-进入中转平均时间"
+              width="170"
+            >
+            </el-table-column>
+            <el-table-column
+              prop="province"
+              label="卸机-到达平均时间"
+              width="140"
+            >
+            </el-table-column>
+            <el-table-column
+              prop="city"
+              label="装车-装机平均时间"
+              width="140"
+            >
+            </el-table-column>
+            <el-table-column
+              prop="address"
+              label="楼间中转平均时间"
+              width="140"
+            >
+            </el-table-column>
+          </el-table-column>
+          <el-table-column label="行李平均装机时间">
+            <el-table-column
+              prop="zip"
+              label="I-I"
+            >
+            </el-table-column>
+            <el-table-column
+              prop="cp"
+              label="I-D"
+            >
+            </el-table-column>
+            <el-table-column
+              prop="epui"
+              label="D-I"
+            >
+            </el-table-column>
+            <el-table-column
+              prop="cpu"
+              label=" D-D"
+            >
+            </el-table-column>
+            <el-table-column
+              prop="gpu"
+              label="始发行李平均时间"
+            >
+            </el-table-column>
+          </el-table-column>
+          <el-table-column
+            prop="amd"
+            label="值机-分拣平均时间"
+          >
+          </el-table-column>
+          <el-table-column
+            prop="ywd"
+            label="值机-装车平均时间"
+          >
+          </el-table-column>
+        </el-table>
+      </template>
+      <template v-else>
+        <NoData
+          image-width="auto"
+          image-height="100%"
+        />
+      </template>
+    </div>
+  </div>
+</template>
+<script>
+import NoData from '@/components/nodata'
+import { exportToExcel } from '@/utils/table'
+export default {
+  props: {
+    isloadings: {
+      type: Number,
+    },
+  },
+  data() {
+    return {
+      loading: false,
+      tableData: [
+        {
+          date: '2022/1/1',
+          name: '20',
+          province: '20',
+          city: '30',
+          address: '30',
+          zip: '30',
+          cp: '30',
+          epui: '30',
+          cpu: '30',
+          gpu: '30',
+          amd: '20',
+          ywd: '20',
+        },
+        {
+          date: '2022/1/2',
+          name: '',
+          province: '',
+          city: '',
+          address: '',
+          zip: '30',
+          cp: '30',
+          epui: '30',
+          cpu: '30',
+          gpu: '30',
+          amd: '20',
+          ywd: '20',
+        },
+        {
+          date: '2022/1/3',
+          name: '0',
+          province: '0',
+          city: '0',
+          address: '0',
+          zip: '30',
+          cp: '30',
+          epui: '30',
+          cpu: '30',
+          gpu: '30',
+          amd: '20',
+          ywd: '20',
+        },
+      ],
+    }
+  },
+  components: {
+    NoData,
+  },
+  watch: {
+    isloadings: {
+      handler(val) {
+        this.downFile()
+      },
+    },
+  },
+  computed: {
+    dataTableContentStyle() {
+      const style = {}
+      if (this.minHeight) {
+        style['min-height'] = this.minHeight
+      }
+      if (this.tableHeight) {
+        style['height'] = this.tableHeight
+      }
+      return style
+    },
+  },
+  methods: {
+    downFile() {
+      let tableName = '运送效率报表'
+      const table = this.$refs['userTableDatasr'].$el.cloneNode(true)
+      const fileName = `${tableName}.xlsx`
+      exportToExcel(table, tableName, fileName)
+    },
+  },
+}
+</script>
+<style lang="scss" scoped></style>

+ 22 - 0
src/views/statisticsCharts/index.vue

@@ -0,0 +1,22 @@
+<template>
+  <div class="statistics-charts-wrapper">
+    <!--导航-->
+    <StatisticsTabs />
+    <router-view />
+  </div>
+</template>
+
+<script>
+import StatisticsTabs from './components/statisticsTabs.vue'
+
+export default {
+  name: 'Dashboard',
+  components: { StatisticsTabs }
+}
+</script>
+
+<style lang="scss" scoped>
+.statistics-charts-wrapper {
+  padding: 24px 24px 0;
+}
+</style>

+ 55 - 0
src/views/statisticsCharts/mixins/noTerminal.js

@@ -0,0 +1,55 @@
+export default {
+  data() {
+    return {
+      customFormItems: [
+        {
+          itemIndex: 0,
+          replaceNum: 1,
+          prop: 'range',
+          inputType: 'select',
+          placeholder: '统计范围',
+          requiredWarning: '请先选择统计范围',
+          options: [
+            {
+              value: '全部',
+              label: '全部'
+            },
+            {
+              value: '航线',
+              label: '航线'
+            },
+            {
+              value: '基地分公司',
+              label: '基地分公司'
+            },
+            {
+              value: '航站',
+              label: '航站'
+            }
+          ],
+          changeHandler(value) {
+            this.setInOrOutOptions(value)
+            const rangeMap = {
+              航线: 'airline',
+              基地分公司: 'area',
+              航站: 'airport'
+            }
+            Object.entries(rangeMap).forEach(([k, v]) => {
+              const theItem = this.formItems.find(item => item.prop === v)
+              if (value === k) {
+                theItem && (theItem.disabled = false)
+              } else {
+                this.formData[v] = ''
+                theItem && (theItem.disabled = true)
+              }
+            })
+          }
+        },
+        {
+          itemIndex: 7,
+          replaceNum: 1
+        }
+      ]
+    }
+  }
+}

+ 65 - 0
src/views/statisticsCharts/mixins/onlyAirline.js

@@ -0,0 +1,65 @@
+export default {
+  data() {
+    return {
+      customFormItems: [
+        {
+          itemIndex: 0,
+          replaceNum: 1,
+          prop: 'range',
+          inputType: 'select',
+          placeholder: '统计范围',
+          requiredWarning: '请先选择统计范围',
+          options: [
+            {
+              value: '全部',
+              label: '全部'
+            },
+            {
+              value: '航线',
+              label: '航线'
+            }
+          ],
+          changeHandler(value) {
+            this.setInOrOutOptions(value)
+            const rangeMap = {
+              航线: 'airline'
+            }
+            Object.entries(rangeMap).forEach(([k, v]) => {
+              const theItem = this.formItems.find(item => item.prop === v)
+              if (value === k) {
+                theItem && (theItem.disabled = false)
+              } else {
+                this.formData[v] = ''
+                theItem && (theItem.disabled = true)
+              }
+            })
+          }
+        },
+        {
+          itemIndex: 2,
+          replaceNum: 1,
+          prop: 'interval',
+          inputType: 'select',
+          placeholder: '时间维度',
+          requiredWarning: '请先选择统计时间维度',
+          disabled: true,
+          defaultOption: '日',
+          options: [
+            {
+              value: '日',
+              label: '按日统计'
+            }
+          ]
+        },
+        {
+          itemIndex: 5,
+          replaceNum: 3
+        },
+        {
+          itemIndex: 1,
+          replaceNum: 1
+        }
+      ]
+    }
+  }
+}

+ 67 - 0
src/views/statisticsCharts/mixins/passengerType.js

@@ -0,0 +1,67 @@
+export default {
+  created() {
+    if (!this.customFormItems) {
+      this.customFormItems = []
+    }
+    this.customFormItems.push({
+      prop: 'passengerType',
+      inputType: 'cascader',
+      placeholder: '旅客类型',
+      requiredWarning: '请先选择旅客类型',
+      clearable: true,
+      options: [
+        {
+          value: '常客等级',
+          label: '常客',
+          children: [
+            {
+              value: '全部',
+              label: '全部'
+            },
+            {
+              value: '白金卡',
+              label: '白金卡'
+            },
+            {
+              value: '金卡',
+              label: '金卡'
+            },
+            {
+              value: '银卡',
+              label: '银卡'
+            },
+            {
+              value: '普卡',
+              label: '普卡'
+            },
+            {
+              value: '其它',
+              label: '其它'
+            }
+          ]
+        },
+        {
+          value: '要客类型',
+          label: '要客',
+          children: [
+            {
+              value: '全部',
+              label: '全部'
+            },
+            {
+              value: 'VVIP',
+              label: 'VVIP'
+            },
+            {
+              value: 'VIP',
+              label: 'VIP'
+            }
+          ]
+        }
+      ],
+      props: {
+        expandTrigger: 'hover'
+      }
+    })
+  }
+}

+ 64 - 0
src/views/statisticsCharts/views/abnormalBaggageClassificationStatisticsCharts.vue

@@ -0,0 +1,64 @@
+<template>
+  <CommonPieStatisticsCharts
+    charts-title="异常行李分类"
+    :query-settings="querySettings"
+    :categories="categories"
+    :form-data="formData"
+    :form-items="formItems"
+  />
+</template>
+
+<script>
+import CommonPieStatisticsCharts from '../components/newPieStatisticsCharts.vue'
+
+export default {
+  name: 'AbnormalBaggageClassificationStatisticsCharts',
+  components: { CommonPieStatisticsCharts },
+
+  data() {
+    return {
+      querySettings: {
+        serviceId: SERVICE_ID.abnormalBaggageClassification,
+      },
+      categories: [
+        {
+          name: '少收',
+          key: 'shaoshou',
+        },
+        {
+          name: '多收',
+          key: 'duoshou',
+        },
+        {
+          name: '破损',
+          key: 'posun',
+        },
+      ],
+      formData: {
+        dateTime: [],
+        airport: '',
+      },
+      formItems: [
+        {
+          prop: 'airport',
+          inputType: 'select',
+          placeholder: '航站',
+          width: '150px',
+          filterable: true,
+          // multiple: true,
+          queryId: SERVICE_ID.AirportIds,
+          setKey: 'code3',
+          requiredWarning: '请先选择航站',
+          options: [],
+        },
+        {
+          prop: 'dateTime',
+          inputType: 'datePicker',
+          width: '240px',
+          requiredWarning: '请先选择统计时间范围',
+        },
+      ],
+    }
+  },
+}
+</script>

+ 26 - 0
src/views/statisticsCharts/views/airlineCompany/abnormalBaggageStatisticsCharts.vue

@@ -0,0 +1,26 @@
+<template>
+  <CommonBarStatisticsCharts
+    charts-title="异常行李量"
+    :query-settings="querySettings"
+    :custom-form-items="customFormItems"
+  />
+</template>
+
+<script>
+import CommonBarStatisticsCharts from '../../components/commonBarStatisticsCharts.vue'
+import noTerminal from '../../mixins/noTerminal'
+
+export default {
+  name: 'AbnormalBaggageStatisticsCharts',
+  components: { CommonBarStatisticsCharts },
+  mixins: [noTerminal],
+  data() {
+    return {
+      querySettings: {
+        byArea: SERVICE_ID.abnormalBaggageByArea,
+        byOther: SERVICE_ID.abnormalBaggageByOther
+      }
+    }
+  }
+}
+</script>

+ 22 - 0
src/views/statisticsCharts/views/airlineCompany/baggageAverageStatisticsCharts.vue

@@ -0,0 +1,22 @@
+<template>
+  <CommonBarStatisticsCharts
+    charts-title="平均行李量"
+    :query-settings="querySettings"
+  />
+</template>
+
+<script>
+import CommonBarStatisticsCharts from '../../components/commonBarStatisticsCharts.vue'
+export default {
+  name: 'BaggageAverageStatisticsCharts',
+  components: { CommonBarStatisticsCharts },
+  data() {
+    return {
+      querySettings: {
+        byArea: SERVICE_ID.baggageAverageByArea,
+        byOther: SERVICE_ID.baggageAverageByOther
+      }
+    }
+  }
+}
+</script>

+ 22 - 0
src/views/statisticsCharts/views/airlineCompany/baggagePassengerStatisticsCharts.vue

@@ -0,0 +1,22 @@
+<template>
+  <CommonBarStatisticsCharts
+    charts-title="行李旅客量"
+    :query-settings="querySettings"
+  />
+</template>
+
+<script>
+import CommonBarStatisticsCharts from '../../components/commonBarStatisticsCharts.vue'
+export default {
+  name: 'BaggagePassengerStatisticsCharts',
+  components: { CommonBarStatisticsCharts },
+  data() {
+    return {
+      querySettings: {
+        byArea: SERVICE_ID.baggagePassengerByArea,
+        byOther: SERVICE_ID.baggagePassengerByOther
+      }
+    }
+  }
+}
+</script>

+ 44 - 0
src/views/statisticsCharts/views/airlineCompany/baggageStatisticsCharts.vue

@@ -0,0 +1,44 @@
+<template>
+  <CommonBarStatisticsCharts
+    charts-title="行李量"
+    :query-settings="querySettings"
+    :custom-form-items="customFormItems"
+  />
+</template>
+
+<script>
+import CommonBarStatisticsCharts from '../../components/commonBarStatisticsCharts.vue'
+export default {
+  name: 'BaggageStatisticsCharts',
+  components: { CommonBarStatisticsCharts },
+  data() {
+    return {
+      querySettings: {
+        byArea: SERVICE_ID.baggageByArea,
+        byOther: SERVICE_ID.baggageByOther,
+        notDelByArea: SERVICE_ID.notDelByArea,
+        notDelByOther: SERVICE_ID.notDelByOther
+      },
+      customFormItems: [
+        {
+          prop: 'baggageType',
+          inputType: 'select',
+          placeholder: '行李类型',
+          requiredWarning: '请先选择行李类型',
+          clearable: true,
+          options: [
+            {
+              value: '全部',
+              label: '全部'
+            },
+            {
+              value: '不包含DEL',
+              label: '实际托运'
+            }
+          ]
+        }
+      ]
+    }
+  }
+}
+</script>

+ 26 - 0
src/views/statisticsCharts/views/airlineCompany/compensationBaggageStatisticsCharts.vue

@@ -0,0 +1,26 @@
+<template>
+  <CommonBarStatisticsCharts
+    charts-title="赔偿行李量"
+    :query-settings="querySettings"
+    :custom-form-items="customFormItems"
+  />
+</template>
+
+<script>
+import CommonBarStatisticsCharts from '../../components/commonBarStatisticsCharts.vue'
+import noTerminal from '../../mixins/noTerminal'
+
+export default {
+  name: 'CompensationBaggageStatisticsCharts',
+  components: { CommonBarStatisticsCharts },
+  mixins: [noTerminal],
+  data() {
+    return {
+      querySettings: {
+        byArea: SERVICE_ID.compensationBaggageByArea,
+        byOther: SERVICE_ID.compensationBaggageByOther
+      }
+    }
+  }
+}
+</script>

+ 26 - 0
src/views/statisticsCharts/views/airlineCompany/compensationStatisticsCharts.vue

@@ -0,0 +1,26 @@
+<template>
+  <CommonBarStatisticsCharts
+    charts-title="赔偿金额"
+    :query-settings="querySettings"
+    :custom-form-items="customFormItems"
+  />
+</template>
+
+<script>
+import CommonBarStatisticsCharts from '../../components/commonBarStatisticsCharts.vue'
+import noTerminal from '../../mixins/noTerminal'
+
+export default {
+  name: 'CompensationStatisticsCharts',
+  components: { CommonBarStatisticsCharts },
+  mixins: [noTerminal],
+  data() {
+    return {
+      querySettings: {
+        byArea: SERVICE_ID.compensationByArea,
+        byOther: SERVICE_ID.compensationByOther
+      }
+    }
+  }
+}
+</script>

+ 26 - 0
src/views/statisticsCharts/views/airlineCompany/complaintBaggageStatisticsCharts.vue

@@ -0,0 +1,26 @@
+<template>
+  <CommonBarStatisticsCharts
+    charts-title="投诉行李量"
+    :query-settings="querySettings"
+    :custom-form-items="customFormItems"
+  />
+</template>
+
+<script>
+import CommonBarStatisticsCharts from '../../components/commonBarStatisticsCharts.vue'
+import noTerminal from '../../mixins/noTerminal'
+
+export default {
+  name: 'ComplaintBaggageStatisticsCharts',
+  components: { CommonBarStatisticsCharts },
+  mixins: [noTerminal],
+  data() {
+    return {
+      querySettings: {
+        byArea: SERVICE_ID.complaintBaggageByArea,
+        byOther: SERVICE_ID.complaintBaggageByOther
+      }
+    }
+  }
+}
+</script>

+ 44 - 0
src/views/statisticsCharts/views/airlineCompany/flightStatisticsCharts.vue

@@ -0,0 +1,44 @@
+<template>
+  <CommonBarStatisticsCharts
+    charts-title="航班量"
+    :query-settings="querySettings"
+    :custom-form-items="customFormItems"
+  />
+</template>
+
+<script>
+import CommonBarStatisticsCharts from '../../components/commonBarStatisticsCharts.vue'
+export default {
+  name: 'FlightStatisticsCharts',
+  components: { CommonBarStatisticsCharts },
+  data() {
+    return {
+      querySettings: {
+        byArea: SERVICE_ID.byArea,
+        byOther: SERVICE_ID.byOther,
+        withBaggageByArea: SERVICE_ID.withBaggageByArea,
+        withBaggageByOther: SERVICE_ID.withBaggageByOther
+      },
+      customFormItems: [
+        {
+          prop: 'flightType',
+          inputType: 'select',
+          placeholder: '航班属性',
+          requiredWarning: '请先选择航班属性',
+          clearable: true,
+          options: [
+            {
+              value: '全部',
+              label: '全部'
+            },
+            {
+              value: '有行李',
+              label: '有行李'
+            }
+          ]
+        }
+      ]
+    }
+  }
+}
+</script>

+ 22 - 0
src/views/statisticsCharts/views/airlineCompany/specialBaggageStatisticsCharts.vue

@@ -0,0 +1,22 @@
+<template>
+  <CommonBarStatisticsCharts
+    charts-title="特殊行李量"
+    :query-settings="querySettings"
+  />
+</template>
+
+<script>
+import CommonBarStatisticsCharts from '../../components/commonBarStatisticsCharts.vue'
+export default {
+  name: 'SpecialBaggageStatisticsCharts',
+  components: { CommonBarStatisticsCharts },
+  data() {
+    return {
+      querySettings: {
+        byArea: SERVICE_ID.specialBaggageByArea,
+        byOther: SERVICE_ID.specialBaggageByOther
+      }
+    }
+  }
+}
+</script>

+ 177 - 0
src/views/statisticsCharts/views/averagepassengers/averagepassairlineStatisticsCharts.vue

@@ -0,0 +1,177 @@
+<template>
+  <CommonBarStatisticsCharts charts-title="航司平均旅客行李量" :rol="rol" :query-settings="querySettings" :form-data="formData" :form-items="formItems" />
+</template>
+
+<script>
+import CommonBarStatisticsCharts from '../../components/newBarStatisticsCharts.vue'
+import { Query } from '@/api/webApi'
+import { parseTime } from '@/utils'
+
+export default {
+  name: 'WorkloadStatisticsCharts',
+  components: { CommonBarStatisticsCharts },
+  data () {
+    const that = this
+    return {
+      querySettings: {
+        serviceId: SERVICE_ID.averagepassairline,
+        seriesKey: 'workload',
+        xAxisKey: 'fd',
+      },
+      formData: {
+        td: '日',
+        aircompany: '',
+        status: '',
+        // agent_number: '',
+        // airport: '',
+        dateTime: [],
+      },
+      rol: 'avgbag',
+      formItems: [
+        {
+          prop: 'td',
+          inputType: 'select',
+          placeholder: '时间维度',
+          requiredWarning: '请先选择统计时间维度',
+          options: [
+            {
+              value: '日',
+              label: '按日统计',
+            },
+            {
+              value: '月',
+              label: '按月统计',
+            },
+            {
+              value: '年',
+              label: '按年统计',
+            },
+          ],
+          changeHandler (value, oldValue) {
+            const typeMap = {
+              日: 'datePicker',
+              月: 'monthPicker',
+              年: 'yearPicker',
+            }
+            const dateTimeItem = this.formItems.find(
+              item => item.prop === 'dateTime'
+            )
+            const formData = this._.cloneDeep(this.formData)
+            if (dateTimeItem) {
+              dateTimeItem.inputType = typeMap[value]
+              const dateTime = formData.dateTime
+              if (dateTime && dateTime[0] && dateTime[1]) {
+                if (value === '年') {
+                  this.formData.dateTime[0] = dateTime[0].split('-')[0]
+                  this.formData.dateTime[1] = dateTime[1].split('-')[0]
+                }
+                if (value === '月') {
+                  if (oldValue === '年') {
+                    this.formData.dateTime[0] = `${dateTime[0].split('-')[0]
+                      }-01`
+                    this.formData.dateTime[1] = `${dateTime[1].split('-')[0]
+                      }-12`
+                  }
+                  if (oldValue === '日') {
+                    this.formData.dateTime[0] = dateTime[0]
+                      .split('-')
+                      .slice(0, 2)
+                      .join('-')
+                    this.formData.dateTime[1] = dateTime[1]
+                      .split('-')
+                      .slice(0, 2)
+                      .join('-')
+                  }
+                }
+                if (value === '日') {
+                  if (oldValue === '年') {
+                    this.formData.dateTime[0] = `${dateTime[0].split('-')[0]
+                      }-01-01`
+                    this.formData.dateTime[1] = `${dateTime[1].split('-')[0]
+                      }-12-31`
+                  }
+                  if (oldValue === '月') {
+                    this.formData.dateTime[0] = `${dateTime[0]
+                      .split('-')
+                      .slice(0, 2)
+                      .join('-')}-01`
+                    let [year, month] = dateTime[1].split('-')
+                    if (month === '12') {
+                      year = Number(year) + 1
+                      month = 1
+                    } else {
+                      month = Number(month) + 1
+                    }
+                    const day = 24 * 60 * 60 * 1000
+                    this.formData.dateTime[1] = parseTime(
+                      new Date(`${year}-${month}-01`) - day * 1,
+                      '{y}-{m}-{d}'
+                    )
+                  }
+                }
+              }
+            }
+          },
+        },
+        {
+          prop: 'aircompany',
+          inputType: 'select',
+          placeholder: '航司',
+          filterable: true,
+          queryId: SERVICE_ID.AirlinportId,
+          setKey: 'ITATCode',
+          requiredWarning: '请先选择航司',
+          options: [],
+        },{
+          prop: 'status',
+          inputType: 'select',
+          placeholder: '全部',
+          requiredWarning: '请先选择行李状态',
+          filterable: true,
+          options: [{
+              value: '正常',
+              label: "正常",
+            },{
+              value: '取消',
+              label: "取消",
+            },{
+              value: '全部',
+              label: "全部",
+            }],
+        },
+        {
+          prop: 'dateTime',
+          inputType: 'datePicker',
+          width: '240px',
+          requiredWarning: '请先选择时间范围',
+        },
+      ],
+    }
+  },
+  methods: {
+    async getAgentOptions (airport) {
+      try {
+        const { code, returnData, message } = await Query({
+          serviceId: SERVICE_ID.agentCode,
+          dataContent: [
+            {
+              airport,
+            },
+          ],
+        })
+        if (String(code) === '0') {
+          const listValues = returnData.listValues || returnData
+          // this.formItems[2].options = listValues.map(element => ({
+          //   label: element.agent_number,
+          //   value: element.agent_number,
+          // }))
+        } else {
+          this.$message.error(message)
+        }
+      } catch (error) {
+        this.$message.error('失败')
+      }
+    },
+  },
+}
+</script>

+ 177 - 0
src/views/statisticsCharts/views/averagepassengers/averagepassrouteStatisticsCharts.vue

@@ -0,0 +1,177 @@
+<template>
+  <CommonBarStatisticsCharts charts-title="航线平均旅客行李量" :rol="rol" :query-settings="querySettings" :form-data="formData" :form-items="formItems" />
+</template>
+
+<script>
+import CommonBarStatisticsCharts from '../../components/newBarStatisticsCharts.vue'
+import { Query } from '@/api/webApi'
+import { parseTime } from '@/utils'
+
+export default {
+  name: 'WorkloadStatisticsCharts',
+  components: { CommonBarStatisticsCharts },
+  data () {
+    const that = this
+    return {
+      querySettings: {
+        serviceId: SERVICE_ID.averagepassroute,
+        seriesKey: 'workload',
+        xAxisKey: 'fd',
+      },
+      formData: {
+        td: '日',
+        // agent_number: '',
+        // airport: '',
+        line: '',
+        status: '',
+        dateTime: [],
+      },
+      rol: 'avgbag',
+      formItems: [
+        {
+          prop: 'td',
+          inputType: 'select',
+          placeholder: '时间维度',
+          requiredWarning: '请先选择统计时间维度',
+          options: [
+            {
+              value: '日',
+              label: '按日统计',
+            },
+            {
+              value: '月',
+              label: '按月统计',
+            },
+            {
+              value: '年',
+              label: '按年统计',
+            },
+          ],
+          changeHandler (value, oldValue) {
+            const typeMap = {
+              日: 'datePicker',
+              月: 'monthPicker',
+              年: 'yearPicker',
+            }
+            const dateTimeItem = this.formItems.find(
+              item => item.prop === 'dateTime'
+            )
+            const formData = this._.cloneDeep(this.formData)
+            if (dateTimeItem) {
+              dateTimeItem.inputType = typeMap[value]
+              const dateTime = formData.dateTime
+              if (dateTime && dateTime[0] && dateTime[1]) {
+                if (value === '年') {
+                  this.formData.dateTime[0] = dateTime[0].split('-')[0]
+                  this.formData.dateTime[1] = dateTime[1].split('-')[0]
+                }
+                if (value === '月') {
+                  if (oldValue === '年') {
+                    this.formData.dateTime[0] = `${dateTime[0].split('-')[0]
+                      }-01`
+                    this.formData.dateTime[1] = `${dateTime[1].split('-')[0]
+                      }-12`
+                  }
+                  if (oldValue === '日') {
+                    this.formData.dateTime[0] = dateTime[0]
+                      .split('-')
+                      .slice(0, 2)
+                      .join('-')
+                    this.formData.dateTime[1] = dateTime[1]
+                      .split('-')
+                      .slice(0, 2)
+                      .join('-')
+                  }
+                }
+                if (value === '日') {
+                  if (oldValue === '年') {
+                    this.formData.dateTime[0] = `${dateTime[0].split('-')[0]
+                      }-01-01`
+                    this.formData.dateTime[1] = `${dateTime[1].split('-')[0]
+                      }-12-31`
+                  }
+                  if (oldValue === '月') {
+                    this.formData.dateTime[0] = `${dateTime[0]
+                      .split('-')
+                      .slice(0, 2)
+                      .join('-')}-01`
+                    let [year, month] = dateTime[1].split('-')
+                    if (month === '12') {
+                      year = Number(year) + 1
+                      month = 1
+                    } else {
+                      month = Number(month) + 1
+                    }
+                    const day = 24 * 60 * 60 * 1000
+                    this.formData.dateTime[1] = parseTime(
+                      new Date(`${year}-${month}-01`) - day * 1,
+                      '{y}-{m}-{d}'
+                    )
+                  }
+                }
+              }
+            }
+          },
+        },
+        {
+          prop: 'line',
+          inputType: 'select',
+          placeholder: '航线',
+          filterable: true,
+          queryId: SERVICE_ID.AirlineIds,
+          setKey: 'air_line',
+          requiredWarning: '请先选择航线',
+          options: [],
+        },{
+          prop: 'status',
+          inputType: 'select',
+          placeholder: '全部',
+          requiredWarning: '请先选择行李状态',
+          filterable: true,
+          options: [{
+              value: '正常',
+              label: "正常",
+            },{
+              value: '取消',
+              label: "取消",
+            },{
+              value: '全部',
+              label: "全部",
+            }],
+        },
+        {
+          prop: 'dateTime',
+          inputType: 'datePicker',
+          width: '240px',
+          requiredWarning: '请先选择时间范围',
+        },
+      ],
+    }
+  },
+  methods: {
+    async getAgentOptions (airport) {
+      try {
+        const { code, returnData, message } = await Query({
+          serviceId: SERVICE_ID.agentCode,
+          dataContent: [
+            {
+              airport,
+            },
+          ],
+        })
+        if (String(code) === '0') {
+          const listValues = returnData.listValues || returnData
+          // this.formItems[2].options = listValues.map(element => ({
+          //   label: element.agent_number,
+          //   value: element.agent_number,
+          // }))
+        } else {
+          this.$message.error(message)
+        }
+      } catch (error) {
+        this.$message.error('失败')
+      }
+    },
+  },
+}
+</script>

+ 195 - 0
src/views/statisticsCharts/views/averagepassengers/averagepassterminalStatisticsCharts.vue

@@ -0,0 +1,195 @@
+<template>
+  <CommonBarStatisticsCharts charts-title="航站平均旅客行李量" :rol="rol" :query-settings="querySettings" :form-data="formData" :form-items="formItems" />
+</template>
+
+<script>
+import CommonBarStatisticsCharts from '../../components/newBarStatisticsCharts.vue'
+import { Query } from '@/api/webApi'
+import { parseTime } from '@/utils'
+
+export default {
+  name: 'WorkloadStatisticsCharts',
+  components: { CommonBarStatisticsCharts },
+  data () {
+    const that = this
+    return {
+      querySettings: {
+        serviceId: SERVICE_ID.averagepassterminal,
+        seriesKey: 'workload',
+        xAxisKey: 'fd',
+      },
+      formData: {
+        td: '日',
+        // agent_number: '',
+        airport: '',
+        iotype: '',
+        status: '',
+        dateTime: [],
+      },
+      rol: 'avgbag',
+      formItems: [
+        {
+          prop: 'td',
+          inputType: 'select',
+          placeholder: '时间维度',
+          requiredWarning: '请先选择统计时间维度',
+          options: [
+            {
+              value: '日',
+              label: '按日统计',
+            },
+            {
+              value: '月',
+              label: '按月统计',
+            },
+            {
+              value: '年',
+              label: '按年统计',
+            },
+          ],
+          changeHandler (value, oldValue) {
+            const typeMap = {
+              日: 'datePicker',
+              月: 'monthPicker',
+              年: 'yearPicker',
+            }
+            const dateTimeItem = this.formItems.find(
+              item => item.prop === 'dateTime'
+            )
+            const formData = this._.cloneDeep(this.formData)
+            if (dateTimeItem) {
+              dateTimeItem.inputType = typeMap[value]
+              const dateTime = formData.dateTime
+              if (dateTime && dateTime[0] && dateTime[1]) {
+                if (value === '年') {
+                  this.formData.dateTime[0] = dateTime[0].split('-')[0]
+                  this.formData.dateTime[1] = dateTime[1].split('-')[0]
+                }
+                if (value === '月') {
+                  if (oldValue === '年') {
+                    this.formData.dateTime[0] = `${dateTime[0].split('-')[0]
+                      }-01`
+                    this.formData.dateTime[1] = `${dateTime[1].split('-')[0]
+                      }-12`
+                  }
+                  if (oldValue === '日') {
+                    this.formData.dateTime[0] = dateTime[0]
+                      .split('-')
+                      .slice(0, 2)
+                      .join('-')
+                    this.formData.dateTime[1] = dateTime[1]
+                      .split('-')
+                      .slice(0, 2)
+                      .join('-')
+                  }
+                }
+                if (value === '日') {
+                  if (oldValue === '年') {
+                    this.formData.dateTime[0] = `${dateTime[0].split('-')[0]
+                      }-01-01`
+                    this.formData.dateTime[1] = `${dateTime[1].split('-')[0]
+                      }-12-31`
+                  }
+                  if (oldValue === '月') {
+                    this.formData.dateTime[0] = `${dateTime[0]
+                      .split('-')
+                      .slice(0, 2)
+                      .join('-')}-01`
+                    let [year, month] = dateTime[1].split('-')
+                    if (month === '12') {
+                      year = Number(year) + 1
+                      month = 1
+                    } else {
+                      month = Number(month) + 1
+                    }
+                    const day = 24 * 60 * 60 * 1000
+                    this.formData.dateTime[1] = parseTime(
+                      new Date(`${year}-${month}-01`) - day * 1,
+                      '{y}-{m}-{d}'
+                    )
+                  }
+                }
+              }
+            }
+          },
+        },
+        {
+          prop: 'airport',
+          inputType: 'select',
+          placeholder: '航站',
+          filterable: true,
+          queryId: SERVICE_ID.AirportIds,
+          setKey: 'code3',
+          requiredWarning: '请先选择航站',
+          options: [],
+        },
+        {
+          prop: 'iotype',
+          inputType: 'select',
+          placeholder: '进港离港',
+          requiredWarning: '请先选择进港离港',
+          filterable: true,
+          options: [{
+              value: '离港',
+              label: "离港",
+            },{
+              value: '进港',
+              label: "进港",
+            },{
+              value: '中转',
+              label: "中转",
+            }],
+        },
+        {
+          prop: 'status',
+          inputType: 'select',
+          placeholder: '全部',
+          requiredWarning: '请先选择行李状态',
+          filterable: true,
+          options: [{
+              value: '正常',
+              label: "正常",
+            },{
+              value: '取消',
+              label: "取消",
+            },{
+              value: '全部',
+              label: "全部",
+            }],
+        },
+        {
+          prop: 'dateTime',
+          inputType: 'datePicker',
+          width: '240px',
+          requiredWarning: '请先选择时间范围',
+        },
+      ],
+    }
+  },
+  methods: {
+    async getAgentOptions (airport) {
+      try {
+        const { code, returnData, message } = await Query({
+          serviceId: SERVICE_ID.agentCode,
+          dataContent: [
+            {
+              airport,
+            },
+          ],
+        })
+        if (String(code) === '0') {
+          const listValues = returnData.listValues || returnData
+          // this.formItems[2].options = listValues.map(element => ({
+          //   label: element.agent_number,
+          //   value: element.agent_number,
+          // }))
+        } else {
+          this.$message.error(message)
+        }
+      } catch (error) {
+        this.$message.error('失败')
+      }
+    },
+  },
+}
+</script>

+ 181 - 0
src/views/statisticsCharts/views/baggage/airlineStatisticsCharts.vue

@@ -0,0 +1,181 @@
+<template>
+  <CommonBarStatisticsCharts
+    charts-title="航线行李量"
+    :query-settings="querySettings"
+    :formItems="formItems"
+    :formData="formData"
+  />
+</template>
+
+<script>
+import CommonBarStatisticsCharts from '../../components/newBarStatisticsCharts.vue'
+import { mapGetters } from 'vuex'
+export default {
+  name: 'BaggagePassengerStatisticsCharts',
+  components: { CommonBarStatisticsCharts },
+  data() {
+    return {
+      querySettings: {
+        serviceid: '',
+      },
+      formData: {
+        td: '日',
+        air_line: null,
+        dateTime: [],
+        baggageType: '',
+      },
+      formItems: [
+        {
+          prop: 'td',
+          inputType: 'select',
+          placeholder: '时间维度',
+          requiredWarning: '请先选择统计时间维度',
+          options: [
+            {
+              value: '日',
+              label: '按日统计',
+            },
+            {
+              value: '月',
+              label: '按月统计',
+            },
+            {
+              value: '年',
+              label: '按年统计',
+            },
+          ],
+          changeHandler(value, oldValue) {
+            const typeMap = {
+              日: 'datePicker',
+              月: 'monthPicker',
+              年: 'yearPicker',
+            }
+            const dateTimeItem = this.formItems.find(
+              item => item.prop === 'dateTime'
+            )
+            const formData = this._.cloneDeep(this.formData)
+            if (dateTimeItem) {
+              dateTimeItem.inputType = typeMap[value]
+              const dateTime = formData.dateTime
+              if (dateTime && dateTime[0] && dateTime[1]) {
+                if (value === '年') {
+                  this.formData.dateTime[0] = dateTime[0].split('-')[0]
+                  this.formData.dateTime[1] = dateTime[1].split('-')[0]
+                }
+                if (value === '月') {
+                  if (oldValue === '年') {
+                    this.formData.dateTime[0] = `${
+                      dateTime[0].split('-')[0]
+                    }-01`
+                    this.formData.dateTime[1] = `${
+                      dateTime[1].split('-')[0]
+                    }-12`
+                  }
+                  if (oldValue === '日') {
+                    this.formData.dateTime[0] = dateTime[0]
+                      .split('-')
+                      .slice(0, 2)
+                      .join('-')
+                    this.formData.dateTime[1] = dateTime[1]
+                      .split('-')
+                      .slice(0, 2)
+                      .join('-')
+                  }
+                }
+                if (value === '日') {
+                  if (oldValue === '年') {
+                    this.formData.dateTime[0] = `${
+                      dateTime[0].split('-')[0]
+                    }-01-01`
+                    this.formData.dateTime[1] = `${
+                      dateTime[1].split('-')[0]
+                    }-12-31`
+                  }
+                  if (oldValue === '月') {
+                    this.formData.dateTime[0] = `${dateTime[0]
+                      .split('-')
+                      .slice(0, 2)
+                      .join('-')}-01`
+                    let [year, month] = dateTime[1].split('-')
+                    if (month === '12') {
+                      year = Number(year) + 1
+                      month = 1
+                    } else {
+                      month = Number(month) + 1
+                    }
+                    const day = 24 * 60 * 60 * 1000
+                    this.formData.dateTime[1] = parseTime(
+                      new Date(`${year}-${month}-01`) - day * 1,
+                      '{y}-{m}-{d}'
+                    )
+                  }
+                }
+              }
+            }
+          },
+        },
+        {
+          prop: 'air_line',
+          inputType: 'select',
+          placeholder: '航线',
+          requiredWarning: '请先选择航线',
+          filterable: true,
+          // clearable: true,
+          width: '180px',
+          queryId: SERVICE_ID.AirlineIds,
+          setKey: 'air_line',
+          options: [],
+        },
+        {
+          prop: 'baggageType',
+          inputType: 'select',
+          placeholder: '行李类型',
+          requiredWarning: '请先选择行李类型',
+          // clearable: true,
+          options: [
+            {
+              value: '正常',
+              label: '正常',
+            },
+            {
+              value: '异常',
+              label: '取消',
+            },
+          ],
+        },
+        {
+          prop: 'dateTime',
+          inputType: 'datePicker',
+          // clearable: true,
+          width: '240px',
+          requiredWarning: '请先选择时间范围',
+        },
+      ],
+    }
+  },
+  computed: {
+    ...mapGetters(['authArrs']),
+  },
+  mounted() {
+    this.pageInit()
+  },
+  methods: {
+    //页面初始化
+    pageInit () {
+      //获取页面查询参数
+      const { query } = this.$route
+      this.pageQuery = query
+      //获取页面配置
+      const { pagecode, qid, auth_id } = this.$route.meta
+      //获取页面权限类型组件  pagetype 1模块  2页面  3按钮 4表格 5树形  6弹窗 
+      const pageAuths = this.authArrs
+      if (!pageAuths.length) return
+      //获取当前页面权限类型
+      const pageAuthArrs = pageAuths.filter(item => item['superiorid'] == auth_id)
+      if (!pageAuthArrs.length) return
+      // console.log(pageAuthArrs)
+      this.querySettings.serviceid = pageAuthArrs[0].serviceid
+    },
+  },
+}
+</script>

+ 185 - 0
src/views/statisticsCharts/views/baggage/baggageAllStatisticsCharts.vue

@@ -0,0 +1,185 @@
+<template>
+  <CommonBarStatisticsCharts
+    charts-title="行李数量"
+    :query-settings="querySettings"
+    :formItems="formItems"
+    :formData="formData"
+  />
+</template>
+
+<script>
+import CommonBarStatisticsCharts from '../../components/newBarStatisticsCharts.vue'
+import { mapGetters } from 'vuex'
+export default {
+  name: 'FlightStatisticsCharts',
+  components: { CommonBarStatisticsCharts },
+  data() {
+    return {
+      querySettings: {
+        serviceid: '',
+      },
+      formData: {
+        td: '日',
+        airport: 'CAN',
+        dateTime: [],
+        io: '',
+      },
+      formItems: [
+        {
+          prop: 'td',
+          inputType: 'select',
+          placeholder: '时间维度',
+          requiredWarning: '请先选择统计时间维度',
+          options: [
+            {
+              value: '日',
+              label: '按日统计',
+            },
+            {
+              value: '月',
+              label: '按月统计',
+            },
+            {
+              value: '年',
+              label: '按年统计',
+            },
+          ],
+          changeHandler(value, oldValue) {
+            const typeMap = {
+              日: 'datePicker',
+              月: 'monthPicker',
+              年: 'yearPicker',
+            }
+            const dateTimeItem = this.formItems.find(
+              item => item.prop === 'dateTime'
+            )
+            const formData = this._.cloneDeep(this.formData)
+            if (dateTimeItem) {
+              dateTimeItem.inputType = typeMap[value]
+              const dateTime = formData.dateTime
+              if (dateTime && dateTime[0] && dateTime[1]) {
+                if (value === '年') {
+                  this.formData.dateTime[0] = dateTime[0].split('-')[0]
+                  this.formData.dateTime[1] = dateTime[1].split('-')[0]
+                }
+                if (value === '月') {
+                  if (oldValue === '年') {
+                    this.formData.dateTime[0] = `${
+                      dateTime[0].split('-')[0]
+                    }-01`
+                    this.formData.dateTime[1] = `${
+                      dateTime[1].split('-')[0]
+                    }-12`
+                  }
+                  if (oldValue === '日') {
+                    this.formData.dateTime[0] = dateTime[0]
+                      .split('-')
+                      .slice(0, 2)
+                      .join('-')
+                    this.formData.dateTime[1] = dateTime[1]
+                      .split('-')
+                      .slice(0, 2)
+                      .join('-')
+                  }
+                }
+                if (value === '日') {
+                  if (oldValue === '年') {
+                    this.formData.dateTime[0] = `${
+                      dateTime[0].split('-')[0]
+                    }-01-01`
+                    this.formData.dateTime[1] = `${
+                      dateTime[1].split('-')[0]
+                    }-12-31`
+                  }
+                  if (oldValue === '月') {
+                    this.formData.dateTime[0] = `${dateTime[0]
+                      .split('-')
+                      .slice(0, 2)
+                      .join('-')}-01`
+                    let [year, month] = dateTime[1].split('-')
+                    if (month === '12') {
+                      year = Number(year) + 1
+                      month = 1
+                    } else {
+                      month = Number(month) + 1
+                    }
+                    const day = 24 * 60 * 60 * 1000
+                    this.formData.dateTime[1] = parseTime(
+                      new Date(`${year}-${month}-01`) - day * 1,
+                      '{y}-{m}-{d}'
+                    )
+                  }
+                }
+              }
+            }
+          },
+        },
+        {
+          prop: 'airport',
+          inputType: 'select',
+          placeholder: '航站',
+          width: '150px',
+          filterable: true,
+          // clearable: true,
+          requiredWarning: '请先选择航站',
+          queryId: 74,
+          setKey: 'IATACode',
+          options: [],
+        },
+        {
+          prop: 'io',
+          inputType: 'select',
+          placeholder: '进出港',
+          requiredWarning: '请先选择进出港',
+          // clearable: true,
+          options: [
+            {
+              value: '离港',
+              label: '离港',
+            },
+            {
+              value: '进港',
+              label: '进港',
+            },
+            {
+              value: '中转',
+              label: '中转',
+            },
+          ],
+        },
+        {
+          prop: 'dateTime',
+          inputType: 'datePicker',
+          // clearable: true,
+          width: '240px',
+          requiredWarning: '请先选择统计时间范围',
+        },
+      ],
+    }
+  },
+  computed: {
+    ...mapGetters(['authArrs']),
+  },
+  mounted() {
+    this.pageInit()
+  },
+  methods: {
+    //页面初始化
+    pageInit () {
+      //获取页面查询参数
+      const { query } = this.$route
+      this.pageQuery = query
+      //获取页面配置
+      const { pagecode, qid, auth_id } = this.$route.meta
+      //获取页面权限类型组件  pagetype 1模块  2页面  3按钮 4表格 5树形  6弹窗 
+      const pageAuths = this.authArrs
+      if (!pageAuths.length) return
+      //获取当前页面权限类型
+      const pageAuthArrs = pageAuths.filter(item => item['superiorid'] == auth_id)
+      if (!pageAuthArrs.length) return
+      // console.log(pageAuthArrs)
+      this.querySettings.serviceid = pageAuthArrs[0].serviceid
+    },
+  },
+}
+</script>

+ 183 - 0
src/views/statisticsCharts/views/baggage/companyStatisticsCharts.vue

@@ -0,0 +1,183 @@
+<template>
+  <CommonBarStatisticsCharts
+    charts-title="航司行李量"
+    :query-settings="querySettings"
+    :formItems="formItems"
+    :formData="formData"
+  />
+</template>
+
+<script>
+import CommonBarStatisticsCharts from '../../components/newBarStatisticsCharts.vue'
+import { mapGetters } from 'vuex'
+export default {
+  name: 'BaggageStatisticsCharts',
+  components: { CommonBarStatisticsCharts },
+  data() {
+    return {
+      querySettings: {
+        serviceid: '',
+      },
+      formData: {
+        td: '日',
+        iata_code: null,
+        dateTime: [],
+        baggageType: '',
+      },
+      formItems: [
+        {
+          prop: 'td',
+          inputType: 'select',
+          placeholder: '时间维度',
+          requiredWarning: '请先选择统计时间维度',
+          options: [
+            {
+              value: '日',
+              label: '按日统计',
+            },
+            {
+              value: '月',
+              label: '按月统计',
+            },
+            {
+              value: '年',
+              label: '按年统计',
+            },
+          ],
+          changeHandler(value, oldValue) {
+            const typeMap = {
+              日: 'datePicker',
+              月: 'monthPicker',
+              年: 'yearPicker',
+            }
+            const dateTimeItem = this.formItems.find(
+              item => item.prop === 'dateTime'
+            )
+            const formData = this._.cloneDeep(this.formData)
+            if (dateTimeItem) {
+              dateTimeItem.inputType = typeMap[value]
+              const dateTime = formData.dateTime
+              if (dateTime && dateTime[0] && dateTime[1]) {
+                if (value === '年') {
+                  this.formData.dateTime[0] = dateTime[0].split('-')[0]
+                  this.formData.dateTime[1] = dateTime[1].split('-')[0]
+                }
+                if (value === '月') {
+                  if (oldValue === '年') {
+                    this.formData.dateTime[0] = `${
+                      dateTime[0].split('-')[0]
+                    }-01`
+                    this.formData.dateTime[1] = `${
+                      dateTime[1].split('-')[0]
+                    }-12`
+                  }
+                  if (oldValue === '日') {
+                    this.formData.dateTime[0] = dateTime[0]
+                      .split('-')
+                      .slice(0, 2)
+                      .join('-')
+                    this.formData.dateTime[1] = dateTime[1]
+                      .split('-')
+                      .slice(0, 2)
+                      .join('-')
+                  }
+                }
+                if (value === '日') {
+                  if (oldValue === '年') {
+                    this.formData.dateTime[0] = `${
+                      dateTime[0].split('-')[0]
+                    }-01-01`
+                    this.formData.dateTime[1] = `${
+                      dateTime[1].split('-')[0]
+                    }-12-31`
+                  }
+                  if (oldValue === '月') {
+                    this.formData.dateTime[0] = `${dateTime[0]
+                      .split('-')
+                      .slice(0, 2)
+                      .join('-')}-01`
+                    let [year, month] = dateTime[1].split('-')
+                    if (month === '12') {
+                      year = Number(year) + 1
+                      month = 1
+                    } else {
+                      month = Number(month) + 1
+                    }
+                    const day = 24 * 60 * 60 * 1000
+                    this.formData.dateTime[1] = parseTime(
+                      new Date(`${year}-${month}-01`) - day * 1,
+                      '{y}-{m}-{d}'
+                    )
+                  }
+                }
+              }
+            }
+          },
+        },
+        {
+          prop: 'iata_code',
+          inputType: 'select',
+          placeholder: '航司',
+          requiredWarning: '请先选择航司',
+          width: '150px',
+          filterable: true,
+          // clearable: true,
+          // multiple: true,
+          // disabled: true,
+          queryId: 73,
+          setKey: 'ITATCode',
+          options: [],
+        },
+        {
+          prop: 'baggageType',
+          inputType: 'select',
+          placeholder: '行李类型',
+          requiredWarning: '请先选择行李类型',
+          // clearable: true,
+          options: [
+            {
+              value: '正常',
+              label: '正常',
+            },
+            {
+              value: '异常',
+              label: '取消',
+            },
+          ],
+        },
+        {
+          prop: 'dateTime',
+          inputType: 'datePicker',
+          // clearable: true,
+          width: '240px',
+          requiredWarning: '请先选择时间范围',
+        },
+      ],
+    }
+  },
+  computed: {
+    ...mapGetters(['authArrs']),
+  },
+  mounted() {
+    this.pageInit()
+  },
+  methods: {
+    //页面初始化
+    pageInit () {
+      //获取页面查询参数
+      const { query } = this.$route
+      this.pageQuery = query
+      //获取页面配置
+      const { pagecode, qid, auth_id } = this.$route.meta
+      //获取页面权限类型组件  pagetype 1模块  2页面  3按钮 4表格 5树形  6弹窗 
+      const pageAuths = this.authArrs
+      if (!pageAuths.length) return
+      //获取当前页面权限类型
+      const pageAuthArrs = pageAuths.filter(item => item['superiorid'] == auth_id)
+      if (!pageAuthArrs.length) return
+      // console.log(pageAuthArrs)
+      this.querySettings.serviceid = pageAuthArrs[0].serviceid
+    },
+  },
+}
+</script>

+ 74 - 0
src/views/statisticsCharts/views/baggage/hourStatisticsCharts.vue

@@ -0,0 +1,74 @@
+<template>
+  <CommonBarStatisticsCharts
+    charts-title="行李小时量数量"
+    :query-settings="querySettings"
+    :formItems="formItems"
+    :formData="formData"
+  />
+</template>
+
+<script>
+import CommonBarStatisticsCharts from '../../components/newBarStatisticsCharts.vue'
+export default {
+  name: 'FlightStatisticsCharts',
+  components: { CommonBarStatisticsCharts },
+  data() {
+    return {
+      querySettings: {
+        serviceId: SERVICE_ID.LuggageHourId,
+        seriesKey: 'bags',
+        xAxisKey: 'dat',
+      },
+      formData: {
+        airport: 'CAN',
+        dateTime: [],
+        io_type: '',
+      },
+      formItems: [
+        {
+          prop: 'airport',
+          inputType: 'select',
+          placeholder: '航站',
+          requiredWarning: '请先选择航站',
+          width: '150px',
+          filterable: true,
+          // clearable: true,
+          // multiple: true,
+          // disabled: true,
+          queryId: SERVICE_ID.AirportIds,
+          setKey: 'code3',
+          options: [],
+        },
+        {
+          prop: 'io_type',
+          inputType: 'select',
+          placeholder: '进出港',
+          requiredWarning: '请先选择进出港',
+          // clearable: true,
+          options: [
+            {
+              value: '离港',
+              label: '离港',
+            },
+            {
+              value: '进港',
+              label: '进港',
+            },
+            {
+              value: '中转',
+              label: '中转',
+            },
+          ],
+        },
+        {
+          prop: 'dateTime',
+          inputType: 'datePicker',
+          // clearable: true,
+          width: '240px',
+          requiredWarning: '请先选择时间范围',
+        },
+      ],
+    }
+  },
+}
+</script>

+ 244 - 0
src/views/statisticsCharts/views/flight/flightvolumeStatisticsCharts.vue

@@ -0,0 +1,244 @@
+<template>
+  <CommonBarStatisticsCharts charts-title="航站航班量" :rol="rol" :query-settings="querySettings" :form-data="formData" :form-items="formItems" />
+</template>
+
+<script>
+import CommonBarStatisticsCharts from '../../components/newBarStatisticsCharts.vue'
+import { Query } from '@/api/webApi'
+import { parseTime } from '@/utils'
+
+export default {
+  name: 'WorkloadStatisticsCharts',
+  components: { CommonBarStatisticsCharts },
+  data () {
+    const that = this
+    return {
+      querySettings: {
+        serviceId: SERVICE_ID.terminalflight,
+        seriesKey: 'workload',
+        xAxisKey: 'fd',
+      },
+      rol: 'fly',
+      formData: {
+        td: '日',
+        // agent_number: '',
+        airport: '',
+        iotype: '',
+        flightstatus: '',
+        crafttype: '',
+        ditype: '',
+        ishas: '',
+        dateTime: [],
+      },
+      formItems: [
+        {
+          prop: 'td',
+          inputType: 'select',
+          placeholder: '时间维度',
+          requiredWarning: '请先选择统计时间维度',
+          options: [
+            {
+              value: '日',
+              label: '按日统计',
+            },
+            {
+              value: '月',
+              label: '按月统计',
+            },
+            {
+              value: '年',
+              label: '按年统计',
+            },
+          ],
+          // changeHandler (value, oldValue) {
+          //   const typeMap = {
+          //     日: 'datePicker',
+          //     月: 'monthPicker',
+          //     年: 'yearPicker',
+          //   }
+          //   const dateTimeItem = this.formItems.find(
+          //     item => item.prop === 'dateTime'
+          //   )
+          //   const formData = this._.cloneDeep(this.formData)
+          //   if (dateTimeItem) {
+          //     dateTimeItem.inputType = typeMap[value]
+          //     const dateTime = formData.dateTime
+          //     if (dateTime && dateTime[0] && dateTime[1]) {
+          //       if (value === '年') {
+          //         this.formData.dateTime[0] = dateTime[0].split('-')[0]
+          //         this.formData.dateTime[1] = dateTime[1].split('-')[0]
+          //       }
+          //       if (value === '月') {
+          //         if (oldValue === '年') {
+          //           this.formData.dateTime[0] = `${dateTime[0].split('-')[0]
+          //             }-01`
+          //           this.formData.dateTime[1] = `${dateTime[1].split('-')[0]
+          //             }-12`
+          //         }
+          //         if (oldValue === '日') {
+          //           this.formData.dateTime[0] = dateTime[0]
+          //             .split('-')
+          //             .slice(0, 2)
+          //             .join('-')
+          //           this.formData.dateTime[1] = dateTime[1]
+          //             .split('-')
+          //             .slice(0, 2)
+          //             .join('-')
+          //         }
+          //       }
+          //       if (value === '日') {
+          //         if (oldValue === '年') {
+          //           this.formData.dateTime[0] = `${dateTime[0].split('-')[0]
+          //             }-01-01`
+          //           this.formData.dateTime[1] = `${dateTime[1].split('-')[0]
+          //             }-12-31`
+          //         }
+          //         if (oldValue === '月') {
+          //           this.formData.dateTime[0] = `${dateTime[0]
+          //             .split('-')
+          //             .slice(0, 2)
+          //             .join('-')}-01`
+          //           let [year, month] = dateTime[1].split('-')
+          //           if (month === '12') {
+          //             year = Number(year) + 1
+          //             month = 1
+          //           } else {
+          //             month = Number(month) + 1
+          //           }
+          //           const day = 24 * 60 * 60 * 1000
+          //           this.formData.dateTime[1] = parseTime(
+          //             new Date(`${year}-${month}-01`) - day * 1,
+          //             '{y}-{m}-{d}'
+          //           )
+          //         }
+          //       }
+          //     }
+          //   }
+          // },
+        },
+        {
+          prop: 'airport',
+          inputType: 'select',
+          placeholder: '航站',
+          filterable: true,
+          queryId: SERVICE_ID.AirportIds,
+          setKey: 'code3',
+          requiredWarning: '请先选择航站',
+          options: [],
+        },
+        {
+          prop: 'iotype',
+          inputType: 'select',
+          placeholder: '进港离港',
+          requiredWarning: '请先选择进港离港',
+          filterable: true,
+          options: [{
+              value: '离港',
+              label: "离港",
+            },{
+              value: '进港',
+              label: "进港",
+            },{
+              value: '中转',
+              label: "中转",
+            }],
+        },
+        {
+          prop: 'flightstatus',
+          inputType: 'select',
+          placeholder: '航班状态',
+          requiredWarning: '请先选择航班状态',
+          filterable: true,
+          options: [{
+              value: '正常',
+              label: "正常",
+            },{
+              value: '延误',
+              label: "延误",
+            },{
+              value: '取消',
+              label: "取消",
+            },{
+              value: '全部',
+              label: "全部",
+            }],
+        },
+        {
+          prop: 'crafttype',
+          inputType: 'select',
+          placeholder: '机型',
+          requiredWarning: '请先选择机型',
+          filterable: true,
+          queryId: SERVICE_ID.ModelIds,
+          setKey: 'craftType',
+          options: [],
+        },
+        {
+          prop: 'ditype',
+          inputType: 'select',
+          placeholder: '国内国际',
+          requiredWarning: '请先选择国内国际',
+          filterable: true,
+          options: [{
+              value: '国内',
+              label: "国内",
+            },{
+              value: '国际',
+              label: "国际",
+            },{
+              value: '全部',
+              label: "全部",
+            }],
+        },{
+          prop: 'ishas',
+          inputType: 'select',
+          placeholder: '无行李',
+          requiredWarning: '请先选择有无行李',
+          filterable: true,
+          options: [{
+              value: '有行李',
+              label: "有行李",
+            },{
+              value: '无行李',
+              label: "无行李",
+            },{
+              value: '全部',
+              label: "全部",
+            }],
+        },
+        {
+          prop: 'dateTime',
+          inputType: 'datePicker',
+          width: '240px',
+          requiredWarning: '请先选择时间范围',
+        },
+      ],
+    }
+  },
+  methods: {
+    async getAgentOptions (airport) {
+      try {
+        const { code, returnData, message } = await Query({
+          serviceId: SERVICE_ID.agentCode,
+          dataContent: [
+            {
+              airport,
+            },
+          ],
+        })
+        if (String(code) === '0') {
+          const listValues = returnData.listValues || returnData
+          // this.formItems[2].options = listValues.map(element => ({
+          //   label: element.agent_number,
+          //   value: element.agent_number,
+          // }))
+        } else {
+          this.$message.error(message)
+        }
+      } catch (error) {
+        this.$message.error('失败')
+      }
+    },
+  },
+}
+</script>

+ 227 - 0
src/views/statisticsCharts/views/flight/numberairStatisticsCharts.vue

@@ -0,0 +1,227 @@
+<template>
+  <CommonBarStatisticsCharts charts-title="航司航班量" :rol="rol" :query-settings="querySettings" :form-data="formData" :form-items="formItems" />
+</template>
+
+<script>
+import CommonBarStatisticsCharts from '../../components/newBarStatisticsCharts.vue'
+import { Query } from '@/api/webApi'
+import { parseTime } from '@/utils'
+
+export default {
+  name: 'WorkloadStatisticsCharts',
+  components: { CommonBarStatisticsCharts },
+  data () {
+    const that = this
+    return {
+      querySettings: {
+        serviceId: SERVICE_ID.numberairline,
+        seriesKey: 'workload',
+        xAxisKey: 'fd',
+      },
+      formData: {
+        td: '日',
+        aircompany: '',
+        flightstatus: '',
+        crafttype: '',
+        ditype: '',
+        ishas: '',
+        // agent_number: '',
+        // airport: '',
+        dateTime: [],
+      },
+      rol: 'fly',
+      formItems: [
+        {
+          prop: 'td',
+          inputType: 'select',
+          placeholder: '时间维度',
+          requiredWarning: '请先选择统计时间维度',
+          options: [
+            {
+              value: '日',
+              label: '按日统计',
+            },
+            {
+              value: '月',
+              label: '按月统计',
+            },
+            {
+              value: '年',
+              label: '按年统计',
+            },
+          ],
+          changeHandler (value, oldValue) {
+            const typeMap = {
+              日: 'datePicker',
+              月: 'monthPicker',
+              年: 'yearPicker',
+            }
+            const dateTimeItem = this.formItems.find(
+              item => item.prop === 'dateTime'
+            )
+            const formData = this._.cloneDeep(this.formData)
+            if (dateTimeItem) {
+              dateTimeItem.inputType = typeMap[value]
+              const dateTime = formData.dateTime
+              if (dateTime && dateTime[0] && dateTime[1]) {
+                if (value === '年') {
+                  this.formData.dateTime[0] = dateTime[0].split('-')[0]
+                  this.formData.dateTime[1] = dateTime[1].split('-')[0]
+                }
+                if (value === '月') {
+                  if (oldValue === '年') {
+                    this.formData.dateTime[0] = `${dateTime[0].split('-')[0]
+                      }-01`
+                    this.formData.dateTime[1] = `${dateTime[1].split('-')[0]
+                      }-12`
+                  }
+                  if (oldValue === '日') {
+                    this.formData.dateTime[0] = dateTime[0]
+                      .split('-')
+                      .slice(0, 2)
+                      .join('-')
+                    this.formData.dateTime[1] = dateTime[1]
+                      .split('-')
+                      .slice(0, 2)
+                      .join('-')
+                  }
+                }
+                if (value === '日') {
+                  if (oldValue === '年') {
+                    this.formData.dateTime[0] = `${dateTime[0].split('-')[0]
+                      }-01-01`
+                    this.formData.dateTime[1] = `${dateTime[1].split('-')[0]
+                      }-12-31`
+                  }
+                  if (oldValue === '月') {
+                    this.formData.dateTime[0] = `${dateTime[0]
+                      .split('-')
+                      .slice(0, 2)
+                      .join('-')}-01`
+                    let [year, month] = dateTime[1].split('-')
+                    if (month === '12') {
+                      year = Number(year) + 1
+                      month = 1
+                    } else {
+                      month = Number(month) + 1
+                    }
+                    const day = 24 * 60 * 60 * 1000
+                    this.formData.dateTime[1] = parseTime(
+                      new Date(`${year}-${month}-01`) - day * 1,
+                      '{y}-{m}-{d}'
+                    )
+                  }
+                }
+              }
+            }
+          },
+        },
+        {
+          prop: 'aircompany',
+          inputType: 'select',
+          placeholder: '航司',
+          filterable: true,
+          queryId: SERVICE_ID.AirlinportId,
+          setKey: 'ITATCode',
+          requiredWarning: '请先选择航司',
+          options: [],
+        },
+        {
+          prop: 'flightstatus',
+          inputType: 'select',
+          placeholder: '全部',
+          requiredWarning: '请先选择航班状态',
+          filterable: true,
+          options: [{
+              value: '正常',
+              label: "正常",
+            },{
+              value: '延误',
+              label: "延误",
+            },{
+              value: '取消',
+              label: "取消",
+            },{
+              value: '全部',
+              label: "全部",
+            }],
+        },
+        {
+          prop: 'crafttype',
+          inputType: 'select',
+          placeholder: '全部',
+          requiredWarning: '请先选择机型',
+          filterable: true,
+          queryId: SERVICE_ID.ModelIds,
+          setKey: 'craftType',
+          options: [],
+        },
+        {
+          prop: 'ditype',
+          inputType: 'select',
+          placeholder: '全部',
+          requiredWarning: '请先选择国内国际',
+          filterable: true,
+          options: [{
+              value: '国内',
+              label: "国内",
+            },{
+              value: '国际',
+              label: "国际",
+            },{
+              value: '全部',
+              label: "全部",
+            }],
+        },{
+          prop: 'ishas',
+          inputType: 'select',
+          placeholder: '全部',
+          requiredWarning: '请先选择有无行李',
+          filterable: true,
+          options: [{
+              value: '有行李',
+              label: "有行李",
+            },{
+              value: '无行李',
+              label: "无行李",
+            },{
+              value: '全部',
+              label: "全部",
+            }],
+        },
+        {
+          prop: 'dateTime',
+          inputType: 'datePicker',
+          width: '240px',
+          requiredWarning: '请先选择时间范围',
+        },
+      ],
+    }
+  },
+  methods: {
+    async getAgentOptions (airport) {
+      try {
+        const { code, returnData, message } = await Query({
+          serviceId: SERVICE_ID.agentCode,
+          dataContent: [
+            {
+              airport,
+            },
+          ],
+        })
+        if (String(code) === '0') {
+          const listValues = returnData.listValues || returnData
+          // this.formItems[2].options = listValues.map(element => ({
+          //   label: element.agent_number,
+          //   value: element.agent_number,
+          // }))
+        } else {
+          this.$message.error(message)
+        }
+      } catch (error) {
+        this.$message.error('失败')
+      }
+    },
+  },
+}
+</script>

+ 227 - 0
src/views/statisticsCharts/views/flight/volumeofStatisticsCharts.vue

@@ -0,0 +1,227 @@
+<template>
+  <CommonBarStatisticsCharts charts-title="航线航班量" :rol="rol" :query-settings="querySettings" :form-data="formData" :form-items="formItems" />
+</template>
+
+<script>
+import CommonBarStatisticsCharts from '../../components/newBarStatisticsCharts.vue'
+import { Query } from '@/api/webApi'
+import { parseTime } from '@/utils'
+
+export default {
+  name: 'WorkloadStatisticsCharts',
+  components: { CommonBarStatisticsCharts },
+  data () {
+    const that = this
+    return {
+      querySettings: {
+        serviceId: SERVICE_ID.flightvolume,
+        seriesKey: 'workload',
+        xAxisKey: 'fd',
+      },
+      formData: {
+        td: '日',
+        line: '',
+        flightstatus: '',
+        crafttype: '',
+        ditype: '',
+        ishas: '',
+        // agent_number: '',
+        // airport: '',
+        dateTime: [],
+      },
+      rol: 'fly',
+      formItems: [
+        {
+          prop: 'td',
+          inputType: 'select',
+          placeholder: '时间维度',
+          requiredWarning: '请先选择统计时间维度',
+          options: [
+            {
+              value: '日',
+              label: '按日统计',
+            },
+            {
+              value: '月',
+              label: '按月统计',
+            },
+            {
+              value: '年',
+              label: '按年统计',
+            },
+          ],
+          changeHandler (value, oldValue) {
+            const typeMap = {
+              日: 'datePicker',
+              月: 'monthPicker',
+              年: 'yearPicker',
+            }
+            const dateTimeItem = this.formItems.find(
+              item => item.prop === 'dateTime'
+            )
+            const formData = this._.cloneDeep(this.formData)
+            if (dateTimeItem) {
+              dateTimeItem.inputType = typeMap[value]
+              const dateTime = formData.dateTime
+              if (dateTime && dateTime[0] && dateTime[1]) {
+                if (value === '年') {
+                  this.formData.dateTime[0] = dateTime[0].split('-')[0]
+                  this.formData.dateTime[1] = dateTime[1].split('-')[0]
+                }
+                if (value === '月') {
+                  if (oldValue === '年') {
+                    this.formData.dateTime[0] = `${dateTime[0].split('-')[0]
+                      }-01`
+                    this.formData.dateTime[1] = `${dateTime[1].split('-')[0]
+                      }-12`
+                  }
+                  if (oldValue === '日') {
+                    this.formData.dateTime[0] = dateTime[0]
+                      .split('-')
+                      .slice(0, 2)
+                      .join('-')
+                    this.formData.dateTime[1] = dateTime[1]
+                      .split('-')
+                      .slice(0, 2)
+                      .join('-')
+                  }
+                }
+                if (value === '日') {
+                  if (oldValue === '年') {
+                    this.formData.dateTime[0] = `${dateTime[0].split('-')[0]
+                      }-01-01`
+                    this.formData.dateTime[1] = `${dateTime[1].split('-')[0]
+                      }-12-31`
+                  }
+                  if (oldValue === '月') {
+                    this.formData.dateTime[0] = `${dateTime[0]
+                      .split('-')
+                      .slice(0, 2)
+                      .join('-')}-01`
+                    let [year, month] = dateTime[1].split('-')
+                    if (month === '12') {
+                      year = Number(year) + 1
+                      month = 1
+                    } else {
+                      month = Number(month) + 1
+                    }
+                    const day = 24 * 60 * 60 * 1000
+                    this.formData.dateTime[1] = parseTime(
+                      new Date(`${year}-${month}-01`) - day * 1,
+                      '{y}-{m}-{d}'
+                    )
+                  }
+                }
+              }
+            }
+          },
+        },
+        {
+          prop: 'line',
+          inputType: 'select',
+          placeholder: '航线',
+          filterable: true,
+          queryId: SERVICE_ID.AirlineIds,
+          setKey: 'air_line',
+          requiredWarning: '请先选择航线',
+          options: [],
+        },
+        {
+          prop: 'flightstatus',
+          inputType: 'select',
+          placeholder: '全部',
+          requiredWarning: '请先选择航班状态',
+          filterable: true,
+          options: [{
+              value: '正常',
+              label: "正常",
+            },{
+              value: '延误',
+              label: "延误",
+            },{
+              value: '取消',
+              label: "取消",
+            },{
+              value: '全部',
+              label: "全部",
+            }],
+        },
+        {
+          prop: 'crafttype',
+          inputType: 'select',
+          placeholder: '全部',
+          requiredWarning: '请先选择机型',
+          filterable: true,
+          queryId: SERVICE_ID.ModelIds,
+          setKey: 'craftType',
+          options: [],
+        },
+        {
+          prop: 'ditype',
+          inputType: 'select',
+          placeholder: '全部',
+          requiredWarning: '请先选择国内国际',
+          filterable: true,
+          options: [{
+              value: '国内',
+              label: "国内",
+            },{
+              value: '国际',
+              label: "国际",
+            },{
+              value: '全部',
+              label: "全部",
+            }],
+        },{
+          prop: 'ishas',
+          inputType: 'select',
+          placeholder: '全部',
+          requiredWarning: '请先选择有无行李',
+          filterable: true,
+          options: [{
+              value: '有行李',
+              label: "有行李",
+            },{
+              value: '无行李',
+              label: "无行李",
+            },{
+              value: '全部',
+              label: "全部",
+            }],
+        },
+        {
+          prop: 'dateTime',
+          inputType: 'datePicker',
+          width: '240px',
+          requiredWarning: '请先选择时间范围',
+        },
+      ],
+    }
+  },
+  methods: {
+    async getAgentOptions (airport) {
+      try {
+        const { code, returnData, message } = await Query({
+          serviceId: SERVICE_ID.agentCode,
+          dataContent: [
+            {
+              airport,
+            },
+          ],
+        })
+        if (String(code) === '0') {
+          const listValues = returnData.listValues || returnData
+          // this.formItems[2].options = listValues.map(element => ({
+          //   label: element.agent_number,
+          //   value: element.agent_number,
+          // }))
+        } else {
+          this.$message.error(message)
+        }
+      } catch (error) {
+        this.$message.error('失败')
+      }
+    },
+  },
+}
+</script>

+ 26 - 0
src/views/statisticsCharts/views/flightClassification/baggageClassificationStatisticsCharts.vue

@@ -0,0 +1,26 @@
+<template>
+  <CommonPieStatisticsCharts
+    charts-title="航班行李"
+    :query-settings="querySettings"
+    :categories="categories"
+  />
+</template>
+
+<script>
+import CommonPieStatisticsCharts from '../../components/commonPieStatisticsCharts.vue'
+export default {
+  name: 'FlightBaggageClassificationStatisticsCharts',
+  components: { CommonPieStatisticsCharts },
+  data() {
+    return {
+      querySettings: {
+        byArea: SERVICE_ID.flightClassificationByArea,
+        byOther: SERVICE_ID.flightClassificationByOther,
+        categoryKey: 'ditype',
+        seriesKey: '行李量'
+      },
+      categories: ['国内', '国际', '其它', '混合']
+    }
+  }
+}
+</script>

+ 27 - 0
src/views/statisticsCharts/views/flightClassification/flightClassificationStatisticsCharts.vue

@@ -0,0 +1,27 @@
+<template>
+  <CommonPieStatisticsCharts
+    charts-title="航班量"
+    :query-settings="querySettings"
+    :categories="categories"
+    pie-title="航班总数"
+  />
+</template>
+
+<script>
+import CommonPieStatisticsCharts from '../../components/commonPieStatisticsCharts.vue'
+export default {
+  name: 'FlightClassificationStatisticsCharts',
+  components: { CommonPieStatisticsCharts },
+  data() {
+    return {
+      querySettings: {
+        byArea: SERVICE_ID.flightClassificationByArea,
+        byOther: SERVICE_ID.flightClassificationByOther,
+        categoryKey: 'ditype',
+        seriesKey: '航班量'
+      },
+      categories: ['国内', '国际', '其它', '混合']
+    }
+  }
+}
+</script>

+ 27 - 0
src/views/statisticsCharts/views/flightClassification/passengerClassificationStatisticsCharts.vue

@@ -0,0 +1,27 @@
+<template>
+  <CommonPieStatisticsCharts
+    charts-title="行李旅客量"
+    :query-settings="querySettings"
+    :categories="categories"
+    pie-title="旅客总数"
+  />
+</template>
+
+<script>
+import CommonPieStatisticsCharts from '../../components/commonPieStatisticsCharts.vue'
+export default {
+  name: 'FlightPassengerClassificationStatisticsCharts',
+  components: { CommonPieStatisticsCharts },
+  data() {
+    return {
+      querySettings: {
+        byArea: SERVICE_ID.flightClassificationByArea,
+        byOther: SERVICE_ID.flightClassificationByOther,
+        categoryKey: 'ditype',
+        seriesKey: '行李旅客量'
+      },
+      categories: ['国内', '国际', '其它', '混合']
+    }
+  }
+}
+</script>

+ 774 - 0
src/views/statisticsCharts/views/nodeStatisticsCharts.vue

@@ -0,0 +1,774 @@
+<template>
+  <div v-loading="loading" element-loading-text="拼命加载中" element-loading-spinner="el-icon-loading" element-loading-background="rgba(0, 0, 0, 0.8)" class="statstics-wrapper">
+    <div ref="headerWrapper" class="statstics-header">
+      <StatisticsHeader title="扫描节点与位置分析" :items="formItems" :data="formData" with-setting @getFormData="getFormData" @export="exportHandler" @setting="settingHandler" />
+    </div>
+    <div class="statstics-content">
+      <div ref="myChart" class="node-statistics-chart" :style="{ height: chartHeight }" />
+      <div v-if="checkedTooltips.length" class="node-tooltip">
+        <div class="node-tooltip-title">节点扫描率</div>
+        <div v-for="tooltip in checkedTooltips" :key="tooltip.label" class="node-tooltip-content">
+          <span>{{ tooltip.label }}:</span><span>{{ tooltip.ratio }}</span>
+        </div>
+      </div>
+    </div>
+    <Dialog :flag="dialogFlag" class="dialog-check-group">
+      <div class="dialog-wrapper">
+        <div class="title">列设置</div>
+        <div class="content">
+          <el-checkbox-group v-model="checkListTemp">
+            <el-checkbox v-for="node in nodeList" :key="node.name" :label="node.name" :disabled="node.disabled" />
+          </el-checkbox-group>
+        </div>
+        <div class="foot right t30">
+          <el-button size="medium" class="r24" type="primary" @click="onCheck">确定</el-button>
+          <el-button size="medium" @click="hide">取消</el-button>
+        </div>
+      </div>
+    </Dialog>
+  </div>
+</template>
+
+<script>
+import StatisticsHeader from '../components/statisticsHeader.vue'
+import Dialog from '@/layout/components/Dialog'
+import { TempQuery } from '@/api/temp'
+import { mapGetters } from 'vuex'
+import * as XLSX from 'xlsx'
+import XLSX_STYLE from 'xlsx-style'
+import FileSaver from 'file-saver'
+
+export default {
+  name: 'FlightStatisticsCharts',
+  components: { StatisticsHeader, Dialog },
+  data () {
+    return {
+      formData: {
+        range: '',
+        airline: '',
+        airport: '',
+        inOrOut: '',
+        dateTime: '',
+      },
+      formItems: [
+        {
+          prop: 'range',
+          inputType: 'select',
+          placeholder: '统计范围',
+          options: [
+            {
+              value: 'airline',
+              label: '航线',
+            },
+            {
+              value: 'airport',
+              label: '航站',
+            },
+          ],
+          setKey: 'a1',
+          changeHandler (value) {
+            switch (value) {
+              case 'airline':
+                this.formData.airport = null
+                this.formData.inOrOut = null
+                this.formItems[1].disabled = false
+                this.formItems[2].disabled = true
+                this.formItems[3].disabled = true
+                break
+              case 'airport':
+                this.formData.airline = null
+                this.formItems[1].disabled = true
+                this.formItems[2].disabled = false
+                this.formItems[3].disabled = false
+                break
+              default:
+                this.formItems[1].disabled = false
+                this.formItems[2].disabled = false
+                this.formItems[3].disabled = false
+                break
+            }
+          },
+        },
+        {
+          prop: 'airline',
+          inputType: 'select',
+          placeholder: '航线',
+          filterable: true,
+          clearable: true,
+          // disabled: true,
+          queryId: SERVICE_ID.AirlineIds,
+          setKey: 'air_line',
+          options: [],
+        },
+        {
+          prop: 'airport',
+          inputType: 'select',
+          placeholder: '航站',
+          filterable: true,
+          clearable: true,
+          // multiple: true,
+          // disabled: true,
+          queryId: SERVICE_ID.AirportIds,
+          setKey: 'code3',
+          options: [],
+        },
+        {
+          prop: 'inOrOut',
+          inputType: 'select',
+          placeholder: '进离港',
+          clearable: true,
+          options: [
+            {
+              value: '离港',
+              label: '离港',
+            },
+            {
+              value: '进港',
+              label: '进港',
+            },
+          ],
+        },
+        {
+          prop: 'dateTime',
+          inputType: 'datePicker',
+          clearable: true,
+          width: '240px',
+          options: [],
+        },
+      ],
+      queryData: null,
+      nodeList: [
+        {
+          name: '行李总件数',
+          label: '',
+          disabled: true,
+          nodeKey: 'bags',
+        },
+        {
+          name: '值机件数',
+          label: '值机',
+          nodeKey: 'check_in',
+        },
+        {
+          name: '安检件数',
+          label: '安检',
+          nodeKey: 'security',
+        },
+        {
+          name: '分拣件数',
+          label: '分拣',
+          nodeKey: 'sort_num',
+        },
+        {
+          name: '装车件数',
+          label: '装车',
+          nodeKey: 'load_car',
+        },
+        {
+          name: '装机件数',
+          label: '装机',
+          nodeKey: 'load_plane',
+          // disabled: true
+        },
+        {
+          name: '卸机件数',
+          label: '卸机',
+          disabled: true,
+          nodeKey: '',
+        },
+        // {
+        //   name: '中转件数',
+        //   label: '中转',
+        //   nodeKey: 'transfer'
+        // },
+        {
+          name: '到达件数',
+          label: '到达',
+          nodeKey: 'arrive',
+        },
+      ],
+      checkList: [],
+      checkListTemp: [],
+      dialogFlag: false,
+      myChart: null,
+      debounceTime: 300,
+      chartHeight: '70vh',
+      hasChartData: false,
+      echartsOptions: {
+        tooltip: {
+          trigger: 'item',
+        },
+        label: {
+          show: true,
+          formatter: function (params) {
+            return params.value
+          },
+        },
+        radar: {
+          indicator: [],
+          axisName: {
+            padding: 10,
+            color: '#303133',
+            fontFamily: 'Helvetica, "Microsoft YaHei"',
+          },
+        },
+        triggerEvent: true,
+        series: [
+          {
+            name: 'nodeRadar',
+            type: 'radar',
+            areaStyle: {
+              color: '#6897D8',
+            },
+            itemStyle: {
+              color: '#ffffff',
+              borderWidth: 2,
+              borderColor: '#4475B8',
+            },
+            lineStyle: {
+              color: '#4475B8',
+              width: 2,
+            },
+            data: [],
+          },
+        ],
+      },
+      indicator: [],
+      seriesData: [],
+      tooltips: [],
+      descriptions: {},
+      loading: false,
+      msgDatas: [],
+      msgObj: {}
+    }
+  },
+  computed: {
+    ...mapGetters(['sidebar']),
+    checkedTooltips () {
+      return this.tooltips.filter(tooltip =>
+        this.checkList.includes(tooltip.name)
+      )
+    },
+    checkedSeriesData () {
+      return this.seriesData.reduce((pre, curr) => {
+        if (this.checkList.includes(curr.name)) {
+          return [...pre, curr.value]
+        } else {
+          return pre
+        }
+      }, [])
+    },
+    checkedIndicator () {
+      return this.indicator.filter(node => this.checkList.includes(node.name))
+    },
+  },
+  watch: {
+    checkedIndicator: {
+      handler (arr) {
+        this.echartsOptions.radar.indicator = arr
+      },
+      deep: true,
+    },
+    checkedSeriesData: {
+      handler (arr) {
+        this.echartsOptions.series[0].data = [
+          {
+            name: this.queryData[2],
+            value: arr,
+          },
+        ]
+      },
+      deep: true,
+    },
+    // 监听数据变化 重绘图形
+    echartsOptions: {
+      handler (obj) {
+        this.myChart && this.myChart.setOption(obj)
+        this.resizeHandler()
+      },
+      deep: true,
+    },
+    'sidebar.expand' () {
+      this.setChartHeight()
+    },
+  },
+  created () {
+    this.getTips()
+
+    this.tooltips = this.nodeList.reduce((pre, curr) => {
+      if (curr.label) {
+        return [
+          ...pre,
+          {
+            name: curr.name,
+            key: curr.nodeKey,
+            label: curr.label,
+            ratio: '0%',
+          },
+        ]
+      } else {
+        return pre
+      }
+    }, [])
+
+    this.indicator = this.nodeList.map(node => ({
+      name: node.name,
+      max: 10000,
+      key: node.nodeKey,
+    }))
+
+    this.checkList = this.nodeList.reduce((pre, curr) => {
+      if (
+        [
+          // '装机件数',
+          '卸机件数',
+        ].includes(curr.name)
+      ) {
+        return pre
+      } else {
+        return [...pre, curr.name]
+      }
+    }, [])
+  },
+  mounted () {
+    const that = this
+
+    this.setChartHeight()
+    this.myChart = this.$echarts.init(this.$refs['myChart'])
+    this.myChart.setOption(this.echartsOptions)
+
+    // 监听页面缩放
+    this.debouncedChartHeightSetter = this._.debounce(
+      this.setChartHeight,
+      this.debounceTime
+    )
+    window.addEventListener('resize', this.debouncedChartHeightSetter)
+
+    // 防止修改标签造成的闪烁
+    this.myChart.on('mousedown', this.hideTips)
+    // 修改雷达图标签说明
+    this.myChart.on('mousemove', this.changeTips)
+    this.myChart.on('mouseup', params => {
+      setTimeout(that.changeTips.bind(that, params), 0)
+    })
+  },
+  beforeDestroy () {
+    // 销毁实例和移除监听
+    window.removeEventListener('resize', this.debouncedChartHeightSetter)
+    if (this.myChart) {
+      this.myChart.dispose()
+      this.myChart = null
+    }
+  },
+  methods: {
+    hideTips (params) {
+      if (params.componentType === 'radar') {
+        this.myChart._dom.children[1].style.opacity = 0
+      }
+    },
+    changeTips (params) {
+      const tip = this.myChart._dom.children[1]
+      if (params.componentType === 'radar' && this.descriptions[params.name]) {
+        tip.innerHTML = tip.textContent = this.descriptions[params.name]
+      }
+    },
+    getFormData (data) {
+      this.queryChartsData(data)
+    },
+    setInOrOutOptions (range) {
+      const theInOrOutItem = this.formItems.find(
+        item => item.prop === 'inOrOut'
+      )
+      switch (range) {
+        case 'airline':
+          this.formItems[2].disabled = true
+          this.formItems[3].disabled = true
+          break
+        case 'airport':
+          this.formItems[3].disabled = false
+          break
+        default:
+          theInOrOutItem.options = []
+          this.formItems[3].disabled = false
+          break
+      }
+    },
+    async getTips () {
+      try {
+        const { code, returnData, message } = await TempQuery({
+          serviceId: SERVICE_ID.nodeAxisDesc,
+          dataContent: [],
+        })
+        if (Number(code) === 0 && returnData?.length) {
+          this.descriptions = JSON.parse(returnData[0].jieshi)
+        } else {
+          this.$message.error(message ?? '失败')
+        }
+      } catch (error) {
+        this.$message.error('失败')
+      }
+    },
+    async queryChartsData (data) {
+      this.loading = true
+      const params = []
+      let queryId
+      // if (data.range === '航线' && data.airline === '') {
+      //   this.$message.warning('请先选择航线')
+      //   return
+      // }
+      // if (data.range === '航站' && data.airport === '') {
+      //   this.$message.warning('请先选择航站')
+      //   return
+      // }
+      // switch (data.inOrOut) {
+      //   case '全部':
+      //     queryId = SERVICE_ID.nodeAll
+      //     break
+      //   case '进港':
+      //     queryId = SERVICE_ID.nodeIn
+      //     break
+      //   case '离港':
+      //     queryId = SERVICE_ID.nodeOut
+      //     break
+      //   default:
+      //     this.$message.warning('请先选择进离港')
+      //     return
+      // }
+      // if (data.dateTime === '') {
+      //   this.$message.warning('请先选择统计时间范围')
+      //   return
+      // }
+      if (data.airline) {
+        data.airport = null
+        data.inOrOut = null
+      }
+      if (data.airport || data.inOrOut) {
+        data.airline = null
+      }
+      const dataObj = {
+        air_line: data.airline,
+        airport: data.airport,
+        io_type: data.inOrOut,
+        fd1: data.dateTime[0],
+        fd2: data.dateTime[1],
+      }
+      params.push(dataObj)
+      // if (data.range === '航线') {
+      //   params.splice(1, 0, data.airline)
+      // } else if (data.range === '航站') {
+      //   params.splice(1, 0, data.airport)
+      // } else {
+      //   params.splice(1, 0, '全部')
+      // }
+      // console.log(params)
+      this.queryData = params
+      this.msgObj = { ...dataObj }
+      try {
+        this.echartsOptions.series[0].data = []
+        this.tooltips.forEach(tooltip => (tooltip.ratio = '0%'))
+        this.hasChartData = false
+
+        const res = await TempQuery({
+          serviceId: SERVICE_ID.LuggageNodeId,
+          dataContent: params,
+        })
+        if (Number(res.code) === 0) {
+          if (res.returnData.length) {
+            const list = Object.entries(res.returnData[0])
+            const max = Math.max(...list.map(element => element[1]))
+            this.indicator.forEach(node => {
+              node.max = max
+            })
+            list.forEach(([name, value]) => {
+              const tooltip = this.tooltips.find(
+                tooltip => tooltip.key === name
+              )
+              if (tooltip && value) {
+                tooltip.ratio = ((value / max) * 100).toFixed(2) + '%'
+              }
+            })
+            this.seriesData = this.indicator.map(node => {
+              const result = {
+                name: node.name,
+                value: 0,
+              }
+              const data = list.find(([key, value]) => key === node.key)
+              if (data) {
+                result.value = data[1]
+              }
+              return result
+            })
+            this.msgDatas = _.cloneDeep(this.seriesData)
+            this.hasChartData = true
+          }
+        } else {
+          this.$message.error(res.message || '失败')
+        }
+        this.loading = false
+      } catch (error) {
+        this.loading = false
+        this.$message.error('失败')
+      }
+    },
+    setChartHeight () {
+      const topBarHeight = 80
+      const headerBlankHeight = 24
+      const tabsWrapperHeight = 62
+      const headerHeight = this.$refs['headerWrapper'].offsetHeight
+      const footerBlankHeight = 24
+      this.chartHeight = `calc(100vh - ${topBarHeight +
+        headerBlankHeight +
+        tabsWrapperHeight +
+        headerHeight +
+        footerBlankHeight
+        }px)`
+      this.$nextTick(() => {
+        this.resizeHandler()
+      })
+    },
+    resizeHandler () {
+      if (this.myChart) {
+        this.myChart.resize()
+      }
+    },
+    exportHandler () {
+      if (!this.hasChartData) {
+        this.$message.warning('请查询后再进行导出')
+        return
+      }
+      this.queryExportData(this.queryData)
+      // const myCanvas = this.myChart._dom.querySelectorAll('canvas')[0]
+      // const image = myCanvas.toDataURL('image/png')
+      // const $a = document.createElement('a')
+      // $a.setAttribute('href', image)
+      // $a.setAttribute('download', '扫描节点与位置分析统计.png')
+      // $a.click()
+    },
+    async queryExportData (queryData) {
+      const { range } = this.formData
+      let queryId
+      switch (range) {
+        case 'airport':
+          queryId = SERVICE_ID.nodeExportAirport
+          break
+        case 'airline':
+          queryId = SERVICE_ID.nodeExportAirline
+          break
+        default:
+          this.$message.warning('请先选择统计范围')
+          return
+      }
+      try {
+        const listValues = this.msgDatas
+        if (listValues.length) {
+          // 生成表格数据
+          const xlsxDatas = [[]]
+          const listArray = [[]]
+          listValues.map(item => {
+            if (item.key) {
+              delete item.key
+            }
+            listArray[0].push(Object.values(item))
+          })
+          listArray[0].unshift(['a4', this.msgObj.fd1])
+          xlsxDatas[0].push(...listArray[0].map(([key, value]) => key))
+          xlsxDatas.push(
+            ...listArray.map(record =>
+              record.map(([key, value]) => value || 0)
+            )
+          )
+          xlsxDatas[0][0] = '日期'
+          // 添加合计行
+          if (xlsxDatas.length > 2) {
+            const summaryRow = ['合计']
+            const colNum = xlsxDatas[0].length
+            for (let columnIndex = 1; columnIndex < colNum; columnIndex++) {
+              summaryRow[columnIndex] = xlsxDatas.reduce(
+                (pre, currentRow, currentRowIndex) => {
+                  if (currentRowIndex === 0) {
+                    return pre
+                  } else {
+                    return pre + currentRow[columnIndex]
+                  }
+                },
+                0
+              )
+            }
+            xlsxDatas.push(summaryRow)
+          }
+          // 添加节点扫描率列,计算列宽
+          const columnWidths = []
+          xlsxDatas.forEach((row, rowIndex) => {
+            // 从行李总件数后一列开始遍历,添加节点扫描率数据
+            for (
+              let columnIndex = 2;
+              columnIndex < row.length;
+              columnIndex += 2
+            ) {
+              const totalcell = row[1]
+              const cell = row[columnIndex]
+              const newCell =
+                rowIndex === 0
+                  ? `${cell.slice(0, 2)}扫描率`
+                  : `${cell ? ((cell / totalcell) * 100).toFixed(2) : 0}%`
+              row.splice(columnIndex + 1, 0, newCell)
+            }
+            // 计算每一列宽度,考虑换行
+            row.forEach((cell, columnIndex) => {
+              const cellWidth = Math.max(
+                ...String(cell)
+                  .split('\n')
+                  .map(cellRow =>
+                    cellRow.split('').reduce((pre, curr) => {
+                      const letterSize = curr.charCodeAt(0) > 255 ? 2 : 1
+                      return pre + letterSize
+                    }, 0)
+                  )
+              )
+              if (
+                (!columnWidths[columnIndex] && cellWidth > 0) ||
+                cellWidth > columnWidths[columnIndex]
+              ) {
+                columnWidths[columnIndex] = cellWidth
+              }
+            })
+          })
+          // 生成表格
+          const sheet = XLSX.utils.aoa_to_sheet(xlsxDatas)
+          // 添加列宽度
+          sheet['!cols'] = columnWidths.map(width => ({
+            wch: width + 2,
+          }))
+          const borderStyle = {
+            style: 'medium',
+            color: {
+              rgb: 'FFFFFF',
+            },
+          }
+          const reg = /^[A-Z]+([\d]+$)/
+          for (const key in sheet) {
+            const match = reg.test(key)
+            if (match) {
+              const rowIndex = reg.exec(key)[1]
+              let cellStyle = {
+                alignment: {
+                  horizontal: 'center',
+                  vertical: 'center',
+                  wrapText: true,
+                },
+              }
+              if (Number(rowIndex) === 1) {
+                cellStyle = {
+                  ...cellStyle,
+                  border: {
+                    top: borderStyle,
+                    right: borderStyle,
+                    bottom: borderStyle,
+                    left: borderStyle,
+                  },
+                  font: {
+                    color: {
+                      rgb: 'FFFFFF',
+                    },
+                  },
+                  fill: {
+                    fgColor: {
+                      rgb: '3366FF',
+                    },
+                  },
+                }
+              } else {
+                cellStyle.alignment.horizontal = 'left'
+              }
+              sheet[key].s = cellStyle
+            }
+          }
+          // 表格数据转换
+          const workBook = XLSX.utils.book_new()
+          XLSX.utils.book_append_sheet(workBook, sheet, '扫描节点与位置分析')
+          const tableWrite = XLSX_STYLE.write(workBook, {
+            bookType: 'xlsx',
+            bookSST: true,
+            type: 'buffer',
+            cellStyles: true,
+          })
+          // 下载表格
+          const nData = { ...queryData[0] }
+          const nDownList = Object.values(nData)
+          const fileName = `扫描节点与位置分析-${nDownList.join('-')}.xlsx`
+          FileSaver.saveAs(
+            new Blob([tableWrite], { type: 'application/octet-stream' }),
+            fileName
+          )
+        }
+      } catch (error) {
+        console.log(error)
+        this.$message.error('失败')
+      }
+    },
+    settingHandler () {
+      this.dialogFlag = true
+      this.checkListTemp = [...this.checkList]
+    },
+    onCheck () {
+      if (this.dialogFlag === false) {
+        return
+      }
+      if (this.checkListTemp.length < 3) {
+        this.$message.warning('至少需要勾选2项(不包含行李总件数)')
+        return
+      }
+      this.checkList = [...this.checkListTemp]
+      this.dialogFlag = false
+    },
+    hide () {
+      this.dialogFlag = false
+    },
+  },
+}
+</script>
+
+<style lang="scss" scoped>
+.statstics-wrapper {
+  .statstics-content {
+    background-color: #fff;
+    position: relative;
+    .node-tooltip {
+      // width: 100px;
+      position: absolute;
+      bottom: 48px;
+      left: 64px;
+      z-index: 100;
+      font-size: 14px;
+      font-family: Helvetica, "Microsoft YaHei";
+      color: #303133;
+      .node-tooltip-title {
+        line-height: 14px;
+        margin-bottom: 30px;
+        font-weight: bold;
+      }
+      .node-tooltip-content {
+        line-height: 14px;
+        display: flex;
+        justify-content: space-between;
+        &:not(:last-child) {
+          margin-bottom: 21px;
+        }
+      }
+    }
+    .node-statistics-chart {
+      width: 100%;
+    }
+  }
+  .dialog-check-group {
+    .el-checkbox-group {
+      display: flex;
+      flex-wrap: wrap;
+      .el-checkbox {
+        margin-right: 0;
+        width: 33.3%;
+      }
+    }
+  }
+}
+</style>

+ 177 - 0
src/views/statisticsCharts/views/passenger/passengerairlineStatisticsCharts.vue

@@ -0,0 +1,177 @@
+<template>
+  <CommonBarStatisticsCharts charts-title="航司旅客量" :rol="rol"  :query-settings="querySettings" :form-data="formData" :form-items="formItems" />
+</template>
+
+<script>
+import CommonBarStatisticsCharts from '../../components/newBarStatisticsCharts.vue'
+import { Query } from '@/api/webApi'
+import { parseTime } from '@/utils'
+
+export default {
+  name: 'WorkloadStatisticsCharts',
+  components: { CommonBarStatisticsCharts },
+  data () {
+    const that = this
+    return {
+      querySettings: {
+        serviceId: SERVICE_ID.passengerairline,
+        seriesKey: 'workload',
+        xAxisKey: 'fd',
+      },
+      formData: {
+        td: '日',
+        aircompany: '',
+        status: '',
+        // agent_number: '',
+        // airport: '',
+        dateTime: [],
+      },
+      rol: 'passenger',
+      formItems: [
+        {
+          prop: 'td',
+          inputType: 'select',
+          placeholder: '时间维度',
+          requiredWarning: '请先选择统计时间维度',
+          options: [
+            {
+              value: '日',
+              label: '按日统计',
+            },
+            {
+              value: '月',
+              label: '按月统计',
+            },
+            {
+              value: '年',
+              label: '按年统计',
+            },
+          ],
+          changeHandler (value, oldValue) {
+            const typeMap = {
+              日: 'datePicker',
+              月: 'monthPicker',
+              年: 'yearPicker',
+            }
+            const dateTimeItem = this.formItems.find(
+              item => item.prop === 'dateTime'
+            )
+            const formData = this._.cloneDeep(this.formData)
+            if (dateTimeItem) {
+              dateTimeItem.inputType = typeMap[value]
+              const dateTime = formData.dateTime
+              if (dateTime && dateTime[0] && dateTime[1]) {
+                if (value === '年') {
+                  this.formData.dateTime[0] = dateTime[0].split('-')[0]
+                  this.formData.dateTime[1] = dateTime[1].split('-')[0]
+                }
+                if (value === '月') {
+                  if (oldValue === '年') {
+                    this.formData.dateTime[0] = `${dateTime[0].split('-')[0]
+                      }-01`
+                    this.formData.dateTime[1] = `${dateTime[1].split('-')[0]
+                      }-12`
+                  }
+                  if (oldValue === '日') {
+                    this.formData.dateTime[0] = dateTime[0]
+                      .split('-')
+                      .slice(0, 2)
+                      .join('-')
+                    this.formData.dateTime[1] = dateTime[1]
+                      .split('-')
+                      .slice(0, 2)
+                      .join('-')
+                  }
+                }
+                if (value === '日') {
+                  if (oldValue === '年') {
+                    this.formData.dateTime[0] = `${dateTime[0].split('-')[0]
+                      }-01-01`
+                    this.formData.dateTime[1] = `${dateTime[1].split('-')[0]
+                      }-12-31`
+                  }
+                  if (oldValue === '月') {
+                    this.formData.dateTime[0] = `${dateTime[0]
+                      .split('-')
+                      .slice(0, 2)
+                      .join('-')}-01`
+                    let [year, month] = dateTime[1].split('-')
+                    if (month === '12') {
+                      year = Number(year) + 1
+                      month = 1
+                    } else {
+                      month = Number(month) + 1
+                    }
+                    const day = 24 * 60 * 60 * 1000
+                    this.formData.dateTime[1] = parseTime(
+                      new Date(`${year}-${month}-01`) - day * 1,
+                      '{y}-{m}-{d}'
+                    )
+                  }
+                }
+              }
+            }
+          },
+        },
+        {
+          prop: 'aircompany',
+          inputType: 'select',
+          placeholder: '航司',
+          filterable: true,
+          queryId: SERVICE_ID.AirlinportId,
+          setKey: 'ITATCode',
+          requiredWarning: '请先选择航司',
+          options: [],
+        },{
+          prop: 'status',
+          inputType: 'select',
+          placeholder: '全部',
+          requiredWarning: '请先选择行李状态',
+          filterable: true,
+          options: [{
+              value: '正常',
+              label: "正常",
+            },{
+              value: '取消',
+              label: "取消",
+            },{
+              value: '全部',
+              label: "全部",
+            }],
+        },
+        {
+          prop: 'dateTime',
+          inputType: 'datePicker',
+          width: '240px',
+          requiredWarning: '请先选择时间范围',
+        },
+      ],
+    }
+  },
+  methods: {
+    async getAgentOptions (airport) {
+      try {
+        const { code, returnData, message } = await Query({
+          serviceId: SERVICE_ID.agentCode,
+          dataContent: [
+            {
+              airport,
+            },
+          ],
+        })
+        if (String(code) === '0') {
+          const listValues = returnData.listValues || returnData
+          // this.formItems[2].options = listValues.map(element => ({
+          //   label: element.agent_number,
+          //   value: element.agent_number,
+          // }))
+        } else {
+          this.$message.error(message)
+        }
+      } catch (error) {
+        this.$message.error('失败')
+      }
+    },
+  },
+}
+</script>

+ 177 - 0
src/views/statisticsCharts/views/passenger/passengerrouteStatisticsCharts.vue

@@ -0,0 +1,177 @@
+<template>
+  <CommonBarStatisticsCharts charts-title="航线旅客量" :rol="rol" :query-settings="querySettings" :form-data="formData" :form-items="formItems" />
+</template>
+
+<script>
+import CommonBarStatisticsCharts from '../../components/newBarStatisticsCharts.vue'
+import { Query } from '@/api/webApi'
+import { parseTime } from '@/utils'
+
+export default {
+  name: 'WorkloadStatisticsCharts',
+  components: { CommonBarStatisticsCharts },
+  data () {
+    const that = this
+    return {
+      querySettings: {
+        serviceId: SERVICE_ID.passengerroute,
+        seriesKey: 'workload',
+        xAxisKey: 'fd',
+      },
+      formData: {
+        td: '日',
+        // agent_number: '',
+        // airport: '',
+        line: '',
+        status: '',
+        dateTime: [],
+      },
+      rol: 'passenger',
+      formItems: [
+        {
+          prop: 'td',
+          inputType: 'select',
+          placeholder: '时间维度',
+          requiredWarning: '请先选择统计时间维度',
+          options: [
+            {
+              value: '日',
+              label: '按日统计',
+            },
+            {
+              value: '月',
+              label: '按月统计',
+            },
+            {
+              value: '年',
+              label: '按年统计',
+            },
+          ],
+          changeHandler (value, oldValue) {
+            const typeMap = {
+              日: 'datePicker',
+              月: 'monthPicker',
+              年: 'yearPicker',
+            }
+            const dateTimeItem = this.formItems.find(
+              item => item.prop === 'dateTime'
+            )
+            const formData = this._.cloneDeep(this.formData)
+            if (dateTimeItem) {
+              dateTimeItem.inputType = typeMap[value]
+              const dateTime = formData.dateTime
+              if (dateTime && dateTime[0] && dateTime[1]) {
+                if (value === '年') {
+                  this.formData.dateTime[0] = dateTime[0].split('-')[0]
+                  this.formData.dateTime[1] = dateTime[1].split('-')[0]
+                }
+                if (value === '月') {
+                  if (oldValue === '年') {
+                    this.formData.dateTime[0] = `${dateTime[0].split('-')[0]
+                      }-01`
+                    this.formData.dateTime[1] = `${dateTime[1].split('-')[0]
+                      }-12`
+                  }
+                  if (oldValue === '日') {
+                    this.formData.dateTime[0] = dateTime[0]
+                      .split('-')
+                      .slice(0, 2)
+                      .join('-')
+                    this.formData.dateTime[1] = dateTime[1]
+                      .split('-')
+                      .slice(0, 2)
+                      .join('-')
+                  }
+                }
+                if (value === '日') {
+                  if (oldValue === '年') {
+                    this.formData.dateTime[0] = `${dateTime[0].split('-')[0]
+                      }-01-01`
+                    this.formData.dateTime[1] = `${dateTime[1].split('-')[0]
+                      }-12-31`
+                  }
+                  if (oldValue === '月') {
+                    this.formData.dateTime[0] = `${dateTime[0]
+                      .split('-')
+                      .slice(0, 2)
+                      .join('-')}-01`
+                    let [year, month] = dateTime[1].split('-')
+                    if (month === '12') {
+                      year = Number(year) + 1
+                      month = 1
+                    } else {
+                      month = Number(month) + 1
+                    }
+                    const day = 24 * 60 * 60 * 1000
+                    this.formData.dateTime[1] = parseTime(
+                      new Date(`${year}-${month}-01`) - day * 1,
+                      '{y}-{m}-{d}'
+                    )
+                  }
+                }
+              }
+            }
+          },
+        },
+        {
+          prop: 'line',
+          inputType: 'select',
+          placeholder: '航线',
+          filterable: true,
+          queryId: SERVICE_ID.AirlineIds,
+          setKey: 'air_line',
+          requiredWarning: '请先选择航线',
+          options: [],
+        },{
+          prop: 'status',
+          inputType: 'select',
+          placeholder: '全部',
+          requiredWarning: '请先选择行李状态',
+          filterable: true,
+          options: [{
+              value: '正常',
+              label: "正常",
+            },{
+              value: '取消',
+              label: "取消",
+            },{
+              value: '全部',
+              label: "全部",
+            }],
+        },
+        {
+          prop: 'dateTime',
+          inputType: 'datePicker',
+          width: '240px',
+          requiredWarning: '请先选择时间范围',
+        },
+      ],
+    }
+  },
+  methods: {
+    async getAgentOptions (airport) {
+      try {
+        const { code, returnData, message } = await Query({
+          serviceId: SERVICE_ID.agentCode,
+          dataContent: [
+            {
+              airport,
+            },
+          ],
+        })
+        if (String(code) === '0') {
+          const listValues = returnData.listValues || returnData
+          // this.formItems[2].options = listValues.map(element => ({
+          //   label: element.agent_number,
+          //   value: element.agent_number,
+          // }))
+        } else {
+          this.$message.error(message)
+        }
+      } catch (error) {
+        this.$message.error('失败')
+      }
+    },
+  },
+}
+</script>

+ 195 - 0
src/views/statisticsCharts/views/passenger/terminalpassengersStatisticsCharts.vue

@@ -0,0 +1,195 @@
+<template>
+  <CommonBarStatisticsCharts charts-title="航站旅客量" :rol="rol" :query-settings="querySettings" :form-data="formData" :form-items="formItems" />
+</template>
+
+<script>
+import CommonBarStatisticsCharts from '../../components/newBarStatisticsCharts.vue'
+import { Query } from '@/api/webApi'
+import { parseTime } from '@/utils'
+
+export default {
+  name: 'WorkloadStatisticsCharts',
+  components: { CommonBarStatisticsCharts },
+  data () {
+    const that = this
+    return {
+      querySettings: {
+        serviceId: SERVICE_ID.passengerterminal,
+        seriesKey: 'workload',
+        xAxisKey: 'fd',
+      },
+      formData: {
+        td: '日',
+        // agent_number: '',
+        airport: '',
+        iotype: '',
+        status: '',
+        dateTime: [],
+      },
+      rol: 'passenger',
+      formItems: [
+        {
+          prop: 'td',
+          inputType: 'select',
+          placeholder: '时间维度',
+          requiredWarning: '请先选择统计时间维度',
+          options: [
+            {
+              value: '日',
+              label: '按日统计',
+            },
+            {
+              value: '月',
+              label: '按月统计',
+            },
+            {
+              value: '年',
+              label: '按年统计',
+            },
+          ],
+          changeHandler (value, oldValue) {
+            const typeMap = {
+              日: 'datePicker',
+              月: 'monthPicker',
+              年: 'yearPicker',
+            }
+            const dateTimeItem = this.formItems.find(
+              item => item.prop === 'dateTime'
+            )
+            const formData = this._.cloneDeep(this.formData)
+            if (dateTimeItem) {
+              dateTimeItem.inputType = typeMap[value]
+              const dateTime = formData.dateTime
+              if (dateTime && dateTime[0] && dateTime[1]) {
+                if (value === '年') {
+                  this.formData.dateTime[0] = dateTime[0].split('-')[0]
+                  this.formData.dateTime[1] = dateTime[1].split('-')[0]
+                }
+                if (value === '月') {
+                  if (oldValue === '年') {
+                    this.formData.dateTime[0] = `${dateTime[0].split('-')[0]
+                      }-01`
+                    this.formData.dateTime[1] = `${dateTime[1].split('-')[0]
+                      }-12`
+                  }
+                  if (oldValue === '日') {
+                    this.formData.dateTime[0] = dateTime[0]
+                      .split('-')
+                      .slice(0, 2)
+                      .join('-')
+                    this.formData.dateTime[1] = dateTime[1]
+                      .split('-')
+                      .slice(0, 2)
+                      .join('-')
+                  }
+                }
+                if (value === '日') {
+                  if (oldValue === '年') {
+                    this.formData.dateTime[0] = `${dateTime[0].split('-')[0]
+                      }-01-01`
+                    this.formData.dateTime[1] = `${dateTime[1].split('-')[0]
+                      }-12-31`
+                  }
+                  if (oldValue === '月') {
+                    this.formData.dateTime[0] = `${dateTime[0]
+                      .split('-')
+                      .slice(0, 2)
+                      .join('-')}-01`
+                    let [year, month] = dateTime[1].split('-')
+                    if (month === '12') {
+                      year = Number(year) + 1
+                      month = 1
+                    } else {
+                      month = Number(month) + 1
+                    }
+                    const day = 24 * 60 * 60 * 1000
+                    this.formData.dateTime[1] = parseTime(
+                      new Date(`${year}-${month}-01`) - day * 1,
+                      '{y}-{m}-{d}'
+                    )
+                  }
+                }
+              }
+            }
+          },
+        },
+        {
+          prop: 'airport',
+          inputType: 'select',
+          placeholder: '航站',
+          filterable: true,
+          queryId: SERVICE_ID.AirportIds,
+          setKey: 'code3',
+          requiredWarning: '请先选择航站',
+          options: [],
+        },
+        {
+          prop: 'iotype',
+          inputType: 'select',
+          placeholder: '进港离港',
+          requiredWarning: '请先选择进港离港',
+          filterable: true,
+          options: [{
+              value: '离港',
+              label: "离港",
+            },{
+              value: '进港',
+              label: "进港",
+            },{
+              value: '中转',
+              label: "中转",
+            }],
+        },
+        {
+          prop: 'status',
+          inputType: 'select',
+          placeholder: '全部',
+          requiredWarning: '请先选择行李状态',
+          filterable: true,
+          options: [{
+              value: '正常',
+              label: "正常",
+            },{
+              value: '取消',
+              label: "取消",
+            },{
+              value: '全部',
+              label: "全部",
+            }],
+        },
+        {
+          prop: 'dateTime',
+          inputType: 'datePicker',
+          width: '240px',
+          requiredWarning: '请先选择时间范围',
+        },
+      ],
+    }
+  },
+  methods: {
+    async getAgentOptions (airport) {
+      try {
+        const { code, returnData, message } = await Query({
+          serviceId: SERVICE_ID.agentCode,
+          dataContent: [
+            {
+              airport,
+            },
+          ],
+        })
+        if (String(code) === '0') {
+          const listValues = returnData.listValues || returnData
+          // this.formItems[2].options = listValues.map(element => ({
+          //   label: element.agent_number,
+          //   value: element.agent_number,
+          // }))
+        } else {
+          this.$message.error(message)
+        }
+      } catch (error) {
+        this.$message.error('失败')
+      }
+    },
+  },
+}
+</script>

+ 30 - 0
src/views/statisticsCharts/views/passengerClassification/abnormalBaggageStatisticsCharts.vue

@@ -0,0 +1,30 @@
+<template>
+  <CommonBarStatisticsCharts
+    charts-title="异常行李量"
+    :query-settings="querySettings"
+    :custom-form-items="customFormItems"
+  />
+</template>
+
+<script>
+import CommonBarStatisticsCharts from '../../components/commonBarStatisticsCharts.vue'
+import noTerminal from '../../mixins/noTerminal'
+import passengerType from '../../mixins/passengerType'
+
+export default {
+  name: 'PassengerAbnormalBaggageStatisticsCharts',
+  components: { CommonBarStatisticsCharts },
+  mixins: [noTerminal, passengerType],
+  data() {
+    return {
+      querySettings: {
+        byArea: SERVICE_ID.passengerNormalClassificationByArea,
+        byOther: SERVICE_ID.passengerNormalClassificationByOther,
+        importantByArea: SERVICE_ID.passengerImportantClassificationByArea,
+        importantByOther: SERVICE_ID.passengerImportantClassificationByOther,
+        seriesKey: '异常行李量'
+      }
+    }
+  }
+}
+</script>

+ 29 - 0
src/views/statisticsCharts/views/passengerClassification/baggagePassengerStatisticsCharts.vue

@@ -0,0 +1,29 @@
+<template>
+  <CommonBarStatisticsCharts
+    charts-title="行李旅客量"
+    :query-settings="querySettings"
+    :custom-form-items="customFormItems"
+  />
+</template>
+
+<script>
+import CommonBarStatisticsCharts from '../../components/commonBarStatisticsCharts.vue'
+import passengerType from '../../mixins/passengerType'
+
+export default {
+  name: 'PassengerStatisticsCharts',
+  components: { CommonBarStatisticsCharts },
+  mixins: [passengerType],
+  data() {
+    return {
+      querySettings: {
+        byArea: SERVICE_ID.passengerNormalClassificationByArea,
+        byOther: SERVICE_ID.passengerNormalClassificationByOther,
+        importantByArea: SERVICE_ID.passengerImportantClassificationByArea,
+        importantByOther: SERVICE_ID.passengerImportantClassificationByOther,
+        seriesKey: '异常行李量'
+      }
+    }
+  }
+}
+</script>

+ 29 - 0
src/views/statisticsCharts/views/passengerClassification/baggageStatisticsCharts.vue

@@ -0,0 +1,29 @@
+<template>
+  <CommonBarStatisticsCharts
+    charts-title="行李量"
+    :query-settings="querySettings"
+    :custom-form-items="customFormItems"
+  />
+</template>
+
+<script>
+import CommonBarStatisticsCharts from '../../components/commonBarStatisticsCharts.vue'
+import passengerType from '../../mixins/passengerType'
+
+export default {
+  name: 'PassengerBaggageStatisticsCharts',
+  components: { CommonBarStatisticsCharts },
+  mixins: [passengerType],
+  data() {
+    return {
+      querySettings: {
+        byArea: SERVICE_ID.passengerNormalClassificationByArea,
+        byOther: SERVICE_ID.passengerNormalClassificationByOther,
+        importantByArea: SERVICE_ID.passengerImportantClassificationByArea,
+        importantByOther: SERVICE_ID.passengerImportantClassificationByOther,
+        seriesKey: '行李量'
+      }
+    }
+  }
+}
+</script>

+ 30 - 0
src/views/statisticsCharts/views/passengerClassification/compensationBaggageStatisticsCharts.vue

@@ -0,0 +1,30 @@
+<template>
+  <CommonBarStatisticsCharts
+    charts-title="赔偿行李量"
+    :query-settings="querySettings"
+    :custom-form-items="customFormItems"
+  />
+</template>
+
+<script>
+import CommonBarStatisticsCharts from '../../components/commonBarStatisticsCharts.vue'
+import noTerminal from '../../mixins/noTerminal'
+import passengerType from '../../mixins/passengerType'
+
+export default {
+  name: 'PassengerCompensationBaggageStatisticsCharts',
+  components: { CommonBarStatisticsCharts },
+  mixins: [noTerminal, passengerType],
+  data() {
+    return {
+      querySettings: {
+        byArea: SERVICE_ID.passengerNormalClassificationByArea,
+        byOther: SERVICE_ID.passengerNormalClassificationByOther,
+        importantByArea: SERVICE_ID.passengerImportantClassificationByArea,
+        importantByOther: SERVICE_ID.passengerImportantClassificationByOther,
+        seriesKey: '赔偿行李量'
+      }
+    }
+  }
+}
+</script>

+ 30 - 0
src/views/statisticsCharts/views/passengerClassification/compensationStatisticsCharts.vue

@@ -0,0 +1,30 @@
+<template>
+  <CommonBarStatisticsCharts
+    charts-title="赔偿金额"
+    :query-settings="querySettings"
+    :custom-form-items="customFormItems"
+  />
+</template>
+
+<script>
+import CommonBarStatisticsCharts from '../../components/commonBarStatisticsCharts.vue'
+import noTerminal from '../../mixins/noTerminal'
+import passengerType from '../../mixins/passengerType'
+
+export default {
+  name: 'CompensationStatisticsCharts',
+  components: { CommonBarStatisticsCharts },
+  mixins: [noTerminal, passengerType],
+  data() {
+    return {
+      querySettings: {
+        byArea: SERVICE_ID.passengerNormalClassificationByArea,
+        byOther: SERVICE_ID.passengerNormalClassificationByOther,
+        importantByArea: SERVICE_ID.passengerImportantClassificationByArea,
+        importantByOther: SERVICE_ID.passengerImportantClassificationByOther,
+        seriesKey: '赔偿金额'
+      }
+    }
+  }
+}
+</script>

+ 30 - 0
src/views/statisticsCharts/views/passengerClassification/complaintBaggageStatisticsCharts.vue

@@ -0,0 +1,30 @@
+<template>
+  <CommonBarStatisticsCharts
+    charts-title="投诉行李量"
+    :query-settings="querySettings"
+    :custom-form-items="customFormItems"
+  />
+</template>
+
+<script>
+import CommonBarStatisticsCharts from '../../components/commonBarStatisticsCharts.vue'
+import noTerminal from '../../mixins/noTerminal'
+import passengerType from '../../mixins/passengerType'
+
+export default {
+  name: 'ComplaintBaggageStatisticsCharts',
+  components: { CommonBarStatisticsCharts },
+  mixins: [noTerminal, passengerType],
+  data() {
+    return {
+      querySettings: {
+        byArea: SERVICE_ID.passengerNormalClassificationByArea,
+        byOther: SERVICE_ID.passengerNormalClassificationByOther,
+        importantByArea: SERVICE_ID.passengerImportantClassificationByArea,
+        importantByOther: SERVICE_ID.passengerImportantClassificationByOther,
+        seriesKey: '投诉行李量'
+      }
+    }
+  }
+}
+</script>

+ 30 - 0
src/views/statisticsCharts/views/passengerClassification/specialBaggageStatisticsCharts.vue

@@ -0,0 +1,30 @@
+<template>
+  <CommonBarStatisticsCharts
+    charts-title="特殊行李量"
+    :query-settings="querySettings"
+    :custom-form-items="customFormItems"
+  />
+</template>
+
+<script>
+import CommonBarStatisticsCharts from '../../components/commonBarStatisticsCharts.vue'
+import noTerminal from '../../mixins/noTerminal'
+import passengerType from '../../mixins/passengerType'
+
+export default {
+  name: 'SpecialBaggageStatisticsCharts',
+  components: { CommonBarStatisticsCharts },
+  mixins: [noTerminal, passengerType],
+  data() {
+    return {
+      querySettings: {
+        byArea: SERVICE_ID.passengerNormalClassificationByArea,
+        byOther: SERVICE_ID.passengerNormalClassificationByOther,
+        importantByArea: SERVICE_ID.passengerImportantClassificationByArea,
+        importantByOther: SERVICE_ID.passengerImportantClassificationByOther,
+        seriesKey: '特殊行李量'
+      }
+    }
+  }
+}
+</script>

+ 110 - 0
src/views/statisticsCharts/views/report/Percentageofbaggage.vue

@@ -0,0 +1,110 @@
+<template>
+  <!-- 行李全流程服务水平百分比 -->
+  <div class="statstics-wrapper">
+    <StatisticsHeader title="行李全流程服务水平百分比" :items="formItems" :data.sync="formData" with-setting :withSetting="false" @export="exportup" @getFormData="getFormData" />
+    <!-- <Tableformcp
+      :isloadings="isloadings"
+      :rows="12"
+      label-width="140px"
+      :min-height="70"
+      width="800px"
+      tableHeight="750"
+    /> -->
+    <Tableformbrs :data-id="dataId" upid="8" :textShow="textShow" :isloadings="isloadings" :data-content="dataContent" :rows="12" label-width="140px" :min-height="70" width="800px" tableHeight="750"/>
+  </div>
+</template>
+<script>
+import StatisticsHeader from '../../components/statisticsHeader.vue'
+// import Tableformcp from "../../components/tableformcp";
+import Tableformbrs from '../../components/tableformbrs'
+import TableDialog from '../../components/TableDialog.vue'
+import { Format } from '@/utils/validate'
+export default {
+  name: 'ReportStatistics',
+  data () {
+    return {
+      textShow: null,
+      formData: {
+        airport: '',
+        dateTime: [],
+        company: '',
+        timedim: '',
+        trd: [],
+      },
+      isloadings: 1,
+      dataContent: [],
+      dataId: '1847',
+      formItems: [
+        {
+          prop: 'dateTime',
+          inputType: 'datePicker',
+          clearable: true,
+          width: '240px',
+          options: [],
+        },
+      ],
+      dialogFlag: false,
+      dialogTitle: '',
+      queryParams: [],
+    }
+  },
+  components: {
+    StatisticsHeader,
+    // Tableformcp,
+    Tableformbrs,
+    TableDialog,
+  },
+  mounted () {
+    this.dataContent = [
+      this.formData.dateTime[0] || Format('yyyy-MM-dd', new Date()),
+      this.formData.dateTime[1] || Format('yyyy-MM-dd', new Date()),
+    ]
+  },
+  methods: {
+    getFormData (data) {
+      this.textShow = data.trd
+      this.dataContent = [
+        data.dateTime[0],
+        data.dateTime[1]
+      ]
+    },
+    exportup () {
+      this.isloadings = this.isloadings += 1
+    },
+    cellClickHandler (row, column, cell, event) {
+      if (
+        column.property.includes('trans_bag') &&
+        row[column.property] &&
+        Number(row[column.property])
+      ) {
+        const queryParams = [
+          this.formData.airport || 'PEK',
+          row.fd || Format('yyyy-MM-dd', new Date()),
+          row.fd || Format('yyyy-MM-dd', new Date()),
+          ...Array(4).fill(this.formData.company || '国航'),
+        ]
+        const flow = column.property
+          .split('_')
+          .pop()
+          .toUpperCase()
+          .split('')
+          .join('-')
+        queryParams.push(...Array(4).fill(flow))
+        queryParams.push(...Array(4).fill(null))
+        const processMap = {
+          need: '需中转',
+          finish: '已中转',
+          not: '未中转',
+        }
+        const process = processMap[column.property.split('_')[0]]
+        queryParams.push(...Array(3).fill(process))
+        // console.log(queryParams)
+        this.queryParams = queryParams
+        this.dialogTitle = column.label
+        this.dialogFlag = true
+      }
+    },
+  },
+}
+</script>
+<style lang="scss" scoped></style>

+ 161 - 0
src/views/statisticsCharts/views/report/baggageProportionTable.vue

@@ -0,0 +1,161 @@
+<template>
+  <!-- 中转行李比例明细统计 -->
+  <div class="statstics-wrapper">
+    <StatisticsHeader
+      title="中转行李比例明细统计"
+      :items="formItems"
+      :data="formData"
+      with-setting
+      :withSetting="false"
+      @export="exportup"
+      @getFormData="getFormData"
+    />
+    <!-- <Tableformcp
+      :isloadings="isloadings"
+      :rows="12"
+      label-width="140px"
+      :min-height="70"
+      width="800px"
+      tableHeight="750"
+    /> -->
+    <Tableformbrs
+      :data-id="dataId"
+      upid="7"
+      :isloadings="isloadings"
+      :data-content="dataContent"
+      :rows="12"
+      label-width="140px"
+      :min-height="70"
+      width="800px"
+      tableHeight="750"
+    />
+  </div>
+</template>
+<script>
+import StatisticsHeader from '../../components/statisticsHeader.vue'
+// import Tableformcp from "../../components/tableformcp";
+import Tableformbrs from '../../components/tableformbrs'
+import { Format } from '@/utils/validate'
+export default {
+  name: 'ReportStatistics',
+  data() {
+    return {
+      formData: {
+        airport: '',
+        dateTime: [],
+        company: '',
+        timedim: '',
+      },
+      isloadings: 1,
+      dataContent: [],
+      dataId: '1842',
+      formItems: [
+        {
+          prop: 'airport',
+          inputType: 'select',
+          placeholder: 'PEK',
+          filterable: true,
+          clearable: true,
+          // multiple: true,
+          // disabled: true,
+          queryId: SERVICE_ID.nodeAirport,
+          setKey: 'a2',
+          options: [],
+        },
+        {
+          prop: 'company',
+          inputType: 'select',
+          placeholder: '航班分类',
+          requiredWarning: '请先选择航班分类',
+          clearable: true,
+          options: [
+            {
+              value: '国航',
+              label: '国航',
+            },
+            {
+              value: '代理国内',
+              label: '代理国内',
+            },
+            {
+              value: '代理国际',
+              label: '代理国际',
+            },
+            {
+              value: '非代理',
+              label: '非代理',
+            },
+          ],
+        },
+        {
+          prop: 'timedim',
+          inputType: 'select',
+          placeholder: '时间维度',
+          requiredWarning: '请先选择统计时间维度',
+          clearable: true,
+          options: [
+            {
+              value: '日',
+              label: '按日统计',
+            },
+            {
+              value: '月',
+              label: '按月统计',
+            },
+            {
+              value: '年',
+              label: '按年统计',
+            },
+          ],
+        },
+        {
+          prop: 'dateTime',
+          inputType: 'datePicker',
+          clearable: true,
+          width: '240px',
+          options: [],
+        },
+      ],
+    }
+  },
+  components: {
+    StatisticsHeader,
+    // Tableformcp,
+    Tableformbrs,
+  },
+  mounted() {
+    this.dataContent = [
+      '日',
+      '日',
+      '日',
+      '国航',
+      '国航',
+      '国航',
+      '国航',
+      Format('yyyy-MM-dd', new Date()),
+      Format('yyyy-MM-dd', new Date()),
+      'PEK',
+    ]
+  },
+  methods: {
+    getFormData(data) {
+      this.dataContent = [
+        data.timedim,
+        data.timedim,
+        data.timedim,
+        data.company,
+        data.company,
+        data.company,
+        data.company,
+        data.dateTime[0],
+        data.dateTime[1],
+        data.airport ? data.airport : 'PEK',
+      ]
+    },
+    exportup() {
+      this.isloadings = this.isloadings += 1
+    },
+  },
+}
+</script>
+<style lang="scss" scoped></style>

+ 68 - 0
src/views/statisticsCharts/views/report/reportStatistics.vue

@@ -0,0 +1,68 @@
+<template>
+  <!-- 运送效率报表统计 -->
+  <div class="statstics-wrapper">
+    <StatisticsHeader
+      title="运送效率报表"
+      :items="formItems"
+      :data="formData"
+      with-setting
+      :withSetting="false"
+      @export="exportup"
+    />
+    <Tableforms
+      :rows="12"
+      label-width="140px"
+      :min-height="70"
+      width="800px"
+      tableHeight="750"
+      :isloadings="isloadings"
+    />
+  </div>
+</template>
+<script>
+import StatisticsHeader from '../../components/statisticsHeader.vue'
+import Tableforms from '../../components/tableforms'
+export default {
+  name: 'ReportStatistics',
+  data() {
+    return {
+      formData: {
+        airport: '',
+        dateTime: '',
+      },
+      isloadings: 1,
+      formItems: [
+        {
+          prop: 'airport',
+          inputType: 'select',
+          placeholder: '航站选择',
+          filterable: true,
+          clearable: true,
+          // multiple: true,
+          disabled: true,
+          queryId: SERVICE_ID.nodeAirport,
+          setKey: 'a2',
+          options: [],
+        },
+        {
+          prop: 'dateTime',
+          inputType: 'datePicker',
+          clearable: true,
+          width: '240px',
+          options: [],
+        },
+      ],
+    }
+  },
+  components: {
+    StatisticsHeader,
+    Tableforms,
+  },
+  methods: {
+    exportup() {
+      this.isloadings = this.isloadings += 1
+    },
+  },
+}
+</script>
+<style lang="scss" scoped></style>

+ 124 - 0
src/views/statisticsCharts/views/report/rfldTable.vue

@@ -0,0 +1,124 @@
+<template>
+  <!-- 航易行RFID扫描数据统计表 -->
+  <div class="statstics-wrapper">
+    <StatisticsHeader
+      title="航易行RFID扫描数据统计表"
+      :items="formItems"
+      :data="formData"
+      with-setting
+      :withSetting="false"
+      @getFormData="getFormData"
+      @export="exportup"
+    />
+    <Tableformbrs
+      :data-id="dataId"
+      upid="3"
+      :isloadings="isloadings"
+      :data-content="dataContent"
+      :rows="12"
+      label-width="140px"
+      :min-height="70"
+      width="800px"
+      tableHeight="750"
+    />
+  </div>
+</template>
+<script>
+import StatisticsHeader from '../../components/statisticsHeader.vue'
+import Tableformbrs from '../../components/tableformbrs'
+import { Format } from '@/utils/validate'
+export default {
+  name: 'ReportStatistics',
+  data() {
+    return {
+      formData: {
+        airport: '',
+        dateTime: [],
+        interval: '',
+      },
+      formItems: [
+        {
+          prop: 'airport',
+          inputType: 'select',
+          placeholder: '航站选择',
+          filterable: true,
+          clearable: true,
+          // multiple: true,
+          // disabled: true,
+          queryId: SERVICE_ID.termSeleid,
+          setKey: 'a2',
+          options: [],
+        },
+        {
+          prop: 'interval',
+          inputType: 'select',
+          placeholder: '时间维度',
+          requiredWarning: '请先选择统计时间维度',
+          clearable: true,
+          options: [
+            {
+              value: '日',
+              label: '按日统计',
+            },
+            {
+              value: '月',
+              label: '按月统计',
+            },
+            {
+              value: '季',
+              label: '按季统计',
+            },
+            {
+              value: '年',
+              label: '按年统计',
+            },
+          ],
+        },
+        {
+          prop: 'dateTime',
+          inputType: 'datePicker',
+          clearable: true,
+          width: '240px',
+          options: [],
+        },
+      ],
+      dataId: SERVICE_ID.stBrsId,
+      dataContent: [],
+      isloadings: 1,
+      tableData: [],
+      loading: false,
+      page: 0,
+      serviceId: null,
+      rowTitle: '',
+      tableCols: [], //表头数据
+    }
+  },
+  components: {
+    StatisticsHeader,
+    Tableformbrs,
+  },
+  mounted() {
+    this.dataContent = [
+      '日',
+      'PEK',
+      Format('yyyy-MM-dd', new Date()),
+      Format('yyyy-MM-dd', new Date()),
+    ]
+  },
+  methods: {
+    getFormData(data) {
+      this.dataContent = []
+      this.dataContent.push(
+        data.interval,
+        data.airport,
+        data.dateTime[0] ? data.dateTime[0] : '',
+        data.dateTime[1] ? data.dateTime[1] : ''
+      )
+    },
+    exportup() {
+      this.isloadings = this.isloadings += 1
+    },
+  },
+}
+</script>
+<style lang="scss" scoped></style>

+ 124 - 0
src/views/statisticsCharts/views/report/scanDataTable.vue

@@ -0,0 +1,124 @@
+<template>
+  <!-- Mannual Load扫描数据统计表 -->
+  <div class="statstics-wrapper">
+    <StatisticsHeader
+      title="Mannual Load扫描数据统计表"
+      :items="formItems"
+      :data="formData"
+      with-setting
+      :withSetting="false"
+      @getFormData="getFormData"
+      @export="exportup"
+    />
+    <Tableformbrs
+      :data-id="dataId"
+      upid="2"
+      :isloadings="isloadings"
+      :data-content="dataContent"
+      :rows="12"
+      label-width="140px"
+      :min-height="70"
+      width="800px"
+      tableHeight="750"
+    />
+  </div>
+</template>
+<script>
+import StatisticsHeader from '../../components/statisticsHeader.vue'
+import Tableformbrs from '../../components/tableformbrs'
+import { Format } from '@/utils/validate'
+export default {
+  name: 'ReportStatistics',
+  data() {
+    return {
+      formData: {
+        airport: '',
+        dateTime: [],
+        interval: '',
+      },
+      formItems: [
+        {
+          prop: 'airport',
+          inputType: 'select',
+          placeholder: '航站选择',
+          filterable: true,
+          clearable: true,
+          // multiple: true,
+          // disabled: true,
+          queryId: SERVICE_ID.termSeleid,
+          setKey: 'a2',
+          options: [],
+        },
+        {
+          prop: 'interval',
+          inputType: 'select',
+          placeholder: '时间维度',
+          requiredWarning: '请先选择统计时间维度',
+          clearable: true,
+          options: [
+            {
+              value: '日',
+              label: '按日统计',
+            },
+            {
+              value: '月',
+              label: '按月统计',
+            },
+            {
+              value: '季',
+              label: '按季统计',
+            },
+            {
+              value: '年',
+              label: '按年统计',
+            },
+          ],
+        },
+        {
+          prop: 'dateTime',
+          inputType: 'datePicker',
+          clearable: true,
+          width: '240px',
+          options: [],
+        },
+      ],
+      dataId: SERVICE_ID.stBrsId,
+      dataContent: [],
+      isloadings: 1,
+      tableData: [],
+      loading: false,
+      page: 0,
+      serviceId: null,
+      rowTitle: '',
+      tableCols: [], //表头数据
+    }
+  },
+  components: {
+    StatisticsHeader,
+    Tableformbrs,
+  },
+  mounted() {
+    this.dataContent = [
+      '日',
+      'PEK',
+      Format('yyyy-MM-dd', new Date()),
+      Format('yyyy-MM-dd', new Date()),
+    ]
+  },
+  methods: {
+    getFormData(data) {
+      this.dataContent = []
+      this.dataContent.push(
+        data.interval,
+        data.airport,
+        data.dateTime[0] ? data.dateTime[0] : '',
+        data.dateTime[1] ? data.dateTime[1] : ''
+      )
+    },
+    exportup() {
+      this.isloadings = this.isloadings += 1
+    },
+  },
+}
+</script>
+<style lang="scss" scoped></style>

+ 119 - 0
src/views/statisticsCharts/views/report/scanningStatistics.vue

@@ -0,0 +1,119 @@
+<template>
+  <!-- 航站BRS扫描统计 -->
+  <div class="statstics-wrapper">
+    <StatisticsHeader
+      title="航站BRS扫描统计"
+      :items="formItems"
+      :data="formData"
+      with-setting
+      :withSetting="false"
+      @getFormData="getFormData"
+      @export="exportup"
+    />
+    <Tableformbrs
+      upid="1"
+      :data-id="dataId"
+      :isloadings="isloadings"
+      :data-content="dataContent"
+      :rows="12"
+      label-width="140px"
+      :min-height="70"
+      width="800px"
+      tableHeight="750"
+    />
+  </div>
+</template>
+<script>
+import StatisticsHeader from '../../components/statisticsHeader.vue'
+import Tableformbrs from '../../components/tableformbrs'
+import { Format } from '@/utils/validate'
+export default {
+  name: 'ReportStatistics',
+  data() {
+    return {
+      formData: {
+        airport: '',
+        dateTime: [],
+        interval: '',
+
+      },
+      formItems: [
+        {
+          prop: 'airport',
+          inputType: 'select',
+          placeholder: '航站选择',
+          filterable: true,
+          clearable: true,
+          // multiple: true,
+          // disabled: true,
+          queryId: SERVICE_ID.termSeleid,
+          setKey: 'a2',
+          options: [],
+        },
+        {
+          prop: 'interval',
+          inputType: 'select',
+          placeholder: '时间维度',
+          requiredWarning: '请先选择统计时间维度',
+          clearable: true,
+          options: [
+            {
+              value: '日',
+              label: '按日统计',
+            },
+            {
+              value: '月',
+              label: '按月统计',
+            },
+            {
+              value: '季',
+              label: '按季统计',
+            },
+            {
+              value: '年',
+              label: '按年统计',
+            },
+          ],
+        },
+        {
+          prop: 'dateTime',
+          inputType: 'datePicker',
+          clearable: true,
+          width: '240px',
+          options: [],
+        },
+      ],
+      dataId: SERVICE_ID.stBrsId,
+      dataContent: [],
+      isloadings: 1,
+    }
+  },
+  components: {
+    StatisticsHeader,
+    Tableformbrs,
+  },
+  mounted() {
+    this.dataContent = [
+      '日',
+      'PEK',
+      Format('yyyy-MM-dd', new Date()),
+      Format('yyyy-MM-dd', new Date()),
+    ]
+  },
+  methods: {
+    getFormData(data) {
+      this.dataContent = []
+      this.dataContent.push(
+        data.interval,
+        data.airport,
+        data.dateTime[0] ? data.dateTime[0] : '',
+        data.dateTime[1] ? data.dateTime[1] : ''
+      )
+    },
+    exportup() {
+      this.isloadings = this.isloadings += 1
+    },
+  },
+}
+</script>
+<style lang="scss" scoped></style>

+ 167 - 0
src/views/statisticsCharts/views/report/transferBaggageTable.vue

@@ -0,0 +1,167 @@
+<template>
+  <!-- 中转行李因素分析统计 -->
+  <div class="statstics-wrapper">
+    <StatisticsHeader
+      title="中转行李因素分析统计"
+      :items="formItems"
+      :data="formData"
+      with-setting
+      :withSetting="false"
+      @export="exportup"
+      @getFormData="getFormData"
+    />
+    <!-- <Tableformcp
+      :isloadings="isloadings"
+      :rows="12"
+      label-width="140px"
+      :min-height="70"
+      width="800px"
+      tableHeight="750"
+    /> -->
+    <Tableformbrs
+      :data-id="dataId"
+      upid="6"
+      :isloadings="isloadings"
+      :data-content="dataContent"
+      :rows="12"
+      label-width="140px"
+      :min-height="70"
+      width="800px"
+      tableHeight="750"
+    />
+  </div>
+</template>
+<script>
+import StatisticsHeader from '../../components/statisticsHeader.vue'
+// import Tableformcp from "../../components/tableformcp";
+import Tableformbrs from '../../components/tableformbrs'
+import { Format } from '@/utils/validate'
+export default {
+  name: 'ReportStatistics',
+  data() {
+    return {
+      formData: {
+        airport: '',
+        dateTime: [],
+        company: '',
+        timedim: '',
+      },
+      isloadings: 1,
+      dataContent: [],
+      dataId: '1843',
+      formItems: [
+        {
+          prop: 'airport',
+          inputType: 'select',
+          placeholder: 'PEK',
+          filterable: true,
+          clearable: true,
+          // multiple: true,
+          // disabled: true,
+          queryId: SERVICE_ID.nodeAirport,
+          setKey: 'a2',
+          options: [],
+        },
+        {
+          prop: 'company',
+          inputType: 'select',
+          placeholder: '航班分类',
+          requiredWarning: '请先选择航班分类',
+          clearable: true,
+          options: [
+            {
+              value: '国航',
+              label: '国航',
+            },
+            {
+              value: '代理国内',
+              label: '代理国内',
+            },
+            {
+              value: '代理国际',
+              label: '代理国际',
+            },
+            {
+              value: '非代理',
+              label: '非代理',
+            },
+          ],
+        },
+        {
+          prop: 'timedim',
+          inputType: 'select',
+          placeholder: '时间维度',
+          requiredWarning: '请先选择统计时间维度',
+          clearable: true,
+          options: [
+            {
+              value: '日',
+              label: '按日统计',
+            },
+            {
+              value: '月',
+              label: '按月统计',
+            },
+            {
+              value: '年',
+              label: '按年统计',
+            },
+          ],
+        },
+        {
+          prop: 'dateTime',
+          inputType: 'datePicker',
+          clearable: true,
+          width: '240px',
+          options: [],
+        },
+      ],
+    }
+  },
+  components: {
+    StatisticsHeader,
+    // Tableformcp,
+    Tableformbrs,
+  },
+  mounted() {
+    this.dataContent = [
+      '日',
+      '日',
+      '日',
+      '国航',
+      '国航',
+      '国航',
+      '国航',
+      Format('yyyy-MM-dd', new Date()),
+      Format('yyyy-MM-dd', new Date()),
+      'PEK',
+      Format('yyyy-MM-dd', new Date()),
+      Format('yyyy-MM-dd', new Date()),
+      'PEK',
+    ]
+  },
+  methods: {
+    getFormData(data) {
+      this.dataContent = [
+        data.timedim,
+        data.timedim,
+        data.timedim,
+        data.company,
+        data.company,
+        data.company,
+        data.company,
+        data.dateTime[0],
+        data.dateTime[1],
+        data.airport ? data.airport : 'PEK',
+        data.dateTime[0],
+        data.dateTime[1],
+        data.airport ? data.airport : 'PEK',
+      ]
+    },
+    exportup() {
+      this.isloadings = this.isloadings += 1
+    },
+  },
+}
+</script>
+<style lang="scss" scoped></style>

+ 268 - 0
src/views/statisticsCharts/views/report/transferDirectionTable.vue

@@ -0,0 +1,268 @@
+<template>
+  <!-- 中转流向明细统计 -->
+  <div class="statstics-wrapper">
+    <StatisticsHeader
+      title="中转流向明细统计"
+      :items="formItems"
+      :data.sync="formData"
+      with-setting
+      :withSetting="false"
+      @export="exportup"
+      @getFormData="getFormData"
+    />
+    <!-- <Tableformcp
+      :isloadings="isloadings"
+      :rows="12"
+      label-width="140px"
+      :min-height="70"
+      width="800px"
+      tableHeight="750"
+    /> -->
+    <Tableformbrs
+      :data-id="dataId"
+      :textShow="textShow"
+      :textShowtp="textShowtp"
+      upid="5"
+      :isloadings="isloadings"
+      :data-content="dataContent"
+      :rows="12"
+      label-width="140px"
+      :min-height="70"
+      width="800px"
+      tableHeight="750"
+      @cell-click="cellClickHandler"
+    />
+    <TableDialog
+      :flag.sync="dialogFlag"
+      :query-params="queryParams"
+      :title="dialogTitle"
+    />
+  </div>
+</template>
+<script>
+import StatisticsHeader from '../../components/statisticsHeader.vue'
+// import Tableformcp from "../../components/tableformcp";
+import Tableformbrs from '../../components/tableformbrs'
+import TableDialog from '../../components/TableDialog.vue'
+import { Format } from '@/utils/validate'
+export default {
+  name: 'ReportStatistics',
+  data() {
+    return {
+      textShow: [],
+      textShowtp: [],
+      formData: {
+        airport: '',
+        dateTime: '',
+        company: '',
+        timedim: '',
+        dateTime: [],
+        trd: [],
+        ts: [],
+      },
+      isloadings: 1,
+      dataContent: [],
+      dataId: '1846',
+      formItems: [
+        {
+          prop: 'trd',
+          inputType: 'select',
+          placeholder: '全部',
+          requiredWarning: '',
+          clearable: true,
+          multiple: true,
+          options: [
+            {
+              value: 'D-D',
+              label: 'D-D',
+            },
+            {
+              value: 'D-I',
+              label: 'D-I',
+            },
+            {
+              value: 'I-I',
+              label: 'I-I',
+            },
+            {
+              value: 'I-D',
+              label: 'I-D',
+            },
+          ],
+        },
+        {
+          prop: 'ts',
+          inputType: 'select',
+          placeholder: '全部',
+          requiredWarning: '',
+          clearable: true,
+          multiple: true,
+          options: [
+            {
+              value: 'T2-T2',
+              label: 'T2-T2',
+            },
+            {
+              value: 'T2-T3',
+              label: 'T2-T3',
+            },
+            {
+              value: 'T3-T3',
+              label: 'T3-T3',
+            },
+            {
+              value: 'T3-T2',
+              label: 'T3-T2',
+            },
+          ],
+        },
+        {
+          prop: 'airport',
+          inputType: 'select',
+          placeholder: 'PEK',
+          filterable: true,
+          clearable: true,
+          // multiple: true,
+          disabled: true,
+          queryId: SERVICE_ID.nodeAirport,
+          setKey: 'a2',
+          options: [],
+        },
+        {
+          prop: 'company',
+          inputType: 'select',
+          placeholder: '航班分类',
+          requiredWarning: '请先选择航班分类',
+          clearable: true,
+          options: [
+            {
+              value: '国航',
+              label: '国航',
+            },
+            {
+              value: '代理国内',
+              label: '代理国内',
+            },
+            {
+              value: '代理国际',
+              label: '代理国际',
+            },
+            {
+              value: '非代理',
+              label: '非代理',
+            },
+          ],
+        },
+        {
+          prop: 'timedim',
+          inputType: 'select',
+          placeholder: '时间维度',
+          requiredWarning: '请先选择统计时间维度',
+          clearable: true,
+          options: [
+            {
+              value: '日',
+              label: '按日统计',
+            },
+            {
+              value: '月',
+              label: '按月统计',
+            },
+            {
+              value: '年',
+              label: '按年统计',
+            },
+          ],
+        },
+        {
+          prop: 'dateTime',
+          inputType: 'datePicker',
+          clearable: true,
+          width: '240px',
+          options: [],
+        },
+      ],
+      dialogFlag: false,
+      dialogTitle: '',
+      queryParams: [],
+    }
+  },
+  components: {
+    StatisticsHeader,
+    // Tableformcp,
+    Tableformbrs,
+    TableDialog,
+  },
+  mounted() {
+    this.dataContent = [
+      ...Array(3).fill(this.formData.timedim || '日'),
+      this.formData.airport || 'PEK',
+      this.formData.dateTime[0] || Format('yyyy-MM-dd', new Date()),
+      this.formData.dateTime[1] || Format('yyyy-MM-dd', new Date()),
+      ...Array(4).fill(this.formData.company || '国航'),
+    ]
+  },
+  methods: {
+    getFormData(data) {
+      this.textShow = data.trd
+      this.textShowtp = data.ts
+      this.dataContent = [
+        data.timedim,
+        data.timedim,
+        data.timedim,
+        'PEK',
+        data.dateTime[0],
+        data.dateTime[1],
+        data.company,
+        data.company,
+        data.company,
+        data.company,
+      ]
+    },
+    exportup() {
+      this.isloadings = this.isloadings += 1
+    },
+    cellClickHandler(row, column, cell, event) {
+      if (
+        column.property.includes('trans_bag') &&
+        row[column.property] &&
+        Number(row[column.property])
+      ) {
+        const queryParams = [
+          this.formData.airport || 'PEK',
+          row.fd || Format('yyyy-MM-dd', new Date()),
+          row.fd || Format('yyyy-MM-dd', new Date()),
+          ...Array(4).fill(this.formData.company || '国航'),
+        ]
+        const flow = column.property
+          .split('_')
+          .at(-2)
+          .toUpperCase()
+          .split('')
+          .join('-')
+        queryParams.push(...Array(4).fill(flow))
+        const direction = column.property
+          .split('_')
+          .at(-1)
+          .split('')
+          .map(v => `T${v}`)
+          .join('-')
+        queryParams.push(...Array(4).fill(direction))
+        const processMap = {
+          need: '需中转',
+          finish: '已中转',
+          not: '未中转',
+        }
+        const process = processMap[column.property.split('_')[0]]
+        queryParams.push(...Array(3).fill(process))
+        // console.log(queryParams)
+        // return
+        this.queryParams = queryParams
+        this.dialogTitle = column.label
+        this.dialogFlag = true
+      }
+    },
+  },
+}
+</script>
+<style lang="scss" scoped></style>

+ 206 - 0
src/views/statisticsCharts/views/report/transitTables.vue

@@ -0,0 +1,206 @@
+<template>
+  <!-- 中转四个流向统计 -->
+  <div class="statstics-wrapper">
+    <StatisticsHeader title="中转四个流向统计" :items="formItems" :data.sync="formData" with-setting :withSetting="false" @export="exportup" @getFormData="getFormData" />
+    <!-- <Tableformcp
+      :isloadings="isloadings"
+      :rows="12"
+      label-width="140px"
+      :min-height="70"
+      width="800px"
+      tableHeight="750"
+    /> -->
+    <Tableformbrs :data-id="dataId" upid="4" :textShow="textShow" :isloadings="isloadings" :data-content="dataContent" :rows="12" label-width="140px" :min-height="70" width="800px" tableHeight="750" @cell-click="cellClickHandler" />
+    <TableDialog :flag.sync="dialogFlag" :query-params="queryParams" with-setting :title="dialogTitle" />
+  </div>
+</template>
+<script>
+import StatisticsHeader from '../../components/statisticsHeader.vue'
+// import Tableformcp from "../../components/tableformcp";
+import Tableformbrs from '../../components/tableformbrs'
+import TableDialog from '../../components/TableDialog.vue'
+import { Format } from '@/utils/validate'
+export default {
+  name: 'ReportStatistics',
+  data () {
+    return {
+      textShow: null,
+      formData: {
+        airport: '',
+        dateTime: [],
+        company: '',
+        timedim: '',
+        trd: [],
+      },
+      isloadings: 1,
+      dataContent: [],
+      dataId: '1845',
+      formItems: [
+        {
+          prop: 'trd',
+          inputType: 'select',
+          placeholder: '',
+          requiredWarning: '',
+          clearable: true,
+          multiple: true,
+          options: [
+            {
+              value: 'D-D',
+              label: 'D-D',
+            },
+            {
+              value: 'D-I',
+              label: 'D-I',
+            },
+            {
+              value: 'I-I',
+              label: 'I-I',
+            },
+            {
+              value: 'I-D',
+              label: 'I-D',
+            },
+          ],
+        },
+        {
+          prop: 'airport',
+          inputType: 'select',
+          placeholder: 'PEK',
+          filterable: true,
+          clearable: true,
+          // multiple: true,
+          // disabled: true,
+          queryId: SERVICE_ID.nodeAirport,
+          setKey: 'a2',
+          options: [],
+        },
+        {
+          prop: 'company',
+          inputType: 'select',
+          placeholder: '航班分类',
+          requiredWarning: '请先选择航班分类',
+          clearable: true,
+          options: [
+            {
+              value: '国航',
+              label: '国航',
+            },
+            {
+              value: '代理国内',
+              label: '代理国内',
+            },
+            {
+              value: '代理国际',
+              label: '代理国际',
+            },
+            {
+              value: '非代理',
+              label: '非代理',
+            },
+          ],
+        },
+        {
+          prop: 'timedim',
+          inputType: 'select',
+          placeholder: '时间维度',
+          requiredWarning: '请先选择统计时间维度',
+          clearable: true,
+          options: [
+            {
+              value: '日',
+              label: '按日统计',
+            },
+            {
+              value: '月',
+              label: '按月统计',
+            },
+            {
+              value: '年',
+              label: '按年统计',
+            },
+          ],
+        },
+        {
+          prop: 'dateTime',
+          inputType: 'datePicker',
+          clearable: true,
+          width: '240px',
+          options: [],
+        },
+      ],
+      dialogFlag: false,
+      dialogTitle: '',
+      queryParams: [],
+    }
+  },
+  components: {
+    StatisticsHeader,
+    // Tableformcp,
+    Tableformbrs,
+    TableDialog,
+  },
+  mounted () {
+    this.dataContent = [
+      ...Array(3).fill(this.formData.timedim || '日'),
+      this.formData.airport || 'PEK',
+      this.formData.dateTime[0] || Format('yyyy-MM-dd', new Date()),
+      this.formData.dateTime[1] || Format('yyyy-MM-dd', new Date()),
+      ...Array(4).fill(this.formData.company || '国航'),
+    ]
+  },
+  methods: {
+    getFormData (data) {
+      this.textShow = data.trd
+      this.dataContent = [
+        data.timedim,
+        data.timedim,
+        data.timedim,
+        data.airport ? data.airport : 'PEK',
+        data.dateTime[0],
+        data.dateTime[1],
+        data.company,
+        data.company,
+        data.company,
+        data.company,
+      ]
+    },
+    exportup () {
+      this.isloadings = this.isloadings += 1
+    },
+    cellClickHandler (row, column, cell, event) {
+      if (
+        column.property.includes('trans_bag') &&
+        row[column.property] &&
+        Number(row[column.property])
+      ) {
+        const queryParams = [
+          this.formData.airport || 'PEK',
+          row.fd || Format('yyyy-MM-dd', new Date()),
+          row.fd || Format('yyyy-MM-dd', new Date()),
+          ...Array(4).fill(this.formData.company || '国航'),
+        ]
+        const flow = column.property
+          .split('_')
+          .pop()
+          .toUpperCase()
+          .split('')
+          .join('-')
+        queryParams.push(...Array(4).fill(flow))
+        queryParams.push(...Array(4).fill(null))
+        const processMap = {
+          need: '需中转',
+          finish: '已中转',
+          not: '未中转',
+        }
+        const process = processMap[column.property.split('_')[0]]
+        queryParams.push(...Array(3).fill(process))
+        // console.log(queryParams)
+        this.queryParams = queryParams
+        this.dialogTitle = column.label
+        this.dialogFlag = true
+      }
+    },
+  },
+}
+</script>
+<style lang="scss" scoped></style>

+ 34 - 0
src/views/statisticsCharts/views/special/abnormalBaggageClassificationStatisticsCharts.vue

@@ -0,0 +1,34 @@
+<template>
+  <CommonPieStatisticsCharts
+    charts-title="异常行李分类"
+    :query-settings="querySettings"
+    :custom-form-items="customFormItems"
+    :categories="categories"
+    only-airline
+  />
+</template>
+
+<script>
+import CommonPieStatisticsCharts from '../../components/commonPieStatisticsCharts.vue'
+import onlyAirline from '../../mixins/onlyAirline'
+
+export default {
+  name: 'AbnormalBaggageClassificationStatisticsCharts',
+  components: { CommonPieStatisticsCharts },
+  mixins: [onlyAirline],
+
+  data() {
+    return {
+      querySettings: {
+        // byArea: SERVICE_ID.abnormalBaggageClassificationByArea,
+        // byOther: SERVICE_ID.abnormalBaggageClassificationByOther,
+        all: SERVICE_ID.abnormalBaggageClassificationAll,
+        byAirline: SERVICE_ID.abnormalBaggageClassificationByAirline,
+        categoryKey: 'RECTYPE',
+        seriesKey: 'nums'
+      },
+      categories: ['少收', '多收', '破损']
+    }
+  }
+}
+</script>

+ 34 - 0
src/views/statisticsCharts/views/special/compensationBaggageClassificationStatisticsCharts.vue

@@ -0,0 +1,34 @@
+<template>
+  <CommonPieStatisticsCharts
+    charts-title="赔偿行李量分类"
+    :query-settings="querySettings"
+    :custom-form-items="customFormItems"
+    :categories="categories"
+    only-airline
+  />
+</template>
+
+<script>
+import CommonPieStatisticsCharts from '../../components/commonPieStatisticsCharts.vue'
+import onlyAirline from '../../mixins/onlyAirline'
+
+export default {
+  name: 'CompensationClassificationStatisticsCharts',
+  components: { CommonPieStatisticsCharts },
+  mixins: [onlyAirline],
+
+  data() {
+    return {
+      querySettings: {
+        // byArea: SERVICE_ID.compensationClassificationByArea,
+        // byOther: SERVICE_ID.compensationClassificationByOther,
+        all: SERVICE_ID.compensationBaggageClassificationAll,
+        byAirline: SERVICE_ID.compensationBaggageClassificationByAirline,
+        categoryKey: 'costType',
+        seriesKey: 'nums'
+      },
+      categories: ['F', 'D', 'A', 'X', 'G'],
+    }
+  }
+}
+</script>

+ 35 - 0
src/views/statisticsCharts/views/special/compensationClassificationStatisticsCharts.vue

@@ -0,0 +1,35 @@
+<template>
+  <CommonPieStatisticsCharts
+    charts-title="赔偿金额分类"
+    :query-settings="querySettings"
+    :custom-form-items="customFormItems"
+    :categories="categories"
+    pie-title="总金额"
+    only-airline
+  />
+</template>
+
+<script>
+import CommonPieStatisticsCharts from '../../components/commonPieStatisticsCharts.vue'
+import onlyAirline from '../../mixins/onlyAirline'
+
+export default {
+  name: 'CompensationClassificationStatisticsCharts',
+  components: { CommonPieStatisticsCharts },
+  mixins: [onlyAirline],
+
+  data() {
+    return {
+      querySettings: {
+        // byArea: SERVICE_ID.compensationClassificationByArea,
+        // byOther: SERVICE_ID.compensationClassificationByOther,
+        all: SERVICE_ID.compensationClassificationAll,
+        byAirline: SERVICE_ID.compensationClassificationByAirline,
+        categoryKey: 'costType',
+        seriesKey: 'amount'
+      },
+      categories: ['F', 'D', 'A', 'X', 'G'],
+    }
+  }
+}
+</script>

+ 26 - 0
src/views/statisticsCharts/views/special/specialBaggageClassificationStatisticsCharts.vue

@@ -0,0 +1,26 @@
+<template>
+  <CommonPieStatisticsCharts
+    charts-title="特殊行李分类"
+    :query-settings="querySettings"
+    :categories="categories"
+  />
+</template>
+
+<script>
+import CommonPieStatisticsCharts from '../../components/commonPieStatisticsCharts.vue'
+export default {
+  name: 'SpecialBaggageClassificationStatisticsCharts',
+  components: { CommonPieStatisticsCharts },
+  data() {
+    return {
+      querySettings: {
+        byArea: SERVICE_ID.specialBaggageClassificationByArea,
+        byOther: SERVICE_ID.specialBaggageClassificationByOther,
+        categoryKey: 'special',
+        seriesKey: 'specialnum'
+      },
+      categories: ['小动物', '乘务员', '枪支', '其它', '超规']
+    }
+  }
+}
+</script>

+ 51 - 0
src/views/statisticsCharts/views/specialbaggageanalysisStatisticsCharts.vue

@@ -0,0 +1,51 @@
+<template>
+  <CommonPieStatisticsCharts
+    charts-title="特殊行李分析"
+    :query-settings="querySettings"
+    :categories="categories"
+    :form-data="formData"
+    :form-items="formItems"
+  />
+</template>
+
+<script>
+import CommonPieStatisticsCharts from '../components/newPieStatisticsChartscpsy.vue'
+
+export default {
+  name: 'AbnormalBaggageClassificationStatisticsCharts',
+  components: { CommonPieStatisticsCharts },
+
+  data() {
+    return {
+      querySettings: {
+        serviceId: SERVICE_ID.specialbaggageanalysis,
+      },
+      categories: ['小动物', '机组', '枪支', '其它', '超规'],
+      formData: {
+        dateTime: [],
+        airport: '',
+      },
+      formItems: [
+        {
+          prop: 'airport',
+          inputType: 'select',
+          placeholder: '航站',
+          width: '150px',
+          filterable: true,
+          // multiple: true,
+          queryId: SERVICE_ID.AirportIds,
+          setKey: 'code3',
+          requiredWarning: '请先选择航站',
+          options: [],
+        },
+        {
+          prop: 'dateTime',
+          inputType: 'datePicker',
+          width: '240px',
+          requiredWarning: '请先选择统计时间范围',
+        },
+      ],
+    }
+  },
+}
+</script>

+ 142 - 0
src/views/statisticsCharts/views/transitTables.vue

@@ -0,0 +1,142 @@
+<template>
+  <!-- 中转四个流向统计 -->
+  <div class="statstics-wrapper">
+    <StatisticsHeader title="中转四个流向统计" :items="formItems" :data.sync="formData" with-setting :withSetting="false" @export="exportup" @getFormData="getFormData" />
+    <!-- <Tableformcp
+      :isloadings="isloadings"
+      :rows="12"
+      label-width="140px"
+      :min-height="70"
+      width="800px"
+      tableHeight="750"
+    /> -->
+    <Tableformbrs class="statstics-wrapper-table" :data-id="dataId" upid="4" :textShow="textShow" :isloadings="isloadings" :data-content="dataContent" :rows="12" label-width="140px" :min-height="70" width="800px" tableHeight="750" @cell-click="cellClickHandler" />
+    <TableDialog :flag.sync="dialogFlag" :query-params="queryParams" with-setting :title="dialogTitle" />
+  </div>
+</template>
+<script>
+import StatisticsHeader from '../components/statisticsHeader.vue'
+// import Tableformcp from "../../components/tableformcp";
+import Tableformbrs from '../components/tableformbrs'
+import TableDialog from '../components/TableDialog.vue'
+import { Format } from '@/utils/validate'
+export default {
+  name: 'ReportStatistics',
+  data () {
+    return {
+      textShow: null,
+      formData: {
+        airport: '',
+        dateTime: [],
+        company: ['国航'],
+        timedim: '',
+        trd: [],
+      },
+      isloadings: 1,
+      dataContent: [],
+      dataId: SERVICE_ID.transferBaggageDirection,
+      formItems: [
+        {
+          prop: 'airport',
+          inputType: 'select',
+          placeholder: '航站',
+          filterable: true,
+          queryId: SERVICE_ID.AirportIds,
+          setKey: 'code3',
+          requiredWarning: '请先选择航站',
+          options: [],
+        },
+        {
+          prop: 'dateTime',
+          inputType: 'datePicker',
+          clearable: true,
+          width: '240px',
+          options: [],
+        },
+      ],
+      dialogFlag: false,
+      dialogTitle: '',
+      queryParams: [],
+    }
+  },
+  components: {
+    StatisticsHeader,
+    // Tableformcp,
+    Tableformbrs,
+    TableDialog,
+  },
+  mounted () {
+    // this.dataContent = [
+    //   ...Array(3).fill(this.formData.timedim || '日'),
+    //   this.formData.airport || 'PEK',
+    //   this.formData.dateTime[0] || Format('yyyy-MM-dd', new Date()),
+    //   this.formData.dateTime[1] || Format('yyyy-MM-dd', new Date()),
+    //   ...Array(4).fill(this.formData.company?.join(',') || '国航'),
+    // ]
+  },
+  methods: {
+    getFormData (data) {
+      this.textShow = data.trd
+      this.dataContent = [{
+        airport: data.airport,
+        fd1: data.dateTime[0],
+        fd2: data.dateTime[1]
+      }]
+      // this.dataContent = [
+      //   ...Array(3).fill(data.timedim || '日'),
+      //   data.airport || 'PEK',
+      //   data.dateTime[0] || Format('yyyy-MM-dd', new Date()),
+      //   data.dateTime[1] || Format('yyyy-MM-dd', new Date()),
+      //   ...Array(4).fill(this.formData.company?.join(',') || '国航'),
+      // ]
+    },
+    exportup () {
+      this.isloadings = this.isloadings += 1
+    },
+    cellClickHandler (row, column, cell, event) {
+      if (
+        column.property.includes('trans_bag') &&
+        row[column.property] &&
+        Number(row[column.property])
+      ) {
+        const queryParams = [
+          this.formData.airport || 'PEK',
+          row.fd || Format('yyyy-MM-dd', new Date()),
+          row.fd || Format('yyyy-MM-dd', new Date()),
+          ...Array(4).fill(this.formData.company?.join(',') || '国航'),
+        ]
+        const flow = column.property
+          .split('_')
+          .pop()
+          .toUpperCase()
+          .split('')
+          .join('-')
+        queryParams.push(...Array(4).fill(flow))
+        queryParams.push(...Array(4).fill(null))
+        const processMap = {
+          need: '需中转',
+          finish: '已中转',
+          not: '未中转',
+        }
+        const process = processMap[column.property.split('_')[0]]
+        queryParams.push(...Array(3).fill(process))
+        // console.log(queryParams)
+        this.queryParams = queryParams
+        this.dialogTitle = column.label
+        this.dialogFlag = true
+      }
+    },
+  },
+}
+</script>
+<style lang="scss" scoped>
+::v-deep .statstics-wrapper-table {
+  height: calc(100vh - 265px);
+  .data-table-content {
+    height: 100%;
+    .el-table {
+      height: 100%;
+    }
+  }
+}
+</style>

+ 170 - 0
src/views/statisticsCharts/views/workloadStatisticsCharts.vue

@@ -0,0 +1,170 @@
+<template>
+  <CommonBarStatisticsCharts charts-title="工作量" :query-settings="querySettings" :form-data="formData" :form-items="formItems" />
+</template>
+
+<script>
+import CommonBarStatisticsCharts from '../components/newBarStatisticsCharts.vue'
+import { Query } from '@/api/webApi'
+import { parseTime } from '@/utils'
+
+export default {
+  name: 'WorkloadStatisticsCharts',
+  components: { CommonBarStatisticsCharts },
+  data () {
+    const that = this
+    return {
+      querySettings: {
+        serviceId: SERVICE_ID.workload,
+        seriesKey: 'workload',
+        xAxisKey: 'fd',
+      },
+      formData: {
+        td: '日',
+        agent_number: '',
+        airport: '',
+        dateTime: [],
+      },
+      formItems: [
+        {
+          prop: 'td',
+          inputType: 'select',
+          placeholder: '时间维度',
+          requiredWarning: '请先选择统计时间维度',
+          options: [
+            {
+              value: '日',
+              label: '按日统计',
+            },
+            {
+              value: '月',
+              label: '按月统计',
+            },
+            {
+              value: '年',
+              label: '按年统计',
+            },
+          ],
+          changeHandler (value, oldValue) {
+            const typeMap = {
+              日: 'datePicker',
+              月: 'monthPicker',
+              年: 'yearPicker',
+            }
+            const dateTimeItem = this.formItems.find(
+              item => item.prop === 'dateTime'
+            )
+            const formData = this._.cloneDeep(this.formData)
+            if (dateTimeItem) {
+              dateTimeItem.inputType = typeMap[value]
+              const dateTime = formData.dateTime
+              if (dateTime && dateTime[0] && dateTime[1]) {
+                if (value === '年') {
+                  this.formData.dateTime[0] = dateTime[0].split('-')[0]
+                  this.formData.dateTime[1] = dateTime[1].split('-')[0]
+                }
+                if (value === '月') {
+                  if (oldValue === '年') {
+                    this.formData.dateTime[0] = `${dateTime[0].split('-')[0]
+                      }-01`
+                    this.formData.dateTime[1] = `${dateTime[1].split('-')[0]
+                      }-12`
+                  }
+                  if (oldValue === '日') {
+                    this.formData.dateTime[0] = dateTime[0]
+                      .split('-')
+                      .slice(0, 2)
+                      .join('-')
+                    this.formData.dateTime[1] = dateTime[1]
+                      .split('-')
+                      .slice(0, 2)
+                      .join('-')
+                  }
+                }
+                if (value === '日') {
+                  if (oldValue === '年') {
+                    this.formData.dateTime[0] = `${dateTime[0].split('-')[0]
+                      }-01-01`
+                    this.formData.dateTime[1] = `${dateTime[1].split('-')[0]
+                      }-12-31`
+                  }
+                  if (oldValue === '月') {
+                    this.formData.dateTime[0] = `${dateTime[0]
+                      .split('-')
+                      .slice(0, 2)
+                      .join('-')}-01`
+                    let [year, month] = dateTime[1].split('-')
+                    if (month === '12') {
+                      year = Number(year) + 1
+                      month = 1
+                    } else {
+                      month = Number(month) + 1
+                    }
+                    const day = 24 * 60 * 60 * 1000
+                    this.formData.dateTime[1] = parseTime(
+                      new Date(`${year}-${month}-01`) - day * 1,
+                      '{y}-{m}-{d}'
+                    )
+                  }
+                }
+              }
+            }
+          },
+        },
+        {
+          prop: 'airport',
+          inputType: 'select',
+          placeholder: '航站',
+          filterable: true,
+          queryId: SERVICE_ID.AirportIds,
+          setKey: 'code3',
+          requiredWarning: '请先选择航站',
+          options: [],
+          changeHandler (value) {
+            that.agent_number = ''
+            that.getAgentOptions(value)
+          },
+        },
+        {
+          prop: 'agent_number',
+          inputType: 'select',
+          placeholder: '操作人',
+          requiredWarning: '请先选择操作人',
+          filterable: true,
+          options: [],
+        },
+        {
+          prop: 'dateTime',
+          inputType: 'datePicker',
+          width: '240px',
+          requiredWarning: '请先选择时间范围',
+        },
+      ],
+    }
+  },
+  methods: {
+    async getAgentOptions (airport) {
+      try {
+        const { code, returnData, message } = await Query({
+          serviceId: SERVICE_ID.agentCode,
+          dataContent: [
+            {
+              airport,
+            },
+          ],
+        })
+        if (String(code) === '0') {
+          const listValues = returnData.listValues || returnData
+          this.formItems[2].options = listValues.map(element => ({
+            label: element.agent_number,
+            value: element.agent_number,
+          }))
+        } else {
+          this.$message.error(message)
+        }
+      } catch (error) {
+        this.$message.error('失败')
+      }
+    },
+  },
+}
+</script>