|
@@ -0,0 +1,564 @@
|
|
|
+<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"
|
|
|
+ value-format="yyyy-MM-dd"
|
|
|
+ range-separator="至"
|
|
|
+ start-placeholder="开始日期"
|
|
|
+ end-placeholder="结束日期"
|
|
|
+ />
|
|
|
+ </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'
|
|
|
+export default {
|
|
|
+ name: 'StatisticsHeader',
|
|
|
+ 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: '',
|
|
|
+ interval: '',
|
|
|
+ airline: [],
|
|
|
+ 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 = {
|
|
|
+ 航线: 'airline',
|
|
|
+ 基地分公司: '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: 'interval',
|
|
|
+ inputType: 'select',
|
|
|
+ placeholder: '时间维度',
|
|
|
+ requiredWarning: '请先选择统计时间维度',
|
|
|
+ // clearable: true,
|
|
|
+ options: [
|
|
|
+ {
|
|
|
+ value: '日',
|
|
|
+ label: '按日统计'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ value: '月',
|
|
|
+ label: '按月统计'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ value: '季',
|
|
|
+ label: '按季统计'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ value: '年',
|
|
|
+ label: '按年统计'
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ prop: 'dateTime',
|
|
|
+ inputType: 'datePicker',
|
|
|
+ // clearable: true,
|
|
|
+ width: '240px',
|
|
|
+ requiredWarning: '请先选择统计时间范围'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ prop: 'airline',
|
|
|
+ inputType: 'select',
|
|
|
+ placeholder: '航线',
|
|
|
+ width: '180px',
|
|
|
+ filterable: true,
|
|
|
+ clearable: true,
|
|
|
+ multiple: true,
|
|
|
+ disabled: true,
|
|
|
+ queryId: SERVICE_ID.airlineOptions,
|
|
|
+ setKey: 'a2',
|
|
|
+ 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.AirportId,
|
|
|
+ setKey: 'a2',
|
|
|
+ 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])
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ 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.queryId, item.setKey, item.prop)
|
|
|
+ }
|
|
|
+ if (savedFormData?.[item.prop]) {
|
|
|
+ this.formData[item.prop] = savedFormData[item.prop]
|
|
|
+ } else if (item.defaultOption) {
|
|
|
+ this.formData[item.prop] = item.defaultOption
|
|
|
+ }
|
|
|
+ })
|
|
|
+ this.$emit('update:data', this.formData)
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ getData() {
|
|
|
+ try {
|
|
|
+ this.formItems.forEach(item => {
|
|
|
+ if (item.requiredWarning && (!this.formData[item.prop] || this.formData[item.prop].length === 0)) {
|
|
|
+ throw new Error(item.requiredWarning)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ } catch (error) {
|
|
|
+ this.$message.warning(error.message)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if (this.formData.range === '航线' && !this.formData.airline) {
|
|
|
+ this.$message.warning('请先选择航线')
|
|
|
+ return
|
|
|
+ } else if (this.formData.range === '航站' && !this.formData.airport) {
|
|
|
+ this.$message.warning('请先选择航站')
|
|
|
+ return
|
|
|
+ } else if (this.formData.range === '基地分公司' && !this.formData.area) {
|
|
|
+ this.$message.warning('请先选择基地分公司')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ this.$emit('getFormData', this.formData)
|
|
|
+ this.$store.dispatch('savedSettings/saveFormData', {
|
|
|
+ formData: this.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(queryId, setKey, prop) {
|
|
|
+ try {
|
|
|
+ const { code, returnData, message } = await TempQuery({
|
|
|
+ serviceId: queryId,
|
|
|
+ dataContent: []
|
|
|
+ })
|
|
|
+ if (Number(code) === 0) {
|
|
|
+ const arr = returnData.map(element => ({
|
|
|
+ label: element[setKey],
|
|
|
+ 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--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>
|