index.vue 5.8 KB
<template>
  <n-date-picker
    v-model:value="option.dataset"
    clearable
    :panel="!!chartConfig.option.isPanel"
    :type="chartConfig.option.componentInteractEventKey"
    :style="`width:${w}px;`"
    :to="true"
    @update:value="onChange"
    :shortcuts="rangeShortcuts"
  />
</template>

<script setup lang="ts">
import { PropType, toRefs, shallowReactive, watch, ref, computed } from 'vue'
import dayjs, { ManipulateType } from 'dayjs'
import { CreateComponentType } from '@/packages/index.d'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import { useChartInteract } from '@/hooks/external/useChartDateInteract.hook'
import { InteractEventOn } from '@/enums/eventEnum'
import { ComponentInteractEventEnum, ComponentInteractParamsEnum, DefaultTypeEnum } from './interact'
import quarterOfYear from 'dayjs/plugin/quarterOfYear'

const props = defineProps({
  chartConfig: {
    type: Object as PropType<CreateComponentType>,
    required: true
  }
})

const { w, h } = toRefs(props.chartConfig.attr)

const rangeDate = ref<number | number[]>()

const rangeShortcuts = {
  昨天: () => {
    const cur = new Date().getTime()
    return [cur - 86400000, cur] as const
  },
  最近7天: () => {
    const cur = new Date().getTime()
    return [cur - 604800000, cur] as const
  },
  最近30天: () => {
    const cur = new Date().getTime()
    return [cur - 2592000000, cur] as const
  }
}

const option = shallowReactive({
  dataset: props.chartConfig.option.dataset
})

const isRange = computed(() => {
  return props.chartConfig.option.componentInteractEventKey.endsWith('range')
})

// 监听事件改变
const onChange = (v: number | number[] | null) => {
  if (isRange.value) {
    let dateStart = null
    let dateEnd = null
    let daterange = null
    if (v instanceof Array) {
      dateStart = v[0]
      dateEnd = v[1]
      daterange = `${v[0]}-${v[1]}`
      //特殊处理 针对日期类型为日期范围的,控件是不带时间的,比如选择当天,[2023-09-08,2023-09-08],传给服务端是没有返回的,服务端需要这种[2023-09-08:00:00:00,2023-09-08:23:59:59]
      if (dateStart === dateEnd) {
        const lastTs = dayjs(dateEnd).format('YYYY-MM-DD HH:mm:ss')
        dateEnd = dayjs(lastTs).set('hour', 23).set('minute', 59).set('second', 59).valueOf()
      }
    }
    console.log(daterange)
    // 存储到联动数据
    useChartInteract(
      props.chartConfig,
      useChartEditStore,
      {
        [ComponentInteractParamsEnum.DATE_START]: dateStart,
        [ComponentInteractParamsEnum.DATE_END]: dateEnd,
        [ComponentInteractParamsEnum.DATE_RANGE]: daterange
      },
      InteractEventOn.CHANGE
    )
  } else {
    // 存储到联动数据
    useChartInteract(
      props.chartConfig,
      useChartEditStore,
      { [ComponentInteractParamsEnum.DATE]: v },
      InteractEventOn.CHANGE
    )
  }
}

const getDiffDate = (type: ComponentInteractEventEnum, date: dayjs.Dayjs) => {
  // 注册 quarterOfYear 插件
  dayjs.extend(quarterOfYear)
  switch (type) {
    case ComponentInteractEventEnum.DATE:
    case ComponentInteractEventEnum.DATE_RANGE:
      date = date.startOf('day')
      break
    case ComponentInteractEventEnum.MONTH:
    case ComponentInteractEventEnum.MONTH_RANGE:
      date = date.startOf('month')
      break
    case ComponentInteractEventEnum.YEAR:
    case ComponentInteractEventEnum.YEAR_RANGE:
      date = date.startOf('year')
      break
    case ComponentInteractEventEnum.QUARTER:
    case ComponentInteractEventEnum.QUARTER_RANGE:
      date = date.startOf('quarter')
      break
    default:
      break
  }
  return date
}

watch(
  () => {
    return {
      type: props.chartConfig.option.componentInteractEventKey as ComponentInteractEventEnum,
      defaultType: props.chartConfig.option.defaultType as string,
      differValue: props.chartConfig.option.differValue as number[],
      differUnit: props.chartConfig.option.differUnit as ManipulateType[],
      dataset: props.chartConfig.option.dataset as number | number[] | null
    }
  },
  (newData, oldData) => {
    const hasTypeChanged = newData.type !== oldData?.type
    const hasDefaultTypeChanged = newData.defaultType !== oldData?.defaultType
    const hasDifferValueChanged = newData.differValue !== oldData?.differValue
    const hasDifferUnitChanged = newData.differUnit !== oldData?.differUnit

    if (hasTypeChanged || hasDefaultTypeChanged || hasDifferValueChanged || hasDifferUnitChanged) {
      if (newData.defaultType === DefaultTypeEnum.NONE) {
        props.chartConfig.option.dataset = null
      } else if (newData.defaultType === DefaultTypeEnum.DYNAMIC) {
        let date = dayjs()
        if (isRange.value) {
          props.chartConfig.option.dataset = [
            getDiffDate(newData.type, date.add(newData.differValue[0], newData.differUnit[0])).valueOf(),
            getDiffDate(newData.type, date.add(newData.differValue[1], newData.differUnit[1])).valueOf()
          ]
        } else {
          props.chartConfig.option.dataset = getDiffDate(
            newData.type,
            date.add(newData.differValue[0], newData.differUnit[0])
          ).valueOf()
        }
      } else if (newData.defaultType === DefaultTypeEnum.STATIC) {
        option.dataset = props.chartConfig.option.dataset
      }
    }
    option.dataset = props.chartConfig.option.dataset
    onChange(option.dataset)
  },
  {
    immediate: true
  }
)

// watch(
//   () => props.chartConfig.option.shortcut,
//   newData => {
//     if (!newData) return
//     const startTs = Date.now() - newData
//     const endTs = Date.now()
//     option.dataset = [startTs, endTs]
//     onChange(option.dataset)
//   },
//   {
//     immediate: true
//   }
// )
</script>

<style lang="scss" scoped>
@include deep() {
  .n-input {
    height: v-bind('h + "px"');
    display: flex;
    align-items: center;
  }
}
</style>