Procházet zdrojové kódy

feat: 重构首页跳转功能部分代码

Jack Zhou před 2 týdny
rodič
revize
3e5cd64a68

+ 186 - 379
src/views/Dashboard/src/DashboardView.new.vue

@@ -89,7 +89,7 @@ const GetDashboardData = () => {
       nextTick(() => {
         GetKpiData(KPIDefaulteData.value)
         GetPendingEcharts(PendingDefaulteData.value)
-        getTableData(false, RecentDefaulteData.value)
+        getTableData(RecentDefaulteData.value, false)
         GetETDEcharts(ETDDefaulteData.value)
         GetContainerCountEcharts(ContainerefaultData.value)
         GetTop10ODEcharts(Top10DefaultData.value)
@@ -101,7 +101,7 @@ const GetDashboardData = () => {
   })
 }
 // 获取表单数据
-const getTableData = (isPage: any, val: any) => {
+const getTableData = (val: any, isPage?: any) => {
   dashboardObj.RecentDefaultData = val
   const rc = isPage ? pageInfo.value.total : -1
   $api
@@ -477,440 +477,248 @@ const seller_chart_top10_destination = ref()
 const seller_chart_CO2_origin = ref()
 const seller_chart_CO2_destination = ref()
 
-// 1. 定义配置映射表
+// 定义点击项的配置类型
 interface ClickConfig {
   reportType: string
   reportRefGetter: () => string
-  extraFilters?: Array<FiltersType>
-  useContainerFormat?: boolean // 是否使用 Container 格式(MM/YYYY → DD=01)
-  dateSource?: {
-    type: string
+  extraFilters?: Record<string, any>
+  dateConfig?: {
+    type: 'ETD' | 'ETA'
     start: string
     end: string
+    formatType?: 'Container' | 'Revenue'
   }
-  originCityKey?: string
-  destinationCityKey?: string
+  transportMode: any
 }
 
-const CLICK_CONFIG_MAP: Record<string, ClickConfig> = {
-  KPI0: {
+// 配置映射表:将 val 映射到具体配置
+const CLICK_CONFIG_MAP: Record<string, (val: string) => ClickConfig> = {
+  'KPI Departure': () => ({
     reportType: 'atd_r4',
     reportRefGetter: () => pie_chart_kpi_departure.value[0]?.paramsdata?.name || '',
-    dateSource: dashboardObj.KPIDefaulteData
-  },
-  KPI1: {
+    dateConfig: {
+      title: 'KPI Departure',
+      type: dashboardObj.KPIDefaulteData.date_type,
+      start: dashboardObj.KPIDefaulteData.date_start,
+      end: dashboardObj.KPIDefaulteData.date_end
+    },
+    transportMode: dashboardObj.KPIDefaulteData.transportation
+  }),
+  'KPI Arrival': () => ({
     reportType: 'ata_r3',
     reportRefGetter: () => pie_chart_kpi_arrival.value[0]?.paramsdata?.name || '',
-    dateSource: dashboardObj.KPIDefaulteData
-  },
-  Pending0: {
+    dateConfig: {
+      title: 'KPI Arrival',
+      type: dashboardObj.KPIDefaulteData.date_type,
+      start: dashboardObj.KPIDefaulteData.date_start,
+      end: dashboardObj.KPIDefaulteData.date_end
+    },
+    transportMode: dashboardObj.KPIDefaulteData.transportation
+  }),
+  'Pending Departure': () => ({
     reportType: 'r4',
-    reportRefGetter: () => pie_chart_pending_departure.value[0]?.paramsdata?.name || ''
-  },
-  Pending1: {
+
+    reportRefGetter: () => pie_chart_pending_departure.value[0]?.paramsdata?.name || '',
+    transportMode: dashboardObj.PendingDefaultData.transportation
+  }),
+  'Pending Arrival': () => ({
     reportType: 'r3',
-    reportRefGetter: () => pie_chart_pending_arrival.value[0]?.paramsdata?.name || ''
-  },
-  'ETD to ETA (Days)': {
+    reportRefGetter: () => pie_chart_pending_arrival.value[0]?.paramsdata?.name || '',
+    transportMode: dashboardObj.PendingDefaultData.transportation
+  }),
+  'ETD to ETA (Days)': () => ({
     reportType: 'r1',
     reportRefGetter: () => pie_chart_ETD.value[0]?.paramsdata?.name || '',
-    useContainerFormat: true,
-    dateSource: dashboardObj.ETDDefaultData,
-    extraFilters: [
-      {
-        title: '_reportRefe_date',
-        key: ['_reportRefe_date', '_reportRefb_date'],
+    dateConfig: {
+      type: dashboardObj.ETDDefaultData.date_type,
+      start: dashboardObj.ETDDefaultData.date_start,
+      end: dashboardObj.ETDDefaultData.date_end,
+      formatType: 'Container'
+    },
+    transportMode: dashboardObj.ETDDefaultData.transportation,
+    extraFilters: {
+      _reportRefe_date: {
         value: [dayjs().startOf('year').format('MM/YYYY'), dayjs().endOf('year').format('MM/YYYY')],
-        keyType: 'dateRange',
-        isHide: true
+        keyType: 'dateRange'
       }
-    ]
-  },
-  'Top 10 Origin': {
+    }
+  }),
+  'Top 10 Origin': () => ({
     reportType: 'top',
     reportRefGetter: () => seller_chart_top10_origin.value[0]?.paramsdata || '',
-    dateSource: dashboardObj.Top10faultData,
-    originCityKey: 'shipper_city',
-    extraFilters: [
-      {
-        title: '_reportStationType',
-        key: '_reportStationType',
+    dateConfig: {
+      type: dashboardObj.Top10faultData.date_type,
+      start: dashboardObj.Top10faultData.date_start,
+      end: dashboardObj.Top10faultData.date_end
+    },
+    transportMode: dashboardObj.Top10faultData.transportation,
+    extraFilters: {
+      _reportStationType: {
         value: toporiginType.value,
-        keyType: 'normal',
-        isHide: true
+        keyType: 'normal'
       }
-    ]
-  },
-  'Top 10 Destination': {
+    }
+  }),
+  'Top 10 Destination': () => ({
     reportType: 'top',
     reportRefGetter: () => seller_chart_top10_destination.value[0]?.paramsdata || '',
-    dateSource: dashboardObj.Top10faultData,
-    destinationCityKey: 'consignee_city',
-    extraFilters: [
-      {
-        title: '_reportStationType',
-        key: '_reportStationType',
+    dateConfig: {
+      type: dashboardObj.Top10faultData.date_type,
+      start: dashboardObj.Top10faultData.date_start,
+      end: dashboardObj.Top10faultData.date_end
+    },
+    transportMode: dashboardObj.Top10faultData.transportation,
+    extraFilters: {
+      _reportStationType: {
         value: topdestinationinType.value,
-        keyType: 'normal',
-        isHide: true
+        keyType: 'normal'
+      },
+      consignee_city: {
+        value: [seller_chart_top10_destination.value[0]?.paramscityname],
+        keyType: 'array'
       }
-    ]
-  },
-  'CO2e Emission by Origin (Top 10)': {
+    }
+  }),
+  'CO2e Emission by Origin (Top 10)': () => ({
     reportType: 'co2e',
-    reportRefGetter: () => seller_chart_CO2_origin.value?.[0]?.paramsdata?.name || '',
-    dateSource: dashboardObj.OriginCo2Top10faultData,
-    extraFilters: [
-      {
-        title: '_reportDataType',
-        key: '_reportDataType',
-        value: seller_chart_CO2_origin.value?.[0]?.paramsdata?.type || '',
-        keyType: 'normal',
-        isHide: true
+    reportRefGetter: () => seller_chart_CO2_origin.value[0]?.paramsdata?.name || '',
+    dateConfig: {
+      type: dashboardObj.OriginCo2Top10faultData.date_type,
+      start: dashboardObj.OriginCo2Top10faultData.date_start,
+      end: dashboardObj.OriginCo2Top10faultData.date_end
+    },
+    transportMode: dashboardObj.OriginCo2Top10faultData.transportation,
+    extraFilters: {
+      _reportDataType: {
+        value: seller_chart_CO2_origin.value[0]?.paramsdata?.type,
+        keyType: 'normal'
       },
-      {
-        title: '_reportStationType',
-        key: '_reportStationType',
+      _reportStationType: {
         value: 'origin',
-        keyType: 'normal',
-        isHide: true
+        keyType: 'normal'
       }
-    ]
-  },
-  'CO2e Emission by Destination (Top 10)': {
+    }
+  }),
+  'CO2e Emission by Destination (Top 10)': () => ({
     reportType: 'co2e',
     reportRefGetter: () => seller_chart_CO2_destination.value[0]?.paramsdata?.name || '',
-    dateSource: dashboardObj.DestinationCo2Top10faultData,
-    extraFilters: [
-      {
-        title: '_reportDataType',
-        key: '_reportDataType',
-        value: seller_chart_CO2_destination.value?.[0]?.paramsdata?.type || '',
-        keyType: 'normal',
-        isHide: true
+    dateConfig: {
+      type: dashboardObj.DestinationCo2Top10faultData.date_type,
+      start: dashboardObj.DestinationCo2Top10faultData.date_start,
+      end: dashboardObj.DestinationCo2Top10faultData.date_end
+    },
+    transportMode: dashboardObj.DestinationCo2Top10faultData.transportation,
+    extraFilters: {
+      _reportDataType: {
+        value: seller_chart_CO2_destination.value[0]?.paramsdata?.type,
+        keyType: 'normal'
       },
-      {
-        title: '_reportStationType',
-        key: '_reportStationType',
+      _reportStationType: {
         value: 'agent',
-        keyType: 'normal',
-        isHide: true
+        keyType: 'normal'
       }
-    ]
-  }
+    }
+  })
 }
 
-// === 2. 提取 setEstimatedTime 为独立函数(可复用)===
-const setEstimatedTime = (
+// 公共工具函数:处理日期转换
+const transformDateRange = (
   type: 'ETD' | 'ETA',
-  value: string[],
-  formatType: 'Container' | 'Revenue' = 'Revenue'
-) => {
+  [start, end]: [string, string],
+  formatType?: 'Container' | 'Revenue'
+): [string, string] => {
   const parseFormat = formatType === 'Container' ? 'MM/YYYY' : 'MM/DD/YYYY'
-  const transformDate = (dateStr: string): string => {
+
+  const transform = (dateStr: string): string => {
     let parsed = dayjs(dateStr, parseFormat, true)
-    if (formatType === 'Container') parsed = parsed.date(1)
-    return parsed.format('MM/DD/YYYY') // 或你实际需要的 formatDate
+    if (formatType === 'Container') {
+      parsed = parsed.date(1)
+    }
+    return parsed.format(formatDate)
   }
 
-  const config =
-    type === 'ETD'
-      ? { title: 'ETD', key: ['etd_start', 'etd_end'] }
-      : { title: 'ETA', key: ['eta_start', 'eta_end'] }
-
-  filtersStore.updateFilter({
-    ...config,
-    value: [transformDate(value[0]), transformDate(value[1])],
-    keyType: 'dateRange'
-  })
+  return [transform(start), transform(end)]
 }
 
-const ClickParams = (val: any) => {
-  const setEstimatedTime = (
-    type: 'ETD' | 'ETA',
-    value: string[],
-    formatType?: 'Container' | 'Revenue'
-  ) => {
-    const parseFormat = formatType === 'Container' ? 'MM/YYYY' : 'MM/DD/YYYY'
+// 主函数
+const ClickParams = (val: string) => {
+  const configFactory = CLICK_CONFIG_MAP[val]
+  if (!configFactory) {
+    console.warn(`No config found for click value: ${val}`)
+    return
+  }
 
-    // 处理单个日期字符串的转换函数
-    const transformDate = (dateStr: string): string => {
-      let parsed = dayjs(dateStr, parseFormat, true) // 使用 strict 模式更安全
+  const config = configFactory(val)
 
-      // 如果是 Container 格式(MM/YYYY),强制日期为 1 号
-      if (formatType === 'Container') {
-        parsed = parsed.date(1) // 设置为当月 1 日
-      }
+  // 1. 设置日期范围(如果存在)
+  if (config.dateConfig) {
+    const { type, start, end, formatType } = config.dateConfig
+    const [etdStart, etdEnd] = transformDateRange(type, [start, end], formatType)
 
-      return parsed.format(formatDate)
-    }
-    const config =
-      type === 'ETD'
-        ? {
-            title: 'ETD',
-            key: ['etd_start', 'etd_end']
-          }
-        : {
-            title: 'ETA',
-            key: ['eta_start', 'eta_end']
-          }
+    const keyMap = { ETD: ['etd_start', 'etd_end'], ETA: ['eta_start', 'eta_end'] }
     filtersStore.updateFilter({
-      ...config,
-      value: [transformDate(value[0]), transformDate(value[1])],
+      title: type,
+      key: keyMap[type],
+      value: [etdStart, etdEnd],
       keyType: 'dateRange'
     })
   }
 
-  const setTransportMode = (value: any) => {
-    filtersStore.updateFilter({
-      title: 'Transport Mode',
-      key: 'transport_mode',
-      value: value,
-      keyType: 'array'
-    })
-  }
+  // 2. 设置运输方式
+  filtersStore.updateFilter({
+    title: 'Transport Mode',
+    key: 'transport_mode',
+    value: config.transportMode,
+    keyType: 'array'
+  })
 
-  // KPI Departure点击跳转
-  if (val === 'KPI0') {
-    setEstimatedTime(dashboardObj.KPIDefaulteData.date_type, [
-      dashboardObj.KPIDefaulteData.date_start,
-      dashboardObj.KPIDefaulteData.date_end
-    ])
-    setTransportMode(dashboardObj.KPIDefaulteData.transportation)
-    // KPI Departure点击跳转
-    filtersStore.updateFilter({
-      title: 'KPI Departure',
-      key: '_reportRef',
-      value: pie_chart_kpi_departure.value[0].paramsdata.name,
-      keyType: 'normal'
-    })
-    filtersStore.updateFilter({
-      title: '_reportType',
-      key: '_reportType',
-      value: 'atd_r4',
-      keyType: 'normal',
-      isHide: true
-    })
-  } else if (val === 'KPI1') {
-    setEstimatedTime(dashboardObj.KPIDefaulteData.date_type, [
-      dashboardObj.KPIDefaulteData.date_start,
-      dashboardObj.KPIDefaulteData.date_end
-    ])
-    setTransportMode(dashboardObj.KPIDefaulteData.transportation)
-    // KPI Arrival点击跳转
-    filtersStore.updateFilter({
-      title: 'KPI Arrival',
-      key: '_reportRef',
-      value: pie_chart_kpi_arrival.value[0]?.paramsdata?.name || '',
-      keyType: 'normal'
-    })
-    filtersStore.updateFilter({
-      title: '_reportType',
-      key: '_reportType',
-      value: 'ata_r3',
-      keyType: 'normal',
-      isHide: true
-    })
-  } else if (val === 'Pending0') {
-    setTransportMode(dashboardObj.PendingDefaultData.transportation)
-    // PendingDeparture点击跳转
-    filtersStore.updateFilter({
-      title: 'Pending Departure',
-      key: '_reportRef',
-      value: pie_chart_pending_departure.value[0].paramsdata.name,
-      keyType: 'normal'
-    })
-    filtersStore.updateFilter({
-      title: '_reportType',
-      key: '_reportType',
-      value: 'r4',
-      keyType: 'normal',
-      isHide: true
-    })
-  } else if (val === 'Pending1') {
-    setTransportMode(dashboardObj.PendingDefaultData.transportation)
-    //  PendingArrival点击跳转
-    filtersStore.updateFilter({
-      title: 'Pending Arrival',
-      key: '_reportRef',
-      value: pie_chart_pending_arrival.value[0].paramsdata.name,
-      keyType: 'normal'
-    })
-    filtersStore.updateFilter({
-      title: '_reportType',
-      key: '_reportType',
-      value: 'r3',
-      keyType: 'normal',
-      isHide: true
-    })
-  } else if (val === 'ETD to ETA (Days)') {
-    // ETD to ETA(DAYS)点击跳转
-    setEstimatedTime(
-      dashboardObj.ETDDefaultData.date_type,
-      [dashboardObj.ETDDefaultData.date_start, dashboardObj.ETDDefaultData.date_end],
-      'Container'
-    )
-    setTransportMode(dashboardObj.ETDDefaultData.transportation)
-    filtersStore.updateFilter({
-      title: 'ETD to ETA (Days)',
-      key: '_reportRef',
-      value: pie_chart_ETD.value[0].paramsdata.name,
-      keyType: 'normal'
-    })
-    filtersStore.updateFilter({
-      title: '_reportType',
-      key: '_reportType',
-      value: 'r1',
-      keyType: 'normal',
-      isHide: true
-    })
-    filtersStore.updateFilter({
-      title: '_reportRefe_date',
-      key: ['_reportRefe_date', '_reportRefb_date'],
-      value: [dayjs().startOf('year').format('MM/YYYY'), dayjs().endOf('year').format('MM/YYYY')],
-      keyType: 'dateRange',
-      isHide: true
-    })
-  } else if (val === 'Top 10 Origin') {
-    // Top10 origin点击跳转
-    setEstimatedTime(dashboardObj.Top10faultData.date_type, [
-      dashboardObj.Top10faultData.date_start,
-      dashboardObj.Top10faultData.date_end
-    ])
-    setTransportMode(dashboardObj.Top10faultData.transportation)
-    filtersStore.updateFilter({
-      title: 'Top 10 Origin',
-      key: '_reportRef',
-      value: seller_chart_top10_origin.value[0].paramsdata,
-      keyType: 'normal'
-    })
-    filtersStore.updateFilter({
-      title: '_reportType',
-      key: '_reportType',
-      value: 'top',
-      keyType: 'normal',
-      isHide: true
-    })
-    filtersStore.updateFilter({
-      title: '_reportStationType',
-      key: '_reportStationType',
-      value: toporiginType.value,
-      keyType: 'normal',
-      isHide: true
-    })
+  // 3. 设置报告引用和类型
+  filtersStore.updateFilter({
+    title: val,
+    key: '_reportRef',
+    value: config.reportRefGetter(),
+    keyType: 'normal'
+  })
+
+  filtersStore.updateFilter({
+    title: '_reportType',
+    key: '_reportType',
+    value: config.reportType,
+    keyType: 'normal',
+    isHide: true
+  })
+  if (val === 'Top 10 Origin') {
     filtersStore.updateFilter({
       title: 'Origin',
       key: 'shipper_city',
-      value: [seller_chart_top10_origin.value[0].paramscityname],
+      value: [seller_chart_top10_origin.value[0]?.paramscityname],
       keyType: 'array'
     })
-  } else if (val === 'Top 10 Destination') {
-    setEstimatedTime(dashboardObj.Top10faultData.date_type, [
-      dashboardObj.Top10faultData.date_start,
-      dashboardObj.Top10faultData.date_end
-    ])
-    setTransportMode(dashboardObj.Top10faultData.transportation)
-    // Top10 destination点击跳转
-    filtersStore.updateFilter({
-      title: 'Top 10 Destination',
-      key: '_reportRef',
-      value: seller_chart_top10_destination.value[0].paramsdata,
-      keyType: 'normal'
-    })
-    filtersStore.updateFilter({
-      title: '_reportType',
-      key: '_reportType',
-      value: 'top',
-      keyType: 'normal',
-      isHide: true
-    })
-    filtersStore.updateFilter({
-      title: '_reportStationType',
-      key: '_reportStationType',
-      value: topdestinationinType.value,
-      keyType: 'normal',
-      isHide: true
-    })
+  }
+  if (val === 'Top 10 Destination') {
     filtersStore.updateFilter({
       title: 'Destination',
       key: 'consignee_city',
-      value: [seller_chart_top10_destination.value[0].paramscityname],
-      keyType: 'array',
-      isHide: true
-    })
-  } else if (val === 'CO2e Emission by Origin (Top 10)') {
-    // CO2e Emission by Origin (Top 10)点击跳转
-    setEstimatedTime(dashboardObj.OriginCo2Top10faultData.date_type, [
-      dashboardObj.OriginCo2Top10faultData.date_start,
-      dashboardObj.OriginCo2Top10faultData.date_end
-    ])
-    setTransportMode(dashboardObj.OriginCo2Top10faultData.transportation)
-    filtersStore.updateFilter({
-      title: 'CO2e Emission by Origin (Top 10)',
-      key: '_reportRef',
-      value: seller_chart_CO2_origin.value[0].paramsdata.name,
-      keyType: 'normal'
-    })
-    filtersStore.updateFilter({
-      title: '_reportDataType',
-      key: '_reportDataType',
-      value: seller_chart_CO2_origin.value[0].paramsdata.type,
-      keyType: 'normal',
-      isHide: true
-    })
-    filtersStore.updateFilter({
-      title: '_reportStationType',
-      key: '_reportStationType',
-      value: 'origin',
-      keyType: 'normal',
-      isHide: true
-    })
-    filtersStore.updateFilter({
-      title: '_reportType',
-      key: '_reportType',
-      value: 'co2e',
-      keyType: 'normal',
-      isHide: true
-    })
-  } else if (val === 'CO2e Emission by Destination (Top 10)') {
-    // CO2e Emission by Origin (Top 10)点击跳转
-    setEstimatedTime(dashboardObj.DestinationCo2Top10faultData.date_type, [
-      dashboardObj.DestinationCo2Top10faultData.date_start,
-      dashboardObj.DestinationCo2Top10faultData.date_end
-    ])
-    setTransportMode(dashboardObj.DestinationCo2Top10faultData.transportation)
-    filtersStore.updateFilter({
-      title: 'CO2e Emission by Destination (Top 10)',
-      key: '_reportRef',
-      value: seller_chart_CO2_destination.value[0].paramsdata.name,
-      keyType: 'normal'
-    })
-    filtersStore.updateFilter({
-      title: '_reportDataType',
-      key: '_reportDataType',
-      value: seller_chart_CO2_destination.value[0].paramsdata.type,
-      keyType: 'normal',
-      isHide: true
-    })
-    filtersStore.updateFilter({
-      title: '_reportType',
-      key: '_reportType',
-      value: 'co2e',
-      keyType: 'normal',
-      isHide: true
+      value: [seller_chart_top10_destination.value[0]?.paramscityname],
+      keyType: 'array'
     })
-    filtersStore.updateFilter({
-      title: '_reportStationType',
-      key: '_reportStationType',
-      value: 'agent',
-      keyType: 'normal',
-      isHide: true
+  }
+
+  // 4. 设置额外过滤器(如有)
+  if (config.extraFilters) {
+    Object.entries(config.extraFilters).forEach(([key, data]) => {
+      filtersStore.updateFilter({
+        title: key,
+        key: key,
+        value: data.value,
+        keyType: data.keyType,
+        isHide: true
+      })
     })
   }
 
-  router.push({
-    path: '/tracking'
-  })
+  // 5. 跳转
+  router.push({ path: '/tracking' })
 }
 
 import { useGuideStore } from '@/stores/modules/guide'
@@ -940,7 +748,6 @@ import saveConfigLight from './guideImage/save-config-guide.png'
 import saveConfigDark from './guideImage/dark-save-config-guide.png'
 import kpiChartLight from './guideImage/kpi-chart-guide.png'
 import kpiChartDark from './guideImage/dark-kpi-chart-guide.png'
-import { set } from 'lodash'
 
 // ====== 2. 主题 store ======
 const themeStore = useThemeStore()
@@ -1023,7 +830,7 @@ const handleGuide = () => {
                 </div>
               </div>
             </div>
-            <el-divider style="margin-top: 0" />
+            <el-divider style="margin-top: 0; margin-bottom: 8px" />
             <div class="tips">
               <span class="iconfont_icon">
                 <svg class="iconfont iconfont_tips" aria-hidden="true">
@@ -1166,7 +973,7 @@ const handleGuide = () => {
                   <div class="kpi">
                     <PieChart
                       ref="pie_chart_kpi_departure"
-                      @ClickParams="ClickParams(item.title + '0')"
+                      @ClickParams="ClickParams(item.title + ' Departure')"
                       :PieData="KPIobj"
                       v-vloading="KPILoading"
                       style="height: 300px"
@@ -1177,7 +984,7 @@ const handleGuide = () => {
                       ref="pie_chart_kpi_arrival"
                       :PieData="Arrivalobj"
                       v-vloading="KPIArrivalLoading"
-                      @ClickParams="ClickParams(item.title + '1')"
+                      @ClickParams="ClickParams(item.title + ' Arrival')"
                       style="height: 300px"
                     ></PieChart>
                   </div>
@@ -1214,14 +1021,14 @@ const handleGuide = () => {
                       ref="pie_chart_pending_departure"
                       :PieData="Pendingobj"
                       v-vloading="PendingLoading"
-                      @ClickParams="ClickParams(item.title + '0')"
+                      @ClickParams="ClickParams(item.title + ' Departure')"
                       style="height: 300px"
                     ></PieChart>
                   </div>
                   <div class="kpi">
                     <PieChart
                       ref="pie_chart_pending_arrival"
-                      @ClickParams="ClickParams(item.title + '1')"
+                      @ClickParams="ClickParams(item.title + ' Arrival')"
                       :PieData="PendingArrivalobj"
                       v-vloading="PendingArrivalLoading"
                       style="height: 300px"
@@ -1483,8 +1290,8 @@ const handleGuide = () => {
                     layout="prev, pager, next"
                     :pager-count="3"
                     :total="pageInfo.total"
-                    @size-change="getTableData(true, RecentDefaulteData)"
-                    @current-change="getTableData(true, RecentDefaulteData)"
+                    @size-change="getTableData(RecentDefaulteData, true)"
+                    @current-change="getTableData(RecentDefaulteData, true)"
                   />
                 </div>
               </template>

+ 3 - 8
src/views/Dashboard/src/components/DashFiters.vue

@@ -44,11 +44,11 @@ watch(
 const isDisabled = ref(false)
 const checkboxGroup1 = ref(['All'])
 const CheckboxGroup2 = ref('ETD')
-const CheckboxGroup3 = ref('invoice Issue Date')
+const CheckboxGroup3 = ref('Invoice Issue Date')
 const filters_visible = ref(false)
 const shipper = ref(['All', 'Air', 'Sea', 'Road', 'Rail'])
 const shipper_two = ref(['ETD', 'ETA'])
-const shipper_three = ref(['invoice Issue Date'])
+const shipper_three = ref(['Invoice Issue Date'])
 const DashDate = ref()
 DashDate.value = []
 const startDate = ref()
@@ -161,16 +161,11 @@ const clearrest = () => {
 }
 // 查询
 const DateRangeSearch = () => {
-  if (props.isRecent) {
-    emit('FilterSearch', false, dashboardObj)
-  } else {
-    emit('FilterSearch', dashboardObj)
-  }
+  emit('FilterSearch', dashboardObj)
   filters_visible.value = false
 }
 
 import { useThemeStore } from '@/stores/modules/theme'
-
 import { useGuideStore } from '@/stores/modules/guide'
 import transportModeLight from '@/views/Dashboard/src/guideImage/transport-mode.png'
 import transportModeDark from '@/views/Dashboard/src/guideImage/dark-transport-mode.png'

+ 1614 - 0
src/views/Dashboard/src/components/test.vue

@@ -0,0 +1,1614 @@
+<script lang="ts" setup>
+import { ref, onMounted, reactive } from 'vue'
+import { VueDraggable } from 'vue-draggable-plus'
+import PieChart from './components/PieChart.vue'
+import SellerChart from './components/SellerChart.vue'
+import BarChart from './components/BarChart.vue'
+import RevenueChart from './components/RevenueChart.vue'
+import RecentStatus from './components/RecentStatus.vue'
+import ScoringSystem from './components/ScoringSystem.vue'
+import TopMap from './components/TopMap.vue'
+import DashFilters from './components/DashFiters.vue'
+import { useRouter } from 'vue-router'
+import { ElMessage } from 'element-plus'
+import { formatNumber } from '@/utils/tools'
+import { useFiltersStore, FiltersType } from '@/stores/modules/filtersList'
+import dayjs from 'dayjs'
+import { useUserStore } from '@/stores/modules/user'
+
+const userStore = useUserStore()
+const formatDate = userStore.dateFormat
+const filtersStore = useFiltersStore()
+
+const router = useRouter()
+const activeName = ref('first')
+const SaveVisible = ref(false)
+// 可拖拽模块的列表
+interface ManagementItem {
+  title: string
+  switchValue: boolean
+  isRevenueDisplay: boolean
+  text: string
+  id: number
+  title1: string
+  title2: string
+}
+const Management = ref<ManagementItem[]>([])
+
+const changeCancel = (id: any) => {
+  Management.value[id - 1].switchValue = false
+}
+
+//RecentStatusList
+const RecentStatusList = ref()
+const pageInfo = ref({ pageNo: 1, pageSize: 10, total: 10000 })
+const isShowtitle1 = ref(true)
+// 点击tab
+const handleTabClick = (tab: any) => {
+  if (tab.props.name == 'first') {
+    isShowtitle1.value = true
+  } else {
+    isShowtitle1.value = false
+  }
+  GetTop10ODEcharts(dashboardObj.Top10faultData)
+}
+const KPIDefaulteData = ref()
+const PendingDefaulteData = ref()
+const RecentDefaulteData = ref()
+const ETDDefaulteData = ref()
+const ContainerefaultData = ref()
+const Top10DefaultData = ref()
+const Co2OriginDefaultData = ref()
+const Co2DestinationDefaultData = ref()
+const RevenueDefaultData = ref()
+// 获取首页数据
+let dashboardObj: any = {}
+const GetDashboardData = () => {
+  $api.getDashboardFilters({}).then((res: any) => {
+    if (res.code == 200) {
+      //给默认筛选条件赋值
+      KPIDefaulteData.value = res.data.KPIDefaulteData
+      dashboardObj.KPIDefaulteData = res.data.KPIDefaulteData
+      PendingDefaulteData.value = res.data.PendingDefaultData
+      dashboardObj.PendingDefaultData = res.data.PendingDefaultData
+      RecentDefaulteData.value = res.data.RecentDefaultData
+      dashboardObj.RecentDefaultData = res.data.RecentDefaultData
+      ETDDefaulteData.value = res.data.ETDDefaultData
+      dashboardObj.ETDDefaultData = res.data.ETDDefaultData
+      ContainerefaultData.value = res.data.ContainerefaultData
+      dashboardObj.ContainerefaultData = res.data.ContainerefaultData
+      Top10DefaultData.value = res.data.Top10faultData
+      dashboardObj.Top10faultData = res.data.Top10faultData
+      Co2OriginDefaultData.value = res.data.OriginCo2Top10faultData
+      dashboardObj.OriginCo2Top10faultData = res.data.OriginCo2Top10faultData
+      Co2DestinationDefaultData.value = res.data.DestinationCo2Top10faultData
+      dashboardObj.DestinationCo2Top10faultData = res.data.DestinationCo2Top10faultData
+      RevenueDefaultData.value = res.data.RevenueDefaultData
+      dashboardObj.RevenueDefaultData = res.data.RevenueDefaultData
+
+      nextTick(() => {
+        GetKpiData(KPIDefaulteData.value)
+        GetPendingEcharts(PendingDefaulteData.value)
+        getTableData(false, RecentDefaulteData.value)
+        GetETDEcharts(ETDDefaulteData.value)
+        GetContainerCountEcharts(ContainerefaultData.value)
+        GetTop10ODEcharts(Top10DefaultData.value)
+        GetCo2EmissionEcharts(Co2OriginDefaultData.value)
+        GetCo2DestinationEcharts(Co2DestinationDefaultData.value)
+        GetRevenueEcharts(RevenueDefaultData.value)
+      })
+    }
+  })
+}
+// 获取表单数据
+const getTableData = (isPage: any, val: any) => {
+  dashboardObj.RecentDefaultData = val
+  const rc = isPage ? pageInfo.value.total : -1
+  $api
+    .GetDashboardData({
+      cp: pageInfo.value.pageNo,
+      ps: pageInfo.value.pageSize,
+      rc,
+      ...val
+    })
+    .then((res: any) => {
+      if (res.code === 200) {
+        pageInfo.value.total = Number(res.data.rc)
+        Management.value = res.data.Management
+        RecentStatusList.value = res.data.searchData
+      }
+    })
+}
+const KPIobj = reactive({
+  ETD_Title: '',
+  ETDList: [],
+  ETD_Radius: [],
+  download_name: ''
+})
+const Arrivalobj = reactive({
+  ETD_Title: '',
+  ETDList: [],
+  ETD_Radius: [],
+  download_name: ''
+})
+const KPILoading = ref(true)
+const KPIArrivalLoading = ref(true)
+//查询KPI
+const GetKpiData = (val: any) => {
+  dashboardObj.KPIDefaulteData = val
+  // 获取KPI Departure图表数据
+  $api
+    .GetKPIEcharts({
+      r_type: 'atd_r4',
+      ...val
+    })
+    .then((res: any) => {
+      if (res.code === 200) {
+        KPIobj.ETD_Title = `{a|${res.data.title1}} {b|${res.data.title2}}`
+        KPIobj.ETDList = res.data.ETDList
+        KPIobj.ETD_Radius = res.data.ETD_Radius
+        KPIobj.download_name = res.data.download_name
+      }
+    })
+    .finally(() => {
+      KPILoading.value = false
+    })
+  // 获取KPI Arrival图表数据
+  $api
+    .GetKPIEcharts({
+      r_type: 'ata_r3',
+      ...val
+    })
+    .then((res: any) => {
+      if (res.code === 200) {
+        Arrivalobj.ETD_Title = `{a|${res.data.title1}} {b|${res.data.title2}}`
+        Arrivalobj.ETDList = res.data.ETDList
+        Arrivalobj.ETD_Radius = res.data.ETD_Radius
+        Arrivalobj.download_name = res.data.download_name
+      }
+    })
+    .finally(() => {
+      KPIArrivalLoading.value = false
+    })
+}
+const Pendingobj = reactive({
+  ETD_Title: '',
+  ETDList: [],
+  ETD_Radius: [],
+  download_name: ''
+})
+const PendingArrivalobj = reactive({
+  ETD_Title: '',
+  ETDList: [],
+  ETD_Radius: [],
+  download_name: ''
+})
+const PendingLoading = ref(true)
+const PendingArrivalLoading = ref(true)
+// 查询Pending
+const GetPendingEcharts = (val: any) => {
+  dashboardObj.PendingDefaultData = val
+  // 获取Pending Departure图表数据
+  $api
+    .GetPendingEcharts({
+      r_type: 'r4',
+      ...val
+    })
+    .then((res: any) => {
+      if (res.code === 200) {
+        Pendingobj.ETD_Title = `{a|${res.data.title1}} {b|${res.data.title2}}`
+        Pendingobj.ETDList = res.data.ETDList
+        Pendingobj.ETD_Radius = res.data.ETD_Radius
+        Pendingobj.download_name = res.data.download_name
+      }
+    })
+    .finally(() => {
+      PendingLoading.value = false
+    })
+  // 获取Pending Arrival图表数据
+  $api
+    .GetPendingEcharts({
+      r_type: 'r3',
+      ...val
+    })
+    .then((res: any) => {
+      if (res.code === 200) {
+        PendingArrivalobj.ETD_Title = `{a|${res.data.title1}} {b|${res.data.title2}}`
+        PendingArrivalobj.ETDList = res.data.ETDList
+        PendingArrivalobj.ETD_Radius = res.data.ETD_Radius
+        PendingArrivalobj.download_name = res.data.download_name
+      }
+    })
+    .finally(() => {
+      PendingArrivalLoading.value = false
+    })
+}
+const ETDobj = reactive({
+  ETD_Title: '',
+  ETDList: [],
+  ETD_Radius: [],
+  download_name: ''
+})
+const ETDLoading = ref(true)
+// 获取ETD/ETA 图表数据
+const GetETDEcharts = (val: any) => {
+  dashboardObj.ETDDefaultData = val
+  $api
+    .GetETDEcharts({
+      ...val
+    })
+    .then((res: any) => {
+      if (res.code === 200) {
+        ETDobj.ETD_Title = `{a|${res.data.ETD_Title}}`
+        ETDobj.ETDList = res.data.ETDList
+        ETDobj.ETD_Radius = res.data.ETD_Radius
+        ETDobj.download_name = res.data.download_name
+      }
+    })
+    .finally(() => {
+      ETDLoading.value = false
+    })
+}
+// 获取ContainerCount
+const containerObj = reactive({
+  bar_title: '',
+  barList: [],
+  barSeries: [],
+  Max: 0,
+  interval: 0,
+  download_name: ''
+})
+const containerLoading = ref(true)
+const GetContainerCountEcharts = (val: any) => {
+  dashboardObj.ContainerefaultData = val
+  $api
+    .GetContainerCountEcharts({
+      ...val
+    })
+    .then((res: any) => {
+      if (res.code === 200) {
+        containerObj.bar_title = res.data.ContainerCount_Title
+        containerObj.barList = res.data.ContainerCountList
+        containerObj.barSeries = res.data.ContainerCounSeries
+        containerObj.Max = res.data.Max
+        containerObj.interval = res.data.interval
+        containerObj.download_name = res.data.download_name
+      }
+    })
+    .finally(() => {
+      containerLoading.value = false
+    })
+}
+const topdestinationinType = ref()
+const toporiginType = ref()
+//获取Top10 Origin/Destination
+const Top10Obj = reactive({
+  OriginData: [],
+  DestinationData: []
+})
+const Top1OInterval = reactive({
+  Max: 0,
+  interval: 0
+})
+const Top1OInterval_dest = reactive({
+  Max: 0,
+  interval: 0
+})
+const TopOriginLoading = ref(true)
+const Top10Originref = ref()
+const Top10Destinationref = ref()
+const GetTop10ODEcharts = (val: any) => {
+  dashboardObj.Top10faultData = val
+  $api
+    .GetTop10ODEcharts({
+      ...val
+    })
+    .then((res: any) => {
+      if (res.code === 200) {
+        // Top10Originref.value[0].updataMapObj(dashboardObj.Top10faultData)
+        if (isShowtitle1.value) {
+          Top10Originref.value[0].updataMapObj(res.data.toporiginMap)
+        } else {
+          Top10Destinationref.value[0].updataMapObj(res.data.topdestinationinMap)
+        }
+        Top10Obj.DestinationData = res.data.seller_data_list_destination
+        Top10Obj.OriginData = res.data.seller_data_list_origin
+        Top1OInterval.Max = res.data.Max
+        Top1OInterval.interval = res.data.interval
+        Top1OInterval_dest.Max = res.data.dest_Max
+        Top1OInterval_dest.interval = res.data.dest_interval
+        topdestinationinType.value = res.data.topdestinationinType
+        toporiginType.value = res.data.toporiginType
+      }
+    })
+    .finally(() => {
+      TopOriginLoading.value = false
+    })
+}
+//获取CO2 Origin
+const EmissionLoading = ref(true)
+const EmissionObj = reactive({
+  bar_title: '',
+  barList: [],
+  barSeries: [],
+  Max: 0,
+  interval: 0,
+  download_name: ''
+})
+const GetCo2EmissionEcharts = (val: any) => {
+  dashboardObj.OriginCo2Top10faultData = val
+  $api
+    .GetCo2EmissionEcharts({
+      ...val
+    })
+    .then((res: any) => {
+      if (res.code === 200) {
+        EmissionObj.bar_title = res.data.ContainerCount_Title
+        EmissionObj.barList = res.data.ContainerCountList
+        EmissionObj.barSeries = res.data.ContainerCounSeries
+        EmissionObj.Max = res.data.Max
+        EmissionObj.interval = res.data.interval
+        EmissionObj.download_name = res.data.download_name
+      }
+    })
+    .finally(() => {
+      EmissionLoading.value = false
+    })
+}
+//获取CO2 Destination
+const DestinationObj = reactive({
+  bar_title: '',
+  barList: [],
+  barSeries: [],
+  Max: 0,
+  interval: 0,
+  download_name: ''
+})
+const DestinationLoading = ref(true)
+const GetCo2DestinationEcharts = (val: any) => {
+  dashboardObj.DestinationCo2Top10faultData = val
+  $api
+    .GetCo2DestinationEcharts({
+      ...val
+    })
+    .then((res: any) => {
+      if (res.code === 200) {
+        DestinationObj.bar_title = res.data.ContainerCount_Title
+        DestinationObj.barList = res.data.ContainerCountList
+        DestinationObj.barSeries = res.data.ContainerCounSeries
+        DestinationObj.Max = res.data.Max
+        DestinationObj.interval = res.data.interval
+        DestinationObj.download_name = res.data.download_name
+      }
+    })
+    .finally(() => {
+      DestinationLoading.value = false
+    })
+}
+//获取Revenue Spent
+
+const RevenueObj = reactive({
+  bar_title: '',
+  barList: [],
+  barSeries: [],
+  Max: 0,
+  interval: 0,
+  download_name: '',
+  isShowTooltips: true
+})
+const RevenueLoading = ref(true)
+const revenue_date_start = ref()
+const revenue_date_end = ref()
+const GetRevenueEcharts = (val: any) => {
+  revenue_date_start.value = val.date_start
+  revenue_date_end.value = val.date_end
+  dashboardObj.RevenueDefaultData = val
+  $api
+    .GetRevenueEcharts({
+      ...val
+    })
+    .then((res: any) => {
+      if (res.code === 200) {
+        RevenueObj.bar_title = res.data.bar_title
+        RevenueObj.barList = res.data.barList
+        RevenueObj.barSeries = res.data.barSeries
+        RevenueObj.Max = res.data.Max
+        RevenueObj.interval = res.data.interval
+        RevenueObj.download_name = res.data.download_name
+      }
+    })
+    .finally(() => {
+      RevenueLoading.value = false
+    })
+}
+onMounted(() => {
+  GetDashboardData()
+})
+
+// Save Layout
+const SaveLayout = () => {
+  SaveVisible.value = false
+  Management.value.forEach((item: any, index: any) => {
+    item.id = index + 1
+  })
+  $api
+    .SaveLayout({
+      management: Management.value
+    })
+    .then((res: any) => {
+      if (res.code == 200) {
+        ElMessage({
+          message: res.data.msg,
+          duration: 3000,
+          type: 'success'
+        })
+      }
+    })
+}
+//Save Filters
+const SaveFilters = () => {
+  SaveVisible.value = false
+  Management.value.forEach((item: any, index: any) => {
+    item.id = index + 1
+  })
+  $api
+    .SaveLayout({
+      management: Management.value,
+      dashboardObj
+    })
+    .then((res: any) => {
+      if (res.code == 200) {
+        ElMessage({
+          message: res.data.msg,
+          duration: 3000,
+          type: 'success'
+        })
+      }
+    })
+}
+//ETD to ETA(DAYS)点击跳转
+const pie_chart_ETD = ref()
+const pie_chart_pending_arrival = ref()
+const pie_chart_pending_departure = ref()
+const pie_chart_kpi_departure = ref()
+const pie_chart_kpi_arrival = ref()
+const seller_chart_top10_origin = ref()
+const seller_chart_top10_destination = ref()
+const seller_chart_CO2_origin = ref()
+const seller_chart_CO2_destination = ref()
+
+const ClickParams = (val: any) => {
+  const setEstimatedTime = (
+    type: 'ETD' | 'ETA',
+    value: string[],
+    formatType?: 'Container' | 'Revenue'
+  ) => {
+    const parseFormat = formatType === 'Container' ? 'MM/YYYY' : 'MM/DD/YYYY'
+
+    // 处理单个日期字符串的转换函数
+    const transformDate = (dateStr: string): string => {
+      let parsed = dayjs(dateStr, parseFormat, true) // 使用 strict 模式更安全
+
+      // 如果是 Container 格式(MM/YYYY),强制日期为 1 号
+      if (formatType === 'Container') {
+        parsed = parsed.date(1) // 设置为当月 1 日
+      }
+
+      return parsed.format(formatDate)
+    }
+    const config =
+      type === 'ETD'
+        ? {
+            title: 'ETD',
+            key: ['etd_start', 'etd_end']
+          }
+        : {
+            title: 'ETA',
+            key: ['eta_start', 'eta_end']
+          }
+    filtersStore.updateFilter({
+      ...config,
+      value: [transformDate(value[0]), transformDate(value[1])],
+      keyType: 'dateRange'
+    })
+  }
+
+  const setTransportMode = (value: any) => {
+    filtersStore.updateFilter({
+      title: 'Transport Mode',
+      key: 'transport_mode',
+      value: value,
+      keyType: 'array'
+    })
+  }
+
+  // KPI Departure点击跳转
+  if (val === 'KPI0') {
+    setEstimatedTime(dashboardObj.KPIDefaulteData.date_type, [
+      dashboardObj.KPIDefaulteData.date_start,
+      dashboardObj.KPIDefaulteData.date_end
+    ])
+    setTransportMode(dashboardObj.KPIDefaulteData.transportation)
+    // KPI Departure点击跳转
+    filtersStore.updateFilter({
+      title: 'KPI Departure',
+      key: '_reportRef',
+      value: pie_chart_kpi_departure.value[0].paramsdata.name,
+      keyType: 'normal'
+    })
+    filtersStore.updateFilter({
+      title: '_reportType',
+      key: '_reportType',
+      value: 'atd_r4',
+      keyType: 'normal',
+      isHide: true
+    })
+  } else if (val === 'KPI1') {
+    setEstimatedTime(dashboardObj.KPIDefaulteData.date_type, [
+      dashboardObj.KPIDefaulteData.date_start,
+      dashboardObj.KPIDefaulteData.date_end
+    ])
+    setTransportMode(dashboardObj.KPIDefaulteData.transportation)
+    // KPI Arrival点击跳转
+    filtersStore.updateFilter({
+      title: 'KPI Arrival',
+      key: '_reportRef',
+      value: pie_chart_kpi_arrival.value[0]?.paramsdata?.name || '',
+      keyType: 'normal'
+    })
+    filtersStore.updateFilter({
+      title: '_reportType',
+      key: '_reportType',
+      value: 'ata_r3',
+      keyType: 'normal',
+      isHide: true
+    })
+  } else if (val === 'Pending0') {
+    setTransportMode(dashboardObj.PendingDefaultData.transportation)
+    // PendingDeparture点击跳转
+    filtersStore.updateFilter({
+      title: 'Pending Departure',
+      key: '_reportRef',
+      value: pie_chart_pending_departure.value[0].paramsdata.name,
+      keyType: 'normal'
+    })
+    filtersStore.updateFilter({
+      title: '_reportType',
+      key: '_reportType',
+      value: 'r4',
+      keyType: 'normal',
+      isHide: true
+    })
+  } else if (val === 'Pending1') {
+    setTransportMode(dashboardObj.PendingDefaultData.transportation)
+    //  PendingArrival点击跳转
+    filtersStore.updateFilter({
+      title: 'Pending Arrival',
+      key: '_reportRef',
+      value: pie_chart_pending_arrival.value[0].paramsdata.name,
+      keyType: 'normal'
+    })
+    filtersStore.updateFilter({
+      title: '_reportType',
+      key: '_reportType',
+      value: 'r3',
+      keyType: 'normal',
+      isHide: true
+    })
+  } else if (val === 'ETD to ETA (Days)') {
+    // ETD to ETA(DAYS)点击跳转
+    setEstimatedTime(
+      dashboardObj.ETDDefaultData.date_type,
+      [dashboardObj.ETDDefaultData.date_start, dashboardObj.ETDDefaultData.date_end],
+      'Container'
+    )
+    setTransportMode(dashboardObj.ETDDefaultData.transportation)
+    filtersStore.updateFilter({
+      title: 'ETD to ETA (Days)',
+      key: '_reportRef',
+      value: pie_chart_ETD.value[0].paramsdata.name,
+      keyType: 'normal'
+    })
+    filtersStore.updateFilter({
+      title: '_reportType',
+      key: '_reportType',
+      value: 'r1',
+      keyType: 'normal',
+      isHide: true
+    })
+    filtersStore.updateFilter({
+      title: '_reportRefe_date',
+      key: ['_reportRefe_date', '_reportRefb_date'],
+      value: [dayjs().startOf('year').format('MM/YYYY'), dayjs().endOf('year').format('MM/YYYY')],
+      keyType: 'dateRange',
+      isHide: true
+    })
+  } else if (val === 'Top 10 Origin') {
+    // Top10 origin点击跳转
+    setEstimatedTime(dashboardObj.Top10faultData.date_type, [
+      dashboardObj.Top10faultData.date_start,
+      dashboardObj.Top10faultData.date_end
+    ])
+    setTransportMode(dashboardObj.Top10faultData.transportation)
+    filtersStore.updateFilter({
+      title: 'Top 10 Origin',
+      key: '_reportRef',
+      value: seller_chart_top10_origin.value[0].paramsdata,
+      keyType: 'normal'
+    })
+    filtersStore.updateFilter({
+      title: '_reportType',
+      key: '_reportType',
+      value: 'top',
+      keyType: 'normal',
+      isHide: true
+    })
+    filtersStore.updateFilter({
+      title: '_reportStationType',
+      key: '_reportStationType',
+      value: toporiginType.value,
+      keyType: 'normal',
+      isHide: true
+    })
+    filtersStore.updateFilter({
+      title: 'Origin',
+      key: 'shipper_city',
+      value: [seller_chart_top10_origin.value[0].paramscityname],
+      keyType: 'array'
+    })
+  } else if (val === 'Top 10 Destination') {
+    setEstimatedTime(dashboardObj.Top10faultData.date_type, [
+      dashboardObj.Top10faultData.date_start,
+      dashboardObj.Top10faultData.date_end
+    ])
+    setTransportMode(dashboardObj.Top10faultData.transportation)
+    // Top10 destination点击跳转
+    filtersStore.updateFilter({
+      title: 'Top 10 Destination',
+      key: '_reportRef',
+      value: seller_chart_top10_destination.value[0].paramsdata,
+      keyType: 'normal'
+    })
+    filtersStore.updateFilter({
+      title: '_reportType',
+      key: '_reportType',
+      value: 'top',
+      keyType: 'normal',
+      isHide: true
+    })
+    filtersStore.updateFilter({
+      title: '_reportStationType',
+      key: '_reportStationType',
+      value: topdestinationinType.value,
+      keyType: 'normal',
+      isHide: true
+    })
+    filtersStore.updateFilter({
+      title: 'Destination',
+      key: 'consignee_city',
+      value: [seller_chart_top10_destination.value[0].paramscityname],
+      keyType: 'array'
+    })
+  } else if (val === 'CO2e Emission by Origin (Top 10)') {
+    // CO2e Emission by Origin (Top 10)点击跳转
+    setEstimatedTime(dashboardObj.OriginCo2Top10faultData.date_type, [
+      dashboardObj.OriginCo2Top10faultData.date_start,
+      dashboardObj.OriginCo2Top10faultData.date_end
+    ])
+    setTransportMode(dashboardObj.OriginCo2Top10faultData.transportation)
+    filtersStore.updateFilter({
+      title: 'CO2e Emission by Origin (Top 10)',
+      key: '_reportRef',
+      value: seller_chart_CO2_origin.value[0].paramsdata.name,
+      keyType: 'normal'
+    })
+    filtersStore.updateFilter({
+      title: '_reportDataType',
+      key: '_reportDataType',
+      value: seller_chart_CO2_origin.value[0].paramsdata.type,
+      keyType: 'normal',
+      isHide: true
+    })
+    filtersStore.updateFilter({
+      title: '_reportStationType',
+      key: '_reportStationType',
+      value: 'origin',
+      keyType: 'normal',
+      isHide: true
+    })
+    filtersStore.updateFilter({
+      title: '_reportType',
+      key: '_reportType',
+      value: 'co2e',
+      keyType: 'normal',
+      isHide: true
+    })
+  } else if (val === 'CO2e Emission by Destination (Top 10)') {
+    // CO2e Emission by Origin (Top 10)点击跳转
+    setEstimatedTime(dashboardObj.DestinationCo2Top10faultData.date_type, [
+      dashboardObj.DestinationCo2Top10faultData.date_start,
+      dashboardObj.DestinationCo2Top10faultData.date_end
+    ])
+    setTransportMode(dashboardObj.DestinationCo2Top10faultData.transportation)
+    filtersStore.updateFilter({
+      title: 'CO2e Emission by Destination (Top 10)',
+      key: '_reportRef',
+      value: seller_chart_CO2_destination.value[0].paramsdata.name,
+      keyType: 'normal'
+    })
+    filtersStore.updateFilter({
+      title: '_reportDataType',
+      key: '_reportDataType',
+      value: seller_chart_CO2_destination.value[0].paramsdata.type,
+      keyType: 'normal',
+      isHide: true
+    })
+    filtersStore.updateFilter({
+      title: '_reportType',
+      key: '_reportType',
+      value: 'co2e',
+      keyType: 'normal',
+      isHide: true
+    })
+    filtersStore.updateFilter({
+      title: '_reportStationType',
+      key: '_reportStationType',
+      value: 'agent',
+      keyType: 'normal',
+      isHide: true
+    })
+  }
+
+  router.push({
+    path: '/tracking'
+  })
+}
+
+import { useGuideStore } from '@/stores/modules/guide'
+import { useThemeStore } from '@/stores/modules/theme'
+
+import kpiChartTipLight from './tipsImage/kpi-chart-tip.png'
+import kpiChartTipDark from './tipsImage/dark-kpi-chart-tip.png'
+import pendingChartTipLight from './tipsImage/pending-chart-tip.png'
+import pendingChartTipDark from './tipsImage/dark-pending-chart-tip.png'
+import etdToEtaChartsTipLight from './tipsImage/etd-to-eta-chart-tip.png'
+import etdToEtaChartsTipDark from './tipsImage/dark-etd-to-eta-chart-tip.png'
+import containerChartTipLight from './tipsImage/container-count-chart-tip.png'
+import containerChartTipDark from './tipsImage/dark-container-count-chart-tip.png'
+import top10ChartTipLight from './tipsImage/top-10-chart-tip.png'
+import top10ChartTipDark from './tipsImage/dark-top-10-chart-tip.png'
+import co2eChartTipLight from './tipsImage/co2e-chart-tip.png'
+import co2eChartTipDark from './tipsImage/dark-co2e-chart-tip.png'
+import revenueSpentChartTipLight from './tipsImage/revenue-spent-chart-tip.png'
+import revenueSpentChartTipDark from './tipsImage/dark-revenue-spent-chart-tip.png'
+import recentStatusChartTipLight from './tipsImage/recent-status-chart-tip.png'
+import recentStatusChartTipDark from './tipsImage/dark-recent-status-chart-tip.png'
+
+// Guide 图片
+import viewManagementLight from './guideImage/view-management.png'
+import viewManagementDark from './guideImage/dark-view-management.png'
+import saveConfigLight from './guideImage/save-config-guide.png'
+import saveConfigDark from './guideImage/dark-save-config-guide.png'
+import kpiChartLight from './guideImage/kpi-chart-guide.png'
+import kpiChartDark from './guideImage/dark-kpi-chart-guide.png'
+import { set } from 'lodash'
+
+// ====== 2. 主题 store ======
+const themeStore = useThemeStore()
+const guideStore = useGuideStore()
+
+// ====== 3. 工具函数:根据主题返回对应图片 ======
+const getThemeImage = (light: string, dark: string) => {
+  return computed(() => (themeStore.theme === 'dark' ? dark : light))
+}
+
+// ====== 4. 自动生成 computed 图片引用 ======
+// Tips 图片
+const kpiChartTip = getThemeImage(kpiChartTipLight, kpiChartTipDark)
+const pendingChartTip = getThemeImage(pendingChartTipLight, pendingChartTipDark)
+const etdToEtaChartsTip = getThemeImage(etdToEtaChartsTipLight, etdToEtaChartsTipDark)
+const containerChartTip = getThemeImage(containerChartTipLight, containerChartTipDark)
+const top10ChartTip = getThemeImage(top10ChartTipLight, top10ChartTipDark)
+const co2eChartTip = getThemeImage(co2eChartTipLight, co2eChartTipDark)
+const revenueSpentChartTip = getThemeImage(revenueSpentChartTipLight, revenueSpentChartTipDark)
+const recentStatusChartTip = getThemeImage(recentStatusChartTipLight, recentStatusChartTipDark)
+
+// Guide 图片
+const viewManagementImg = getThemeImage(viewManagementLight, viewManagementDark)
+const saveConfigImg = getThemeImage(saveConfigLight, saveConfigDark)
+const kpiChartImg = getThemeImage(kpiChartLight, kpiChartDark)
+
+// ====== 5. 其他逻辑 ======
+const dashboardGuideRef = ref(null)
+const handleGuide = () => {
+  dashboardGuideRef.value?.startGuide()
+}
+</script>
+<template>
+  <div class="dashboard">
+    <!-- 评分 -->
+    <ScoringSystem></ScoringSystem>
+    <DashboardGuide ref="dashboardGuideRef"></DashboardGuide>
+    <!-- Title -->
+    <div class="Title">
+      <div>
+        <span>Dashboard</span>
+        <VDriverGuide style="margin-top: -1px" @click="handleGuide"></VDriverGuide>
+      </div>
+
+      <div style="position: relative">
+        <el-popover trigger="click" width="400" popper-style="border-radius: 12px">
+          <template #reference>
+            <el-button class="el-button--default">
+              <span class="iconfont_icon">
+                <svg class="iconfont" aria-hidden="true">
+                  <use xlink:href="#icon-icon_view__management_b"></use>
+                </svg>
+              </span>
+              View Management
+            </el-button>
+          </template>
+
+          <div class="Management">
+            <div class="title">View Management</div>
+            <div class="management-content">
+              <div class="management-item" v-for="(item, index) in Management" :key="index">
+                <div class="management_flex">
+                  <div class="content_title">{{ item.title }}</div>
+                  <div>
+                    <el-switch
+                      v-model="item.switchValue"
+                      :disabled="
+                        item.isRevenueDisplay != undefined && item.isRevenueDisplay == false
+                      "
+                    />
+                  </div>
+                </div>
+                <div class="content_text">{{ item.text }}</div>
+                <div
+                  class="content_text_warining"
+                  v-if="item.isRevenueDisplay != undefined && item.isRevenueDisplay == false"
+                >
+                  *To ensure the accuracy of the data display, this report needs to be configured
+                  and displayed after communicating clearly with Sales.
+                </div>
+              </div>
+            </div>
+            <el-divider style="margin-top: 0; margin-bottom: 8px" />
+            <div class="tips">
+              <span class="iconfont_icon">
+                <svg class="iconfont iconfont_tips" aria-hidden="true">
+                  <use xlink:href="#icon-icon_info_b"></use>
+                </svg>
+              </span>
+              <div class="tips_text">
+                Please remember to click the save button in order to keep the new dashboard layout
+                and widgets.
+              </div>
+            </div>
+          </div>
+        </el-popover>
+
+        <img
+          id="view-management-guide"
+          v-if="guideStore.dashboard.isShowViewManagementGuidePhoto"
+          class="view-management-guide-class"
+          :class="{
+            'view-management-guide-dark-class': themeStore.theme === 'dark'
+          }"
+          :src="viewManagementImg"
+          alt=""
+        />
+        <el-popover
+          :visible="SaveVisible"
+          :popper-style="{
+            display: 'flex',
+            flexDirection: 'column',
+            alignItems: 'center',
+            padding: '8px 4px',
+            borderRadius: '12px',
+            width: '142px',
+            minWidth: '140px',
+            backgroundColor: 'var(--management-bg-color)'
+          }"
+        >
+          <template #reference>
+            <el-button
+              class="el-button--default"
+              @blur="SaveVisible = false"
+              @click="SaveVisible = !SaveVisible"
+            >
+              <span class="iconfont_icon">
+                <svg class="iconfont" aria-hidden="true">
+                  <use xlink:href="#icon-icon_save_b"></use>
+                </svg>
+              </span>
+              Save
+              <span class="iconfont_icon">
+                <svg class="iconfont" aria-hidden="true">
+                  <use xlink:href="#icon-icon_dropdown_b"></use>
+                </svg>
+              </span>
+            </el-button>
+          </template>
+          <div class="Save_filters" @click="SaveFilters">
+            <span class="iconfont_icon iconfont_icon_save">
+              <svg class="iconfont" aria-hidden="true">
+                <use xlink:href="#icon-icon_save_b"></use>
+              </svg>
+            </span>
+            <div>Save Filters</div>
+          </div>
+          <div class="Save_filters" @click="SaveLayout">
+            <span class="iconfont_icon iconfont_icon_save">
+              <svg class="iconfont" aria-hidden="true">
+                <use xlink:href="#icon-icon_save_b"></use>
+              </svg>
+            </span>
+            <div>Save Layout</div>
+          </div>
+        </el-popover>
+
+        <!--  -->
+        <img
+          id="save-config-guide"
+          v-if="guideStore.dashboard.isShowSaveConfigGuidePhoto"
+          class="save-config-guide-class position-absolute-guide"
+          :src="saveConfigImg"
+          :class="{
+            'save-config-guide-dark-class': themeStore.theme === 'dark'
+          }"
+          alt=""
+        />
+      </div>
+    </div>
+    <!-- 图表 -->
+    <div class="echarts">
+      <VueDraggable
+        style="
+          display: flex;
+          flex-wrap: wrap;
+          justify-content: space-between;
+          gap: 8px;
+          width: 100%;
+        "
+        ref="infoContentRef"
+        ghost-class="ghost-class"
+        :forceFallback="true"
+        fallback-class="fallback-class"
+        v-model="Management"
+        handle=".handle-draggable"
+      >
+        <template v-for="item in Management" :key="item">
+          <div v-if="item.title === 'KPI' && item.switchValue" class="filters_left">
+            <!-- KPI -->
+            <VBox_Dashboard
+              style="overflow: visible"
+              @changeCancel="changeCancel(item.id)"
+              :isShowDragIconGudie="true"
+            >
+              <template #header>
+                <div class="Title_flex" style="position: relative">
+                  <img
+                    id="kpi-chart-guide"
+                    v-if="guideStore.dashboard.isShowKpiChartGuidePhoto"
+                    class="kpi-chart-guide-class position-absolute-guide"
+                    :src="kpiChartImg"
+                    alt=""
+                  />
+                  <div>
+                    {{ item.title }}
+                    <VTipTooltip
+                      :img="kpiChartTip"
+                      :width="410"
+                      :label="'KPI Report:Day difference between actual and estimate.'"
+                      placement="bottom-start"
+                    ></VTipTooltip>
+                  </div>
+                  <DashFilters
+                    :defaultData="KPIDefaulteData"
+                    :isShowTransportModeGuide="true"
+                    @FilterSearch="GetKpiData"
+                  ></DashFilters>
+                </div>
+              </template>
+              <template #content>
+                <div class="KPI_Pending">
+                  <div class="kpi">
+                    <PieChart
+                      ref="pie_chart_kpi_departure"
+                      @ClickParams="ClickParams(item.title + '0')"
+                      :PieData="KPIobj"
+                      v-vloading="KPILoading"
+                      style="height: 300px"
+                    ></PieChart>
+                  </div>
+                  <div class="kpi">
+                    <PieChart
+                      ref="pie_chart_kpi_arrival"
+                      :PieData="Arrivalobj"
+                      v-vloading="KPIArrivalLoading"
+                      @ClickParams="ClickParams(item.title + '1')"
+                      style="height: 300px"
+                    ></PieChart>
+                  </div>
+                </div>
+              </template>
+            </VBox_Dashboard>
+          </div>
+          <div v-else-if="item.title === 'Pending' && item.switchValue" class="filters_left">
+            <!-- Pending -->
+            <VBox_Dashboard @changeCancel="changeCancel(item.id)">
+              <template #header>
+                <div class="Title_flex">
+                  <div>
+                    {{ item.title }}
+                    <VTipTooltip
+                      :img="pendingChartTip"
+                      :width="420"
+                      :placement="'bottom-start'"
+                      :label="'Pending Report:Showing shipments which are soon to depart/arrive.'"
+                    ></VTipTooltip>
+                  </div>
+                  <DashFilters
+                    :defaultData="PendingDefaulteData"
+                    :radioisDisabled="true"
+                    :img="'./image/kpi-chart-tip.png'"
+                    @FilterSearch="GetPendingEcharts"
+                  ></DashFilters>
+                </div>
+              </template>
+              <template #content>
+                <div class="KPI_Pending">
+                  <div class="kpi">
+                    <PieChart
+                      ref="pie_chart_pending_departure"
+                      :PieData="Pendingobj"
+                      v-vloading="PendingLoading"
+                      @ClickParams="ClickParams(item.title + '0')"
+                      style="height: 300px"
+                    ></PieChart>
+                  </div>
+                  <div class="kpi">
+                    <PieChart
+                      ref="pie_chart_pending_arrival"
+                      @ClickParams="ClickParams(item.title + '1')"
+                      :PieData="PendingArrivalobj"
+                      v-vloading="PendingArrivalLoading"
+                      style="height: 300px"
+                    ></PieChart>
+                  </div>
+                </div>
+              </template>
+            </VBox_Dashboard>
+          </div>
+          <!-- ETD to ETA -->
+          <div
+            v-else-if="item.title === 'ETD to ETA (Days)' && item.switchValue"
+            class="filters_left"
+          >
+            <VBox_Dashboard @changeCancel="changeCancel(item.id)">
+              <template #header>
+                <div class="Title_flex">
+                  <div>
+                    {{ item.title }}
+                    <VTipTooltip
+                      :img="etdToEtaChartsTip"
+                      :width="430"
+                      :placement="'bottom-start'"
+                      :label="'ETD to ETA (Days):Distribution of Transit Time (ETA-ETD) for All Shipments in Last 12 Months.'"
+                    ></VTipTooltip>
+                  </div>
+                  <DashFilters
+                    :defaultData="ETDDefaulteData"
+                    @FilterSearch="GetETDEcharts"
+                    :isETDToETA="true"
+                    :isContainer="true"
+                  ></DashFilters>
+                </div>
+              </template>
+              <template #content>
+                <PieChart
+                  ref="pie_chart_ETD"
+                  @ClickParams="ClickParams(item.title)"
+                  :PieData="ETDobj"
+                  v-vloading="ETDLoading"
+                  style="height: 300px"
+                ></PieChart>
+              </template>
+            </VBox_Dashboard>
+          </div>
+          <!-- Container Count -->
+          <div
+            v-else-if="item.title === 'Container Count' && item.switchValue"
+            class="filters_left"
+          >
+            <VBox_Dashboard @changeCancel="changeCancel(item.id)">
+              <template #header>
+                <div class="Title_flex">
+                  <div>
+                    {{ item.title }}
+                    <VTipTooltip
+                      :img="containerChartTip"
+                      :placement="'bottom-start'"
+                      :label="'Container Count:Total Container Volume by Month (Last 12 Months)'"
+                    ></VTipTooltip>
+                  </div>
+                  <DashFilters
+                    :defaultData="ContainerefaultData"
+                    @FilterSearch="GetContainerCountEcharts"
+                    :isContainer="true"
+                  ></DashFilters>
+                </div>
+              </template>
+              <template #content>
+                <BarChart
+                  ref="seller_chart_Container_count"
+                  :BarData="containerObj"
+                  v-vloading="containerLoading"
+                  style="height: 300px"
+                  :isRevenue="true"
+                  save-image-name="Container Count"
+                  :barHeight="{ height: '300px' }"
+                ></BarChart>
+              </template>
+            </VBox_Dashboard>
+          </div>
+          <!-- Top10 Origin/Top 10 Destination -->
+          <div
+            v-else-if="item.title === 'Top 10 Origin/Destination' && item.switchValue"
+            class="KPI_Pending"
+          >
+            <VBox_Dashboard @changeCancel="changeCancel(item.id)" style="width: 100%">
+              <template #header>
+                <div class="Title_flex" style="height: 48px">
+                  <div style="display: flex">
+                    <el-tabs
+                      v-model="activeName"
+                      class="demo-tabs"
+                      style="height: 48px"
+                      @tab-click="handleTabClick"
+                    >
+                      <el-tab-pane :label="item.title1" name="first"></el-tab-pane>
+                      <el-tab-pane :label="item.title2" name="second"></el-tab-pane>
+                    </el-tabs>
+                    <VTipTooltip
+                      style="margin-left: 4px"
+                      :img="top10ChartTip"
+                      :label="'Top 10 Origin & Destination: Last 12 Months Shipment Volume Rankings: Top 10 Origin Cities and Top 10 Destination Cities'"
+                      :width="700"
+                    ></VTipTooltip>
+                  </div>
+                  <DashFilters
+                    :defaultData="Top10DefaultData"
+                    @FilterSearch="GetTop10ODEcharts"
+                  ></DashFilters>
+                </div>
+              </template>
+              <template v-if="isShowtitle1" #content>
+                <div class="KPI_Pending">
+                  <div class="seller_chart">
+                    <SellerChart
+                      ref="seller_chart_top10_origin"
+                      @clickParams="ClickParams(item.title1)"
+                      :SellerData="Top10Obj.OriginData"
+                      v-vloading="TopOriginLoading"
+                      :Interval="Top1OInterval"
+                      saveImageName="Top 10 Origin"
+                    ></SellerChart>
+                  </div>
+                  <div class="map">
+                    <!-- <TopMap :obj="dashboardObj.Top10faultData" ref="Top10Originref"></TopMap> -->
+                    <TopMap ref="Top10Originref"></TopMap>
+                  </div>
+                </div>
+              </template>
+              <template v-else #content2>
+                <div class="KPI_Pending">
+                  <div class="seller_chart">
+                    <SellerChart
+                      ref="seller_chart_top10_destination"
+                      @clickParams="ClickParams(item.title2)"
+                      :SellerData="Top10Obj.DestinationData"
+                      :Interval="Top1OInterval_dest"
+                      v-vloading="TopOriginLoading"
+                      saveImageName="Top 10 Destination"
+                      style="height: 310px"
+                    ></SellerChart>
+                  </div>
+                  <div class="map" style="height: 310px">
+                    <!-- <TopMap :obj="dashboardObj.Top10faultData" ref="Top10Destinationref"></TopMap> -->
+                    <TopMap ref="Top10Destinationref"></TopMap>
+                  </div>
+                </div>
+              </template>
+            </VBox_Dashboard>
+          </div>
+          <!-- CO2e Emission by Origin (Top 10) -->
+          <div
+            v-else-if="item.title === 'CO2e Emission by Origin (Top 10)' && item.switchValue"
+            class="filters_left"
+          >
+            <VBox_Dashboard @changeCancel="changeCancel(item.id)">
+              <template #header>
+                <div class="Title_flex">
+                  <div>
+                    {{ item.title }}
+                    <VTipTooltip
+                      :img="co2eChartTip"
+                      :label="'CO2e Emission by Origin or Destination: Last 12 Months CO2e Emission Rankings: Top 10 Origin Cities and Top 10 Destination Cities'"
+                      :width="700"
+                      :placement="'bottom-start'"
+                    ></VTipTooltip>
+                  </div>
+                  <DashFilters
+                    :defaultData="Co2OriginDefaultData"
+                    @FilterSearch="GetCo2EmissionEcharts"
+                  ></DashFilters>
+                </div>
+              </template>
+              <template #content>
+                <BarChart
+                  ref="seller_chart_CO2_origin"
+                  :BarData="EmissionObj"
+                  save-image-name="CO2e Emission by Origin (Top 10)"
+                  @clickParams="ClickParams(item.title)"
+                  v-vloading="EmissionLoading"
+                  style="height: 250px"
+                  :isRevenue="true"
+                  :barHeight="{ height: '250px' }"
+                ></BarChart>
+              </template>
+            </VBox_Dashboard>
+          </div>
+          <!-- CO2e Emission by Destination (Top 10) -->
+          <div
+            v-else-if="item.title === 'CO2e Emission by Destination (Top 10)' && item.switchValue"
+            class="filters_left"
+          >
+            <VBox_Dashboard @changeCancel="changeCancel(item.id)">
+              <template #header>
+                <div class="Title_flex">
+                  <div>
+                    {{ item.title }}
+                    <!-- <VTipTooltip :img="co2eChartTip"></VTipTooltip> -->
+                  </div>
+                  <DashFilters
+                    :defaultData="Co2DestinationDefaultData"
+                    @FilterSearch="GetCo2DestinationEcharts"
+                  ></DashFilters>
+                </div>
+              </template>
+              <template #content>
+                <BarChart
+                  ref="seller_chart_CO2_destination"
+                  :BarData="DestinationObj"
+                  v-vloading="DestinationLoading"
+                  style="height: 250px"
+                  :isRevenue="true"
+                  save-image-name="CO2e Emission by Destination (Top 10)"
+                  @clickParams="ClickParams(item.title)"
+                  :barHeight="{ height: '250px' }"
+                ></BarChart>
+              </template>
+            </VBox_Dashboard>
+          </div>
+          <!-- <div
+            v-else-if="item.title === 'Revenue' && item.switchValue"
+            class="KPI_Pending"
+          > -->
+          <div
+            v-else-if="
+              item.title === 'Recent Status' && item.switchValue && RecentStatusList.length != 0
+            "
+            class="KPI_Pending"
+          >
+            <!-- Recent Status -->
+            <VBox_Dashboard @changeCancel="changeCancel(item.id)" style="width: 100%">
+              <template #header>
+                <div class="Title_flex">
+                  <div>
+                    {{ item.title }}
+                    <VTipTooltip
+                      :img="recentStatusChartTip"
+                      :label="'Recent Status: Active shipment list with ETD within the past three months and the next month.'"
+                      :width="700"
+                      :placement="'bottom-start'"
+                    ></VTipTooltip>
+                  </div>
+                  <DashFilters
+                    :defaultData="RecentDefaulteData"
+                    @FilterSearch="getTableData"
+                    :isRecent="true"
+                  ></DashFilters>
+                </div>
+              </template>
+              <template #content>
+                <RecentStatus :RecentStatusList="RecentStatusList"></RecentStatus>
+                <div class="pagination">
+                  <span>Total {{ formatNumber(pageInfo.total) }}</span>
+                  <el-pagination
+                    v-model:current-page="pageInfo.pageNo"
+                    v-model:page-size="pageInfo.pageSize"
+                    :page-sizes="[10, 50, 100, 200]"
+                    layout="prev, pager, next"
+                    :pager-count="3"
+                    :total="pageInfo.total"
+                    @size-change="getTableData(true, RecentDefaulteData)"
+                    @current-change="getTableData(true, RecentDefaulteData)"
+                  />
+                </div>
+              </template>
+            </VBox_Dashboard>
+          </div>
+          <!-- Revenue -->
+          <div v-else-if="item.title === 'Revenue Spent' && item.switchValue" class="KPI_Pending">
+            <VBox_Dashboard @changeCancel="changeCancel(item.id)" style="width: 100%">
+              <template #header>
+                <div class="Title_flex">
+                  <div>
+                    Revenue Spent
+                    <VTipTooltip
+                      :img="revenueSpentChartTip"
+                      :label="'Revenue Spent: Based on the billto object, display the corresponding revenue data. '"
+                      :placement="'bottom-start'"
+                      :width="700"
+                    ></VTipTooltip>
+                  </div>
+
+                  <DashFilters
+                    :defaultData="RevenueDefaultData"
+                    @FilterSearch="GetRevenueEcharts"
+                    :isRevenue="true"
+                    :isContainer="true"
+                  ></DashFilters>
+                </div>
+              </template>
+              <template #content>
+                <RevenueChart
+                  :BarData="RevenueObj"
+                  v-vloading="RevenueLoading"
+                  :RevenueStartDate="revenue_date_start"
+                  :RevenueEndDate="revenue_date_end"
+                  style="height: 300px"
+                  :barHeight="{ height: '300px' }"
+                ></RevenueChart>
+              </template>
+            </VBox_Dashboard>
+          </div>
+        </template>
+      </VueDraggable>
+    </div>
+  </div>
+</template>
+<style lang="scss" scoped>
+.Title {
+  display: flex;
+  background-color: var(--color-mode);
+  height: 68px;
+  font-size: var(--font-size-6);
+  font-weight: 700;
+  padding: 0 24px;
+  align-items: center;
+  justify-content: space-between;
+}
+.iconfont {
+  vertical-align: -2px;
+}
+
+.view-management-guide-class {
+  position: absolute;
+  top: 0px;
+  right: 85px;
+  width: 437px;
+  height: 603px;
+  z-index: 1500;
+  &.view-management-guide-dark-class {
+    width: 439px;
+    height: 622px;
+  }
+}
+.save-config-guide-class {
+  position: absolute;
+  top: -1px;
+  right: -13px;
+  width: 183px;
+  height: 160px;
+  z-index: 1500;
+  transform: translate(-0.8px, 0px);
+  &.save-config-guide-dark-class {
+    width: 182px;
+    height: 157px;
+    right: -12px;
+  }
+}
+.kpi-chart-guide-class {
+  top: -2px;
+  left: -50px;
+  width: 589px;
+  height: 478px;
+  z-index: 3500;
+}
+
+.Management {
+  max-height: 640px;
+  overflow: hidden;
+  border-radius: 12px;
+  background-color: var(--management-bg-color);
+}
+
+.management-content {
+  overflow-y: auto;
+  max-height: 533px;
+}
+.title {
+  font-weight: 700;
+  font-size: var(--font-size-5);
+  background-color: var(--color-header-bg);
+  height: 48px;
+  display: flex;
+  align-items: center;
+  padding-left: 16px;
+}
+.management-item {
+  width: 368px;
+  min-height: 54px;
+  margin: 10px auto;
+  background-color: var(--color-header-bg);
+  border-radius: var(--border-radius-6);
+  padding: 8px 16px;
+}
+.management_flex {
+  display: flex;
+  height: 20px;
+  justify-content: space-between;
+  align-items: center;
+}
+.content_title {
+  font-weight: 700;
+  font-size: var(--font-size-3);
+}
+.content_text {
+  color: var(--color-neutral-2);
+  font-size: var(--font-size-2);
+  line-height: 16px;
+}
+.content_text_warining {
+  color: var(--color-warning);
+  font-size: var(--font-size-2);
+  line-height: 16px;
+}
+.tips {
+  display: flex;
+  justify-content: center;
+  padding-bottom: 8px;
+}
+.iconfont_tips {
+  fill: var(--color-neutral-2);
+}
+.tips_text {
+  width: 278.43px;
+  text-align: center;
+  font-size: var(--font-size-2);
+  color: var(--color-neutral-2);
+}
+
+.Save_filters {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  height: 40px;
+  font-size: var(--font-size-3);
+  width: 126px;
+  border-radius: 6px;
+  cursor: pointer;
+}
+.iconfont_icon_save {
+  margin-right: 16px;
+  fill: var(--color-neutral-1);
+}
+.Save_filters:hover {
+  border-color: var(--color-btn-default-bg-hover);
+  background-color: var(--color-btn-default-bg-hover);
+  .iconfont_icon_save {
+    fill: var(--color-theme);
+  }
+  div {
+    color: var(--color-theme);
+  }
+}
+.filters {
+  display: flex;
+  padding: 0 24px;
+  height: 32px;
+  align-items: center;
+  margin-bottom: 8px;
+  justify-content: space-between;
+}
+.KPI_Pending {
+  display: flex;
+  width: 100%;
+}
+.filters_left {
+  border-radius: var(--border-radius-6);
+  width: calc(50% - 4px);
+  flex: 0 0 calc(50% - 4px);
+  min-width: 0;
+  box-sizing: border-box;
+}
+
+:deep(.ETD_title) {
+  margin-bottom: 0 !important;
+}
+:deep(:where(.css-dev-only-do-not-override-19iuou).ant-picker-range) {
+  height: 32px;
+}
+.echarts {
+  padding: 0 22px;
+  background-color: var(--color-mode);
+  :deep(> div) {
+    display: flex;
+    flex-wrap: wrap;
+    justify-content: space-between;
+    gap: 8px;
+    width: 100%;
+    > * {
+      box-sizing: border-box;
+    }
+  }
+}
+.kpi {
+  width: 50%;
+  border-right: 1px solid var(--color-border);
+}
+.kpi:last-child {
+  border-right: none;
+}
+.ghost-class {
+  opacity: 0;
+}
+.fallback-class {
+  opacity: 1 !important;
+  background-color: var(--color-v-box-content-drag-bg);
+  cursor: move !important;
+  box-shadow: 4px 4px 32px 0px rgba(0, 0, 0, 0.2);
+  border-radius: 12px;
+}
+.pagination {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  border-top: 1px solid var(--color-border);
+  padding: 4px 8px;
+}
+
+.seller_chart {
+  width: 30%;
+  border-right: 1px solid var(--color-border);
+}
+.map {
+  width: 70%;
+}
+.Title_flex {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  margin-right: 30px;
+}
+
+.dashboard {
+  z-index: 2014;
+  position: relative;
+  background-color: var(--color-mode);
+  padding-bottom: 40px;
+}
+:deep(.el-tabs__header) {
+  height: 48px;
+  margin-bottom: 0;
+}
+</style>
+<style lang="scss">
+:not(body):has(> img.driver-active-element) {
+  overflow: visible !important;
+}
+</style>