index.vue 3.77 KB
<script lang="ts" setup>
import { NFormItem, NGi, NGrid, NSelect, NDatePicker, NInputNumber } from 'naive-ui';
import { defaultIntervalOptions, aggergationOptions } from '../DynamicForm/timeInterval'
import { unref, computed, ref, watch } from 'vue';
import { isObject } from '@/utils/external/is';

interface Value {
  agg?: Nullable<string>
  interval?: Nullable<number>
  startTs?: Nullable<number>
  endTs?: Nullable<number>
  limit?: Nullable<number>
}

const props = withDefaults(
  defineProps<{
    value?: Value
  }>(),
  {
    value: () => ({})
  }
)

const emit = defineEmits<{
  (e: 'update:value', value: Value): void
  (e: 'change', value: Value): void
}>()


const timePeriod = ref<Nullable<[number, number]>>(null)
const agg = ref()
const interval = ref()
const limit = ref(7)

const getRangeOptions = (number: number) => {
  for (let i = 0; i < defaultIntervalOptions.length; i++) {
    const option = defaultIntervalOptions[i]
    if (option.id >= number || i === defaultIntervalOptions.length - 1) {
      return option.linkage
    }

  }
}

const getShowLimit = computed(() => {
  return unref(agg) === 'NONE'
})

const getIntervalTimeOptions = computed(() => {
  const [startTs, endTs] = unref(timePeriod) || []
  if (!startTs || !endTs) return []
  const diff = Math.abs(startTs - endTs)
  return getRangeOptions(diff)
})

const handleTimePerionChange = (value: number[]) => {
  const [startTs, endTs] = value || []
  emit('update:value', { ...props.value, startTs, endTs, interval: null })
  emit('change', { ...props.value || {}, startTs, endTs, interval: null })
}

const handleAggChange = (value: string) => {
  const _value = { ...props.value, agg: value, ...(value === 'NONE' ? { limit: 7 } : {}) }
  Reflect.deleteProperty(_value, value === 'NONE' ? 'interval' : 'limit')
  emit('update:value', _value)
  emit('change', _value)
}

const handleIntervalChange = (value: number) => {
  const _value = { ...props.value, interval: value }
  emit('update:value', _value)
  emit('change', _value)
}

const handleLimitChange = (value: Nullable<number>) => {
  const _value = { ...props.value, limit: value }
  emit('update:value', _value)
  emit('change', _value)
}

watch(() => props.value, (target) => {
  if (target && isObject(target)) {
    const { agg: _agg, interval: _interval, startTs, endTs, limit: _limit } = target || {}
    if (startTs && endTs) {
      timePeriod.value = [startTs!, endTs!]
    } else {
      timePeriod.value = null
    }
    agg.value = _agg
    limit.value = _limit!
    interval.value = _interval
  }
})
</script>

<template>
  <NGrid :cols="24">
    <NGi :span="16">
      <NFormItem :show-label="false">
        <NDatePicker v-model:value="timePeriod" type="datetimerange" placeholder="请选择时间范围"
          @update-value="handleTimePerionChange" clearable :default-time="['00:00:00', '23:59:59']"></NDatePicker>
      </NFormItem>
    </NGi>
    <NGi :span="4">
      <NFormItem :show-label="false">
        <NSelect v-model:value="agg" @update:value="handleAggChange" :options="aggergationOptions" label-field="name"
          value-field="id" placeholder="聚合方式" clearable></NSelect>
      </NFormItem>
    </NGi>
    <NGi v-if="!getShowLimit" :span="4">
      <NFormItem :show-label="false">
        <NSelect v-model:value="interval" @update:value="handleIntervalChange" :options="getIntervalTimeOptions"
          label-field="name" value-field="id" placeholder="间隔时间" clearable></NSelect>
      </NFormItem>
    </NGi>
    <NGi v-if="getShowLimit" :span="4">
      <NFormItem :show-label="false">
        <NInputNumber v-model:value="limit" :default-value="7" @update:value="handleLimitChange"
          :parse="(input: string) => parseInt(input)" :min="7" :max="50000" :step="1" placeholder="请输入最大条数" />
      </NFormItem>
    </NGi>
  </NGrid>
</template>