<template>
  <!-- 模型构建 -->
    <el-dialog class="model-build" :title="title" width="560px" :visible="isShow" v-if="isShow" :close-on-press-escape="false" :close-on-click-modal="false" :append-to-body="true" @close="isShow && closeModal(false)">
      <div>
        <p class="habird-tips ksd-mb-16" v-if="isHybridModel">{{$t('habirdModelBuildTips')}}</p>
        <el-alert
          :title="$t('secondStoragePartitionTips')"
          type="error"
          :closable="false"
          class="ksd-mb-10"
          v-if="secondStoragePartitionTips"
          show-icon>
        </el-alert>
        <el-alert
          :title="$t('changeBuildTypeTips')"
          type="warning"
          :closable="false"
          class="ksd-mb-10"
          v-if="isShowWarning"
          show-icon>
        </el-alert>
        <div class="ksd-title-label-small ksd-mb-10">{{$t('chooseBuildType')}}</div>
        <el-select v-model="buildType" class="ksd-mb-5" @change="handChangeBuildType" v-if="buildOrComplete == 'build'" :disabled="!datasourceActions.includes('changeBuildType')">
          <el-option :label="$t('incremental')" value="incremental"></el-option>
          <el-option :label="$t('fullLoad')" v-if="!isStreamModel" value="fullLoad"></el-option>
        </el-select>
      </div>
      <div class="tips">{{buildTips}}</div>
      <div v-if="buildType === 'fullLoad'">
        <el-alert
          class="ksd-pt-0 ksd-mt-15"
          :title="$t('segmentTips')"
          type="warning"
          :show-background="false"
          :closable="false"
          show-icon>
        </el-alert>
        <span v-if="isHaveSegment">{{fullLoadBuildTips}}</span>
        <span v-else>{{$t('willAddSegmentTips')}}</span>
      </div>
      <div v-if="buildType === 'incremental' && buildOrComplete === 'build'">
        <el-form class="ksd-mb-20 ksd-mt-15" v-if="isExpand" :model="partitionMeta" ref="partitionForm" :rules="partitionRules"  label-width="85px" label-position="top">
          <el-form-item  :label="$t('partitionDateColumn')" class="clearfix">
            <el-row :gutter="5">
              <el-col :span="12">
                <el-tooltip effect="dark" :content="$t('disableChangePartitionTips')" :disabled="!isNotBatchModel" placement="bottom">
                  <el-select :disabled="isLoadingNewRange || !datasourceActions.includes('changePartition') || isNotBatchModel" v-model="partitionMeta.table" @change="partitionTableChange" :placeholder="$t('kylinLang.common.pleaseSelectOrSearch')" style="width:100%">
                    <el-option :label="t.alias" :value="t.alias" v-for="t in partitionTables" :key="t.alias">{{t.alias}}</el-option>
                  </el-select>
                </el-tooltip>
              </el-col>
              <el-col :span="12" v-if="partitionMeta.table">
                <el-form-item prop="column">
                  <el-tooltip effect="dark" :content="$t('disableChangePartitionTips')" :disabled="!isNotBatchModel" placement="bottom">
                    <el-select :disabled="isLoadingNewRange || !datasourceActions.includes('changePartition')||isNotBatchModel"
                    @change="partitionColumnChange" v-model="partitionMeta.column" :placeholder="$t('kylinLang.common.pleaseSelectOrSearch')" filterable style="width:100%">
                    <i slot="prefix" class="el-input__icon el-ksd-icon-search_22" v-if="!partitionMeta.column.length"></i>
                      <el-option :label="t.name" :value="t.name" v-for="t in columns" :key="t.name">
                        <el-tooltip :content="t.name" effect="dark" placement="top" :disabled="showToolTip(t.name)"><span style="float: left">{{ t.name | omit(15, '...') }}</span></el-tooltip>
                        <span class="ky-option-sub-info">{{ t.datatype.toLocaleLowerCase() }}</span>
                      </el-option>
                    </el-select>
                  </el-tooltip>
                </el-form-item>
              </el-col>
            </el-row>
          </el-form-item>
          <el-form-item  :label="$t('dateFormat')" :class="{'is-error': errorFormat}" v-if="partitionMeta.table">
            <el-row :gutter="5">
              <el-col :span="partitionMeta.column&&$store.state.project.projectPushdownConfig&&!isNotBatchModel ? 22 : 24">
                <el-tooltip effect="dark" :content="$t('disableChangePartitionTips')" :disabled="!isNotBatchModel" placement="bottom">
                  <el-select
                    :disabled="isLoadingNewRange || isLoadingFormat || !datasourceActions.includes('changePartition') || isNotBatchModel"
                    style="width:100%"
                    @change="val => partitionColumnFormatChange(val)"
                    v-model="partitionMeta.format"
                    filterable
                    allow-create
                    default-first-option
                    :placeholder="$t('pleaseInputColumn')">
                    <el-option-group>
                      <el-option v-if="dateFormatsOptions.map(it => it.value).indexOf(prevPartitionMeta.format) === -1 && prevPartitionMeta.format" :label="prevPartitionMeta.format" :value="prevPartitionMeta.format"></el-option>
                      <el-option :label="f.label" :value="f.value" v-for="f in dateFormatsOptions" :key="f.label"></el-option>
                    </el-option-group>
                  </el-select>
                </el-tooltip>
              </el-col>
              <el-col :span="2" v-if="partitionMeta.column&&$store.state.project.projectPushdownConfig&&!isNotBatchModel">
                <el-tooltip effect="dark" :content="$t('detectFormat')" placement="top">
                  <div style="display: inline-block;">
                    <el-button
                      size="medium"
                      class="auto-detect-btn"
                      :loading="isLoadingFormat"
                      :disabled="isLoadingNewRange || !datasourceActions.includes('changePartition')"
                      icon="el-ksd-icon-data_range_search_old"
                      @click="handleLoadFormat">
                    </el-button>
                  </div>
                </el-tooltip>
              </el-col>
            </el-row>
            <div class="error-format" v-if="errorFormat">{{errorFormat}}</div>
            <div class="pre-format" v-if="formatedDate">{{$t('previewFormat')}}{{formatedDate}}</div>
            <div class="format">{{$t('formatRule')}}
              <span v-if="isExpandFormatRule" @click="isExpandFormatRule = false">{{$t('viewDetail')}}<i class="el-icon-ksd-more_01-copy arrow"></i></span>
              <span v-else @click="isExpandFormatRule = true">{{$t('viewDetail')}}<i class="el-icon-ksd-more_02 arrow"></i></span>
            </div>
            <div class="detail-content" v-if="isExpandFormatRule">
              <p><span class="ksd-mr-2">1. </span><span>{{$t('rule1')}}</span></p>
              <p><span class="ksd-mr-2">2. </span><span>{{$t('rule2')}}</span></p>
              <p><span class="ksd-mr-2">3. </span><span>{{$t('rule3')}}</span></p>
            </div>
            <span style="position:absolute;width:1px; height:0" v-if="partitionMeta.format"></span>
          </el-form-item>
          <el-form-item v-if="((!modelDesc.multi_partition_desc && $store.state.project.multi_partition_enabled) || modelDesc.multi_partition_desc) && partitionMeta.table && !isNotBatchModel">
            <span slot="label">
              <span>{{$t('multilevelPartition')}}</span>
              <el-tooltip effect="dark" :content="$t('multilevelPartitionDesc')" placement="right">
                <i class="el-icon-ksd-what"></i>
              </el-tooltip>
            </span>
            <el-row>
              <el-col :span="11">
              <el-select
                :disabled="isLoadingNewRange || !datasourceActions.includes('changePartition')"
                v-model="partitionMeta.multiPartition"
                :placeholder="$t('kylinLang.common.pleaseSelectOrSearch')"
                filterable
                class="partition-multi-partition"
                popper-class="js_multi-partition"
                style="width:100%"
                @change="changePartitionSetting"
              >
                  <i slot="prefix" class="el-input__icon el-ksd-icon-search_22" v-if="!partitionMeta.multiPartition.length"></i>
                  <el-option :label="$t('noPartition')" value=""></el-option>
                  <el-option :label="t.name" :value="t.name" v-for="t in subPartitionColumnsOptions" :key="t.name">
                    <el-tooltip :content="t.name" effect="dark" placement="top" :disabled="showToolTip(t.name)"><span style="float: left">{{ t.name | omit(15, '...') }}</span></el-tooltip>
                    <span class="ky-option-sub-info">{{ t.datatype.toLocaleLowerCase() }}</span>
                  </el-option>
                </el-select>
              </el-col>
            </el-row>
          </el-form-item>
        </el-form>
        <div v-if="partitionMeta.table && partitionMeta.column && partitionMeta.format">
          <div class="divide-block">
            <span v-if="isExpand" @click="toggleShowPartition">{{$t('showLess')}}</span>
            <span v-else @click="toggleShowPartition">{{$t('showMore')}}</span>
            <div class="divide-line"></div>
          </div>
          <div class="ksd-title-label-small ksd-mb-10">{{$t('addRangeTitle')}}</div>
          <el-form :model="modelBuildMeta" ref="buildForm" :rules="rules" label-position="top">
            <el-form-item :class="{'is-error': isShowErrorSegments}" :rule="modelBuildMeta.isLoadExisted ? [] : [{required: true, trigger: 'blur', message: this.$t('dataRangeValValid')}]">
              <p class="ksd-pt-0 ksd-fs-12 segment-tips"><i class="el-icon-ksd-alert ksd-mr-5 alert-icon"></i>{{$t('segmentTips')}}</p>
              <div class="ky-no-br-space" style="height:32px;">
                <el-date-picker
                  type="datetime"
                  style="width: 44%;"
                  :class="['ksd-mr-5', {'is-error': dateErrorMsg}]"
                  :key="`prevPicker_${new Date(modelBuildMeta.dataRangeVal[0]).getTime()}`"
                  ref="prevPicker"
                  v-model="modelBuildMeta.dataRangeVal[0]"
                  :disabled="modelBuildMeta.isLoadExisted || isLoadingNewRange"
                  @change="(v) => handleChangeDateTime(v, 'start')"
                  value-format="timestamp"
                  :is-auto-complete="true"
                  :format="partitionFormat"
                >
                </el-date-picker>
                <el-date-picker
                  type="datetime"
                  style="width: 44%;"
                  ref="nextPicker"
                  :class="{'is-error': dateErrorMsg}"
                  :key="`prevPicker_${new Date(modelBuildMeta.dataRangeVal[1]).getTime()}`"
                  v-model="modelBuildMeta.dataRangeVal[1]"
                  :disabled="modelBuildMeta.isLoadExisted || isLoadingNewRange"
                  value-format="timestamp"
                  @change="(v) => handleChangeDateTime(v, 'end')"
                  :is-auto-complete="true"
                  :format="partitionFormat"
                >
                </el-date-picker>
                <common-tip :content="noPartition ? $t('partitionFirst'):$t('detectAvailableRange')" placement="top">
                  <el-button
                    size="medium"
                    class="auto-detect-btn ksd-ml-10"
                    v-if="$store.state.project.projectPushdownConfig&&!isStreamModel"
                    :disabled="modelBuildMeta.isLoadExisted || noPartition"
                    :loading="isLoadingNewRange"
                    icon="el-ksd-icon-data_range_search_old"
                    @click="handleLoadNewestRange">
                  </el-button>
                </common-tip>
                <span style="position:absolute;width:1px; height:0" @click="handleLoadNewestRange"></span>
                <span style="position:absolute;width:1px; height:0" v-if="modelBuildMeta.dataRangeVal[0] && modelBuildMeta.dataRangeVal[1]"></span>
              </div>
              <p v-if="dateErrorMsg" class="error-date-range error-msg">{{dateErrorMsg}}</p>
              <div class="timestamp-format-tips" v-if="partitionMeta.format.indexOf('TIMESTAMP') !== -1 && (modelBuildMeta.dataRangeVal[0] || modelBuildMeta.dataRangeVal[1])">
                <span>{{partitionMeta.format}}: </span>
                <span v-if="modelBuildMeta.dataRangeVal[0]">{{partitionMeta.format === 'TIMESTAMP MILLISECOND' ? new Date(modelBuildMeta.dataRangeVal[0]).getTime() : Math.round(new Date(modelBuildMeta.dataRangeVal[0]).getTime() / 1000)}}</span> - 
                <span v-if="modelBuildMeta.dataRangeVal[1]">{{partitionMeta.format === 'TIMESTAMP MILLISECOND' ? new Date(modelBuildMeta.dataRangeVal[1]).getTime() : Math.round(new Date(modelBuildMeta.dataRangeVal[1]).getTime() / 1000)}}</span>
              </div>
            </el-form-item>
          </el-form>
          <el-alert
            v-show="!isShowRangeDateError && modelBuildMeta.dataRangeVal[1]"
            class="date-range-alert"
            :title="$t('segmentDateRangeTips')"
            type="warning"
            :closable="false"
          ></el-alert>
          <div class="error-msg" v-if="isShowRangeDateError">{{loadRangeDateError}}</div>
          <div v-if="isShowErrorSegments" class="error_segments">
            <el-alert type="error" :show-background="false" :closable="false" show-icon>
              <span class="overlaps-tips">{{$t('overlapsTips')}}</span>
              <a href="javascript:;" @click="toggleDetail">{{$t('kylinLang.common.seeDetail')}}
                <i class="el-icon-arrow-down" v-show="!showDetail"></i>
                <i class="el-icon-arrow-up" v-show="showDetail"></i>
              </a>
            </el-alert>
            <table class="ksd-table small-size" v-if="showDetail">
              <tr class="ksd-tr" v-for="(s, index) in errorSegments" :key="index">
                <td>{{s.start | toServerGMTDate}}</td>
                <td>{{s.end | toServerGMTDate}}</td>
              </tr>
            </table>
          </div>
          <div v-if="displaySubPartition">
            <div class="ksd-title-label-small ksd-mt-15">{{$t('multiPartitionValue')}}</div>
            <p class="sub-partition-alert"><i class="icon el-icon-ksd-alert ksd-mr-5"></i>{{$t('subPartitionAlert')}}</p>
            <arealabel
              ref="selectSubPartition"
              :class="['select-sub-partition', {'error-border': duplicateValueError}, 'ksd-mt-5']"
              :duplicateremove="false"
              splitChar=","
              :selectedlabels="selectMultiPartitionValues"
              :isNeedNotUpperCase="true"
              :allowcreate="true"
              :isSignSameValue="true"
              :remoteSearch="true"
              :labels="subPartitionOptions"
              :placeholder="$t('multiPartitionPlaceholder')"
              :remote-method="filterPartitions"
              :datamap="{label: 'label', value: 'value'}"
              :selectGroupOne="subPartitionGroupOne"
              @duplicateTags="checkDuplicateValue"
              @refreshData="refreshPartitionValues"
              @removeTag="removeSelectedMultiPartition">
            </arealabel>
            <p class="duplicate-tips" v-if="duplicateValueError"><span class="error-msg">{{$t('duplicatePartitionValueTip')}}</span><span class="clear-value-btn" @click="removeDuplicateValue"><i class="el-icon-ksd-clear ksd-mr-5"></i>{{$t('removeDuplicateValue')}}</span></p>
          </div>
        </div>
      </div>
      <div slot="footer" class="dialog-footer ky-no-br-space">
        <!-- <div class="ksd-fleft" v-if="$store.state.project.multi_partition_enabled&&modelDesc.multi_partition_desc&&modelDesc.multi_partition_desc.columns.length">
          <el-checkbox v-model="isMultipleBuild">
            <span>{{$t('multipleBuild')}}</span>
            <common-tip placement="top" :content="$t('multipleBuildTip')">
              <span class='el-icon-ksd-what'></span>
            </common-tip>
          </el-checkbox>
        </div> -->
        <el-button @click="closeModal(false)" size="medium">{{$t('kylinLang.common.cancel')}}</el-button>
        <template v-if="isAddSegment">
          <el-button type="primary" :loading="btnLoading&&!isBuildLoading&&!isWillAddIndex" @click="setbuildModel(false, 'onlySave')" :disabled="incrementalDisabled || disableFullLoad || btnLoading&&(isBuildLoading || isWillAddIndex)" size="medium">{{$t('kylinLang.common.save')}}</el-button>
          <el-button type="primary" :loading="btnLoading&&isBuildLoading&&!isWillAddIndex" v-if="modelDesc.total_indexes && !multiPartitionEnabled" @click="setbuildModel(true)" :disabled="incrementalDisabled || disableFullLoad || btnLoading&&!isBuildLoading" size="medium">{{$t('saveAndBuild')}}</el-button>
          <el-button type="primary" :loading="btnLoading&&!isBuildLoading&&isWillAddIndex" v-else-if="!multiPartitionEnabled" @click="saveAndAddIndex" :disabled="incrementalDisabled || disableFullLoad || btnLoading&&!isWillAddIndex" size="medium">{{$t('saveAndAddIndex')}}</el-button>
        </template>
        <template v-else>
          <el-button type="primary" :loading="btnLoading" @click="setbuildModel(true)" :disabled="incrementalDisabled || disableFullLoad || duplicateValueError" size="medium">{{$t(buildType)}}</el-button>
        </template>
      </div>
    </el-dialog>
</template>
<script>
  import Vue from 'vue'
  import { Component, Watch } from 'vue-property-decorator'
  import { mapState, mapMutations, mapActions, mapGetters } from 'vuex'
  import vuex from 'store'
  import { handleError, transToUTCMs, getGmtDateFromUtcLike, kylinMessage } from 'util/business'
  import { handleSuccessAsync, transToServerGmtTime, isDatePartitionType, isStreamingPartitionType, isSubPartitionType, kylinConfirm, split_array } from 'util/index'
  import locales from './locales'
  import store, { types } from './store'
  import NModel from '../../ModelEdit/model.js'
  import { BuildIndexStatus } from 'config/model'
  import { dateFormats, timestampFormats, dateTimestampFormats } from 'config'
  import arealabel from '../../../../common/area_label.vue'
  import moment from 'moment'

  vuex.registerModule(['modals', 'ModelBuildModal'], store)

  @Component({
    components: {
      arealabel
    },
    computed: {
      ...mapGetters([
        'currentSelectedProject',
        'datasourceActions'
      ]),
      ...mapState('ModelBuildModal', {
        isShow: state => state.isShow,
        title: state => state.title,
        source: state => state.source,
        type: state => state.type,
        isAddSegment: state => state.isAddSegment,
        buildOrComp: state => state.buildOrComp,
        isHaveSegment: state => state.isHaveSegment,
        disableFullLoad: state => state.disableFullLoad,
        modelDesc: state => state.form.modelDesc,
        modelInstance: state => state.form.modelInstance || state.form.modelDesc && new NModel(state.form.modelDesc) || null,
        callback: state => state.callback
      }),
      ...mapState({
        multiPartitionEnabled: state => state.project.multi_partition_enabled
      })
    },
    methods: {
      ...mapActions({
        buildModel: 'MODEL_BUILD',
        checkDataRange: 'CHECK_DATA_RANGE',
        buildFullLoadModel: 'MODEL_FULLLOAD_BUILD',
        buildIndex: 'BUILD_INDEX',
        fetchNewestModelRange: 'GET_MODEL_NEWEST_RANGE',
        fetchPartitionFormat: 'FETCH_PARTITION_FORMAT',
        updataModel: 'UPDATE_MODEL',
        autoFixSegmentHoles: 'AUTO_FIX_SEGMENT_HOLES',
        setModelPartition: 'MODEL_PARTITION_SET',
        fetchSubPartitionValues: 'FETCH_SUB_PARTITION_VALUES',
        validateDateFormat: 'VALIDATE_DATE_FORMAT'
      }),
      ...mapMutations('ModelBuildModal', {
        setModal: types.SET_MODAL,
        hideModal: types.HIDE_MODAL,
        setModalForm: types.SET_MODAL_FORM,
        resetModalForm: types.RESET_MODAL_FORM
      }),
      ...mapActions('DetailDialogModal', {
        callGlobalDetailDialog: 'CALL_MODAL'
      })
    },
    locales
  })
  export default class ModelBuildModal extends Vue {
    moment = moment
    btnLoading = false
    isLoadingNewRange = false
    modelBuildMeta = {
      dataRangeVal: [],
      isLoadExisted: false
    }
    rules = {}
    loadRangeDateError = ''
    isShowRangeDateError = false
    isShowErrorSegments = false
    showDetail = false
    errorSegments = []
    buildType = ''
    defaultBuildType = ''
    buildOrComplete = 'build'
    partitionMeta = {
      table: '',
      column: '',
      format: '',
      multiPartition: ''
    }
    prevPartitionMeta = {
      table: '',
      column: '',
      format: '',
      multiPartition: ''
    }
    partitionRules = {
      column: [{validator: this.validateBrokenColumn, trigger: 'change'}]
    }
    isLoadingFormat = false
    dateFormats = dateFormats
    timestampFormats = timestampFormats
    dateTimestampFormats = dateTimestampFormats
    isExpand = true
    isShowWarning = false
    isWillAddIndex = false
    inputMultiType = 'select'
    multiPartitionValues = []
    multiPartitionValueOptions = []
    selectMultiPartitionValues = []
    modelSubPartitionValues = []
    isMultipleBuild = false
    duplicateValueError = false
    subPartitionOptions = []
    subPartitionGroupOne = []
    dateErrorMsg = ''
    formatedDate = ''
    errorFormat = ''
    isExpandFormatRule = false
    timestamp = Date.now().toString(32)
    secondStoragePartitionTips = false
    isBuildLoading = false

    @Watch('buildType')
    changeBuildType (newVal, oldVal) {
      newVal !== oldVal && (this.duplicateValueError = false)
    }

    toggleInputMultiPartition () {
      this.inputMultiType = this.inputMultiType === 'select' ? 'textarea' : 'select'
    }

    get modelId () {
      // batch 和 streaming 的都是取 uuid
      if (this.modelDesc.model_type !== 'HYBRID') {
        return this.modelDesc.uuid
      } else { // HYBRID 模式的，传批数据id
        return this.modelDesc.batch_id
      }
    }

    get toggleText () {
      return this.inputMultiType === 'select' ? this.$t('selectInput') : this.$t('batchInput')
    }

    get displaySubPartition () {
      return this.source !== 'addSegment' && this.$store.state.project.multi_partition_enabled && this.partitionMeta.multiPartition
    }

    get isStreamModel () {
      const factTable = this.modelInstance.getFactTable()
      return factTable.source_type === 1 || this.modelDesc.model_type === 'STREAMING'
    }
    get isNotBatchModel () {
      const factTable = this.modelInstance.getFactTable()
      return factTable.source_type === 1 || this.modelInstance.model_type !== 'BATCH'
    }
    get isHybridModel () {
      return this.modelDesc.model_type === 'HYBRID'
    }
    get dateFormatsOptions () {
      return this.isNotBatchModel ? timestampFormats : dateFormats
    }

    refreshPartitionValues (val) {
      this.multiPartitionValues = val
    }

    removeSelectedMultiPartition () {}

    toggleDetail () {
      this.showDetail = !this.showDetail
    }
    get fullLoadBuildTips () {
      return this.$t('fullLoadBuildTips', {storageSize: Vue.filter('dataSize')(this.modelDesc.storage)})
    }
    get noPartition () {
      return !(this.partitionMeta.table && this.partitionMeta.column && this.partitionMeta.format)
    }
    get incrementalDisabled () {
      return !(this.partitionMeta.table && this.partitionMeta.column && this.partitionMeta.format && this.modelBuildMeta.dataRangeVal.length && this.modelBuildMeta.dataRangeVal[0] && this.modelBuildMeta.dataRangeVal[1]) && this.buildType === 'incremental'
    }
    get partitionFormat () {
      if (this.partitionMeta.format === 'TIMESTAMP SECOND') {
        return 'yyyy-MM-dd HH:mm:ss'
      }
      if (this.partitionMeta.format === 'TIMESTAMP MILLISECOND') {
        return 'yyyy-MM-dd HH:mm:ss.SSS'
      }
      return this.partitionMeta.format
    }
    handChangeBuildType () {
      if (this.buildType === 'incremental' && !this.partitionMeta.table) {
        this.isExpand = true
        this.partitionMeta.table = this.partitionTables[0].alias
      }
      this.dateErrorMsg = ''
      this.secondStoragePartitionTips = false
      this.isShowWarning = this.isHaveSegment && (this.buildType !== this.defaultBuildType || JSON.stringify(this.prevPartitionMeta) !== JSON.stringify(this.partitionMeta))
    }
    handleChangeDateTime (val, pos) {
      // 仅在 IE 浏览器下做兼容处理
      if (val && navigator.userAgent.indexOf('Windows NT') >= 0) {
        const newDate = function (date) {
          if (typeof date === 'string' && /^\d{4}-\d{2}-\d{2}/.test(date)) {
            return new Date(date.replace(/-/g, '/'))
          } else {
            return new Date(date)
          }
        }
        let dateVal = this.modelBuildMeta.dataRangeVal
        pos === 'start' ? dateVal.splice(0, 1, newDate(val).getTime()) : dateVal.splice(1, 1, newDate(val).getTime())
        this.$set(this.modelBuildMeta, 'dataRangeVal', dateVal)
      }
      this.resetError()
    }
    validateBrokenColumn (rule, value, callback) {
      if (value) {
        if (this.checkIsBroken(this.brokenPartitionColumns, value)) {
          return callback(new Error(this.$t('noColumnFund')))
        }
      }
      if (!value && this.partitionMeta.table) {
        return callback(new Error(this.$t('pleaseInputColumn')))
      }
      callback()
    }

    checkIsBroken (brokenKeys, key) {
      if (key) {
        return ~brokenKeys.indexOf(key)
      }
      return false
    }
    // 获取破损的partition keys
    get brokenPartitionColumns () {
      if (this.partitionMeta.table) {
        let ntable = this.modelInstance.getTableByAlias(this.partitionMeta.table)
        return this.modelInstance.getBrokenModelLinksKeys(ntable.guid, [this.partitionMeta.column])
      }
      return []
    }

    get selectedTable () {
      if (this.partitionMeta.table) {
        for (let i = 0; i < this.partitionTables.length; i++) {
          if (this.partitionTables[i].alias === this.partitionMeta.table) {
            return this.partitionTables[i]
          }
        }
      }
    }

    async handleLoadFormat () {
      try {
        this.isLoadingFormat = true
        const response = await this.fetchPartitionFormat({ project: this.currentSelectedProject, table: this.selectedTable.name, partition_column: this.partitionMeta.column })
        this.partitionMeta.format = await handleSuccessAsync(response)
        this.partitionColumnFormatChange(this.partitionMeta.format)
        this.isLoadingFormat = false
      } catch (e) {
        this.isLoadingFormat = false
        handleError(e)
      }
    }

    get columns () {
      if (!this.isShow || this.partitionMeta.table === '') {
        return []
      }
      let result = []
      let factTable = this.modelInstance.getFactTable()
      if (factTable) {
        factTable.columns.forEach((x) => {
          if (this.isNotBatchModel && isStreamingPartitionType(x.datatype)) {
            result.push(x)
          } else if (!this.isNotBatchModel && isDatePartitionType(x.datatype)) {
            result.push(x)
          }
        })
      }
      // let ccColumns = this.modelInstance.getComputedColumns()
      // let cloneCCList = objectClone(ccColumns)
      // cloneCCList.forEach((x) => {
      //   let cc = {
      //     name: x.columnName,
      //     datatype: x.datatype
      //   }
      //   result.push(cc)
      // })
      return result
    }

    get subPartitionColumnsOptions () {
      if (!this.isShow || this.partitionMeta.table === '') {
        return []
      }
      let result = []
      let factTable = this.modelInstance.getFactTable()
      if (factTable) {
        factTable.columns.forEach((x) => {
          if (isSubPartitionType(x.datatype)) {
            result.push(x)
          }
        })
      }
      return result
    }

    // 分区设置改变
    changePartitionSetting () {
      if (JSON.stringify(this.prevPartitionMeta) !== JSON.stringify(this.partitionMeta) || this.buildType !== this.defaultBuildType) {
        if (this.isHaveSegment) {
          this.isShowWarning = true
        }
      } else {
        this.isShowWarning = false
      }
    }

    partitionTableChange () {
      this.partitionMeta.column = ''
      this.partitionMeta.format = ''
      this.$refs.partitionForm.validate()
      this.modelBuildMeta.dataRangeVal = []
      this.secondStoragePartitionTips = false
      this.changePartitionSetting()
    }

    partitionColumnChange () {
      // this.partitionMeta.format = 'yyyy-MM-dd'
      // this.$refs.partitionForm.validate()
      this.modelBuildMeta.dataRangeVal = []
      this.secondStoragePartitionTips = false
      this.changePartitionSetting()
    }

    async partitionColumnFormatChange (val) {
      this.formatedDate = ''
      this.errorFormat = ''
      if (val) {
        try {
          const res = await this.validateDateFormat({partition_date_column: this.partitionMeta.column, partition_date_format: this.partitionMeta.format})
          this.formatedDate = await handleSuccessAsync(res)
        } catch (e) {
          this.errorFormat = e.body.msg
          this.formatedDate = ''
        }
      }
      this.modelBuildMeta.dataRangeVal = []
      this.changePartitionSetting()
    }

    get partitionTables () {
      let result = []
      if (this.isShow && this.modelInstance) {
        Object.values(this.modelInstance.tables).forEach((nTable) => {
          if (nTable.kind === 'FACT') {
            result.push(nTable)
          }
        })
      }
      return result
    }

    toggleShowPartition () {
      this.isExpand = !this.isExpand
    }

    showToolTip (value) {
      let len = 0
      value.split('').forEach((v) => {
        if (/[\u4e00-\u9fa5]/.test(v)) {
          len += 2
        } else {
          len += 1
        }
      })
      return len <= 15
    }

    get buildTips () {
      if (this.buildType === 'incremental') {
        return this.$t('incrementalTips')
      } else if (this.buildType === 'fullLoad') {
        return this.$t('fullLoadTips', {storageSize: Vue.filter('dataSize')(this.modelDesc.storage)})
      }
    }
    get format () {
      return this.modelDesc.partition_desc && this.modelDesc.partition_desc.partition_date_format || 'yyyy-MM-dd'
    }
    formatPartition () {
      let format = ''
      switch (this.partitionMeta.format) {
        case 'yyyy-MM-dd':
        case 'yyyyMMdd':
        case 'yyyy/MM/dd':
          format = 'YYYY/MM/DD'
          break
        case 'yyyy-MM':
        case 'yyyyMM':
          format = 'YYYY/MM'
          break
        case 'yyyy-MM-dd HH:mm:ss':
          format = 'YYYY/MM/DD HH:mm:ss'
          break
        case 'yyyy-MM-dd HH:mm:ss.SSS':
          format = 'YYYY/MM/DD HH:mm:ss.SSS'
          break
      }
      return format
    }
    validateRange (value) {
      return new Promise((resolve, reject) => {
        const [ startValue, endValue ] = value
        let format = this.formatPartition()
        const formatTimestampStart = !format ? startValue : (startValue && new Date(moment(new Date(startValue)).format(format)).getTime())
        const formatTimestampEnd = !format ? endValue : (endValue && new Date(moment(new Date(endValue)).format(format)).getTime())
        const isLoadExisted = this.modelBuildMeta.isLoadExisted

        if ((!startValue || !endValue || transToUTCMs(formatTimestampStart) > transToUTCMs(formatTimestampEnd)) && !isLoadExisted) {
          // callback(new Error(this.$t('invaildDate')))
          this.dateErrorMsg = this.$t('invaildDate')
          reject()
        } else if (startValue && endValue && transToUTCMs(formatTimestampStart) === transToUTCMs(formatTimestampEnd) && !isLoadExisted) {
          // callback(new Error(this.$t('invaildDateNoEqual')))
          this.dateErrorMsg = this.$t('invaildDateNoEqual')
          reject()
        } else {
          // callback()
          this.dateErrorMsg = ''
          resolve()
        }
      })
    }
    @Watch('isShow')
    async initModelBuldRange () {
      if (this.isShow) {
        this.buildType = this.type
        this.defaultBuildType = this.type
        this.buildOrComplete = this.buildOrComp
        this.modelBuildMeta.dataRangeVal = []
        if (this.modelDesc.last_build_end && this.buildType === 'incremental') {
          let lastBuildDate = getGmtDateFromUtcLike(+this.modelDesc.last_build_end)
          if (lastBuildDate) {
            this.modelBuildMeta.dataRangeVal.push(lastBuildDate, lastBuildDate)
          }
        }
        this.$nextTick(() => {
          this.$refs.partitionForm && this.$refs.partitionForm.validate()
        })
        if (this.modelDesc && this.modelDesc.partition_desc && this.modelDesc.partition_desc.partition_date_column && this.buildType === 'incremental') {
          let named = this.modelDesc.partition_desc.partition_date_column.split('.')
          this.partitionMeta.table = this.prevPartitionMeta.table = named[0]
          this.partitionMeta.column = this.prevPartitionMeta.column = named[1]
          this.partitionMeta.format = this.prevPartitionMeta.format = this.modelDesc.partition_desc.partition_date_format
          this.partitionMeta.multiPartition = this.prevPartitionMeta.multiPartition = this.modelDesc.multi_partition_desc && this.modelDesc.multi_partition_desc.columns[0] && this.modelDesc.multi_partition_desc.columns[0].split('.')[1] || ''
          this.isExpand = false
        } else {
          this.isExpand = true
        }
        this.isShowWarning = false
        if (this.$store.state.project.multi_partition_enabled && this.modelDesc.multi_partition_desc && this.modelDesc.multi_partition_desc.columns.length) {
          try {
            const res = await this.fetchSubPartitionValues({ project: this.currentSelectedProject, model_id: this.modelId })
            const data = await handleSuccessAsync(res)
            this.modelSubPartitionValues = data.map((p) => {
              return p.partition_value[0]
            })
            this.modelSubPartitionValues.length && (this.subPartitionGroupOne = [{label: this.$t('selectAllSubPartitions'), value: `select_all_${this.timestamp}`}])
            this.subPartitionOptions = this.modelSubPartitionValues.slice(0, 50).map(it => ({label: it, value: it}))
          } catch (e) {
            handleError(e)
          }
        }
      } else {
        this.modelBuildMeta.dataRangeVal = []
        this.resetForm()
      }
    }
    resetForm () {
      this.partitionMeta = {
        table: '',
        column: '',
        format: '',
        multiPartition: ''
      }
      this.prevPartitionMeta = { table: '', column: '', format: '', multiPartition: '' }
      this.filterCondition = ''
      this.isLoadingSave = false
      this.isLoadingFormat = false
      this.secondStoragePartitionTips = false
    }
    async handleLoadNewestRange () {
      this.$refs.buildForm && this.$refs.buildForm.clearValidate()
      this.isLoadingNewRange = true
      this.resetError()
      const partition_desc = {
        partition_date_column: this.partitionMeta.table + '.' + this.partitionMeta.column,
        partition_date_format: this.partitionMeta.format
      }
      try {
        const submitData = {
          project: this.currentSelectedProject,
          model: this.modelId,
          partition_desc: partition_desc
        }
        const response = await this.fetchNewestModelRange(submitData)
        if (submitData.model !== this.modelId) { // 避免ajax耗时太长导致会覆盖新的model的load range数据
          return
        }
        if (response.body.code === '000') {
          const result = await handleSuccessAsync(response)
          const startTime = +result.start_time
          const endTime = +result.end_time
          this.modelBuildMeta.dataRangeVal = [ getGmtDateFromUtcLike(startTime), getGmtDateFromUtcLike(endTime) ]
        } else if (response.body.code === '999') {
          this.loadRangeDateError = response.body.msg
          this.isShowRangeDateError = true
        }
      } catch (e) {
        handleError(e)
      }
      this.isLoadingNewRange = false
    }
    resetError () {
      this.loadRangeDateError = ''
      this.dateErrorMsg = ''
      this.isShowRangeDateError = false
      this.isShowErrorSegments = false
      this.errorSegments = []
      this.showDetail = false
    }
    closeModal (isSubmit) {
      this.isLoadingNewRange = false
      this.btnLoading = false
      this.$refs.buildForm && this.$refs.buildForm.resetFields()
      this.isShowErrorSegments = false
      this.errorSegments = []
      this.showDetail = false
      this.isWillAddIndex = false
      this.multiPartitionValues = []
      this.subPartitionGroupOne = []
      this.dateErrorMsg = ''
      this.isExpandFormatRule = false
      this.resetError()
      this.hideModal()
      setTimeout(() => {
        this.callback && this.callback(isSubmit)
        this.resetModalForm()
      }, 200)
    }
    _buildModel ({start, end, modelId, modelName, isBuild, partition_desc, multi_partition_desc, multi_partition_values, build_all_sub_partitions, segment_holes}) {
      const partitionValuesArr = split_array(multi_partition_values, 1)
      this.buildModel({
        model_id: modelId,
        data: {
          start: start,
          end: end,
          build_all_indexes: isBuild,
          partition_desc: partition_desc,
          sub_partition_values: partitionValuesArr,
          segment_holes: segment_holes || [],
          // parallel_build_by_segment: this.isMultipleBuild,
          multi_partition_desc,
          build_all_sub_partitions,
          project: this.currentSelectedProject
        }
      }).then(() => {
        this.btnLoading = false
        // this.$emit('refreshModelList')
        if (this.isWillAddIndex) {
          this.$emit('isWillAddIndex', modelName)
        } else {
          if (isBuild) {
            this.$message({
              dangerouslyUseHTMLString: true,
              type: 'success',
              customClass: 'build-full-load-success',
              duration: 10000,
              showClose: true,
              message: (
                <div>
                  <span>{this.$t('kylinLang.common.buildSuccess')}</span>
                  <a href="javascript:void(0)" onClick={() => this.jumpToJobs()}>{this.$t('kylinLang.common.toJoblist')}</a>
                </div>
              )
            })
          } else {
            kylinMessage(this.$t('kylinLang.common.submitSuccess'))
          }
        }
        this.closeModal(true)
      }, (res) => {
        this.btnLoading = false
        res && handleError(res)
      })
    }
    saveAndAddIndex () {
      this.isWillAddIndex = true
      this.setbuildModel(false)
    }
    async setbuildModel (isBuild, type) {
      this.isBuildLoading = isBuild
      this.btnLoading = true
      try {
        if (this.buildType === 'incremental' && this.buildOrComplete === 'build') {
          await this.validateRange(this.modelBuildMeta.dataRangeVal)
          this.$refs.buildForm.validate(async (valid) => {
            if (!valid) {
              this.btnLoading = false
              return
            }
            await (this.$refs.rangeForm && this.$refs.rangeForm.validate()) || Promise.resolve()
            await (this.$refs.partitionForm && this.$refs.partitionForm.validate()) || Promise.resolve()
            const { column, table } = this.partitionMeta
            if (this.modelDesc.second_storage_enabled && !this.modelDesc.simplified_dimensions.map(it => it.column).includes(`${table}.${column}`)) {
              this.secondStoragePartitionTips = true
              this.btnLoading = false
              return
            }
            if (type && type === 'onlySave') {
              try {
                await this.$msgbox({
                  title: this.$t('kylinLang.common.tip'),
                  message: <div><p>{this.$t('onlySaveTip1')}</p><p>{this.$t('onlySaveTip2')}</p></div>,
                  showCancelButton: true,
                  confirmButtonText: this.$t('kylinLang.common.save')
                })
              } catch (e) {
                this.btnLoading = false
                return
              }
            }
            const partition_desc = {}
            if (typeof this.modelDesc.available_indexes_count === 'number' && this.modelDesc.available_indexes_count > 0) {
              if (this.prevPartitionMeta.table !== this.partitionMeta.table || this.prevPartitionMeta.column !== this.partitionMeta.column || this.prevPartitionMeta.format !== this.partitionMeta.format || this.prevPartitionMeta.multiPartition !== this.partitionMeta.multiPartition) {
                try {
                  await kylinConfirm(this.$t('changeSegmentTips'), {confirmButtonText: this.$t('kylinLang.common.save'), type: 'warning', dangerouslyUseHTMLString: true}, this.$t('kylinLang.common.tip'))
                } catch (e) {
                  this.btnLoading = false
                  return false
                }
              }
            }
            partition_desc.partition_date_column = this.partitionMeta.table + '.' + this.partitionMeta.column
            partition_desc.partition_date_format = this.partitionMeta.format
            let start = null
            let end = null
            if (!this.modelBuildMeta.isLoadExisted) {
              start = transToUTCMs(this.modelBuildMeta.dataRangeVal[0])
              end = transToUTCMs(this.modelBuildMeta.dataRangeVal[1])
            }
            // 如果切换分区列或者构建方式，会清空segment，不用检测
            const isChangePatition = this.prevPartitionMeta.table && (this.prevPartitionMeta.table !== this.partitionMeta.table || this.prevPartitionMeta.column !== this.partitionMeta.column || this.prevPartitionMeta.format !== this.partitionMeta.format)
            const isChangeBuildType = !this.prevPartitionMeta.table && this.isHaveSegment
            const multi_partition_desc = this.partitionMeta.multiPartition ? {columns: [this.partitionMeta.table + '.' + this.partitionMeta.multiPartition]} : null
            let build_all_sub_partitions = false
            const partitionValues = JSON.parse(JSON.stringify(this.multiPartitionValues))
            if (this.multiPartitionValues.includes(`select_all_${this.timestamp}`)) {
              const index = this.multiPartitionValues.indexOf(`select_all_${this.timestamp}`)
              build_all_sub_partitions = true
              index >= 0 && partitionValues.splice(index, 1)
            }
            if (isChangePatition || isChangeBuildType) {
              this._buildModel({start: start, end: end, modelId: this.modelId, modelName: this.modelDesc.alias, isBuild: isBuild, partition_desc: partition_desc, multi_partition_desc, multi_partition_values: partitionValues, build_all_sub_partitions})
            } else {
              let res
              try {
                res = await this.checkDataRange({modelId: this.modelId, project: this.currentSelectedProject, start: start, end: end})
              } catch (e) {
                this.btnLoading = false
                handleError(e)
              }
              const data = await handleSuccessAsync(res)
              if (data) {
                if (data.overlap_segments.length) {
                  this.btnLoading = false
                  this.isShowErrorSegments = true
                  this.errorSegments = data.overlap_segments
                } else if (data.segment_holes.length) {
                  const tableData = []
                  let selectSegmentHoles = []
                  const segmentHoles = data.segment_holes
                  segmentHoles.forEach((seg) => {
                    const obj = {}
                    obj['start'] = transToServerGmtTime(seg.start)
                    obj['end'] = transToServerGmtTime(seg.end)
                    obj['date_range_start'] = seg.start
                    obj['date_range_end'] = seg.end
                    tableData.push(obj)
                  })
                  try {
                    await this.callGlobalDetailDialog({
                      msg: this.$t('segmentHoletips', {modelName: this.modelDesc.name}),
                      title: this.$t('fixSegmentTitle'),
                      detailTableData: tableData,
                      detailColumns: [
                        {column: 'start', label: this.$t('kylinLang.common.startTime')},
                        {column: 'end', label: this.$t('kylinLang.common.endTime')}
                      ],
                      isShowSelection: true,
                      dialogType: 'warning',
                      showDetailBtn: false,
                      needResolveCancel: true,
                      cancelText: this.$t('ignore'),
                      submitText: this.$t('fixAndBuild'),
                      onlyCloseDialogReject: true,
                      customCallback: async (segments) => {
                        selectSegmentHoles = segments.map((seg) => {
                          return {start: seg.date_range_start, end: seg.date_range_end}
                        })
                        try {
                          this._buildModel({start: start, end: end, modelId: this.modelId, modelName: this.modelDesc.alias, isBuild: isBuild, partition_desc: partition_desc, multi_partition_desc, multi_partition_values: partitionValues, build_all_sub_partitions, segment_holes: selectSegmentHoles})
                        } catch (e) {
                          handleError(e)
                        }
                      }
                    })
                    this._buildModel({start: start, end: end, modelId: this.modelId, modelName: this.modelDesc.alias, isBuild: isBuild, partition_desc: partition_desc, multi_partition_desc, multi_partition_values: partitionValues, build_all_sub_partitions})
                  } catch (e) {
                    this.btnLoading = false
                    handleError(e)
                  }
                } else {
                  this._buildModel({start: start, end: end, modelId: this.modelId, modelName: this.modelDesc.alias, isBuild: isBuild, partition_desc: partition_desc, multi_partition_desc, multi_partition_values: partitionValues, build_all_sub_partitions})
                }
              }
            }
          })
        } else if (this.buildType === 'fullLoad' && this.buildOrComplete === 'build') {
          if (this.modelDesc && this.modelDesc.partition_desc && this.modelDesc.partition_desc.partition_date_column) {
            try {
              await kylinConfirm(this.$t('changeSegmentTips'), {confirmButtonText: this.$t('kylinLang.common.save'), type: 'warning', dangerouslyUseHTMLString: true}, this.$t('kylinLang.common.tip'))
            } catch (e) {
              this.btnLoading = false
              return false
            }
            this.btnLoading = true
            await this.setModelPartition({modelId: this.modelId, project: this.currentSelectedProject, partition_desc: null})
          }
          this.buildFullLoadModel({
            model_id: this.modelId,
            start: null,
            end: null,
            build_all_indexes: isBuild,
            project: this.currentSelectedProject
          }).then(async () => {
            this.btnLoading = false
            if (this.isWillAddIndex) {
              this.$emit('isWillAddIndex')
            } else {
              if (isBuild) {
                this.$message({
                  dangerouslyUseHTMLString: true,
                  type: 'success',
                  customClass: 'build-full-load-success',
                  duration: 10000,
                  showClose: true,
                  message: (
                    <div>
                      <span>{this.$t('kylinLang.common.buildSuccess')}</span>
                      <a href="javascript:void(0)" onClick={() => this.jumpToJobs()}>{this.$t('kylinLang.common.toJoblist')}</a>
                    </div>
                  )
                })
              } else {
                kylinMessage(this.$t('kylinLang.common.submitSuccess'))
              }
            }
            this.closeModal(true)
          }, (res) => {
            this.btnLoading = false
            res && handleError(res)
          })
        }
      } catch (e) {
        this.btnLoading = false
        handleError(e)
      }
    }
    // 补全索引已拿掉
    async completeBuildModel () {
      if (this.modelDesc.segment_holes.length) {
        const segmentHoles = this.modelDesc.segment_holes
        try {
          const tableData = []
          let selectSegmentHoles = []
          segmentHoles.forEach((seg) => {
            const obj = {}
            obj['start'] = transToServerGmtTime(seg.date_range_start)
            obj['end'] = transToServerGmtTime(seg.date_range_end)
            obj['date_range_start'] = seg.date_range_start
            obj['date_range_end'] = seg.date_range_end
            tableData.push(obj)
          })
          await this.callGlobalDetailDialog({
            msg: this.$t('segmentHoletips', {modelName: this.modelDesc.name}),
            title: this.$t('fixSegmentTitle'),
            detailTableData: tableData,
            detailColumns: [
              {column: 'start', label: this.$t('kylinLang.common.startTime')},
              {column: 'end', label: this.$t('kylinLang.common.endTime')}
            ],
            isShowSelection: true,
            dialogType: 'warning',
            showDetailBtn: false,
            needResolveCancel: true,
            cancelText: this.$t('ignore'),
            submitText: this.$t('fixAndBuild'),
            customCallback: async (segments) => {
              selectSegmentHoles = segments.map((seg) => {
                return {start: seg.date_range_start, end: seg.date_range_end}
              })
              try {
                await this.autoFixSegmentHoles({project: this.currentSelectedProject, model_id: this.modelId, segment_holes: selectSegmentHoles})
              } catch (e) {
                handleError(e)
              }
              this.confirmBuild()
            }
          })
          this.confirmBuild()
        } catch (e) {
          e !== 'cancel' && handleError(e)
        }
      } else {
        this.confirmBuild()
      }
    }

    async confirmBuild () {
      try {
        this.btnLoading = true
        let res = await this.buildIndex({
          project: this.currentSelectedProject,
          model_id: this.modelId
        })
        let data = await handleSuccessAsync(res)
        this.handleBuildIndexTip(data)
        this.closeModal(true)
      } catch (e) {
        handleError(e)
      } finally {
        this.btnLoading = false
      }
    }
    handleBuildIndexTip (data) {
      let tipMsg = ''
      if (data.type === BuildIndexStatus.NORM_BUILD) {
        tipMsg = this.$t('kylinLang.model.buildIndexSuccess')
        this.$message({message: tipMsg, type: 'success'})
        return
      }
      if (data.type === BuildIndexStatus.NO_LAYOUT) {
        tipMsg = this.$t('kylinLang.model.buildIndexFail2', {indexType: this.$t('kylinLang.model.index')})
      } else if (data.type === BuildIndexStatus.NO_SEGMENT) {
        tipMsg += this.$t('kylinLang.model.buildIndexFail1', {modelName: this.modelDesc.name})
      }
      this.$confirm(tipMsg, this.$t('kylinLang.common.notice'), {showCancelButton: false, type: 'warning', dangerouslyUseHTMLString: true})
    }
    // 检测是否输入了重复的子分区值
    checkDuplicateValue (type) {
      this.duplicateValueError = type
    }
    removeDuplicateValue () {
      this.$refs.selectSubPartition && this.$refs.selectSubPartition.clearDuplicateValue()
    }

    filterPartitions (query) {
      if (query) {
        this.subPartitionGroupOne = []
      } else if (this.modelSubPartitionValues.length) {
        this.subPartitionGroupOne = [{label: this.$t('selectAllSubPartitions'), value: `select_all_${this.timestamp}`}]
      }
      this.subPartitionOptions = this.modelSubPartitionValues.filter(item => item.indexOf(query) >= 0).slice(0, 50).map(it => ({label: it, value: it}))
    }

    jumpToJobs () {
      this.$router.push('/monitor/job')
    }
    created () {
      this.$on('buildModel', this._buildModel)
    }
  }
</script>
<style lang="less">
@import '../../../../../assets/styles/variables.less';
  .model-build {
    .error-format {
      color: @error-color-1;
      font-size: 12px;
      line-height: 16px;
    }
    .timestamp-format-tips,
    .pre-format {
      color: @text-normal-color;
      font-size: 14px;
      margin-top: 4px;
      background-color: @base-background-color;
      height: 26px;
      line-height: 26px;
      border-radius: 4px;
      display: inline-block;
      padding: 0 4px;
    }
    .format {
      font-size: 12px;
      line-height: 16px;
      color: @text-disabled-color;
      margin-top: 4px;
      span {
        color: @base-color;
        cursor: pointer;
        .arrow {
          transform: rotate( 90deg );
          margin-left: 3px;
        }
      }
    }
    .date-range-alert {
      padding: 10px 0;
      background-color: transparent;
    }
    .auto-detect-btn {
      line-height: 22px;
    }
    .detail-content {
      background-color: @base-background-color-1;
      padding: 8px 16px;
      box-sizing: border-box;
      font-size: 12px;
      color: @text-normal-color;
      line-height: 16px;
      margin-top: 5px;
      p {
        display: flex;
      }
    }
    .habird-tips {
      font-size: 14px;
    }
    .tips {
      font-size: 12px;
      color: @text-disabled-color;
    }
    .add-title {
      font-weight: bold;
      color: @text-title-color;
    }
    .item-desc {
      font-size: 12px;
      line-height: 1;
    }
    .el-date-editor.is-error {
      .el-input__inner {
        border: 1px solid @error-color-1;
      }
    }
    .error-date-range {
      padding: 0;
      margin: 0;
      line-height: 1;
    }
    .error-msg {
      color: @error-color-1;
      font-size: 12px;
      margin-top: 5px;
    }
    .error_segments {
      .el-alert__icon {
        padding-left: 2px;
      }
      .overlaps-tips {
        color: @error-color-1;
      }
    }
    .error_segments a:hover {
      text-decoration: none;
    }
    .divide-block {
      color: @base-color;
      font-size: 12px;
      text-align: center;
      cursor: pointer;
    }
    .divide-line {
      border-top: 1px solid @line-border-color;
      margin-top: 10px;
      margin-bottom: 20px;
    }
    .area-input {
      border: 1px solid @line-border-color3;
      height: 60px;
      overflow-y: auto;
      margin-top: 5px;
      .el-input__inner {
        border: none;
        padding: 0 26px 0 12px;
      }
      .el-select .el-input__suffix {
        display: none;
      }
    }
    .duplicate-tips {
      font-size: 12px;
      margin-top: 5px;
      .clear-value-btn {
        cursor: pointer;
        color: @text-normal-color;
        &:hover {
          color: @base-color;
        }
      }
    }
    .sub-partition-alert {
      font-size: 12px;
      color: @text-title-color;
      margin: 10px 0;
      .icon {
        color: @text-disabled-color;
      }
    }
    .select-sub-partition.error-border {
      .el-input__inner {
        border-color: @error-color-1;
      }
    }
    .select-sub-partition {
      // 针对 IE 游览器下中文输入法下输入文字后面会自带叉叉问题
      .el-select__input::-ms-clear {
        display: none;
      }
    }
    .el-icon-info {
      font-size: 14px;
      padding-left: 1px;
    }
    .segment-tips {
      line-height: 18px;
      margin-bottom: 10px;
    }
    .alert-icon {
      color: @text-disabled-color;
    }
  }
  .build-full-load-success {
    padding: 10px 30px 10px 10px;
    align-items: center;
  }
</style>
