From 9e70e9ca093d751cb494a14440084df6523fe709 Mon Sep 17 00:00:00 2001
From: dingxs <dingronaldo@outlook.com>
Date: Mon, 19 Jun 2023 14:35:17 +0800
Subject: [PATCH] =?UTF-8?q?feat:=E6=97=B6=E9=97=B4=E9=80=89=E6=8B=A9?=
 =?UTF-8?q?=E5=99=A8=E5=A2=9E=E5=8A=A0=E9=BB=98=E8=AE=A4=E5=80=BC=E7=B1=BB?=
 =?UTF-8?q?=E5=9E=8B=E9=80=89=E9=A1=B9?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../Informations/Inputs/InputsDate/config.ts  |  13 +-
 .../Informations/Inputs/InputsDate/config.vue | 135 ++++++++++++++++--
 .../Informations/Inputs/InputsDate/index.vue  | 135 ++++++++++++------
 .../Inputs/InputsDate/interact.ts             |  31 ++++
 4 files changed, 255 insertions(+), 59 deletions(-)
 mode change 100644 => 100755 src/packages/components/Informations/Inputs/InputsDate/config.ts
 mode change 100644 => 100755 src/packages/components/Informations/Inputs/InputsDate/config.vue
 mode change 100644 => 100755 src/packages/components/Informations/Inputs/InputsDate/index.vue
 mode change 100644 => 100755 src/packages/components/Informations/Inputs/InputsDate/interact.ts

diff --git a/src/packages/components/Informations/Inputs/InputsDate/config.ts b/src/packages/components/Informations/Inputs/InputsDate/config.ts
old mode 100644
new mode 100755
index e8f1d233..02b639c6
--- a/src/packages/components/Informations/Inputs/InputsDate/config.ts
+++ b/src/packages/components/Informations/Inputs/InputsDate/config.ts
@@ -4,7 +4,7 @@ import { PublicConfigClass } from '@/packages/public'
 import { CreateComponentType } from '@/packages/index.d'
 import { chartInitConfig } from '@/settings/designSetting'
 import { COMPONENT_INTERACT_EVENT_KET } from '@/enums/eventEnum'
-import { interactActions, ComponentInteractEventEnum } from './interact'
+import { interactActions, ComponentInteractEventEnum, DefaultTypeEnum, DifferUnitEnum } from './interact'
 import { InputsDateConfig } from './index'
 
 export const option = {
@@ -12,9 +12,14 @@ export const option = {
   [COMPONENT_INTERACT_EVENT_KET]: ComponentInteractEventEnum.DATE,
   // 下拉展示
   isPanel: 0,
-  dataset: dayjs().valueOf(),
-  differValue: 0
-
+  // 默认值
+  dataset: dayjs().valueOf() as number | number[] | null,
+  // 默认值类型
+  defaultType: DefaultTypeEnum.STATIC,
+  // 动态默认值偏移单位
+  differUnit: [DifferUnitEnum.DAY, DifferUnitEnum.DAY],
+  // 动态默认值偏移值
+  differValue: [0, 0]
 }
 
 export default class Config extends PublicConfigClass implements CreateComponentType {
diff --git a/src/packages/components/Informations/Inputs/InputsDate/config.vue b/src/packages/components/Informations/Inputs/InputsDate/config.vue
old mode 100644
new mode 100755
index 0d806518..8fa9adaf
--- a/src/packages/components/Informations/Inputs/InputsDate/config.vue
+++ b/src/packages/components/Informations/Inputs/InputsDate/config.vue
@@ -8,39 +8,67 @@
   <collapse-item name="时间配置" :expanded="true">
     <setting-item-box name="基础">
       <setting-item name="类型">
-        <n-select v-model:value="optionData.componentInteractEventKey" size="small" :options="datePickerTypeOptions" />
+        <n-select v-model:value="optionData.componentInteractEventKey" size="small" :options="datePickerTypeOptions"
+                  @update:value="datePickerTypeUpdate"/>
       </setting-item>
     </setting-item-box>
 
-    <setting-item-box name="默认值" :alone="true">
-      <n-date-picker size="small" v-model:value="optionData.dataset" :type="optionData.componentInteractEventKey" />
-    </setting-item-box>
+    <setting-item-box name="默认值">
+      <setting-item name="类型">
+        <n-select v-model:value="optionData.defaultType" size="small" :options="defaultTypeOptions"
+                  @update:value="defaultTypeUpdate" />
+      </setting-item>
 
-    <setting-item-box :alone="true">
+    </setting-item-box>
+    <setting-item-box v-if="optionData.defaultType == DefaultTypeEnum.STATIC" :alone="true">
+      <setting-item name="静态默认值">
+        <n-date-picker size="small" clearable v-model:value="optionData.dataset" :type="optionData.componentInteractEventKey" />
+      </setting-item>
+    </setting-item-box>
+    <setting-item-box v-if="optionData.defaultType === DefaultTypeEnum.DYNAMIC" >
       <template #name>
-        <n-text>动态</n-text>
+        <n-text></n-text>
         <n-tooltip trigger="hover">
           <template #trigger>
             <n-icon size="21" :depth="3">
               <help-outline-icon></help-outline-icon>
             </n-icon>
           </template>
-          <n-text>动态值不为0时,默认值:取当天时间相加当前值</n-text>
+          <n-text>打开页面时浏览器操作系统的系统时间+偏移量(单位)</n-text>
         </n-tooltip>
       </template>
-      <n-input-number v-model:value="optionData.differValue" class="input-num-width" size="small" :min="-40" :max="40">
-        <template #suffix> 天 </template>
-      </n-input-number>
+      <setting-item :name="differValueName">
+        <n-input-number v-model:value="optionData.differValue[0]" class="input-num-width" size="small">
+          <template #suffix>
+            {{DifferUnitObject[optionData.differUnit[0]]}}
+          </template>
+        </n-input-number>
+      </setting-item>
+      <setting-item :name="differUnitName">
+        <n-select v-model:value="optionData.differUnit[0]" size="small" :options="differUnitOptions" />
+      </setting-item>
+      <setting-item v-if="isRange" name="结束值动态偏移量">
+        <n-input-number v-model:value="optionData.differValue[1]" class="input-num-width" size="small">
+          <template #suffix>
+            {{DifferUnitObject[optionData.differUnit[1]]}}
+          </template>
+        </n-input-number>
+      </setting-item>
+      <setting-item v-if="isRange" name="结束值偏移单位">
+        <n-select v-model:value="optionData.differUnit[1]" size="small" :options="differUnitOptions" />
+      </setting-item>
     </setting-item-box>
+
   </collapse-item>
 </template>
 
 <script lang="ts" setup>
-import { PropType } from 'vue'
+import { PropType, computed } from 'vue'
 import { icon } from '@/plugins'
 import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
 import { option } from './config'
-import { ComponentInteractEventEnum } from './interact'
+import { ComponentInteractEventEnum, DefaultTypeEnum, DifferUnitEnum, DifferUnitObject } from './interact'
+import dayjs from "dayjs";
 
 const { HelpOutlineIcon } = icon.ionicons5
 
@@ -100,4 +128,87 @@ const datePickerTypeOptions = [
     value: ComponentInteractEventEnum.QUARTER_RANGE
   }
 ]
+
+const defaultTypeOptions = [
+  {
+    label: '静态',
+    value: DefaultTypeEnum.STATIC
+  },
+  {
+    label: '动态',
+    value: DefaultTypeEnum.DYNAMIC
+  },
+  {
+    label: '无',
+    value: DefaultTypeEnum.NONE
+  }
+]
+
+
+const differUnitOptions = [
+  // ManipulateType
+  {
+    value: DifferUnitEnum.DAY,
+    label: DifferUnitObject[DifferUnitEnum.DAY]
+  },
+  {
+    value: DifferUnitEnum.WEEK,
+    label: DifferUnitObject[DifferUnitEnum.WEEK]
+  },
+  {
+    value: DifferUnitEnum.MONTH,
+    label: DifferUnitObject[DifferUnitEnum.MONTH]
+  },
+  {
+    value: DifferUnitEnum.QUARTER,
+    label: DifferUnitObject[DifferUnitEnum.QUARTER]
+  },
+  {
+    value: DifferUnitEnum.YEAR,
+    label: DifferUnitObject[DifferUnitEnum.YEAR]
+  },
+  {
+    value: DifferUnitEnum.HOUR,
+    label: DifferUnitObject[DifferUnitEnum.HOUR]
+  },
+  {
+    value: DifferUnitEnum.MINUTE,
+    label: DifferUnitObject[DifferUnitEnum.MINUTE]
+  },
+  {
+    value: DifferUnitEnum.SECOND,
+    label: DifferUnitObject[DifferUnitEnum.SECOND]
+  },
+  {
+    value: DifferUnitEnum.MILLISECOND,
+    label: DifferUnitObject[DifferUnitEnum.MILLISECOND]
+  }
+]
+
+
+const isRange = computed(() => {
+  return props.optionData.componentInteractEventKey.endsWith('range')
+})
+
+const differValueName = computed(() => {
+  return isRange.value ? '开始值动态偏移量' : '动态偏移量'
+})
+
+const differUnitName = computed(() => {
+  return isRange.value ? '开始值偏移单位' : '偏移单位'
+})
+
+const datePickerTypeUpdate = () => {
+  props.optionData.dataset = isRange.value ? [dayjs().valueOf(), dayjs().valueOf()] : dayjs().valueOf()
+}
+
+const defaultTypeUpdate = (v: string) => {
+  if (v === DefaultTypeEnum.STATIC) {
+    datePickerTypeUpdate()
+  } else {
+    // DefaultTypeEnum.
+    props.optionData.dataset = null
+  }
+}
+
 </script>
diff --git a/src/packages/components/Informations/Inputs/InputsDate/index.vue b/src/packages/components/Informations/Inputs/InputsDate/index.vue
old mode 100644
new mode 100755
index 3800590f..a8e16bc1
--- a/src/packages/components/Informations/Inputs/InputsDate/index.vue
+++ b/src/packages/components/Informations/Inputs/InputsDate/index.vue
@@ -1,6 +1,7 @@
 <template>
   <n-date-picker
     v-model:value="option.dataset"
+    clearable
     :panel="!!chartConfig.option.isPanel"
     :type="chartConfig.option.componentInteractEventKey"
     :style="`width:${w}px;`"
@@ -9,13 +10,15 @@
 </template>
 
 <script setup lang="ts">
-import { PropType, toRefs, ref, shallowReactive, watch } from 'vue'
-import dayjs from 'dayjs'
+import { computed, PropType, ref, shallowReactive, toRefs, watch } from 'vue'
 import { CreateComponentType } from '@/packages/index.d'
 import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
 import { useChartInteract } from '@/hooks'
 import { InteractEventOn } from '@/enums/eventEnum'
-import { ComponentInteractParamsEnum } from './interact'
+import {ComponentInteractEventEnum, ComponentInteractParamsEnum, DefaultTypeEnum} from './interact'
+import dayjs, {ManipulateType} from 'dayjs'
+import quarterOfYear from 'dayjs/plugin/quarterOfYear';
+
 
 const props = defineProps({
   chartConfig: {
@@ -31,61 +34,107 @@ const option = shallowReactive({
   dataset: props.chartConfig.option.dataset
 })
 
+const isRange = computed(() => {
+  return props.chartConfig.option.componentInteractEventKey.endsWith('range')
+})
+
 // 监听事件改变
-const onChange = (v: number | number[]) => {
-  if (v instanceof Array) {
+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]}`
+    }
     // 存储到联动数据
     useChartInteract(
-      props.chartConfig,
-      useChartEditStore,
-      {
-        [ComponentInteractParamsEnum.DATE_START]: v[0] || dayjs().valueOf(),
-        [ComponentInteractParamsEnum.DATE_END]: v[1] || dayjs().valueOf(),
-        [ComponentInteractParamsEnum.DATE_RANGE]: `${v[0] || dayjs().valueOf()}-${v[1] || dayjs().valueOf()}`
-      },
-      InteractEventOn.CHANGE
+        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 || dayjs().valueOf() },
-      InteractEventOn.CHANGE
+        props.chartConfig,
+        useChartEditStore,
+        { [ComponentInteractParamsEnum.DATE]: v },
+        InteractEventOn.CHANGE
     )
   }
 }
 
-watch(
-  () => props.chartConfig.option.dataset,
-  (newData: number | number[]) => {
-    option.dataset = newData
-    // 关联目标组件首次请求带上默认内容
-    onChange(newData)
-  },
-  {
-    immediate: true
+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(
-  () => props.chartConfig.option.differValue,
-  (newData: number) => {
-    if (props.chartConfig.option.differValue === 0) return
-    if (typeof option.dataset === 'object') {
-      option.dataset[0] = dayjs().add(newData, 'day').valueOf()
-      option.dataset[1] = dayjs().add(newData, 'day').valueOf()
-    } else {
-      option.dataset = dayjs().add(newData, 'day').valueOf()
+    () => {
+      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()
+          }
+        }
+      }
+      option.dataset = props.chartConfig.option.dataset;
+      onChange(option.dataset);
+    },
+    {
+      immediate: true,
     }
-    // 关联目标组件首次请求带上默认内容
-    onChange(newData)
-  },
-  {
-    immediate: true
-  }
-)
+);
 </script>
 
 <style lang="scss" scoped>
diff --git a/src/packages/components/Informations/Inputs/InputsDate/interact.ts b/src/packages/components/Informations/Inputs/InputsDate/interact.ts
old mode 100644
new mode 100755
index a466c989..6690f0eb
--- a/src/packages/components/Informations/Inputs/InputsDate/interact.ts
+++ b/src/packages/components/Informations/Inputs/InputsDate/interact.ts
@@ -22,6 +22,37 @@ export enum ComponentInteractParamsEnum {
   DATE_RANGE = 'daterange'
 }
 
+export enum DefaultTypeEnum {
+  NONE = "none",
+  STATIC = "static",
+  DYNAMIC = "dynamic"
+}
+
+export enum DifferUnitEnum {
+  DAY = 'd',
+  WEEK = 'w',
+  MONTH = 'M',
+  QUARTER = 'Q',
+  YEAR = 'y',
+  HOUR = 'h',
+  MINUTE = 'm',
+  SECOND = 's',
+  MILLISECOND = 'ms',
+}
+
+export const DifferUnitObject = {
+  // https://day.js.org/docs/en/manipulate/add
+  [DifferUnitEnum.DAY]: '天',
+  [DifferUnitEnum.WEEK]: '周',
+  [DifferUnitEnum.MONTH]: '月',
+  [DifferUnitEnum.QUARTER]: '季度',
+  [DifferUnitEnum.YEAR]: '年',
+  [DifferUnitEnum.HOUR]: '小时',
+  [DifferUnitEnum.MINUTE]: '分钟',
+  [DifferUnitEnum.SECOND]: '秒',
+  [DifferUnitEnum.MILLISECOND]: '毫秒',
+}
+
 const time = [
   {
     value: ComponentInteractParamsEnum.DATE,