Bläddra i källkod

图表导出成图片

zhongxiaoyu 2 år sedan
förälder
incheckning
2524d9f11b

+ 28 - 10
src/utils/table.js

@@ -190,19 +190,37 @@ export function exportToExcel(table, tableName, fileName, headerRowNumber = 1) {
         }
         let cellStyle = {
           alignment: {
+            horizontal: 'center',
             vertical: 'center'
           }
         }
-        // if (rowIndex < headerRowNumber) {
-        //   cellStyle = {
-        //     ...cellStyle,
-        //     fill: {
-        //       bgColor: {
-        //         rgb: '3366FF'
-        //       }
-        //     }
-        //   }
-        // }
+        if (rowIndex < headerRowNumber) {
+          const borderStyle = {
+            style: 'medium',
+            color: {
+              rgb: 'FFFFFF'
+            }
+          }
+          cellStyle = {
+            ...cellStyle,
+            border: {
+              top: borderStyle,
+              right: borderStyle,
+              bottom: borderStyle,
+              left: borderStyle
+            },
+            font: {
+              color: {
+                rgb: 'FFFFFF'
+              }
+            },
+            fill: {
+              fgColor: {
+                rgb: '3366FF'
+              }
+            }
+          }
+        }
         xlsxDatas[cellName].s = cellStyle
       }
     }

+ 1 - 1
src/views/baggageManagement/components/arrival/index.vue

@@ -681,7 +681,7 @@ export default {
       }
       const table = this.$refs[refName].$el.cloneNode(true)
       const fileName = `${tableName}-${this.currentAirport}-${this.startDate}-${this.endDate}.xlsx`
-      throttledExportToExcel(table, tableName, fileName)
+      throttledExportToExcel(table, tableName, fileName, 2)
     }
   }
 }

+ 235 - 56
src/views/baggageManagement/components/transferArrival/index.vue

@@ -8,8 +8,17 @@
 <template>
   <div class="transfer-in">
     <!--功能区-表单-->
-    <div ref="formWrap" class="terminal-form-wrap">
-      <el-form ref="form" :inline="true" :model="formData" :rules="rules" class="form">
+    <div
+      ref="formWrap"
+      class="terminal-form-wrap"
+    >
+      <el-form
+        ref="form"
+        :inline="true"
+        :model="formData"
+        :rules="rules"
+        class="form"
+      >
         <div class="form-left">
           <el-form-item prop="currentAirport">
             <!-- <el-cascader
@@ -24,15 +33,52 @@
             filterable
             @change="setCurrentAirport"
           /> -->
-            <el-select v-model="formData.currentAirport" class="input-shadow" size="small" style="width: 100px;" filterable placeholder="请选择机场" @change="airPortChange">
-              <el-option v-for="(item, index) in AirportList" :key="index" :label="item.planDepartureApt" :value="item.planDepartureApt" />
+            <el-select
+              v-model="formData.currentAirport"
+              class="input-shadow"
+              size="small"
+              style="width: 100px;"
+              filterable
+              placeholder="请选择机场"
+              @change="airPortChange"
+            >
+              <el-option
+                v-for="(item, index) in AirportList"
+                :key="index"
+                :label="item.planDepartureApt"
+                :value="item.planDepartureApt"
+              />
             </el-select>
           </el-form-item>
           <el-form-item prop="inboundCarrier">
-            <el-cascader v-model="formData.inboundCarrier" class="input-shadow" style="width: 150px" size="small" :options="carrierProps" :props="optionProps" placeholder="进港承运航司" collapse-tags clearable filterable @change="resetLoopEvent" />
+            <el-cascader
+              v-model="formData.inboundCarrier"
+              class="input-shadow"
+              style="width: 150px"
+              size="small"
+              :options="carrierProps"
+              :props="optionProps"
+              placeholder="进港承运航司"
+              collapse-tags
+              clearable
+              filterable
+              @change="resetLoopEvent"
+            />
           </el-form-item>
           <el-form-item prop="outgoingAirline">
-            <el-cascader v-model="formData.outgoingAirline" class="input-shadow" style="width: 150px" size="small" :options="carrierPropsop" :props="optionPropser" placeholder="离港承运航司" collapse-tags clearable filterable @change="resetLoopEvent" />
+            <el-cascader
+              v-model="formData.outgoingAirline"
+              class="input-shadow"
+              style="width: 150px"
+              size="small"
+              :options="carrierPropsop"
+              :props="optionPropser"
+              placeholder="离港承运航司"
+              collapse-tags
+              clearable
+              filterable
+              @change="resetLoopEvent"
+            />
           </el-form-item>
           <!-- <el-form-item prop="startDate">
             <el-date-picker
@@ -58,51 +104,156 @@
               @change="endDateChangeHandler"
             />
           </el-form-item> -->
-          <el-form-item prop="flightDate" label="航班日期">
-            <el-date-picker v-model="formData.flightDate" size="small" style="width: 300px;" type="daterange" value-format="yyyy-MM-dd" start-placeholder="开始日期" end-placeholder="结束日期" :picker-options="dateRangePickerOptions" @change="dateChangeHandler" />
+          <el-form-item
+            prop="flightDate"
+            label="航班日期"
+          >
+            <el-date-picker
+              v-model="formData.flightDate"
+              size="small"
+              style="width: 300px;"
+              type="daterange"
+              value-format="yyyy-MM-dd"
+              start-placeholder="开始日期"
+              end-placeholder="结束日期"
+              :picker-options="dateRangePickerOptions"
+              @change="dateChangeHandler"
+            />
           </el-form-item>
           <el-form-item>
             <div class="box-item">
               <p>预计中转数:</p>
-              <li v-for="(item, index) in orderNum" :key="index" :class="{ 'number-item': !isNaN(item), 'mark-item': isNaN(item) }">
+              <li
+                v-for="(item, index) in orderNum"
+                :key="index"
+                :class="{ 'number-item': !isNaN(item), 'mark-item': isNaN(item) }"
+              >
                 <span v-if="!isNaN(item)">
                   <i ref="numberItem">0123456789</i>
                 </span>
-                <span v-else class="comma">{{ item }}</span>
+                <span
+                  v-else
+                  class="comma"
+                >{{ item }}</span>
               </li>
             </div>
           </el-form-item>
         </div>
-        <div class="form-right" @keyup.enter="onSubmit(1)">
+        <div
+          class="form-right"
+          @keyup.enter="onSubmit(1)"
+        >
           <el-form-item prop="search">
-            <el-popover :value="popoverVisible" placement="bottom" trigger="manual">
+            <el-popover
+              :value="popoverVisible"
+              placement="bottom"
+              trigger="manual"
+            >
               <span>请输入航班号(示例:CA1234)或行李牌号(示例:1234567890)</span>
-              <el-input slot="reference" v-model="formData.search" class="input-shadow" style="width: 240px;" size="small" placeholder="请输入内容" prefix-icon="el-icon-search" clearable @focus="popoverVisible = true" @blur="popoverVisible = false" />
+              <el-input
+                slot="reference"
+                v-model="formData.search"
+                class="input-shadow"
+                style="width: 240px;"
+                size="small"
+                placeholder="请输入内容"
+                prefix-icon="el-icon-search"
+                clearable
+                @focus="popoverVisible = true"
+                @blur="popoverVisible = false"
+              />
             </el-popover>
           </el-form-item>
           <el-form-item>
-            <el-button class="btn-shadow" size="mini" type="primary" @click="onSubmit(1)">搜索</el-button>
+            <el-button
+              class="btn-shadow"
+              size="mini"
+              type="primary"
+              @click="onSubmit(1)"
+            >搜索</el-button>
           </el-form-item>
           <el-form-item v-is="['ti_showTransit']">
-            <el-button class="btn-shadow" size="mini" type="primary" @click="changeView">切换视角</el-button>
+            <el-button
+              class="btn-shadow"
+              size="mini"
+              type="primary"
+              @click="changeView"
+            >切换视角</el-button>
           </el-form-item>
           <el-form-item v-is="['ti_timeIcon']">
             <TimeZoneSelector />
           </el-form-item>
           <el-form-item v-is="['ti_columnSettings']">
-            <img class="btn-img btn-shadow" src="../../../../assets/baggage/ic_setting.png" @click="show">
+            <img
+              class="btn-img btn-shadow"
+              src="../../../../assets/baggage/ic_setting.png"
+              title="列设置"
+              @click="show"
+            >
+          </el-form-item>
+          <el-form-item v-is="['dm_dt_columnSettings']">
+            <img
+              class="btn-img btn-shadow"
+              src="../../../../assets/baggage/ic_export.png"
+              title="导出"
+              @click="exportHandler('table', '航站中转进港列表')"
+            >
           </el-form-item>
         </div>
       </el-form>
     </div>
     <!--表格-->
-    <div v-loading="loading" class="terminal-table" element-loading-text="拼命加载中" element-loading-spinner="el-icon-loading" element-loading-background="rgba(0, 0, 0, 0.8)">
-      <el-table ref="table" class="table" :data="dealedTableData" :height="computedTableHeight" show-summary :summary-method="summaryMethod" :span-method="arraySpanMethod" :header-cell-class-name="headerCellClass" :row-class-name="tableRowClassName" :cell-class-name="cellClass" border stripe fit @cell-click="cellClickHandler">
-        <el-table-column v-for="col in tableColsCopy" :key="col.prop" :prop="col.prop" :label="col.label" :width="col.width" :fixed="col.fixed">
-          <el-table-column v-for="childCol in col.children" :key="childCol.prop" :prop="childCol.prop" :label="childCol.label" :width="childCol.width" :formatter="tableFormat">
+    <div
+      v-loading="loading"
+      class="terminal-table"
+      element-loading-text="拼命加载中"
+      element-loading-spinner="el-icon-loading"
+      element-loading-background="rgba(0, 0, 0, 0.8)"
+    >
+      <el-table
+        ref="table"
+        class="table"
+        :data="dealedTableData"
+        :height="computedTableHeight"
+        show-summary
+        :summary-method="summaryMethod"
+        :span-method="arraySpanMethod"
+        :header-cell-class-name="headerCellClass"
+        :row-class-name="tableRowClassName"
+        :cell-class-name="cellClass"
+        border
+        stripe
+        fit
+        @cell-click="cellClickHandler"
+      >
+        <el-table-column
+          v-for="col in tableColsCopy"
+          :key="col.prop"
+          :prop="col.prop"
+          :label="col.label"
+          :width="col.width"
+          :fixed="col.fixed"
+        >
+          <el-table-column
+            v-for="childCol in col.children"
+            :key="childCol.prop"
+            :prop="childCol.prop"
+            :label="childCol.label"
+            :width="childCol.width"
+            :formatter="tableFormat"
+          >
             <template #header>
-              <el-tooltip :content="childCol.desc || childCol.label" placement="top">
-                <TableHeaderCell :label="childCol.label" :filter-options="tableDataFilters[childCol.prop]" :filter-values.sync="filterValues[childCol.prop]" :sortable="childCol.sortable" :sort-rule.sync="tableDataSortRules[childCol.prop]" />
+              <el-tooltip
+                :content="childCol.desc || childCol.label"
+                placement="top"
+              >
+                <TableHeaderCell
+                  :label="childCol.label"
+                  :filter-options="tableDataFilters[childCol.prop]"
+                  :filter-values.sync="filterValues[childCol.prop]"
+                  :sortable="childCol.sortable"
+                  :sort-rule.sync="tableDataSortRules[childCol.prop]"
+                />
               </el-tooltip>
             </template>
           </el-table-column>
@@ -110,18 +261,38 @@
       </el-table>
     </div>
     <!--列设置-->
-    <Dialog :flag="dialogFlag" class="dialog-check-cols">
+    <Dialog
+      :flag="dialogFlag"
+      class="dialog-check-cols"
+    >
       <div class="col-dialog">
         <div class="title">列设置</div>
         <div class="content">
-          <el-tree :data="tableCols" :class="colsCheckClass" show-checkbox node-key="index" :default-expand-all="true" :props="{
+          <el-tree
+            :data="tableCols"
+            :class="colsCheckClass"
+            show-checkbox
+            node-key="index"
+            :default-expand-all="true"
+            :props="{
               label: 'label',
               children: 'children',
-            }" :default-checked-keys="checkedKeysTemp" @check="handleCheck" />
+            }"
+            :default-checked-keys="checkedKeysTemp"
+            @check="handleCheck"
+          />
         </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>
+          <el-button
+            size="medium"
+            class="r24"
+            type="primary"
+            @click="onCheck"
+          >确定</el-button>
+          <el-button
+            size="medium"
+            @click="hide"
+          >取消</el-button>
         </div>
       </div>
     </Dialog>
@@ -137,13 +308,13 @@ import tableColsMixin from '../../mixins/tableCols'
 import timeZoneMixin from '../../mixins/timeZone'
 import { getQuery } from '@/api/flight'
 import TableHeaderCell from '@/components/TableHeaderCell'
-import { setTableFilters } from '@/utils/table'
+import { setTableFilters, throttledExportToExcel } from '@/utils/table'
 
 export default {
   name: 'DepartureTerminalView',
   components: { Dialog, TimeZoneSelector, TableHeaderCell },
   mixins: [terminalMixin, formMixin, tableColsMixin, timeZoneMixin],
-  data () {
+  data() {
     return {
       optionProps: {
         value: 'inAicompanyCode2',
@@ -318,13 +489,13 @@ export default {
     }
   },
   computed: {
-    singleDay () {
+    singleDay() {
       return this.startDate === this.endDate
     }
   },
   watch: {
     dealedTableData: {
-      handler (val) {
+      handler(val) {
         this.spanArr = []
         let contactDot = this.contactDot
         val.forEach((item, index, arr) => {
@@ -347,10 +518,10 @@ export default {
       deep: true
     }
   },
-  created () {
+  created() {
     // this.getAirPortData()
   },
-  mounted () {
+  mounted() {
     this.$refs['form'].validateField('flightDate')
     this.getAirPortData()
     this.table = this.$refs.table.bodyWrapper
@@ -359,7 +530,7 @@ export default {
       that.scrollTop = this.table.scrollTop
     })
   },
-  activated () {
+  activated() {
     this.table.scrollTop = this.scrollTop
     this.getTableData()
     const that = this
@@ -379,20 +550,20 @@ export default {
     //   this.formData.flightDate[1] = endDate
     // }
   },
-  deactivated () {
+  deactivated() {
     if (this.loopEvent) {
       clearInterval(this.loopEvent)
       this.loopEvent = null
     }
   },
-  beforeDestroy () {
+  beforeDestroy() {
     if (this.loopEvent) {
       clearInterval(this.loopEvent)
       this.loopEvent = null
     }
   },
   methods: {
-    resetLoopEvent () {
+    resetLoopEvent() {
       this.loading = true
       this.hasSetTableScroll = false
       if (this.loopEvent) {
@@ -404,7 +575,7 @@ export default {
         that.getTableData()
       }, 3000)
     },
-    headerCellClass ({ row, column }) {
+    headerCellClass({ row, column }) {
       const classes = []
       const rule = this.tableDataSortRules[column.property]
       if (rule) {
@@ -412,7 +583,7 @@ export default {
       }
       return classes.join(' ')
     },
-    tableRowClassName ({ row, rowIndex }) {
+    tableRowClassName({ row, rowIndex }) {
       const classes = []
       if (row.hasArrived) {
         classes.push('bgl-hui')
@@ -422,7 +593,7 @@ export default {
       }
       return classes.join(' ')
     },
-    changeView () {
+    changeView() {
       // const query = {
       //   ...this.formData,
       //   startDate: this.startDate,
@@ -435,18 +606,18 @@ export default {
       // })
       this.$router.push('/transfer/departure')
     },
-    airPortChange () {
+    airPortChange() {
       this.getAviationData()
       this.upAviationData()
       this.resetLoopEvent()
     },
-    dateChangeHandler () {
+    dateChangeHandler() {
       this.getAviationData()
       this.upAviationData()
       this.resetLoopEvent()
     },
     // 选择机场
-    async getAirPortData () {
+    async getAirPortData() {
       try {
         const res = await getQuery({
           id: DATACONTENT_ID.departureAirId,
@@ -466,7 +637,7 @@ export default {
       }
     },
     // 选择航司
-    async getAviationData () {
+    async getAviationData() {
       try {
         const res = await getQuery({
           id: DATACONTENT_ID.departureAviJoinId,
@@ -482,7 +653,7 @@ export default {
       }
     },
     // 选择航司
-    async upAviationData () {
+    async upAviationData() {
       try {
         const res = await getQuery({
           id: DATACONTENT_ID.departureAviLeaveId,
@@ -508,7 +679,7 @@ export default {
     //   this.flightAttrQuery(params)
     // },
     // 获取表格数据
-    async getTableData () {
+    async getTableData() {
       if (!this.formData.currentAirport || !this.startDate || !this.endDate) {
         return
       }
@@ -549,7 +720,7 @@ export default {
         console.log('出错了', error.message || error)
       }
     },
-    initTableData (tableData) {
+    initTableData(tableData) {
       this.arrivalCount = 0
       this.baggageCount = 0
       tableData.forEach(item => {
@@ -565,7 +736,7 @@ export default {
         this.setTableScroll()
       })
     },
-    hasArrived (flight) {
+    hasArrived(flight) {
       if (flight.actualLandingTime) {
         const now = new Date()
         const actualLandingTime = new Date(flight.actualLandingTime.replace('T', ' '))
@@ -575,7 +746,7 @@ export default {
       }
       return flight['hasArrived']
     },
-    setTableScroll () {
+    setTableScroll() {
       if (!this.singleDay || this.hasSetTableScroll || this.arrivalCount === 0) {
         return
       }
@@ -595,7 +766,7 @@ export default {
       }, 0)
       this.hasSetTableScroll = true
     },
-    setNumberTransform () {
+    setNumberTransform() {
       const numberItems = this.$refs.numberItem // 拿到数字的ref,计算元素数量
       const numberArr = this.orderNum.filter(item => !isNaN(item))
       // 结合CSS 对数字字符进行滚动,显示订单数量
@@ -605,7 +776,7 @@ export default {
       }
     },
 
-    toOrderNum (num) {
+    toOrderNum(num) {
       num = num.toString()
       if (num.length < 6) {
         num = '0' + num // 如未满八位数,添加"0"补位
@@ -618,7 +789,7 @@ export default {
       }
       this.setNumberTransform()
     },
-    arraySpanMethod ({ row, column, rowIndex, columnIndex }) {
+    arraySpanMethod({ row, column, rowIndex, columnIndex }) {
       for (let i = 0; i < 7; i++) {
         if (columnIndex === i) {
           const _row = this.spanArr[rowIndex]
@@ -629,6 +800,14 @@ export default {
           }
         }
       }
+    },
+    exportHandler(refName, tableName) {
+      if (this.loading) {
+        return
+      }
+      const table = this.$refs[refName].$el.cloneNode(true)
+      const fileName = `${tableName}-${this.currentAirport}-${this.startDate}-${this.endDate}.xlsx`
+      throttledExportToExcel(table, tableName, fileName, 2)
     }
   }
 }
@@ -645,7 +824,7 @@ export default {
       flex: 1;
     }
     .form-right {
-      flex: 0 1 490px;
+      flex: 0 1 auto;
     }
     .el-form-item {
       margin-bottom: 0px;
@@ -655,7 +834,7 @@ export default {
       optgroup,
       select,
       textarea {
-        font-family: Helvetica, "Microsoft YaHei";
+        font-family: Helvetica, 'Microsoft YaHei';
         font-size: 14px;
       }
       .el-switch__label {
@@ -761,7 +940,7 @@ export default {
       padding: 0;
       text-align: center;
       font-size: 14px;
-      font-family: Helvetica, "Microsoft YaHei";
+      font-family: Helvetica, 'Microsoft YaHei';
       letter-spacing: 0;
     }
     .cell-click {
@@ -795,7 +974,7 @@ export default {
         &.redBorder {
           position: relative;
           &::after {
-            content: "";
+            content: '';
             position: absolute;
             left: 0;
             bottom: 0;

+ 234 - 55
src/views/baggageManagement/components/transferDeparture/index.vue

@@ -8,8 +8,17 @@
 <template>
   <div class="transfer-out">
     <!--功能区-表单-->
-    <div ref="formWrap" class="terminal-form-wrap">
-      <el-form ref="form" :inline="true" :model="formData" :rules="rules" class="form">
+    <div
+      ref="formWrap"
+      class="terminal-form-wrap"
+    >
+      <el-form
+        ref="form"
+        :inline="true"
+        :model="formData"
+        :rules="rules"
+        class="form"
+      >
         <div class="form-left">
           <el-form-item prop="currentAirport">
             <!-- <el-cascader
@@ -24,15 +33,52 @@
             filterable
             @change="setCurrentAirport"
           /> -->
-            <el-select v-model="formData.currentAirport" class="input-shadow" size="small" style="width: 100px;" filterable placeholder="请选择机场" @change="airPortChange">
-              <el-option v-for="(item, index) in AirportList" :key="index" :label="item.planDepartureApt" :value="item.planDepartureApt" />
+            <el-select
+              v-model="formData.currentAirport"
+              class="input-shadow"
+              size="small"
+              style="width: 100px;"
+              filterable
+              placeholder="请选择机场"
+              @change="airPortChange"
+            >
+              <el-option
+                v-for="(item, index) in AirportList"
+                :key="index"
+                :label="item.planDepartureApt"
+                :value="item.planDepartureApt"
+              />
             </el-select>
           </el-form-item>
           <el-form-item prop="inboundCarrier">
-            <el-cascader v-model="formData.inboundCarrier" class="input-shadow" style="width: 150px" size="small" :options="carrierProps" :props="optionProps" placeholder="进港承运航司" collapse-tags clearable filterable @change="resetLoopEvent" />
+            <el-cascader
+              v-model="formData.inboundCarrier"
+              class="input-shadow"
+              style="width: 150px"
+              size="small"
+              :options="carrierProps"
+              :props="optionProps"
+              placeholder="进港承运航司"
+              collapse-tags
+              clearable
+              filterable
+              @change="resetLoopEvent"
+            />
           </el-form-item>
           <el-form-item prop="outgoingAirline">
-            <el-cascader v-model="formData.outgoingAirline" class="input-shadow" style="width: 150px" size="small" :options="carrierPropsop" :props="optionPropser" placeholder="离港承运航司" collapse-tags clearable filterable @change="resetLoopEvent" />
+            <el-cascader
+              v-model="formData.outgoingAirline"
+              class="input-shadow"
+              style="width: 150px"
+              size="small"
+              :options="carrierPropsop"
+              :props="optionPropser"
+              placeholder="离港承运航司"
+              collapse-tags
+              clearable
+              filterable
+              @change="resetLoopEvent"
+            />
           </el-form-item>
           <!-- <el-form-item prop="startDate">
             <el-date-picker
@@ -58,51 +104,156 @@
               @change="endDateChangeHandler"
             />
           </el-form-item> -->
-          <el-form-item prop="flightDate" label="航班日期">
-            <el-date-picker v-model="formData.flightDate" size="small" style="width: 300px;" type="daterange" value-format="yyyy-MM-dd" start-placeholder="开始日期" end-placeholder="结束日期" :picker-options="dateRangePickerOptions" @change="dateChangeHandler" />
+          <el-form-item
+            prop="flightDate"
+            label="航班日期"
+          >
+            <el-date-picker
+              v-model="formData.flightDate"
+              size="small"
+              style="width: 300px;"
+              type="daterange"
+              value-format="yyyy-MM-dd"
+              start-placeholder="开始日期"
+              end-placeholder="结束日期"
+              :picker-options="dateRangePickerOptions"
+              @change="dateChangeHandler"
+            />
           </el-form-item>
           <el-form-item>
             <div class="box-item">
               <p>预计中转数:</p>
-              <li v-for="(item, index) in orderNum" :key="index" :class="{ 'number-item': !isNaN(item), 'mark-item': isNaN(item) }">
+              <li
+                v-for="(item, index) in orderNum"
+                :key="index"
+                :class="{ 'number-item': !isNaN(item), 'mark-item': isNaN(item) }"
+              >
                 <span v-if="!isNaN(item)">
                   <i ref="numberItem">0123456789</i>
                 </span>
-                <span v-else class="comma">{{ item }}</span>
+                <span
+                  v-else
+                  class="comma"
+                >{{ item }}</span>
               </li>
             </div>
           </el-form-item>
         </div>
-        <div class="form-right" @keyup.enter="onSubmit(0)">
+        <div
+          class="form-right"
+          @keyup.enter="onSubmit(0)"
+        >
           <el-form-item prop="search">
-            <el-popover :value="popoverVisible" placement="bottom" trigger="manual">
+            <el-popover
+              :value="popoverVisible"
+              placement="bottom"
+              trigger="manual"
+            >
               <span>请输入航班号(示例:CA1234)或行李牌号(示例:1234567890)</span>
-              <el-input slot="reference" v-model="formData.search" class="input-shadow" style="width: 240px;" size="small" placeholder="请输入内容" prefix-icon="el-icon-search" clearable @focus="popoverVisible = true" @blur="popoverVisible = false" />
+              <el-input
+                slot="reference"
+                v-model="formData.search"
+                class="input-shadow"
+                style="width: 240px;"
+                size="small"
+                placeholder="请输入内容"
+                prefix-icon="el-icon-search"
+                clearable
+                @focus="popoverVisible = true"
+                @blur="popoverVisible = false"
+              />
             </el-popover>
           </el-form-item>
           <el-form-item>
-            <el-button class="btn-shadow" size="mini" type="primary" @click="onSubmit(0)">搜索</el-button>
+            <el-button
+              class="btn-shadow"
+              size="mini"
+              type="primary"
+              @click="onSubmit(0)"
+            >搜索</el-button>
           </el-form-item>
           <el-form-item v-is="['td_showTransit']">
-            <el-button class="btn-shadow" size="mini" type="primary" @click="changeView">切换视角</el-button>
+            <el-button
+              class="btn-shadow"
+              size="mini"
+              type="primary"
+              @click="changeView"
+            >切换视角</el-button>
           </el-form-item>
           <el-form-item v-is="['td_timeIcon']">
             <TimeZoneSelector />
           </el-form-item>
           <el-form-item v-is="['td_columnSettings']">
-            <img class="btn-img btn-shadow" src="../../../../assets/baggage/ic_setting.png" @click="show">
+            <img
+              class="btn-img btn-shadow"
+              src="../../../../assets/baggage/ic_setting.png"
+              title="列设置"
+              @click="show"
+            >
+          </el-form-item>
+          <el-form-item v-is="['dm_dt_columnSettings']">
+            <img
+              class="btn-img btn-shadow"
+              src="../../../../assets/baggage/ic_export.png"
+              title="导出"
+              @click="exportHandler('table', '航站中转进港列表')"
+            >
           </el-form-item>
         </div>
       </el-form>
     </div>
     <!--表格-->
-    <div v-loading="loading" class="terminal-table" element-loading-text="拼命加载中" element-loading-spinner="el-icon-loading" element-loading-background="rgba(0, 0, 0, 0.8)">
-      <el-table ref="table" class="table" :data="dealedTableData" :height="computedTableHeight" show-summary :summary-method="summaryMethod" :span-method="arraySpanMethod" :header-cell-class-name="headerCellClass" :row-class-name="tableRowClassName" :cell-class-name="cellClass" border stripe fit @cell-click="cellClickHandler">
-        <el-table-column v-for="col in tableColsCopy" :key="col.prop" :prop="col.prop" :label="col.label" :width="col.width" :fixed="col.fixed">
-          <el-table-column v-for="childCol in col.children" :key="childCol.prop" :prop="childCol.prop" :label="childCol.label" :width="childCol.width" :formatter="tableFormat">
+    <div
+      v-loading="loading"
+      class="terminal-table"
+      element-loading-text="拼命加载中"
+      element-loading-spinner="el-icon-loading"
+      element-loading-background="rgba(0, 0, 0, 0.8)"
+    >
+      <el-table
+        ref="table"
+        class="table"
+        :data="dealedTableData"
+        :height="computedTableHeight"
+        show-summary
+        :summary-method="summaryMethod"
+        :span-method="arraySpanMethod"
+        :header-cell-class-name="headerCellClass"
+        :row-class-name="tableRowClassName"
+        :cell-class-name="cellClass"
+        border
+        stripe
+        fit
+        @cell-click="cellClickHandler"
+      >
+        <el-table-column
+          v-for="col in tableColsCopy"
+          :key="col.prop"
+          :prop="col.prop"
+          :label="col.label"
+          :width="col.width"
+          :fixed="col.fixed"
+        >
+          <el-table-column
+            v-for="childCol in col.children"
+            :key="childCol.prop"
+            :prop="childCol.prop"
+            :label="childCol.label"
+            :width="childCol.width"
+            :formatter="tableFormat"
+          >
             <template #header>
-              <el-tooltip :content="childCol.desc || childCol.label" placement="top">
-                <TableHeaderCell :label="childCol.label" :filter-options="tableDataFilters[childCol.prop]" :filter-values.sync="filterValues[childCol.prop]" :sortable="childCol.sortable" :sort-rule.sync="tableDataSortRules[childCol.prop]" />
+              <el-tooltip
+                :content="childCol.desc || childCol.label"
+                placement="top"
+              >
+                <TableHeaderCell
+                  :label="childCol.label"
+                  :filter-options="tableDataFilters[childCol.prop]"
+                  :filter-values.sync="filterValues[childCol.prop]"
+                  :sortable="childCol.sortable"
+                  :sort-rule.sync="tableDataSortRules[childCol.prop]"
+                />
               </el-tooltip>
             </template>
           </el-table-column>
@@ -110,18 +261,38 @@
       </el-table>
     </div>
     <!--列设置-->
-    <Dialog :flag="dialogFlag" class="dialog-check-cols">
+    <Dialog
+      :flag="dialogFlag"
+      class="dialog-check-cols"
+    >
       <div class="col-dialog">
         <div class="title">列设置</div>
         <div class="content">
-          <el-tree :data="tableCols" :class="colsCheckClass" show-checkbox node-key="index" :default-expand-all="true" :props="{
+          <el-tree
+            :data="tableCols"
+            :class="colsCheckClass"
+            show-checkbox
+            node-key="index"
+            :default-expand-all="true"
+            :props="{
               label: 'label',
               children: 'children',
-            }" :default-checked-keys="checkedKeysTemp" @check="handleCheck" />
+            }"
+            :default-checked-keys="checkedKeysTemp"
+            @check="handleCheck"
+          />
         </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>
+          <el-button
+            size="medium"
+            class="r24"
+            type="primary"
+            @click="onCheck"
+          >确定</el-button>
+          <el-button
+            size="medium"
+            @click="hide"
+          >取消</el-button>
         </div>
       </div>
     </Dialog>
@@ -137,13 +308,13 @@ import tableColsMixin from '../../mixins/tableCols'
 import timeZoneMixin from '../../mixins/timeZone'
 import { getQuery } from '@/api/flight'
 import TableHeaderCell from '@/components/TableHeaderCell'
-import { setTableFilters } from '@/utils/table'
+import { setTableFilters, throttledExportToExcel } from '@/utils/table'
 
 export default {
   name: 'DepartureTerminalView',
   components: { Dialog, TimeZoneSelector, TableHeaderCell },
   mixins: [terminalMixin, formMixin, tableColsMixin, timeZoneMixin],
-  data () {
+  data() {
     return {
       optionProps: {
         value: 'inAicompanyCode2',
@@ -318,14 +489,14 @@ export default {
     }
   },
   computed: {
-    singleDay () {
+    singleDay() {
       return this.startDate === this.endDate
     }
   },
-  created () {
+  created() {
     // this.getAirPortData()
   },
-  mounted () {
+  mounted() {
     this.$refs['form'].validateField('flightDate')
     this.getAirPortData()
     this.table = this.$refs.table.bodyWrapper
@@ -334,7 +505,7 @@ export default {
       that.scrollTop = this.table.scrollTop
     })
   },
-  activated () {
+  activated() {
     this.table.scrollTop = this.scrollTop
     this.getTableData()
     const that = this
@@ -354,20 +525,20 @@ export default {
     //   this.formData.flightDate[1] = endDate
     // }
   },
-  deactivated () {
+  deactivated() {
     if (this.loopEvent) {
       clearInterval(this.loopEvent)
       this.loopEvent = null
     }
   },
-  beforeDestroy () {
+  beforeDestroy() {
     if (this.loopEvent) {
       clearInterval(this.loopEvent)
       this.loopEvent = null
     }
   },
   methods: {
-    resetLoopEvent () {
+    resetLoopEvent() {
       this.loading = true
       this.hasSetTableScroll = false
       if (this.loopEvent) {
@@ -379,7 +550,7 @@ export default {
         that.getTableData()
       }, 3000)
     },
-    headerCellClass ({ row, column }) {
+    headerCellClass({ row, column }) {
       const classes = []
       const rule = this.tableDataSortRules[column.property]
       if (rule) {
@@ -387,7 +558,7 @@ export default {
       }
       return classes.join(' ')
     },
-    tableRowClassName ({ row, rowIndex }) {
+    tableRowClassName({ row, rowIndex }) {
       const classes = []
       if (row.hasTakeOff) {
         classes.push('bgl-hui')
@@ -397,7 +568,7 @@ export default {
       }
       return classes.join(' ')
     },
-    changeView () {
+    changeView() {
       // const query = {
       //   ...this.formData,
       //   startDate: this.startDate,
@@ -410,18 +581,18 @@ export default {
       // })
       this.$router.push('/transfer/arrival')
     },
-    airPortChange () {
+    airPortChange() {
       this.getAviationData()
       this.upAviationData()
       this.resetLoopEvent()
     },
-    dateChangeHandler () {
+    dateChangeHandler() {
       this.getAviationData()
       this.upAviationData()
       this.resetLoopEvent()
     },
     // 选择机场
-    async getAirPortData () {
+    async getAirPortData() {
       try {
         const res = await getQuery({
           id: DATACONTENT_ID.departureAirLtId,
@@ -441,7 +612,7 @@ export default {
       }
     },
     // 选择航司
-    async getAviationData () {
+    async getAviationData() {
       try {
         const res = await getQuery({
           id: DATACONTENT_ID.departureAviJoinLtId,
@@ -457,7 +628,7 @@ export default {
       }
     },
     // 选择航司
-    async upAviationData () {
+    async upAviationData() {
       try {
         const res = await getQuery({
           id: DATACONTENT_ID.departureAviLeaveLtId,
@@ -483,7 +654,7 @@ export default {
     //   this.flightAttrQuery(params)
     // },
     // 获取表格数据
-    async getTableData () {
+    async getTableData() {
       if (!this.formData.currentAirport || !this.startDate || !this.endDate) {
         return
       }
@@ -524,7 +695,7 @@ export default {
         console.log('出错了', error.message || error)
       }
     },
-    initTableData (tableData) {
+    initTableData(tableData) {
       this.leaveCount = 0
       this.baggageCount = 0
       tableData.forEach(item => {
@@ -540,7 +711,7 @@ export default {
         this.setTableScroll()
       })
     },
-    hasTakeOff (flight) {
+    hasTakeOff(flight) {
       if (flight.actualDepartureTime) {
         const now = new Date()
         const actualDepartureTime = new Date(flight.actualDepartureTime.replace('T', ' '))
@@ -550,7 +721,7 @@ export default {
       }
       return flight['hasTakeOff']
     },
-    setTableScroll () {
+    setTableScroll() {
       if (!this.singleDay || this.hasSetTableScroll || this.leaveCount === 0) {
         return
       }
@@ -570,7 +741,7 @@ export default {
       }, 0)
       this.hasSetTableScroll = true
     },
-    setNumberTransform () {
+    setNumberTransform() {
       const numberItems = this.$refs.numberItem // 拿到数字的ref,计算元素数量
       const numberArr = this.orderNum.filter(item => !isNaN(item))
       // 结合CSS 对数字字符进行滚动,显示订单数量
@@ -580,7 +751,7 @@ export default {
       }
     },
 
-    toOrderNum (num) {
+    toOrderNum(num) {
       num = num.toString()
       if (num.length < 6) {
         num = '0' + num // 如未满八位数,添加"0"补位
@@ -593,7 +764,7 @@ export default {
       }
       this.setNumberTransform()
     },
-    arraySpanMethod ({ row, column, rowIndex, columnIndex }) {
+    arraySpanMethod({ row, column, rowIndex, columnIndex }) {
       for (let i = 0; i < 7; i++) {
         if (columnIndex === i) {
           const _row = this.spanArr[rowIndex]
@@ -604,6 +775,14 @@ export default {
           }
         }
       }
+    },
+    exportHandler(refName, tableName) {
+      if (this.loading) {
+        return
+      }
+      const table = this.$refs[refName].$el.cloneNode(true)
+      const fileName = `${tableName}-${this.currentAirport}-${this.startDate}-${this.endDate}.xlsx`
+      throttledExportToExcel(table, tableName, fileName, 2)
     }
   }
 }
@@ -620,7 +799,7 @@ export default {
       flex: 1;
     }
     .form-right {
-      flex: 0 1 490px;
+      flex: 0 1 auto;
     }
     .el-form-item {
       margin-bottom: 0px;
@@ -630,7 +809,7 @@ export default {
       optgroup,
       select,
       textarea {
-        font-family: Helvetica, "Microsoft YaHei";
+        font-family: Helvetica, 'Microsoft YaHei';
         font-size: 14px;
       }
       .el-switch__label {
@@ -736,7 +915,7 @@ export default {
       padding: 0;
       text-align: center;
       font-size: 14px;
-      font-family: Helvetica, "Microsoft YaHei";
+      font-family: Helvetica, 'Microsoft YaHei';
       letter-spacing: 0;
     }
     .cell-click {
@@ -770,7 +949,7 @@ export default {
         &.redBorder {
           position: relative;
           &::after {
-            content: "";
+            content: '';
             position: absolute;
             left: 0;
             bottom: 0;

+ 16 - 3
src/views/statisticsCharts/components/commonStatisticsCharts.vue

@@ -7,6 +7,7 @@
       <StatisticsHeader
         :title="`${chartsTitle}量统计`"
         @getFormData="getFormData"
+        @export="exportHandler"
       />
     </div>
     <div class="statstics-content">
@@ -42,6 +43,7 @@ export default {
       myChart: null,
       debounceTime: 300,
       chartHeight: '70vh',
+      hasChartData: false,
       options: {
         backgroundColor: '#fff',
         tooltip: {
@@ -204,6 +206,7 @@ export default {
     options: {
       handler(obj) {
         this.myChart.setOption(obj)
+        this.resizeHandler()
       },
       deep: true
     },
@@ -303,8 +306,7 @@ export default {
             if (i > 0) {
               if (listValues[i - 1][this.querySettings.seriesKey] > 0) {
                 yAxisData.push(
-                  (listValues[i][this.querySettings.seriesKey] -
-                    listValues[i - 1][this.querySettings.seriesKey]) /
+                  (listValues[i][this.querySettings.seriesKey] - listValues[i - 1][this.querySettings.seriesKey]) /
                     listValues[i - 1][this.querySettings.seriesKey]
                 )
               } else {
@@ -320,7 +322,7 @@ export default {
           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.resizeHandler()
+          this.hasChartData = true
         } else {
           this.$message.error(message)
         }
@@ -342,6 +344,17 @@ export default {
       if (this.myChart) {
         this.myChart.resize()
       }
+    },
+    exportHandler() {
+      if (!this.hasChartData) {
+        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()
     }
   }
 }

+ 1 - 1
src/views/statisticsCharts/components/statisticsHeader.vue

@@ -306,7 +306,7 @@ export default {
     },
     exportClickHandler() {
       this.$emit('export')
-      this.$message.info('开发中')
+      // this.$message.info('开发中')
     },
     setInOrOutOptions(range) {
       const theInOrOutItem = this.formItems.find(item => item.prop === 'inOrOut')

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

@@ -9,6 +9,7 @@
         :items="formItems"
         :data="formData"
         @getFormData="getFormData"
+        @export="exportHandler"
       />
     </div>
     <div class="statstics-content">
@@ -117,6 +118,7 @@ export default {
       myChart: null,
       debounceTime: 300,
       chartHeight: '70vh',
+      hasChartData: false,
       options: {
         // legend: {
         //   top: 32,
@@ -444,6 +446,7 @@ export default {
           //   ratio: (datas[index] / max).toFixed(2) * 100 + '%'
           // }))
           // .filter(element => !element.label.includes('总'))
+          this.hasChartData = true
         } else {
           this.$message.error(res.message)
         }
@@ -465,6 +468,17 @@ export default {
       if (this.myChart) {
         this.myChart.resize()
       }
+    },
+    exportHandler() {
+      if (!this.hasChartData) {
+        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', '扫描节点与位置分析统计.png')
+      $a.click()
     }
   }
 }