Эх сурвалжийг харах

feat: 重构Booking筛选项

Jack Zhou 2 сар өмнө
parent
commit
b83d51dabf

+ 1 - 1
src/components/DateRange/index.ts

@@ -1 +1 @@
-export { default } from './src/DateRange.vue'
+export { default } from './src/DateRange.new.vue'

+ 329 - 0
src/components/DateRange/src/DateRange.new.vue

@@ -0,0 +1,329 @@
+<script setup lang="ts">
+import { ref, watch, onMounted, onBeforeMount } from 'vue'
+import IconDropDown from '@/components/IconDropDown'
+import VCalendarDate from './components/VCalendarDate.vue'
+import { useFiltersList } from '@/stores/modules/filtersList'
+
+const filtersStore = useFiltersList()
+const filtersList = computed(() => filtersStore.filtersList)
+
+const popoverVisible = ref(false)
+const allOtherType = ref([
+  {
+    title: 'Creation Time',
+    key: ['created_time_start', 'created_time_end']
+  }
+])
+const otherDateType = ref([])
+
+const getRangeDate = (title: string) => {
+  const data = filtersStore.getFilterByTitle(title)
+  if (data) {
+    const [startStr, endStr] = data.value
+    return [startStr, endStr]
+  } else {
+    return ['', '']
+  }
+}
+const initDate = () => {
+  etdDateRange.value = getRangeDate('ETD')
+  etaDateRange.value = getRangeDate('ETA')
+
+  otherDateType.value = []
+  filtersList.value.forEach((item) => {
+    const curIndex = allOtherType.value.findIndex((type) => type.title === item.title)
+    if (curIndex !== -1) {
+      otherDateType.value.push({
+        title: item.title,
+        value: getRangeDate(item.title)
+      })
+    }
+  })
+}
+
+const addType = () => {
+  otherDateType.value.push({
+    label: '',
+    value: ['', '']
+  })
+}
+const deleteType = (i: any) => {
+  otherDateType.value.splice(i, 1)
+}
+const props = defineProps({
+  isShipment: Boolean
+})
+const etdDateRange = ref([])
+const etaDateRange = ref([])
+
+const emit = defineEmits(['DateRangeSearch', 'clearDaterangeTags'])
+const hasValidDate = (date: any) => {
+  return date && date.length === 2 && date[0] && date[1]
+}
+const DateRangeSearch = () => {
+  hasValidDate(etaDateRange.value) &&
+    filtersStore.pushFilter({
+      title: 'ETA',
+      keyType: 'dateRange',
+      value: etaDateRange.value,
+      key: ['f_eta_start', 'f_eta_end']
+    })
+  hasValidDate(etdDateRange.value) &&
+    filtersStore.pushFilter({
+      title: 'ETD',
+      keyType: 'dateRange',
+      value: etdDateRange.value,
+      key: ['f_etd_start', 'f_etd_end']
+    })
+  allOtherType.value.forEach((item) => {
+    const curIndex = otherDateType.value.findIndex((type) => type.title === item.title)
+    if (curIndex !== -1 && hasValidDate(otherDateType[curIndex].value)) {
+      filtersStore.pushFilter({
+        title: item.title,
+        keyType: 'dateRange',
+        value: otherDateType[curIndex].value,
+        key: item.key
+      })
+    } else {
+      console.log('deltet', item.title)
+      filtersStore.deleteFilterByTitle(item.title)
+    }
+  })
+  emit('DateRangeSearch')
+  popoverVisible.value = false
+}
+
+// 清除
+const clearRest = () => {
+  filtersStore.deleteFilterByTitle('ETA')
+  filtersStore.deleteFilterByTitle('ETD')
+  allOtherType.value.forEach((item) => {
+    filtersStore.deleteFilterByTitle(item.title)
+  })
+  emit('clearDaterangeTags')
+}
+
+const closeRset = () => {
+  etdDateRange.value = []
+  etaDateRange.value = []
+  otherDateType.value = []
+}
+</script>
+<template>
+  <div class="select">
+    <el-popover
+      trigger="click"
+      :width="400"
+      :visible="popoverVisible"
+      popper-class="DaterangeClass"
+      @before-enter="initDate()"
+      @close="closeRset"
+    >
+      <template #reference>
+        <div
+          class="Date_Range"
+          @blur="popoverVisible = false"
+          @click="popoverVisible = !popoverVisible"
+        >
+          <div class="select_title">Date Range</div>
+          <span class="iconfont_icon">
+            <svg class="iconfont icon_dark" aria-hidden="true">
+              <use xlink:href="#icon-icon_dropdown_b"></use>
+            </svg>
+          </span>
+        </div>
+      </template>
+      <div class="date_header">
+        <div class="title">Date Range</div>
+        <div class="ETD">
+          <VCalendarDate CalendarTitle="ETD" v-model:date="etdDateRange"></VCalendarDate>
+        </div>
+        <div class="ETA">
+          <VCalendarDate CalendarTitle="ETA" v-model:date="etaDateRange"></VCalendarDate>
+        </div>
+        <div class="addType" v-for="(item, index) in otherDateType" :key="item.title">
+          <div>
+            <div class="ETD_title Date_Title">
+              <div class="Date_type">Date Type</div>
+              <span class="iconfont_icon" @click="deleteType(index)">
+                <svg class="iconfont icon_delete" aria-hidden="true">
+                  <use xlink:href="#icon-icon_delete_b"></use>
+                </svg>
+              </span>
+            </div>
+            <el-select
+              :suffix-icon="IconDropDown"
+              placeholder="Please Select Date Type"
+              v-model="item.title"
+            >
+              <el-option
+                v-for="ite in allOtherType"
+                :key="ite.title"
+                :label="ite.title"
+                :value="ite.title"
+              >
+              </el-option>
+            </el-select>
+          </div>
+          <div style="margin-top: 16px">
+            <VCalendarDate
+              :CalendarTitle="item.label || 'Date Range'"
+              CalendarWidth="352px"
+              v-model:date="item.value"
+              :isType="true"
+            ></VCalendarDate>
+          </div>
+        </div>
+        <div class="MoreType" @click="addType" v-if="otherDateType.length != allOtherType.length">
+          <el-button class="el-button--noborder moretype">+ More Date Type</el-button>
+        </div>
+        <div class="daterange_bottom">
+          <div><el-button type="default" @click="clearRest" class="Clear">Reset</el-button></div>
+          <div>
+            <el-button class="search el-button--dark" @click="DateRangeSearch">Search</el-button>
+          </div>
+        </div>
+      </div>
+    </el-popover>
+  </div>
+</template>
+<style lang="scss" scoped>
+.iconfont_icon {
+  margin-right: 8px;
+}
+.icon_delete {
+  fill: var(--color-danger);
+}
+.select {
+  width: 186px;
+  margin-left: 8px;
+  cursor: pointer;
+  display: flex;
+  align-items: center;
+  border: 1px solid var(--color-select-border);
+  border-radius: var(--border-radius-6);
+}
+.Date_Range {
+  width: 186px;
+  display: flex;
+  position: relative;
+  align-items: center;
+  justify-content: space-between;
+}
+.select_title {
+  font-size: var(--font-size-3);
+  font-weight: 400;
+  margin-left: 8.53px;
+  color: var(--color-neutral-1);
+}
+.select_icon {
+  width: 16px;
+  margin-right: 10.5px;
+}
+.select:hover {
+  border: 1px solid var(--color-theme);
+}
+.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;
+  border-radius: 12px 12px 0 0;
+}
+.ETD {
+  margin: 8px 16px;
+}
+.ETA {
+  margin: 16px 16px;
+}
+.ETD_title {
+  font-size: var(--font-size-2);
+  margin-bottom: 4px;
+  color: var(--color-neutral-2);
+}
+.Date_Title {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+}
+:deep(.el-dialog__header) {
+  display: none;
+}
+:deep(div.el-dialog) {
+  width: 400px;
+  padding: 0;
+  margin-top: 202px;
+  border: 1px solid var(--color-border);
+}
+:deep(div.el-dialog__body) {
+  padding: 0;
+}
+.MoreType {
+  color: var(--color-accent-2);
+  padding: 0 0 16px 16px;
+}
+:deep(.el-select__wrapper) {
+  border-radius: var(--border-radius-6);
+  height: 40px;
+}
+.addType {
+  background-color: var(--color-header-bg);
+  margin: 0 16px 8px 16px;
+  padding: 8px;
+  border-radius: var(--border-radius-6);
+}
+.daterange_bottom {
+  display: flex;
+  justify-content: flex-end;
+  align-items: center;
+  height: 48px;
+  border-top: 1px solid var(--border-color-2);
+  margin-top: 5px;
+  font-weight: 400;
+  font-size: var(--font-size-3);
+}
+.Clear {
+  width: 81px;
+  height: 32px;
+  margin-right: 7.82px;
+}
+.search {
+  width: 86px;
+  height: 32px;
+  margin-right: 16px;
+}
+:deep(.el-date-editor .el-range__icon) {
+  position: absolute;
+  right: 16px;
+}
+@media only screen and (min-width: 1280px) {
+  .Date_Range,
+  .select {
+    width: 224px;
+  }
+}
+@media only screen and (min-width: 1440px) {
+  .Date_Range,
+  .select {
+    width: 336px;
+  }
+}
+.moretype {
+  background-color: transparent;
+  padding: 0 4px;
+  height: 24px;
+}
+.icon_dark {
+  fill: var(--color-neutral-1);
+}
+.date_header {
+  background-color: var(--management-bg-color);
+  border-radius: 12px;
+}
+.Date_type {
+  color: var(--color-neutral-2);
+}
+</style>

+ 8 - 29
src/components/DateRange/src/DateRange.vue

@@ -10,32 +10,7 @@ const userStore = useUserStore()
 const formatDate = userStore.dateFormat
 const valueFormatDate = 'MM/DD/YYYY'
 
-onMounted(() => {
-  const emitPayload = defaultDate()
-  // 统一 emit(只调用一次)
-  emit('defaultDate', daterangeObj2, emitPayload)
-  emitter.on('clearTag', (tag: any) => {
-    if (tag.includes('ETD')) {
-      clearETdDateRange()
-    }
-    if (tag.includes('ETA')) {
-      clearEtaDateRange()
-    }
-    if (tag.includes('Creation Time')) {
-      clearEtaDateRange()
-    }
-  })
-  emitter.on('clearDaterangeObj', () => {
-    clearDaterangeObj()
-  })
-})
-
-onBeforeMount(() => {
-  emitter.off('clearTag')
-  emitter.off('clearDaterangeObj')
-})
-
-const Date_visible = ref(false)
+const popoverVisible = ref(false)
 const DateType = ref()
 const DateTypeoptions = ref([
   {
@@ -218,7 +193,7 @@ const DateRangeChange = (val: any) => {
 const emit = defineEmits(['DateRangeSearch', 'clearDaterangeTags', 'defaultDate'])
 const DateRangeSearch = () => {
   emit('DateRangeSearch', daterangeObj2)
-  Date_visible.value = false
+  popoverVisible.value = false
 }
 
 // 清除
@@ -256,13 +231,17 @@ const clearDaterangeObj = () => {
     <el-popover
       trigger="click"
       :width="400"
-      :visible="Date_visible"
+      :visible="popoverVisible"
       popper-class="DaterangeClass"
       @before-enter="defaultDate()"
       @hide="clearDateCreation()"
     >
       <template #reference>
-        <div class="Date_Range" @blur="Date_visible = false" @click="Date_visible = !Date_visible">
+        <div
+          class="Date_Range"
+          @blur="popoverVisible = false"
+          @click="popoverVisible = !popoverVisible"
+        >
           <div class="select_title">Date Range</div>
           <span class="iconfont_icon">
             <svg class="iconfont icon_dark" aria-hidden="true">

+ 1 - 0
src/components/DateRange/src/components/CalendarDate.vue

@@ -72,6 +72,7 @@ const daterange = (val: any) => {
       title: props.CalendarTitle,
       data: DateList.value
     }
+    console.log(rangedata, 'value')
     emit('DateRangeChange', rangedata)
   }
 }

+ 200 - 0
src/components/DateRange/src/components/VCalendarDate.vue

@@ -0,0 +1,200 @@
+<script lang="ts" setup>
+import dayjs, { Dayjs } from 'dayjs'
+import { ref, watch } from 'vue'
+import { useUserStore } from '@/stores/modules/user'
+
+const userStore = useUserStore()
+const formatDate = userStore.dateFormat
+const valueFormatDate = 'MM/DD/YYYY'
+// type RangeValue = [Dayjs, Dayjs]
+// const ETDDate = ref<RangeValue>()
+const props = defineProps({
+  CalendarWidth: {
+    type: String,
+    default: '368px'
+  },
+  CalendarTitle: {
+    type: String
+  },
+  date: {
+    type: Array
+  },
+  isType: {
+    type: Boolean,
+    default: false
+  },
+  isNeedFooter: {
+    type: Boolean,
+    default: true
+  },
+  isETA: {
+    type: Boolean,
+    default: false
+  },
+  isShowPopupClass: {
+    type: Boolean,
+    default: false
+  }
+})
+const ETDDate = ref([])
+const CreatePlaceholder = computed(() => {
+  if (props.isETA) {
+    return ['Start ETA Time', 'End ETA Time']
+  } else {
+    return ['Start ATA Time', 'End ATA Time']
+  }
+})
+// watch(
+//   () => props.date,
+//   (current: any) => {
+//     if (current?.length == 2) {
+//       ETDDate.value = [
+//         current[0] ? dayjs(current[0], formatDate).format(valueFormatDate) : '',
+//         current[1] ? dayjs(current[1], formatDate).format(valueFormatDate) : ''
+//       ]
+//     } else {
+//       ETDDate.value = []
+//     }
+//   },
+//   { immediate: true, deep: true }
+// )
+
+const emit = defineEmits(['DateRangeChange', 'DateChange', 'update:date'])
+const open = ref(false)
+const isShowExtra = ref(true)
+
+const DateList = ref()
+DateList.value = []
+const daterange = (val: any) => {
+  if (DateList.value.length == 2 && val != undefined) {
+    const rangedata = {
+      title: props.CalendarTitle,
+      data: DateList.value
+    }
+    console.log(rangedata, 'value')
+    emit('DateRangeChange', rangedata)
+  }
+  console.log(props.date, '日期')
+  emit('update:date', props.date)
+}
+const ChangeToday = (val: any) => {
+  if (val == 'Earliest') {
+    DateList.value[0] = dayjs().format(valueFormatDate)
+    daterange(DateList.value[1])
+  } else {
+    DateList.value[1] = dayjs().format(valueFormatDate)
+    daterange(DateList.value[0])
+  }
+}
+
+const Earliest = () => {
+  DateList.value[0] = dayjs('Oct-05-2009').format(valueFormatDate)
+  daterange(DateList.value[1])
+}
+const Latest = () => {
+  DateList.value[1] = dayjs().format(valueFormatDate)
+  daterange(DateList.value[0])
+}
+const changeRangeData = (value: any) => {
+  console.log(value, 'value')
+  // DateList.value = value
+  // if (value != '') {
+  //   const rangedata = {
+  //     title: props.CalendarTitle,
+  //     data: value
+  //   }
+  //   emit('DateRangeChange', rangedata)
+  //   emit('DateChange', value)
+  // }
+  emit('update:date', value)
+}
+const handleCalendarOpen = (date: any) => {
+  open.value = !open.value
+  if (open.value == false) {
+    if (date.length != 2) {
+      DateList.value = []
+      ETDDate.value = []
+    }
+  }
+}
+</script>
+<template>
+  <div>
+    <div class="ETD_title" v-if="props.CalendarTitle">{{ props.CalendarTitle }}</div>
+    <a-range-picker
+      separator="To"
+      :showToday="false"
+      :style="{
+        width: props.CalendarWidth,
+        backgroundColor: props.isType ? 'var(--more-type-bg-color)' : 'var(--management-bg-color)'
+      }"
+      :popupClassName="props.isShowPopupClass ? 'th-color' : ''"
+      :open="open"
+      @change="changeRangeData"
+      :placeholder="isNeedFooter ? ['Start Time', 'End Time'] : CreatePlaceholder"
+      :format="userStore.dateFormat"
+      @openChange="handleCalendarOpen(ETDDate)"
+      :valueFormat="userStore.dateFormat"
+      :value="props.date"
+    >
+      <template #suffixIcon>
+        <span class="iconfont_icon">
+          <svg class="iconfont icon_suffix" aria-hidden="true">
+            <use xlink:href="#icon-icon_date_b"></use>
+          </svg>
+        </span>
+      </template>
+      <template #renderExtraFooter v-if="isShowExtra && isNeedFooter">
+        <div class="calender_flex">
+          <div class="footer_left">
+            <el-button class="el-button--noborder" @click="Earliest">Earliest Time</el-button>
+            <el-button class="el-button--noborder" @click="ChangeToday('Earliest')"
+              >Today</el-button
+            >
+          </div>
+          <div class="footer_left footer_right">
+            <el-button @click="Latest" class="el-button--noborder">Latest Time</el-button>
+            <el-button class="el-button--noborder" @click="ChangeToday('Latest')">Today</el-button>
+          </div>
+        </div>
+      </template>
+    </a-range-picker>
+  </div>
+</template>
+
+<style lang="scss" scoped>
+.calender_flex {
+  display: flex;
+  justify-content: space-between;
+}
+.footer_left {
+  display: flex;
+  flex: 50%;
+  padding: 0 0 0 5px;
+  height: 48px;
+  display: flex;
+  align-items: center;
+}
+.footer_right {
+  border-left: 1px solid var(--border-color-2);
+  padding-left: 8px;
+}
+.el-button--noborder {
+  color: var(--color-theme);
+}
+.ETD_title {
+  font-size: var(--font-size-2);
+  margin-bottom: 4px;
+  color: var(--color-neutral-2);
+}
+.iconfont_icon {
+  margin-right: 0;
+}
+.iconfont {
+  width: 14px;
+  height: 14px;
+}
+.icon_suffix {
+  fill: var(--color-neutral-1);
+}
+</style>

+ 50 - 65
src/components/FliterTags/src/FilterTags.vue

@@ -1,6 +1,6 @@
 <script setup lang="ts">
-import { ref, onMounted, onBeforeMount, watch, computed } from 'vue'
-import emitter from '@/utils/bus'
+import { cloneDeep } from 'lodash'
+
 interface ListItem {
   name: string
   number: number
@@ -8,73 +8,58 @@ interface ListItem {
   checked: boolean
 }
 interface Props {
-  TagsListItem: ListItem[]
+  tagsList: ListItem[]
 }
 const props = withDefaults(defineProps<Props>(), {})
 
-const TagsList = ref(props.TagsListItem)
-const NewTagsList = ref()
-
-watch(
-  () => props.TagsListItem,
-  (current) => {
-    TagsList.value = current
-  }
-)
-onMounted(() => {
-  emitter.on('clearTag', (tag: any) => {
-    if (tag.includes('Shipment status')) {
-      checkedCount = []
-      // TagsList.value.forEach((item: any) => {
-      //   item.checked = false
-      // })
-      // TagsList.value[0].checked = true
-      NewTagsList.value = ['All']
-      emits('changeTag', NewTagsList.value, false)
-    }
-  })
-})
+const emits = defineEmits(['tabChange'])
 
-onBeforeMount(() => {
-  emitter.off('clearTag')
-})
-
-NewTagsList.value = []
-
-let checkedCount: any[] = []
-const emits = defineEmits(['changeTag'])
-const checkedBox = (i: any, name: any, checked: any) => {
-  if (name == 'All') {
-    checkedCount = []
-    TagsList.value.forEach((item: any) => {
-      item.checked = false
-    })
-    TagsList.value[0].checked = true
-  } else if (!checked) {
-    TagsList.value[0].checked = false
-    TagsList.value[i].checked = !TagsList.value[i].checked
-    checkedCount.push(name)
-    const map = new Map()
-    checkedCount.forEach((item) => map.set(item, true))
-    checkedCount = [...map.keys()]
+const getCheckedTabs = (tagsList: ListItem[]) => {
+  const checkedList = tagsList.filter((item) => item.checked)
+  return checkedList.map((item) => item.name)
+}
+// 判断是否除了all,其他的全选了
+const isAllExceptAllSelected = (tagsList: ListItem[]) => {
+  const curCheckedTags = getCheckedTabs(tagsList)
+  if (curCheckedTags.length === tagsList.length - 1 && !curCheckedTags.includes('All')) {
+    return true
   } else {
-    checkedCount.splice(checkedCount.indexOf(name), 1)
-    TagsList.value[0].checked = false
-    TagsList.value[i].checked = !TagsList.value[i].checked
+    return false
   }
-  if (checkedCount.length === TagsList.value.length - 1 || checkedCount.length == 0) {
-    checkedCount = []
-    TagsList.value.forEach((item: any) => {
-      item.checked = false
+}
+//  点击标签 如果除了all
+const handleTagToggle = (index: any, checked: any) => {
+  // 如果点击的是all,并且当前选中也是all,那么直接返回
+  if (index === 0 && checked) return
+
+  const curTagList = cloneDeep(props.tagsList)
+  if (index !== 0) {
+    const curTag = curTagList[index]
+    const curCheckedTags = getCheckedTabs(curTagList)
+    // 如果只选中了一个标签,并且这个标签不是all,那么改为选中all,取消选中当前选项
+    if (curCheckedTags.includes(curTag.name) && curCheckedTags.length === 1) {
+      curTagList[index].checked = false
+      curTagList[0].checked = true
+      emits('tabChange', curTagList)
+      return
+    }
+    curTagList[index].checked = !checked
+    const isCheckedAll = isAllExceptAllSelected(curTagList)
+    if (isCheckedAll) {
+      curTagList[0].checked = true
+      curTagList.forEach((item, index) => {
+        index !== 0 && (item.checked = false)
+      })
+    } else {
+      curTagList[0].checked = false
+    }
+  } else if (index === 0 && !checked) {
+    curTagList[0].checked = true
+    curTagList.forEach((item, index) => {
+      index !== 0 && (item.checked = false)
     })
-    TagsList.value[0].checked = true
-  }
-  if (checkedCount.length == 0) {
-    NewTagsList.value = ['All']
-  } else {
-    NewTagsList.value = checkedCount
   }
-  emits('changeTag', NewTagsList.value, true)
+  emits('tabChange', curTagList)
 }
 </script>
 
@@ -83,10 +68,10 @@ const checkedBox = (i: any, name: any, checked: any) => {
     <div class="TagsBox">
       <div
         class="list"
-        v-for="(item, index) of TagsList"
-        :key="index"
+        v-for="(item, index) of props.tagsList"
+        :key="item.name"
         :class="[item.checked ? 'checked' : '']"
-        @click="checkedBox(index, item.name, item.checked)"
+        @click="handleTagToggle(index, item.checked)"
       >
         {{ item.name }}
         <div
@@ -179,4 +164,4 @@ const checkedBox = (i: any, name: any, checked: any) => {
   background-color: var(--color-tag-all-bg);
   color: var(--color-tag-all);
 }
-</style>
+</style>

+ 1 - 1
src/components/MoreFilters/index.ts

@@ -1 +1 @@
-export { default } from './src/MoreFilters.vue'
+export { default } from './src/MoreFilters.new.vue'

+ 1404 - 0
src/components/MoreFilters/src/MoreFilters.new.vue

@@ -0,0 +1,1404 @@
+<script setup lang="ts">
+import emitter from '@/utils/bus'
+import AutoSelect from '@/components/AutoSelect'
+import SelectAutoSelect from '@/components/SelectAutoSelect'
+import SelectTableSelect from '@/components/SelectTableSelect'
+import { ref, onMounted, onBeforeMount, computed, watch } from 'vue'
+import SelectTable from '@/components/SelectTable/src/SelectTable.vue'
+
+onMounted(() => {
+  if (
+    sessionStorage.getItem('reportList') != null &&
+    sessionStorage.getItem('reportList') != '{}'
+  ) {
+    const reportlist = JSON.parse(sessionStorage.getItem('reportList') as string) || {}
+    const data = JSON.parse(sessionStorage.getItem('tagsList') as string) || {}
+    if (
+      reportlist._city_name != '' &&
+      (reportlist._reportStationType == 'shippr_uncode' ||
+        reportlist._reportStationType == 'consignee_uncode')
+    ) {
+      if (data.title.includes('Origin')) {
+        InputForm.value.palces.Origin.push(reportlist._city_name)
+        MoreFiltersObj.Origin = reportlist._city_name
+        MoreFiltersObj2.Origin = InputForm.value.palces.Origin
+      } else {
+        InputForm.value.palces.Destination.push(reportlist._city_name)
+        MoreFiltersObj.Destination = reportlist._city_name
+        MoreFiltersObj2.Destination = InputForm.value.palces.Destination
+      }
+    }
+  }
+  defaultMorefilters()
+  emitter.on('clearTag', (tag: any) => {
+    if (tag.includes('Shippername')) {
+      clearname(InputForm.value, 'parties', 'Shippername')
+    } else if (tag.includes('Consigneename')) {
+      clearname(InputForm.value, 'parties', 'Consigneename')
+    } else if (tag.includes('Incoterms')) {
+      clearname(InputForm.value, 'General', 'Incoterms')
+    } else if (tag.includes('Service')) {
+      clearname(InputForm.value, 'General', 'Service')
+    } else if (tag.includes('Origin Agent')) {
+      AddDateType.value = AddDateType.value.filter((item: any) => item.partyType !== 'Origin Agent')
+      delete MoreFiltersObj['Origin Agent']
+      selectedPartyTypeoptions.value = selectedPartyTypeoptions.value.filter(
+        (item: any) => item !== 'Origin Agent'
+      )
+    } else if (tag.includes('Destination Agent')) {
+      AddDateType.value = AddDateType.value.filter(
+        (item: any) => item.partyType !== 'Destination Agent'
+      )
+      delete MoreFiltersObj['Destination Agent']
+      selectedPartyTypeoptions.value = selectedPartyTypeoptions.value.filter(
+        (item: any) => item !== 'Destination Agent'
+      )
+    } else if (tag.includes('Notify Party')) {
+      AddDateType.value = AddDateType.value.filter((item: any) => item.partyType !== 'Notify Party')
+      delete MoreFiltersObj['Notify Party']
+      selectedPartyTypeoptions.value = selectedPartyTypeoptions.value.filter(
+        (item: any) => item !== 'Notify Party'
+      )
+    } else if (tag.includes('Bill to')) {
+      AddDateType.value = AddDateType.value.filter((item: any) => item.partyType !== 'Bill to')
+      delete MoreFiltersObj['Bill to']
+      selectedPartyTypeoptions.value = selectedPartyTypeoptions.value.filter(
+        (item: any) => item !== 'Bill to'
+      )
+    } else if (tag.includes('Destination Operator')) {
+      AddDateType.value = AddDateType.value.filter(
+        (item: any) => item.partyType !== 'Destination Operator'
+      )
+      delete MoreFiltersObj['Destination Operator']
+      selectedPartyTypeoptions.value = selectedPartyTypeoptions.value.filter(
+        (item: any) => item !== 'Destination Operator'
+      )
+    } else if (tag.includes('Sales')) {
+      AddDateType.value = AddDateType.value.filter((item: any) => item.partyType !== 'Sales')
+      delete MoreFiltersObj['Sales']
+      selectedPartyTypeoptions.value = selectedPartyTypeoptions.value.filter(
+        (item: any) => item !== 'Sales'
+      )
+    } else if (tag.includes('Place of Receipt')) {
+      AddDatePlaceType.value = AddDatePlaceType.value.filter(
+        (item: any) => item.placesType !== 'Place of Receipt'
+      )
+      delete MoreFiltersObj['Place of Receipt']
+      selectedPlacesTypeoptions.value = selectedPlacesTypeoptions.value.filter(
+        (item: any) => item !== 'Place of Receipt'
+      )
+    } else if (tag.includes('Port of Loading')) {
+      AddDatePlaceType.value = AddDatePlaceType.value.filter(
+        (item: any) => item.placesType !== 'Port of Loading'
+      )
+      delete MoreFiltersObj['Port of Loading']
+      selectedPlacesTypeoptions.value = selectedPlacesTypeoptions.value.filter(
+        (item: any) => item !== 'Port of Loading'
+      )
+    } else if (tag.includes('Place of delivery')) {
+      AddDatePlaceType.value = AddDatePlaceType.value.filter(
+        (item: any) => item.placesType !== 'Place of delivery'
+      )
+      delete MoreFiltersObj['Place of delivery']
+      selectedPlacesTypeoptions.value = selectedPlacesTypeoptions.value.filter(
+        (item: any) => item !== 'Place of delivery'
+      )
+    } else if (tag.includes('Place of Discharge')) {
+      AddDatePlaceType.value = AddDatePlaceType.value.filter(
+        (item: any) => item.placesType !== 'Place of Discharge'
+      )
+      delete MoreFiltersObj['Place of Discharge']
+      selectedPlacesTypeoptions.value = selectedPlacesTypeoptions.value.filter(
+        (item: any) => item !== 'Place of Discharge'
+      )
+    } else if (tag.includes('Origin')) {
+      clearname(InputForm.value, 'palces', 'Origin')
+    } else if (tag.includes('Destination')) {
+      clearname(InputForm.value, 'palces', 'Destination')
+    } else if (tag.includes('Vessel')) {
+      clearname(InputForm.value, 'transportation', 'Vessel')
+    } else if (tag.includes('Voyage')) {
+      clearname(InputForm.value, 'transportation', 'Voyage')
+    }
+  })
+  emitter.on('clearMoreFiltersObj', () => {
+    clearMoreFiltersObj()
+  })
+})
+
+onBeforeMount(() => {
+  emitter.off('clearTag')
+  emitter.off('clearMoreFiltersObj')
+})
+const MoreFiltersSearchQeury = ref()
+const MoreFiltersSearchQeuryTracking = ref()
+interface TypeItem {
+  partyType: ''
+  partyname: []
+}
+interface PlacesTypeItem {
+  placesType: ''
+  placesname: []
+}
+const AddDateType = ref<TypeItem[]>([])
+const AddDatePlaceType = ref<PlacesTypeItem[]>([])
+const defaultAll = (data: any, val: any, value: any, isShipment: any) => {
+  data[val] = isShipment[value]
+  MoreFiltersObj[val] = isShipment[value]
+  MoreFiltersObj2[val] = isShipment[value]
+}
+const defaultAddAll = (data: any, val: any, value: any, type: any, isShipment: any) => {
+  const obj = {
+    partyType: val,
+    partyname: isShipment[value]
+  }
+  const obj2 = {
+    placesType: val,
+    placesname: isShipment[value]
+  }
+  let i = 0
+  if (type == 'AddDateType') {
+    data.push(obj)
+    if (data.length) {
+      data.forEach((item: any, index: any) => {
+        if (item.partyType == val) {
+          i = index
+        }
+      })
+    }
+    MoreFiltersObj[val] = isShipment[value]
+    MoreFiltersObj2[val] = isShipment[value]
+    pushSelectedList(i, val)
+  } else {
+    data.push(obj2)
+    if (data.length) {
+      data.forEach((item: any, index: any) => {
+        if (item.placesType == val) {
+          i = index
+        }
+      })
+    }
+    MoreFiltersObj[val] = isShipment[value]
+    MoreFiltersObj2[val] = isShipment[value]
+    pushPlacesSelectedList(i, val)
+  }
+}
+// 初始判断默认条件
+const defaultMorefilters = () => {
+  if (props.isShipment) {
+    if (
+      sessionStorage.getItem('clickParams') == null ||
+      sessionStorage.getItem('clickParams') == '{}'
+    ) {
+      if (sessionStorage.getItem('searchTableQeuryTracking') != null) {
+        MoreFiltersSearchQeuryTracking.value =
+          JSON.parse(sessionStorage.getItem('searchTableQeuryTracking') as string) || {}
+        if (MoreFiltersSearchQeuryTracking.value.shipper) {
+          defaultAll(
+            InputForm.value.parties,
+            'Shippername',
+            'shipper',
+            MoreFiltersSearchQeuryTracking.value
+          )
+          changeAll(InputForm.value.parties, count.value, PartiesBadge)
+          count.value = []
+        }
+        if (MoreFiltersSearchQeuryTracking.value.consignee) {
+          defaultAll(
+            InputForm.value.parties,
+            'Consigneename',
+            'consignee',
+            MoreFiltersSearchQeuryTracking.value
+          )
+          changeAll(InputForm.value.parties, count.value, PartiesBadge)
+          count.value = []
+        }
+        if (MoreFiltersSearchQeuryTracking.value.incoterms) {
+          defaultAll(
+            InputForm.value.General,
+            'Incoterms',
+            'incoterms',
+            MoreFiltersSearchQeuryTracking.value
+          )
+          changeAll(InputForm.value.General, countG.value, GeneralBadge)
+          countG.value = []
+        }
+        if (MoreFiltersSearchQeuryTracking.value.service) {
+          defaultAll(
+            InputForm.value.General,
+            'Service',
+            'service',
+            MoreFiltersSearchQeuryTracking.value
+          )
+          changeAll(InputForm.value.General, countG.value, GeneralBadge)
+          countG.value = []
+        }
+        if (MoreFiltersSearchQeuryTracking.value['shipper_city/consignee_city']) {
+          defaultAll(
+            InputForm.value.palces,
+            'Origin',
+            ['shipper_city/consignee_city'],
+            MoreFiltersSearchQeuryTracking.value
+          )
+          changeAll(InputForm.value.palces, countP.value, PlacesBadge)
+          countP.value = []
+        }
+        if (MoreFiltersSearchQeuryTracking.value.final_desination) {
+          defaultAll(
+            InputForm.value.palces,
+            'Destination',
+            'final_desination',
+            MoreFiltersSearchQeuryTracking.value
+          )
+          changeAll(InputForm.value.palces, countP.value, PlacesBadge)
+          countP.value = []
+        }
+        if (MoreFiltersSearchQeuryTracking.value['f_vessel/vessel']) {
+          changeAll(InputForm.value.transportation, countT.value, TransportationBadge)
+          countT.value = []
+          defaultAll(
+            InputForm.value.transportation,
+            'Vessel',
+            ['f_vessel/vessel'],
+            MoreFiltersSearchQeuryTracking.value
+          )
+        }
+        if (MoreFiltersSearchQeuryTracking.value['f_voyage/voyage']) {
+          changeAll(InputForm.value.transportation, countT.value, TransportationBadge)
+          countT.value = []
+          defaultAll(
+            InputForm.value.transportation,
+            'Voyage',
+            ['f_voyage/voyage'],
+            MoreFiltersSearchQeuryTracking.value
+          )
+        }
+        if (MoreFiltersSearchQeuryTracking.value.origin) {
+          defaultAddAll(
+            AddDateType.value,
+            'Origin Agent',
+            'origin',
+            'AddDateType',
+            MoreFiltersSearchQeuryTracking.value
+          )
+        }
+        if (MoreFiltersSearchQeuryTracking.value.billto) {
+          defaultAddAll(
+            AddDateType.value,
+            'Bill to',
+            'billto',
+            'AddDateType',
+            MoreFiltersSearchQeuryTracking.value
+          )
+        }
+        if (MoreFiltersSearchQeuryTracking.value.dest_op) {
+          defaultAddAll(
+            AddDateType.value,
+            'Destination Operator',
+            'dest_op',
+            'AddDateType',
+            MoreFiltersSearchQeuryTracking.value
+          )
+        }
+        if (MoreFiltersSearchQeuryTracking.value.notify_party) {
+          defaultAddAll(
+            AddDateType.value,
+            'Notify Party',
+            'notify_party',
+            'AddDateType',
+            MoreFiltersSearchQeuryTracking.value
+          )
+        }
+        if (MoreFiltersSearchQeuryTracking.value.agent) {
+          defaultAddAll(
+            AddDateType.value,
+            'Destination Agent',
+            'agent',
+            'AddDateType',
+            MoreFiltersSearchQeuryTracking.value
+          )
+        }
+        if (MoreFiltersSearchQeuryTracking.value.sales_rep) {
+          defaultAddAll(
+            AddDateType.value,
+            'Sales',
+            'sales_rep',
+            'AddDateType',
+            MoreFiltersSearchQeuryTracking.value
+          )
+        }
+        if (MoreFiltersSearchQeuryTracking.value.place_of_receipt_exp) {
+          defaultAddAll(
+            AddDatePlaceType.value,
+            'Place of Receipt',
+            'place_of_receipt_exp',
+            'AddDatePlaceType',
+            MoreFiltersSearchQeuryTracking.value
+          )
+        }
+        if (MoreFiltersSearchQeuryTracking.value['port_of_loading/fport_of_loading_un']) {
+          defaultAddAll(
+            AddDatePlaceType.value,
+            'Port of Loading',
+            ['port_of_loading/fport_of_loading_un'],
+            'AddDatePlaceType',
+            MoreFiltersSearchQeuryTracking.value
+          )
+        }
+        if (MoreFiltersSearchQeuryTracking.value.place_of_delivery_exp) {
+          defaultAddAll(
+            AddDatePlaceType.value,
+            'Place of delivery',
+            'place_of_delivery_exp',
+            'AddDatePlaceType',
+            MoreFiltersSearchQeuryTracking.value
+          )
+        }
+        if (MoreFiltersSearchQeuryTracking.value.port_of_discharge) {
+          defaultAddAll(
+            AddDatePlaceType.value,
+            'Place of Discharge',
+            'port_of_discharge',
+            'AddDatePlaceType',
+            MoreFiltersSearchQeuryTracking.value
+          )
+        }
+        if (AddDateType.value.length) {
+          AddDateType.value.forEach((item: any) => {
+            if (item.partyType != '' && item.partyname.length != 0) {
+              count.value.push(item.partyname)
+            }
+          })
+          changeAll(InputForm.value.parties, count.value, PartiesBadge)
+          count.value = []
+        } else {
+          PartiesBadge.value = ''
+        }
+        if (AddDatePlaceType.value.length) {
+          AddDatePlaceType.value.forEach((item: any) => {
+            if (item.placesType != '' && item.placesname.length != 0) {
+              count.value.push(item.placesname)
+            }
+          })
+          changeAll(InputForm.value.palces, countP.value, PlacesBadge)
+          countP.value = []
+        } else {
+          PlacesBadge.value = ''
+        }
+      }
+    }
+  } else {
+    if (sessionStorage.getItem('searchTableQeury') != null) {
+      MoreFiltersSearchQeury.value =
+        JSON.parse(sessionStorage.getItem('searchTableQeury') as string) || {}
+      // changeAll(InputForm.value.General, countG.value, GeneralBadge)
+      // countG.value = []
+      if (MoreFiltersSearchQeury.value.shipper) {
+        defaultAll(InputForm.value.parties, 'Shippername', 'shipper', MoreFiltersSearchQeury.value)
+        changeAll(InputForm.value.parties, count.value, PartiesBadge)
+        count.value = []
+      }
+      if (MoreFiltersSearchQeury.value.consignee) {
+        defaultAll(
+          InputForm.value.parties,
+          'Consigneename',
+          'consignee',
+          MoreFiltersSearchQeury.value
+        )
+        changeAll(InputForm.value.parties, count.value, PartiesBadge)
+        count.value = []
+      }
+      if (MoreFiltersSearchQeury.value.shipper_city) {
+        defaultAll(InputForm.value.palces, 'Origin', 'shipper_city', MoreFiltersSearchQeury.value)
+        changeAll(InputForm.value.palces, countP.value, PlacesBadge)
+        countP.value = []
+      }
+      if (MoreFiltersSearchQeury.value.consignee_city) {
+        defaultAll(
+          InputForm.value.palces,
+          'Destination',
+          'consignee_city',
+          MoreFiltersSearchQeury.value
+        )
+        changeAll(InputForm.value.palces, countP.value, PlacesBadge)
+        countP.value = []
+      }
+      if (MoreFiltersSearchQeury.value['f_vessel/m_vessel']) {
+        changeAll(InputForm.value.transportation, countT.value, TransportationBadge)
+        countT.value = []
+        defaultAll(
+          InputForm.value.transportation,
+          'Vessel',
+          ['f_vessel/m_vessel'],
+          MoreFiltersSearchQeury.value
+        )
+      }
+      if (MoreFiltersSearchQeury.value['f_voyage/m_voyage']) {
+        changeAll(InputForm.value.transportation, countT.value, TransportationBadge)
+        countT.value = []
+        defaultAll(
+          InputForm.value.transportation,
+          'Voyage',
+          ['f_voyage/m_voyage'],
+          MoreFiltersSearchQeury.value
+        )
+      }
+      if (MoreFiltersSearchQeury.value.origin) {
+        defaultAddAll(
+          AddDateType.value,
+          'Origin Agent',
+          'origin',
+          'AddDateType',
+          MoreFiltersSearchQeury.value
+        )
+      }
+      if (MoreFiltersSearchQeury.value.agent) {
+        defaultAddAll(
+          AddDateType.value,
+          'Destination Agent',
+          'agent',
+          'AddDateType',
+          MoreFiltersSearchQeury.value
+        )
+      }
+      if (MoreFiltersSearchQeury.value.sales_rep) {
+        defaultAddAll(
+          AddDateType.value,
+          'Sales',
+          'sales_rep',
+          'AddDateType',
+          MoreFiltersSearchQeury.value
+        )
+      }
+      if (MoreFiltersSearchQeury.value['place_of_receipt/place_of_receipt_exp']) {
+        defaultAddAll(
+          AddDatePlaceType.value,
+          'Place of Receipt',
+          ['place_of_receipt/place_of_receipt_exp'],
+          'AddDatePlaceType',
+          MoreFiltersSearchQeury.value
+        )
+      }
+      if (MoreFiltersSearchQeury.value['fport_of_loading_uncode/fport_of_loading_exp']) {
+        defaultAddAll(
+          AddDatePlaceType.value,
+          'Port of Loading',
+          ['fport_of_loading_uncode/fport_of_loading_exp'],
+          'AddDatePlaceType',
+          MoreFiltersSearchQeury.value
+        )
+      }
+      if (MoreFiltersSearchQeury.value['place_of_delivery/place_of_delivery_exp']) {
+        defaultAddAll(
+          AddDatePlaceType.value,
+          'Place of delivery',
+          ['place_of_delivery/place_of_delivery_exp'],
+          'AddDatePlaceType',
+          MoreFiltersSearchQeury.value
+        )
+      }
+      if (AddDateType.value.length) {
+        AddDateType.value.forEach((item: any) => {
+          if (item.partyType != '' && item.partyname.length != 0) {
+            count.value.push(item.partyname)
+          }
+        })
+        changeAll(InputForm.value.parties, count.value, PartiesBadge)
+        count.value = []
+      } else {
+        PartiesBadge.value = ''
+      }
+      if (AddDatePlaceType.value.length) {
+        AddDatePlaceType.value.forEach((item: any) => {
+          if (item.placesType != '' && item.placesname.length != 0) {
+            count.value.push(item.placesname)
+          }
+        })
+        changeAll(InputForm.value.palces, countP.value, PlacesBadge)
+        countP.value = []
+      } else {
+        PlacesBadge.value = ''
+      }
+    }
+  }
+  emit('defaultMorefilters', MoreFiltersObj, MoreFiltersObj2, MoreFiltersSearchQeury.value)
+}
+const drawer = ref(false)
+
+const props = defineProps({
+  isShipment: Boolean,
+  searchTableQeury: Object,
+  isShowMoreFiltersGuidePhoto: Boolean,
+  pageMode: String
+})
+const PartyTypeoptions = computed(() => {
+  if (props.isShipment) {
+    return [
+      {
+        value: 'Notify Party',
+        label: 'Notify Party'
+      },
+      {
+        value: 'Bill to',
+        label: 'Bill to'
+      },
+      {
+        value: 'Origin Agent',
+        label: 'Origin Agent'
+      },
+      {
+        value: 'Destination Agent',
+        label: 'Destination Agent'
+      },
+      {
+        value: 'Destination Operator',
+        label: 'Destination Operator'
+      },
+      {
+        value: 'Sales',
+        label: 'Sales'
+      }
+    ]
+  } else {
+    return [
+      {
+        value: 'Origin Agent',
+        label: 'Origin Agent'
+      },
+      {
+        value: 'Destination Agent',
+        label: 'Destination Agent'
+      },
+      {
+        value: 'Sales',
+        label: 'Sales'
+      }
+    ]
+  }
+})
+
+const PlaceTypeoptions = computed(() => {
+  if (props.isShipment) {
+    return [
+      {
+        value: 'Place of Receipt',
+        label: 'Place of Receipt'
+      },
+      {
+        value: 'Port of Loading',
+        label: 'Port of Loading'
+      },
+      {
+        value: 'Place of Discharge',
+        label: 'Place of Discharge'
+      },
+      {
+        value: 'Place of delivery',
+        label: 'Place of delivery'
+      }
+    ]
+  } else {
+    return [
+      {
+        value: 'Place of Receipt',
+        label: 'Place of Receipt'
+      },
+      {
+        value: 'Port of Loading',
+        label: 'Port of Loading'
+      },
+      {
+        value: 'Place of delivery',
+        label: 'Place of delivery'
+      }
+    ]
+  }
+})
+
+const partSelectTableSelectRef = ref(null)
+const placeSelectTableSelectRef = ref(null)
+
+const selectedPartyTypeoptions = ref()
+selectedPartyTypeoptions.value = []
+
+const selectedPlacesTypeoptions = ref()
+selectedPlacesTypeoptions.value = []
+
+const selectedPartyTypeIndex = ref()
+selectedPartyTypeIndex.value = []
+
+const selectedPlacesTypeIndex = ref()
+selectedPlacesTypeIndex.value = []
+
+const InputForm = ref({
+  parties: {
+    Shippername: [],
+    Consigneename: []
+  },
+  transportation: {
+    Vessel: [],
+    Voyage: []
+  },
+  palces: {
+    Origin: [],
+    Destination: []
+  },
+  General: {
+    Incoterms: '',
+    Service: ''
+  }
+})
+
+const AddType = (item: any) => {
+  if (item == 'party') {
+    AddDateType.value.push({
+      partyType: '',
+      partyname: []
+    })
+  } else if (item == 'place') {
+    AddDatePlaceType.value.push({
+      placesType: '',
+      placesname: []
+    })
+  }
+}
+const count = ref()
+const countT = ref()
+const countP = ref()
+const countG = ref()
+const PartiesBadge = ref()
+const GeneralBadge = ref()
+const TransportationBadge = ref()
+const PlacesBadge = ref()
+count.value = []
+countT.value = []
+countP.value = []
+countG.value = []
+
+const changeAll = (value: any, countTotal: any, BadegTotal: any) => {
+  for (let key in value) {
+    if (key == 'Incoterms') {
+      if (value[key] != 'Please Select Date Range' && value[key] != '') {
+        countTotal.push(value[key])
+      }
+    }
+    if (key == 'Service') {
+      if (value[key] != 'Please Select Service' && value[key] != '') {
+        countTotal.push(value[key])
+      }
+    }
+    if (key != 'Service' && key != 'Incoterms') {
+      if (value[key] != '') {
+        countTotal.push(value[key])
+      }
+    }
+  }
+  if (countTotal.length == 0) {
+    BadegTotal.value = ''
+  } else {
+    BadegTotal.value = countTotal.length
+  }
+}
+// 折叠面板生成badge
+const changeCollapse = (val: any) => {
+  if (val.indexOf('Parties') == -1) {
+    AddDateType.value.forEach((item: any) => {
+      if (item.partyType != '' && item.partyname.length != 0) {
+        count.value.push(item.partyname)
+      }
+    })
+    changeAll(InputForm.value.parties, count.value, PartiesBadge)
+    count.value = []
+  } else {
+    PartiesBadge.value = ''
+  }
+  if (val.indexOf('General') == -1) {
+    changeAll(InputForm.value.General, countG.value, GeneralBadge)
+    countG.value = []
+  } else {
+    GeneralBadge.value = ''
+  }
+  if (val.indexOf('Transportation') == -1) {
+    changeAll(InputForm.value.transportation, countT.value, TransportationBadge)
+    countT.value = []
+  } else {
+    TransportationBadge.value = ''
+  }
+  if (val.indexOf('Places') == -1) {
+    AddDatePlaceType.value.forEach((item: any) => {
+      if (item.placesType != '' && item.placesname.length != 0) {
+        countP.value.push(item.placesname)
+      }
+    })
+    changeAll(InputForm.value.palces, countP.value, PlacesBadge)
+    countP.value = []
+  } else {
+    PlacesBadge.value = ''
+  }
+}
+let MoreFiltersObj: any = {}
+let MoreFiltersObj2: any = {}
+// 赋值
+const changeAutoSelect = (Array: any, val: any, value: any, arraykey1: any, arraykey2: any) => {
+  if (value == 'InputForm') {
+    if (Array) {
+      Array[arraykey1][arraykey2] = val.value
+      MoreFiltersObj[arraykey2] = val.value.join()
+      MoreFiltersObj2[arraykey2] = val.value
+      if (val.value.length == 0) {
+        delete MoreFiltersObj[arraykey2]
+        delete MoreFiltersObj2[arraykey2]
+      }
+    }
+  } else if (value == 'AddDateType') {
+    if (Array.length) {
+      Array.forEach((item: any) => {
+        if (item.partyType == arraykey1) {
+          item.partyname = val.value
+        }
+        MoreFiltersObj[item.partyType] = val.value.join()
+        MoreFiltersObj2[item.partyType] = val.value
+      })
+    }
+  }
+}
+const changeAutoSelectshippername = (val: any) => {
+  changeAutoSelect(InputForm.value, val, 'InputForm', 'parties', 'Shippername')
+}
+const changeAutoSelectconsigneename = (val: any) => {
+  changeAutoSelect(InputForm.value, val, 'InputForm', 'parties', 'Consigneename')
+}
+const changeAutoSelectvessel = (val: any) => {
+  changeAutoSelect(InputForm.value, val, 'InputForm', 'transportation', 'Vessel')
+}
+const changeAutoSelectvoyage = (val: any) => {
+  changeAutoSelect(InputForm.value, val, 'InputForm', 'transportation', 'Voyage')
+}
+const check = (row: any, value: any, key1: any, key2: any) => {
+  value[key1][key2] = row
+  MoreFiltersObj[key2] = row
+  MoreFiltersObj2[key2] = row
+}
+//选择origin
+const checkorigin = (row: any) => {
+  if (row) {
+    check(row, InputForm.value, 'palces', 'Origin')
+  }
+}
+const checkdestination = (row: any) => {
+  if (row) {
+    check(row, InputForm.value, 'palces', 'Destination')
+  }
+}
+const delSelect = (i: any, val: any) => {
+  delete MoreFiltersObj[val]
+  delete MoreFiltersObj2[val]
+  if (sessionStorage.getItem('searchTableQeury') != null) {
+    if (val == 'Origin Agent') {
+      delete MoreFiltersSearchQeury.value.origin
+    } else if (val == 'Destination Agent') {
+      delete MoreFiltersSearchQeury.value.agent
+    } else if (val == 'Sales') {
+      delete MoreFiltersSearchQeury.value.sales_rep
+    }
+  }
+  let index = selectedPartyTypeoptions.value.findIndex((item: any) => {
+    return item == val
+  })
+  if (index >= 0) {
+    selectedPartyTypeoptions.value.splice(index, 1)
+  }
+  let j = selectedPartyTypeIndex.value.findIndex((item: any) => {
+    return item == i
+  })
+  if (j >= 0) {
+    for (let i = 0; i < selectedPartyTypeIndex.value.length; i++) {
+      if (selectedPartyTypeIndex.value[i] > j) {
+        selectedPartyTypeIndex.value[i] = selectedPartyTypeIndex.value[i] - 1
+      }
+    }
+    selectedPartyTypeIndex.value.splice(j, 1)
+  }
+}
+const delPlacesSelect = (i: any, val: any) => {
+  let index = selectedPlacesTypeoptions.value.findIndex((item: any) => {
+    return item == val
+  })
+  if (index >= 0) {
+    selectedPlacesTypeoptions.value.splice(index, 1)
+  }
+  let j = selectedPlacesTypeIndex.value.findIndex((item: any) => {
+    return item == i
+  })
+  if (j >= 0) {
+    for (let i = 0; i < selectedPlacesTypeIndex.value.length; i++) {
+      if (selectedPlacesTypeIndex.value[i] > j) {
+        selectedPlacesTypeIndex.value[i] = selectedPlacesTypeIndex.value[i] - 1
+      }
+    }
+    selectedPlacesTypeIndex.value.splice(j, 1)
+  }
+}
+const pushSelectedList = (i: any, val: any) => {
+  let index = selectedPartyTypeoptions.value.findIndex((item: any) => {
+    return item == val
+  })
+  if (index < 0) {
+    if (!selectedPartyTypeIndex.value.includes(i)) {
+      selectedPartyTypeoptions.value.push(val)
+      selectedPartyTypeIndex.value.push(i)
+    } else {
+      let j = selectedPartyTypeIndex.value.findIndex((con: any) => {
+        return con == i
+      })
+      selectedPartyTypeoptions.value.splice(i, 1, val)
+    }
+  }
+}
+
+const pushPlacesSelectedList = (i: any, val: any) => {
+  let index = selectedPlacesTypeoptions.value.findIndex((item: any) => {
+    return item == val
+  })
+  if (index < 0) {
+    if (!selectedPlacesTypeIndex.value.includes(i)) {
+      selectedPlacesTypeoptions.value.push(val)
+      selectedPlacesTypeIndex.value.push(i)
+    } else {
+      let j = selectedPlacesTypeIndex.value.findIndex((con: any) => {
+        return con == i
+      })
+      selectedPlacesTypeoptions.value.splice(i, 1, val)
+    }
+  }
+}
+const changeAutoSelectAddType = (index: any, val: any) => {
+  pushSelectedList(index, val)
+}
+
+const changeAutoSelectPlacesAddType = (index: any, val: any) => {
+  pushPlacesSelectedList(index, val)
+}
+const isError = ref()
+const changeAutoSelectVal = (val: any, value: any, boolaen: any) => {
+  if (boolaen || value == true) {
+    isError.value = true
+  } else {
+    isError.value = false
+  }
+  MoreFiltersObj = { ...MoreFiltersObj, ...val }
+  MoreFiltersObj2 = { ...MoreFiltersObj2, ...value }
+  // for (const key in value) {
+  //   MoreFiltersObj2[key] = value[key]
+  // }
+}
+// 点击search
+const emit = defineEmits(['MoreFiltersSearch', 'clearMoreFiltersTags', 'defaultMorefilters'])
+const SearchMore = () => {
+  if (AddDatePlaceType.value.length) {
+    const isDateType = AddDatePlaceType.value.some((element) => element.placesType != '')
+    if (isDateType) {
+      if (isError.value && isError.value != undefined) {
+        // 传数据给父组件
+        emit('MoreFiltersSearch', MoreFiltersObj, MoreFiltersObj2)
+        drawer.value = false
+      }
+    } else {
+      // 传数据给父组件
+      emit('MoreFiltersSearch', MoreFiltersObj, MoreFiltersObj2)
+      drawer.value = false
+    }
+  } else if (AddDateType.value.length) {
+    const isDateType = AddDateType.value.some((element) => element.partyType != '')
+    if (isDateType) {
+      if (isError.value && isError.value != undefined) {
+        // 传数据给父组件
+        emit('MoreFiltersSearch', MoreFiltersObj, MoreFiltersObj2)
+        drawer.value = false
+      }
+    } else {
+      // 传数据给父组件
+      emit('MoreFiltersSearch', MoreFiltersObj, MoreFiltersObj2)
+      drawer.value = false
+    }
+  } else {
+    // 传数据给父组件
+    emit('MoreFiltersSearch', MoreFiltersObj, MoreFiltersObj2)
+    drawer.value = false
+  }
+}
+// 清除
+const clearrest = () => {
+  emit('clearMoreFiltersTags')
+  InputForm.value = {
+    parties: {
+      Shippername: [],
+      Consigneename: []
+    },
+    transportation: {
+      Vessel: [],
+      Voyage: []
+    },
+    palces: {
+      Origin: [],
+      Destination: []
+    },
+    General: {
+      Incoterms: 'Please Select Date Range',
+      Service: 'Please Select Service'
+    }
+  }
+  AddDateType.value = []
+  AddDatePlaceType.value = []
+  MoreFiltersObj = {}
+  MoreFiltersObj2 = {}
+  selectedPartyTypeoptions.value = []
+  selectedPlacesTypeoptions.value = []
+  IncotermsList.value.forEach((item) => {
+    item.checked = false
+  })
+  SeiviceList.value.forEach((item) => {
+    item.checked = false
+  })
+  IncotermsCheckAll.value = false
+  ServiceCheckAll.value = false
+}
+// 清除name
+const clearname = (val: any, key1: any, key2: any) => {
+  if (key2 == 'partyType' || key2 == 'partyname') {
+    val[key1][key2] = ''
+  } else if (key2 == 'Incoterms') {
+    val[key1][key2] = 'Please Select Date Range'
+  } else if (key2 == 'Service') {
+    val[key1][key2] = 'Please Select Service'
+  } else {
+    val[key1][key2] = []
+  }
+  delete MoreFiltersObj[key2]
+}
+// 清除 MoreFiltersObj
+const clearMoreFiltersObj = () => {
+  MoreFiltersObj = {}
+}
+const IncotermsCheckAll = ref(false)
+const ServiceCheckAll = ref(false)
+const IncotermsList = ref()
+const SeiviceList = ref()
+const IncotermsSearch = (val: any, value: any) => {
+  InputForm.value.General.Incoterms = val.data
+  MoreFiltersObj[val.title] = val.data
+  MoreFiltersObj2[val.title] = value
+}
+const ServiceSearch = (val: any, value: any) => {
+  InputForm.value.General.Service = val.data
+  MoreFiltersObj[val.title] = val.data
+  MoreFiltersObj2[val.title] = value
+}
+const clickmorefilters = () => {
+  drawer.value = true
+  const incotermsList = JSON.parse(sessionStorage.getItem('incotermsList') as string) || {}
+  if (incotermsList) {
+    IncotermsList.value = incotermsList.IncotermsList
+    SeiviceList.value = incotermsList.ServiceList
+  }
+}
+const searchTableQeurytest = ref(props.searchTableQeury)
+watch(
+  () => props.searchTableQeury,
+  (current) => {
+    searchTableQeurytest.value = current
+  }
+)
+import trackingMoreFiltersImgLight from './image/tracking-more-filters-guide.png'
+import trackingMoreFiltersImgDark from './image/tracking-dark-more-filters-guide.png'
+import bookingMoreFiltersImgLight from './image/booking-more-filters-guide.png'
+import bookingMoreFiltersImgDark from './image/booking-dark-more-filters-guide.png'
+import { useThemeStore } from '@/stores/modules/theme'
+
+const themeStore = useThemeStore()
+
+const moreFiltersGuideImg = computed(() => {
+  if (props.pageMode === 'tracking') {
+    return themeStore.theme === 'dark' ? trackingMoreFiltersImgDark : trackingMoreFiltersImgLight
+  } else {
+    return themeStore.theme === 'dark' ? bookingMoreFiltersImgDark : bookingMoreFiltersImgLight
+  }
+})
+</script>
+<template>
+  <div style="position: relative">
+    <div style="width: 0; height: 0">
+      <img
+        id="more-filters-guide"
+        v-show="props.isShowMoreFiltersGuidePhoto"
+        class="more-filters-guide-class position-absolute-guide"
+        :src="moreFiltersGuideImg"
+        alt=""
+      />
+    </div>
+    <el-button class="More_Filters el-button--grey" @click="clickmorefilters">
+      <span class="iconfont_icon icon_more">
+        <svg class="iconfont" aria-hidden="true">
+          <use xlink:href="#icon-icon_filter_b"></use>
+        </svg>
+      </span>
+      <div class="Filters_title">More Filters</div>
+    </el-button>
+    <el-drawer size="400px" title="More Filters" v-model="drawer">
+      <el-collapse @change="changeCollapse"
+        ><!-- General -->
+        <el-collapse-item class="collapse_item" name="General" v-if="props.isShipment">
+          <template #title>
+            <span class="collapse-title"
+              >General <el-badge class="mark" :value="GeneralBadge" type="warning"
+            /></span>
+          </template>
+          <div class="ETD">
+            <div class="ETD_title">Incoterms</div>
+            <SelectValue
+              :checkAll="IncotermsCheckAll"
+              title="Incoterms"
+              :TransportListItem="IncotermsList"
+              @generalSearch="IncotermsSearch"
+              :Serval="InputForm.General.Incoterms"
+            ></SelectValue>
+          </div>
+          <div class="ETA">
+            <div class="ETD_title">Service</div>
+            <SelectValue
+              :checkAll="ServiceCheckAll"
+              title="Service"
+              :TransportListItem="SeiviceList"
+              @generalSearch="ServiceSearch"
+              :Serval="InputForm.General.Service"
+            ></SelectValue>
+          </div>
+        </el-collapse-item>
+        <!-- Parties -->
+        <el-collapse-item class="collapse_item" name="Parties">
+          <template #title>
+            <span class="collapse-title"
+              >Parties <el-badge class="mark" :value="PartiesBadge" type="warning"
+            /></span>
+          </template>
+          <div class="ETD">
+            <div class="ETD_title">Shipper Name</div>
+            <AutoSelect
+              ASType="contanct"
+              ASSearchFiled="Shipper Name"
+              :ASSearchObj="searchTableQeurytest"
+              :ASSearchMode="props.isShipment ? 'tracking' : 'booking'"
+              @changeAutoSelect="changeAutoSelectshippername"
+              :ASValue="InputForm.parties.Shippername"
+              ASPlaceholder="Please input shipper name"
+            >
+            </AutoSelect>
+          </div>
+          <div class="ETA">
+            <div class="ETD_title">Consignee Name</div>
+            <AutoSelect
+              ASType="contanct"
+              ASSearchFiled="Consignee Name"
+              :ASSearchObj="searchTableQeurytest"
+              :ASSearchMode="props.isShipment ? 'tracking' : 'booking'"
+              @changeAutoSelect="changeAutoSelectconsigneename"
+              :ASValue="InputForm.parties.Consigneename"
+              ASPlaceholder="Please input consignee name"
+            >
+            </AutoSelect>
+          </div>
+          <SelectAutoSelect
+            ref="partSelectTableSelectRef"
+            :AddDateType="AddDateType"
+            :ASSearchMode="props.isShipment ? 'tracking' : 'booking'"
+            :DateTypeoptions="PartyTypeoptions"
+            :ASSearchObj="searchTableQeurytest"
+            @changeAutoSelectAddType="changeAutoSelectAddType"
+            @changeAutoSelect="changeAutoSelectVal"
+            :selectedPartyTypeoptions="selectedPartyTypeoptions"
+            @delSelect="delSelect"
+            ASPlaceholder="Please input party name"
+          >
+          </SelectAutoSelect>
+          <div
+            class="MoreType"
+            @click="AddType('party')"
+            v-if="AddDateType.length != PartyTypeoptions.length"
+          >
+            <el-button class="el-button--noborder moretype">+ More Party Type</el-button>
+          </div>
+        </el-collapse-item>
+        <!-- Places -->
+        <el-collapse-item class="collapse_item" name="Places">
+          <template #title
+            ><span class="collapse-title"
+              >Places<el-badge class="mark" :value="PlacesBadge" type="warning" /></span
+          ></template>
+          <div class="ETD">
+            <div class="ETD_title">Origin</div>
+            <SelectTable
+              ASSearchFiled="Origin"
+              :ASSearchObj="searchTableQeurytest"
+              :ASSearchMode="props.isShipment ? 'tracking' : 'booking'"
+              :searchInput="InputForm.palces.Origin"
+              @check="checkorigin"
+            />
+          </div>
+          <div class="ETA">
+            <div class="ETD_title">Destination</div>
+            <SelectTable
+              ASSearchFiled="Destination"
+              :ASSearchObj="searchTableQeurytest"
+              :ASSearchMode="props.isShipment ? 'tracking' : 'booking'"
+              :searchInput="InputForm.palces.Destination"
+              @check="checkdestination"
+            />
+          </div>
+          <SelectTableSelect
+            :TablesearchTableQeury="searchTableQeurytest"
+            :TablesearchMode="props.isShipment ? 'tracking' : 'booking'"
+            ref="placeSelectTableSelectRef"
+            :AddDateType="AddDatePlaceType"
+            :DateTypeoptions="PlaceTypeoptions"
+            @changeAutoSelectAddType="changeAutoSelectPlacesAddType"
+            @changeAutoSelect="changeAutoSelectVal"
+            :selectedPartyTypeoptions="selectedPlacesTypeoptions"
+            @delSelect="delPlacesSelect"
+            ASPlaceholder="Please input places name"
+          >
+          </SelectTableSelect>
+          <!-- More Place Type -->
+          <div
+            class="MoreType"
+            @click="AddType('place')"
+            v-if="AddDatePlaceType.length != PlaceTypeoptions.length"
+          >
+            <el-button class="el-button--noborder moretype">+ More Place Type</el-button>
+          </div>
+        </el-collapse-item>
+        <!-- Transportation -->
+        <el-collapse-item class="collapse_item" name="Transportation">
+          <template #title
+            ><span class="collapse-title"
+              >Transportation
+              <el-badge class="mark" :value="TransportationBadge" type="warning" /></span
+          ></template>
+          <div class="ETD">
+            <div class="ETD_title">Vessel</div>
+            <AutoSelect
+              ASType="vessel"
+              ASSearchFiled="Vessel"
+              :ASSearchObj="searchTableQeurytest"
+              :ASSearchMode="props.isShipment ? 'tracking' : 'booking'"
+              @changeAutoSelect="changeAutoSelectvessel"
+              :ASValue="InputForm.transportation.Vessel"
+              ASPlaceholder="Please input vessel name or code"
+            >
+            </AutoSelect>
+          </div>
+          <div class="ETA">
+            <div class="ETD_title">Voyage/Flight</div>
+            <AutoSelect
+              ASType="voyage"
+              :ASSearchObj="searchTableQeurytest"
+              :ASSearchMode="props.isShipment ? 'tracking' : 'booking'"
+              ASSearchFiled="Voyage/Flight"
+              @changeAutoSelect="changeAutoSelectvoyage"
+              :ASValue="InputForm.transportation.Voyage"
+              ASPlaceholder="Please input Voyage or flight no."
+            ></AutoSelect>
+          </div>
+        </el-collapse-item>
+        <!-- Others -->
+        <!-- <el-collapse-item class="collapse_item" name="Others">
+          <template #title><span class="collapse-title">Others</span></template>
+        </el-collapse-item> -->
+      </el-collapse>
+      <div class="more_bottom">
+        <el-button class="reset" type="default" @click="clearrest">
+          <span class="iconfont_icon select_icon">
+            <svg class="iconfont" aria-hidden="true">
+              <use xlink:href="#icon-icon_reset_b"></use>
+            </svg>
+          </span>
+          Reset
+        </el-button>
+        <el-button class="reset el-button--dark" style="margin-left: 8px" @click="SearchMore">
+          <span class="iconfont_icon select_icon search_icon">
+            <svg class="iconfont" aria-hidden="true">
+              <use xlink:href="#icon-icon_search_b"></use>
+            </svg>
+          </span>
+          Search
+        </el-button>
+      </div>
+    </el-drawer>
+  </div>
+</template>
+
+<style lang="scss" scoped>
+img.more-filters-guide-class {
+  right: -20px;
+  top: -1px;
+  width: 361px;
+  z-index: 1500;
+}
+
+.icon_more {
+  margin-left: 8px;
+  margin-right: 0;
+}
+
+.icon_delete {
+  fill: var(--color-danger);
+  cursor: pointer;
+}
+
+.More_Filters {
+  display: flex;
+  align-items: center;
+  height: 32px;
+  font-size: var(--font-size-3);
+  margin-left: 8px;
+  width: 116px;
+}
+
+.More_Filters:hover {
+  .Filters_title {
+    color: var(--color-theme);
+  }
+}
+
+.select_icon {
+  margin-right: 8px;
+}
+
+.Filters_title {
+  margin: 0 8px;
+  margin-left: 7px;
+}
+
+:deep(.el-drawer__header) {
+  background-color: var(--color-table-header-bg);
+  display: flex;
+  align-items: center;
+  height: 64px;
+  padding: 0;
+  padding-left: 17.12px;
+  margin-bottom: 0;
+  color: var(--color-neutral-1);
+}
+
+:deep(.el-drawer__title) {
+  font-size: var(--font-size-6);
+  font-weight: bold;
+}
+
+:deep(.el-drawer__close-btn) {
+  font-size: var(--font-size-4);
+  color: var(--icon-color-black);
+  margin-right: 24px;
+  padding: 0;
+}
+
+:deep(.el-drawer__body) {
+  padding: 0;
+  position: relative;
+}
+
+.collapse-title {
+  flex: 1 0 90%;
+  order: 1;
+  text-align: left;
+}
+
+:deep(.el-collapse-item__header) {
+  border-bottom: none;
+  height: 48px;
+  color: var(--icon-color-blac);
+  font-size: var(--font-size-4);
+  font-weight: bold;
+  padding-left: 16px;
+}
+
+:deep(.el-collapse-item__wrap) {
+  border-bottom: none;
+  background-color: var(--more-filters-background-color);
+}
+
+.ETD {
+  margin: 8px 16px;
+}
+
+.ETA {
+  margin: 16px 16px;
+}
+
+.ETD_title {
+  font-size: var(--font-size-2);
+  color: var(--color-neutral-2);
+}
+
+.Date_Title {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+}
+
+.MoreType {
+  color: var(--color-accent-2);
+  padding: 0 0 16px 16px;
+  cursor: pointer;
+}
+
+.AddType {
+  background-color: var(--addparties-background-color);
+  margin: 0 16px 8px 16px;
+  padding: 8px;
+  border-radius: var(--border-radius-6);
+}
+
+.more_bottom {
+  display: flex;
+  align-items: center;
+  bottom: 0;
+  height: 64px;
+  border-top: 1px solid var(--color-border-top);
+  width: 400px;
+  padding: 16px;
+}
+
+.reset {
+  width: 180px;
+  display: flex;
+  align-items: center;
+  height: 40px;
+  justify-content: center;
+  border: 1px solid var(--color-accent-13);
+  border-radius: var(--border-radius-6);
+}
+
+.AlertInput :deep(.el-select__wrapper) {
+  box-shadow: 0 0 0 0.5px var(--color-danger);
+}
+
+:deep(.el-drawer__body) {
+  padding: 0 !important;
+  display: flex;
+  flex-direction: column;
+  justify-content: space-between;
+  overflow-x: hidden;
+}
+
+:deep(.el-overlay) {
+  background-color: transparent;
+}
+:deep(.el-drawer__close-btn) {
+  margin-right: 0;
+}
+.moretype {
+  background-color: transparent;
+  padding: 0 4px;
+  height: 24px;
+}
+</style>

+ 46 - 174
src/components/TransportMode/src/TransportMode.vue

@@ -1,8 +1,10 @@
 <script setup lang="ts">
 import { ref, onMounted, onBeforeMount, watch, computed } from 'vue'
 import type { DropdownInstance } from 'element-plus'
-import emitter from '@/utils/bus'
 import { cloneDeep } from 'lodash'
+import { useFiltersList } from '@/stores/modules/filtersList'
+
+const filtersStore = useFiltersList()
 
 interface ListItem {
   name: string
@@ -12,203 +14,73 @@ interface ListItem {
   checked: boolean
 }
 interface Props {
-  TransportListItem: ListItem[]
-  isShipment: Boolean
+  transportListItem: ListItem[]
 }
 const props = withDefaults(defineProps<Props>(), {})
-const TransportList = ref(props.TransportListItem)
+const transportList = ref()
+const checkAll = ref(false)
+const dropdownVisible = ref<DropdownInstance>()
 const updateTransportList = (data: any) => {
-  TransportList.value = cloneDeep(data)
-  TransportList.value.forEach((item: any) => {
-    if (item.checked) {
-      checkedCount.push(item.sname)
-      const map = new Map()
-      checkedCount.forEach((item) => map.set(item, true))
-      checkedCount = [...map.keys()]
-    }
-    if (checkedCount.length == TransportList.value.length) {
-      checkAll.value = true
-    }
-  })
+  transportList.value = cloneDeep(data)
+  const isCheckedAll = transportList.value?.every((item: any) => item.checked)
+  isCheckedAll ? (checkAll.value = true) : (checkAll.value = false)
 }
 watch(
-  () => props.TransportListItem,
+  () => props.transportListItem,
   (current) => {
+    console.log(current, 'value')
     updateTransportList(current)
+  },
+  {
+    immediate: true,
+    deep: true
   }
 )
 
-onMounted(() => {
-  emitter.on('clearTag', (tag: any) => {
-    if (tag.includes('Transport Mode')) {
-      clearList()
-    }
-  })
-  defaultTransport()
+const totalNumber = computed(() => {
+  return (
+    transportList.value?.filter((item) => {
+      return item.checked
+    }).length || 0
+  )
 })
 
-onBeforeMount(() => {
-  emitter.off('clearTag')
-})
-
-const checkAll = ref(false)
-const dropdownVisible = ref<DropdownInstance>()
-let checkedCount: any[] = []
-const TotalAll = computed(() => {
-  var total_sum = 0
-  if (TransportList.value != undefined) {
-    TransportList.value.map((item) => {
-      total_sum += item.number
-    })
-  }
-  return total_sum
-})
-
-const handleCheckAllChange = (val: any) => {
-  checkedCount = []
-  TransportList.value.forEach((item: any) => {
-    if (val) {
-      item.checked = true
-      checkedCount.push(item.sname)
-    } else {
-      item.checked = false
-      checkedCount = []
-    }
+const handleCheckAllChange = (checked: any) => {
+  transportList.value.forEach((item: any) => {
+    item.checked = checked
   })
 }
-const handleCheckedTransportChange = (value: any, checked: any) => {
-  if (checked) {
-    checkedCount.push(value)
-    const map = new Map()
-    checkedCount.forEach((item) => map.set(item, true))
-    checkedCount = [...map.keys()]
-  } else {
-    checkedCount.splice(checkedCount.indexOf(value), 1)
-  }
-  checkAll.value = checkedCount.length === TransportList.value.length
+const handleCheckedTransportChange = (item: any) => {
+  console.log(item)
+  const isCheckedAll = transportList.value.every((item: any) => item.checked)
+  isCheckedAll ? (checkAll.value = true) : (checkAll.value = false)
 }
 
 // 清除选中
 const clearList = () => {
   checkAll.value = false
-  if (TransportList.value != undefined) {
-    TransportList.value.forEach((item: any) => {
+  if (transportList.value != undefined) {
+    transportList.value.forEach((item: any) => {
       item.checked = false
     })
   }
-  changedata.value = ''
-  checkedCount = []
-  emit('clearTransportTags')
-}
-const emit = defineEmits(['TransportSearch', 'clearTransportTags', 'defaultTransport'])
-const changedata = ref()
-//点击搜索
-const TransportData = {
-  title: 'Transport Mode',
-  data: ['']
-}
-const TransportSearch = (visible: any) => {
-  TransportList.value.forEach((item: any) => {
-    if (item.checked) {
-      checkedCount.push(item.sname)
-      const map = new Map()
-      checkedCount.forEach((item) => map.set(item, true))
-      checkedCount = [...map.keys()]
-    }
-  })
-  if (checkedCount.length == TransportList.value.length) {
-    changedata.value = ['All']
-  } else {
-    changedata.value = checkedCount
-  }
-  TransportData.data = changedata.value
-  emit('TransportSearch', TransportData)
-  if (!dropdownVisible.value) return
-  if (visible) {
-    dropdownVisible.value.handleClose()
-  } else {
-    dropdownVisible.value.handleOpen()
-  }
 }
-const searchTableQeury = ref()
-const searchTableQeuryTracking = ref()
-const defaultTransport = () => {
-  if (props.isShipment) {
-    if (
-      sessionStorage.getItem('clickParams') == null ||
-      sessionStorage.getItem('clickParams') == '{}'
-    ) {
-      if (sessionStorage.getItem('searchTableQeuryTracking') == null) {
-        checkAll.value = true
-        TransportData.data = ['All']
-      } else {
-        searchTableQeuryTracking.value =
-          JSON.parse(sessionStorage.getItem('searchTableQeuryTracking') as string) || {}
-        if (searchTableQeuryTracking.value.transport_mode != undefined) {
-          if (searchTableQeuryTracking.value.transport_mode.length !== 0) {
-            TransportData.data = searchTableQeuryTracking.value.transport_mode
-            searchTableQeuryTracking.value.transport_mode.forEach((item: any) => {
-              if (item == 'All') {
-                checkAll.value = true
-              } else {
-                checkAll.value = false
-              }
-            })
-          }
-        } else {
-          TransportData.data = []
-          checkAll.value = false
-        }
-      }
-      emit('defaultTransport', TransportData, searchTableQeuryTracking.value)
-    } else {
-      const data = JSON.parse(sessionStorage.getItem('reportList') as string) || {}
-      searchTableQeuryTracking.value =
-        JSON.parse(sessionStorage.getItem('searchTableQeuryTracking') as string) || {}
-      if (data.transport_mode) {
-        const obj = {
-          title: 'Transport Mode',
-          data: data.transport_mode
-        }
-        data.transport_mode.forEach((item: any) => {
-          if (item == 'All') {
-            checkAll.value = true
-          }
-        })
-        emit('defaultTransport', obj, searchTableQeuryTracking.value)
-      }
-    }
-  } else {
-    if (sessionStorage.getItem('searchTableQeury') == null) {
-      checkAll.value = true
-      TransportData.data = ['All']
-    } else {
-      searchTableQeury.value =
-        JSON.parse(sessionStorage.getItem('searchTableQeury') as string) || {}
-      if (searchTableQeury.value.transport_mode !== undefined) {
-        if (searchTableQeury.value.transport_mode.length !== 0) {
-          TransportData.data = searchTableQeury.value.transport_mode
-          searchTableQeury.value.transport_mode.forEach((item: any) => {
-            if (item == 'All') {
-              checkAll.value = true
-            } else {
-              checkAll.value = false
-            }
-          })
-        }
-      } else {
-        TransportData.data = []
-        checkAll.value = false
-      }
-    }
-    emit('defaultTransport', TransportData, searchTableQeury.value)
-  }
+const emit = defineEmits(['transportSearch'])
+
+const transportSearch = () => {
+  const allChecked = transportList.value.every((item) => item.checked)
+  const selectedNames = allChecked
+    ? ['All']
+    : transportList.value.filter((item) => item.checked).map((item) => item.sname)
+  filtersStore.updateFilter('transport_mode', selectedNames)
+  dropdownVisible.value.handleClose()
+  emit('transportSearch', transportList.value)
 }
 
 // 每次打开时都应该重新赋值
 const handleDropdownVisibleChange = (visible: boolean) => {
   if (visible) {
-    updateTransportList(props.TransportListItem)
+    updateTransportList(props.transportListItem)
   }
 }
 </script>
@@ -242,16 +114,16 @@ const handleDropdownVisibleChange = (visible: boolean) => {
                   </span>
                   Select All
                 </div>
-                <div class="checkbox_number">({{ TotalAll }})</div>
+                <div class="checkbox_number">({{ totalNumber }})</div>
               </el-checkbox>
             </el-dropdown-item>
             <el-divider></el-divider>
-            <el-dropdown-item v-for="(item, index) in TransportList" :key="index">
+            <el-dropdown-item v-for="(item, index) in transportList" :key="index">
               <el-checkbox
                 :value="item.name"
                 v-model="item.checked"
                 class="checkbox"
-                @change="handleCheckedTransportChange(item.sname, item.checked)"
+                @change="handleCheckedTransportChange(item)"
               >
                 <div class="checkbox_title">
                   <span class="iconfont_icon">
@@ -269,7 +141,7 @@ const handleDropdownVisibleChange = (visible: boolean) => {
                 <el-button class="clear" type="default" @click="clearList">Reset</el-button>
               </div>
               <div>
-                <el-button class="search el-button--dark" @click="TransportSearch"
+                <el-button class="search el-button--dark" @click="transportSearch"
                   >Search</el-button
                 >
               </div>

+ 98 - 0
src/stores/modules/filtersList.ts

@@ -0,0 +1,98 @@
+import { defineStore } from 'pinia'
+import dayjs from 'dayjs'
+import { useUserStore } from '@/stores/modules/user'
+
+const valueFormat = 'MM/DD/YYYY'
+
+interface StateType {
+  filtersList: FiltersType[]
+}
+
+type FiltersType =
+  | {
+    title: string
+    key: string
+    keyType: 'normal'
+    value: string
+  }
+  | {
+    title: string
+    key: string
+    keyType: 'array'
+    value: string[]
+  } | {
+    title: string
+    key: string[]
+    keyType: 'dateRange'
+    value: string[]
+  }
+
+export const useFiltersList = defineStore('filtersList', {
+  state: (): StateType => ({ filtersList: [] }),
+
+  getters: {
+    getQueryData(state) {
+      const userStore = useUserStore()
+      const formatDate = userStore.dateFormat
+      return state.filtersList.reduce((acc, cur) => {
+        if (cur.keyType === 'normal') {
+          acc[cur.key] = cur.value
+        } else if (cur.keyType === 'array') {
+          acc[cur.key] = cur.value
+        } else if (cur.keyType === 'dateRange') {
+          acc[cur.key[0]] = dayjs(cur.value[0], formatDate).format(valueFormat)
+          acc[cur.key[1]] = dayjs(cur.value[1], formatDate).format(valueFormat)
+        }
+        return acc
+      }, {})
+    }
+  },
+  actions: {
+    getFilterIndexByKey(key: string) {
+      return this.filtersList.findIndex(filter => {
+        return filter.key === key
+      })
+    },
+    getFilterIndexByTitle(title: string) {
+      return this.filtersList.findIndex(filter => {
+        return filter.title === title
+      })
+    },
+    getFilterByKey(key: string) {
+      return this.filtersList.find(filter => filter.key === key)
+    },
+    getFilterByTitle(title: string) {
+      return this.filtersList.find(filter => filter.title === title)
+    },
+    deleteFilterByKey(key: string) {
+      const index = this.getFilterIndexByKey(key)
+      if (index !== -1) {
+        this.filtersList.splice(index, 1)
+      }
+    },
+    deleteFilterByTitle(title: string) {
+      const index = this.getFilterIndexByTitle(title)
+      if (index !== -1) {
+        this.filtersList.splice(index, 1)
+      }
+    },
+
+    updateFilter(title: string, value: string | string[]) {
+      const index = this.getFilterIndexByTitle(title)
+      if (index !== -1) {
+        this.filtersList[index].value = value
+      }
+    },
+    pushFilter(filter: FiltersType) {
+      const index = this.getFilterIndexByTitle(filter.title)
+      if (index !== -1) {
+        this.filtersList[index] = filter
+      } else {
+        this.filtersList.push(filter)
+      }
+    },
+  },
+  persist: {
+    storage: sessionStorage // 👈 使用 sessionStorage
+  }
+})

+ 76 - 0
src/utils/filters.ts

@@ -0,0 +1,76 @@
+import dayjs from "dayjs"
+import { useUserStore } from '@/stores/modules/user'
+import { cloneDeep } from "lodash"
+
+const valueFormat = 'MM/DD/YYYY'
+const userStore = useUserStore()
+const formatDate = userStore.dateFormat
+
+export type FiltersType =
+  | {
+    title: string
+    key: string
+    keyType: 'normal'
+    value: string
+  }
+  | {
+    title: string
+    key: string
+    keyType: 'array'
+    value: string[]
+  } | {
+    title: string
+    key: string[]
+    keyType: 'dateRange'
+    value: string[]
+  }
+
+export const getTags = (filtersList: FiltersType[]) => {
+  return filtersList.map(filter => {
+    if (filter.keyType === 'dateRange') {
+      return filter.title + ': ' + filter.value[0] + ' To ' + filter.value[1]
+    } else if (filter.keyType === 'array') {
+      return filter.title + ': ' + filter.value.join(', ')
+    } else {
+      return filter.title + ': ' + filter.value
+    }
+  })
+}
+
+export const getFilterIndex = (filtersList: FiltersType[], key: string) => {
+  return filtersList.findIndex(filter => {
+    return filter.key === key
+  })
+}
+
+export const getFitler = (filtersList: FiltersType[], key: string) => {
+  return filtersList.find(filter => {
+    return filter.key === key
+  })
+}
+
+export const deleteFilter = (filtersList: FiltersType[], key: string) => {
+  const curIndex = filtersList.findIndex(filter => {
+    return filter.key === key
+  })
+  filtersList.splice(curIndex, 1)
+}
+export const updateFilter = (filtersList: FiltersType[], key: string, value: string | string[]) => {
+  const curIndex = filtersList.findIndex(filter => {
+    return filter.key === key
+  })
+  if (curIndex !== -1) {
+    filtersList[curIndex].value = value
+  }
+}
+
+export const pushFilter = (filtersList: FiltersType[], filter: FiltersType) => {
+  const curFilter = cloneDeep(filter)
+  if (curFilter.keyType === 'dateRange') {
+    curFilter.value = curFilter.value.map(item => dayjs(item, valueFormat).format(formatDate))
+  }
+  filtersList.push(curFilter)
+}
+
+export const parseJSONFilsters = (filtersList: FiltersType[]) => {
+}

+ 1 - 1
src/views/Booking/index.ts

@@ -1 +1 @@
-export { default } from './src/BookingView.vue'
+export { default } from './src/BookingView.new.vue'

+ 528 - 0
src/views/Booking/src/BookingView.new.vue

@@ -0,0 +1,528 @@
+<script setup lang="ts">
+import emitter from '@/utils/bus'
+import FilterTags from '@/components/FliterTags'
+import TransportMode from '@/components/TransportMode'
+import BookingTable from './components/BookingTable'
+import DateRange from '@/components/DateRange'
+import MoreFilters from '@/components/MoreFilters'
+import { ref, reactive } from 'vue'
+import { useCalculatingHeight } from '@/hooks/calculatingHeight'
+import { useUserStore } from '@/stores/modules/user'
+import dayjs from 'dayjs'
+import { useFiltersList } from '@/stores/modules/filtersList'
+
+const userStore = useUserStore()
+const formatDate = userStore.dateFormat
+const filtersStore = useFiltersList()
+const filtersList = computed(() => filtersStore.filtersList)
+
+const filterRef: Ref<HTMLElement | null> = ref(null)
+const containerHeight = useCalculatingHeight(document.documentElement, 246, [filterRef])
+
+const filterTagsList = computed(() => {
+  return filtersList.value.map((filter) => {
+    if (filter.keyType === 'dateRange') {
+      return {
+        title: filter.title,
+        value: filter.title + ': ' + filter.value[0] + ' To ' + filter.value[1]
+      }
+    } else if (filter.keyType === 'array') {
+      return {
+        title: filter.title,
+        value: filter.title + ': ' + filter.value.join(', ')
+      }
+    } else {
+      return {
+        title: filter.title,
+        value: filter.title + ': ' + filter.value
+      }
+    }
+  })
+})
+
+const tabList = ref([
+  {
+    name: 'All',
+    number: 0,
+    checked: true,
+    type: 'all'
+  },
+  {
+    name: 'Created',
+    number: 0,
+    checked: false,
+    type: 'created'
+  },
+  {
+    name: 'Confirmed',
+    number: 0,
+    checked: false,
+    type: 'confirmed'
+  },
+  {
+    name: 'Cancelled',
+    number: 0,
+    checked: false,
+    type: 'cancelled'
+  }
+])
+
+const initPage = () => {
+  if (!filtersList.value || (filtersList.value && filtersList.value.length == 0)) {
+    filtersStore.pushFilter({
+      title: 'Transport Mode',
+      value: ['All'],
+      keyType: 'array',
+      key: 'transport_mode'
+    })
+    filtersStore.pushFilter({
+      title: 'ETD',
+      value: [
+        dayjs().subtract(2, 'month').startOf('month').format(formatDate),
+        dayjs().add(1, 'month').format(formatDate)
+      ],
+      keyType: 'dateRange',
+      key: ['f_etd_start', 'f_etd_end']
+    })
+    filtersStore.pushFilter({
+      title: 'Shipment Status',
+      value: ['All'],
+      keyType: 'array',
+      key: 'filterTag'
+    })
+  } else {
+  }
+}
+
+initPage()
+
+const BookingSearch = ref()
+const tableLoadingTableData = ref(false)
+let searchTableQeury: any = {}
+const filterData = reactive({
+  filtersTagData: [] as Array<string>,
+  transportData: [] as Array<string>,
+  daterangeData: [] as Array<string>,
+  morefiltersData: [] as Array<string>
+})
+
+const tagsData: any = ref([])
+const handleClose = (tagTitle: any) => {
+  filtersStore.deleteFilterByTitle(tagTitle)
+  getBookingdata()
+}
+
+const setFilterData = (dateRangeData: any) => {
+  filterData.daterangeData = []
+  for (const key in dateRangeData) {
+    const startEnd = dateRangeData[key].data[0] + ' To ' + dateRangeData[key].data[1]
+    let str = `${key}:${startEnd}`
+    filterData.daterangeData.push(str)
+  }
+}
+
+//MoreFiltersSearch
+const MoreFiltersSearch = (val: any, value: any) => {
+  filterData.morefiltersData = []
+  if (Object.keys(value).length == 0) {
+    delete searchTableQeury.shipper
+    delete searchTableQeury.consignee
+    delete searchTableQeury.origin
+    delete searchTableQeury.agent
+    delete searchTableQeury.sales_rep
+    delete searchTableQeury.shipper_city
+    delete searchTableQeury.consignee_city
+    delete searchTableQeury['place_of_receipt/place_of_receipt_exp']
+    delete searchTableQeury['fport_of_loading_uncode/fport_of_loading_exp']
+    delete searchTableQeury['place_of_delivery/place_of_delivery_exp']
+    delete searchTableQeury['f_vessel/m_vessel']
+    delete searchTableQeury['f_voyage/m_voyage']
+  }
+  for (const key in val) {
+    let str = `${key}:${val[key]}`
+    filterData.morefiltersData.push(str)
+    if (key == 'Shippername') {
+      searchTableQeury.shipper = value[key]
+    } else if (key == 'Consigneename') {
+      searchTableQeury.consignee = value[key]
+    } else if (key == 'Origin Agent') {
+      searchTableQeury.origin = value[key]
+    } else if (key == 'Destination Agent') {
+      searchTableQeury.agent = value[key]
+    } else if (key == 'Sales') {
+      searchTableQeury.sales_rep = value[key]
+    } else if (key == 'Origin') {
+      searchTableQeury.shipper_city = value[key]
+    } else if (key == 'Destination') {
+      searchTableQeury.consignee_city = value[key]
+    } else if (key == 'Place of Receipt') {
+      searchTableQeury['place_of_receipt/place_of_receipt_exp'] = value[key]
+    } else if (key == 'Port of Loading') {
+      searchTableQeury['fport_of_loading_uncode/fport_of_loading_exp'] = value[key]
+    } else if (key == 'Place of delivery') {
+      searchTableQeury['place_of_delivery/place_of_delivery_exp'] = value[key]
+    } else if (key == 'Vessel') {
+      searchTableQeury['f_vessel/m_vessel'] = value[key]
+    } else if (key == 'Voyage') {
+      searchTableQeury['f_voyage/m_voyage'] = value[key]
+    }
+  }
+  sessionStorage.setItem('searchTableQeury', JSON.stringify(searchTableQeury))
+  getBookingdata()
+}
+const defaultMorefilters = (val: any, value: any, data: any) => {
+  filterData.morefiltersData = []
+  for (const key in val) {
+    let str = `${key}:${val[key]}`
+    filterData.morefiltersData.push(str)
+    if (key == 'Shippername') {
+      searchTableQeury.shipper = value[key]
+    } else if (key == 'Consigneename') {
+      searchTableQeury.consignee = value[key]
+    } else if (key == 'Origin Agent') {
+      searchTableQeury.origin = value[key]
+    } else if (key == 'Destination Agent') {
+      searchTableQeury.agent = value[key]
+    } else if (key == 'Sales') {
+      searchTableQeury.sales_rep = value[key]
+    } else if (key == 'Origin') {
+      searchTableQeury.shipper_city = value[key]
+    } else if (key == 'Destination') {
+      searchTableQeury.consignee_city = value[key]
+    } else if (key == 'Place of Receipt') {
+      searchTableQeury['place_of_receipt/place_of_receipt_exp'] = value[key]
+    } else if (key == 'Port of Loading') {
+      searchTableQeury['fport_of_loading_uncode/fport_of_loading_exp'] = value[key]
+    } else if (key == 'Place of delivery') {
+      searchTableQeury['place_of_delivery/place_of_delivery_exp'] = value[key]
+    } else if (key == 'Vessel') {
+      searchTableQeury['f_vessel/m_vessel'] = value[key]
+    } else if (key == 'Voyage') {
+      searchTableQeury['f_voyage/m_voyage'] = value[key]
+    }
+  }
+  if (sessionStorage.getItem('searchTableQeury') != null) {
+    searchTableQeury = data
+  }
+}
+const clearfilters = () => {
+  BookingSearch.value = ''
+  filterData.filtersTagData = []
+  tagsData.value = []
+  let str = 'Shipment status: All'
+  filterData.filtersTagData.push(str)
+  filterData.transportData = []
+  filterData.daterangeData = []
+  filterData.morefiltersData = []
+  emitter.emit('clearTag', 'Shipment status')
+  emitter.emit('clearTag', 'Transport Mode')
+  emitter.emit('clearTag', 'ETD')
+  emitter.emit('clearTag', 'ETA')
+  emitter.emit('clearTag', 'Creation Time')
+  emitter.emit('clearTag', 'Shippername')
+  emitter.emit('clearTag', 'Consigneename')
+  emitter.emit('clearTag', 'Origin Agent')
+  emitter.emit('clearTag', 'Destination Agent')
+  emitter.emit('clearTag', 'Sales')
+  emitter.emit('clearTag', 'Origin')
+  emitter.emit('clearTag', 'Destination')
+  emitter.emit('clearTag', 'Place of Receipt')
+  emitter.emit('clearTag', 'Port of Loading')
+  emitter.emit('clearTag', 'Place of delivery')
+  emitter.emit('clearTag', 'Vessel')
+  emitter.emit('clearTag', 'Voyage')
+  searchTableQeury = {}
+  searchTableQeury.filterTag = ['All']
+  sessionStorage.setItem('searchTableQeury', JSON.stringify(searchTableQeury))
+  getBookingdata()
+}
+
+// 清除 Transport Tags
+const clearTransportTags = () => {
+  filterData.transportData = []
+}
+// 清除 Daterange Tags
+const clearDaterangeTags = () => {
+  filterData.daterangeData = []
+}
+// 清除 MoreFilters Tags
+const clearMoreFiltersTags = () => {
+  filterData.morefiltersData = []
+}
+
+const BookingTable_ref = ref()
+const transportListItem = ref()
+
+const isShowAlertIcon = ref(false)
+const getBookingdata = () => {
+  const queryData = filtersStore.getQueryData
+
+  tableLoadingTableData.value = true
+  BookingTable_ref.value.getLoadingData(tableLoadingTableData.value)
+  $api
+    .getBookingTableData({
+      cp: BookingTable_ref.value.pageInfo.pageNo,
+      ps: BookingTable_ref.value.pageInfo.pageSize,
+      rc: -1,
+      other_filed: '',
+      ...queryData
+    })
+    .then((res: any) => {
+      if (res.code === 200) {
+        transportListItem.value = res.data.TransportList
+
+        tabList.value = res.data.tagsList
+        const checkedTabNames = tabList.value
+          .filter((item) => item.checked)
+          .map((item) => item.name)
+        filtersStore.updateFilter('filterTag', checkedTabNames)
+
+        sessionStorage.setItem('BookingData', JSON.stringify(res.data))
+        BookingTable_ref.value.searchTableData(searchTableQeury)
+        // 查询没结果的话显示icon
+        if (BookingSearch.value != '' && BookingSearch.value != undefined) {
+          if (res.data.searchData.length == 0) {
+            isShowAlertIcon.value = true
+          }
+        } else {
+          isShowAlertIcon.value = false
+        }
+      }
+    })
+}
+const tabChange = (changeTabList: any) => {
+  tabList.value = changeTabList
+  const checkedTabNames = tabList.value.filter((item) => item.checked).map((item) => item.name)
+  filtersStore.updateFilter('filterTag', checkedTabNames)
+
+  getBookingdata()
+}
+// 点击search按钮
+const SearchInput = () => {
+  searchTableQeury._textSearch = BookingSearch.value
+  sessionStorage.setItem('searchTableQeury', JSON.stringify(searchTableQeury))
+  getBookingdata()
+}
+
+onMounted(() => {
+  getBookingdata()
+})
+import BookingGuide from './components/BookingGuide.vue'
+import { useGuideStore } from '@/stores/modules/guide'
+
+const guideStore = useGuideStore()
+const bookingGuideRef = ref()
+const handleGuide = () => {
+  bookingGuideRef.value.startGuide() // 开始引导
+}
+</script>
+
+<template>
+  <div class="Title">
+    <span>Booking</span>
+    <VDriverGuide @click="handleGuide"></VDriverGuide>
+  </div>
+  <BookingGuide ref="bookingGuideRef"></BookingGuide>
+  <div class="display" ref="filterRef">
+    <div class="filter-box">
+      <div class="filters-container" id="booking-filters-container-guide">
+        <FilterTags :tagsList="tabList" @tabChange="tabChange"></FilterTags>
+        <div class="heaer_top">
+          <div class="search">
+            <el-input
+              placeholder="Enter Booking/HBL/PO/Carrier Booking No. "
+              v-model="BookingSearch"
+              class="log_input"
+              @keyup.enter="SearchInput"
+            >
+              <template #prefix>
+                <span class="iconfont_icon">
+                  <svg class="iconfont icon_search" aria-hidden="true">
+                    <use xlink:href="#icon-icon_search_b"></use>
+                  </svg>
+                </span>
+              </template>
+              <template #suffix>
+                <el-tooltip
+                  v-if="isShowAlertIcon"
+                  :offset="6"
+                  popper-class="ShowAlerIcon"
+                  effect="dark"
+                  content="We support the following references number to find bookings:· Booking No./HAWB No./MAWB No./PO No./Carrier Booking No./Contract No./File No./Quote No."
+                  placement="bottom"
+                >
+                  <span class="iconfont_icon iconfont_icon_tip">
+                    <svg class="iconfont icon_search" aria-hidden="true">
+                      <use xlink:href="#icon-icon_info_b"></use>
+                    </svg>
+                  </span>
+                </el-tooltip>
+              </template>
+            </el-input>
+          </div>
+          <TransportMode
+            :isShipment="false"
+            :transportListItem="transportListItem"
+            @transportSearch="getBookingdata()"
+          ></TransportMode>
+          <DateRange
+            :isShipment="false"
+            @DateRangeSearch="getBookingdata()"
+            @clearDaterangeTags="clearDaterangeTags"
+          ></DateRange>
+        </div>
+      </div>
+      <MoreFilters
+        :isShipment="false"
+        :pageMode="'booking'"
+        :searchTableQeury="searchTableQeury"
+        @MoreFiltersSearch="MoreFiltersSearch"
+        @clearMoreFiltersTags="clearMoreFiltersTags"
+        @defaultMorefilters="defaultMorefilters"
+        :isShowMoreFiltersGuidePhoto="guideStore.booking.isShowMoreFiltersGuidePhoto"
+      ></MoreFilters>
+      <el-button class="el-button--dark" style="margin-left: 8px" @click="SearchInput"
+        >Search</el-button
+      >
+    </div>
+    <!-- 筛选项 -->
+    <div class="filtersTag" v-if="filterTagsList.length" id="booking-filter-tag-guide">
+      <el-tag
+        class="tag"
+        v-for="tag in filterTagsList"
+        :key="tag.title"
+        :closable="!tag.title.includes('Shipment')"
+        :disable-transitions="false"
+        @close="handleClose(tag.title)"
+        color="#EFEFF0"
+      >
+        <el-tooltip
+          class="box-item"
+          effect="dark"
+          :content="tag.value"
+          placement="top"
+          v-if="tag.value.length > 39"
+        >
+          {{ tag.value.length > 39 ? tag.value.slice(0, 39) + '...' : tag }}
+        </el-tooltip>
+        <div v-else>{{ tag.value }}</div>
+      </el-tag>
+      <div class="text_button" @click="clearfilters">Clear Filters</div>
+    </div>
+  </div>
+  <BookingTable
+    :height="containerHeight"
+    :tagsData="tagsData"
+    ref="BookingTable_ref"
+  ></BookingTable>
+</template>
+
+<style lang="scss" scoped>
+.filter-box {
+  width: 100%;
+  display: flex;
+  flex-direction: row;
+  align-items: flex-end;
+  height: 100%;
+}
+.filters-container {
+  max-width: 1426px;
+  width: 80%;
+  display: flex;
+  flex-direction: column;
+}
+.filter-guide-class {
+  top: -3px;
+  left: -2px;
+  height: 29px;
+  width: 592px;
+}
+img.more-filters-guide-class {
+  right: 38px;
+  top: 155px;
+  height: 634px;
+  width: 243px;
+  z-index: 20000;
+}
+.download-file-guide-class {
+  right: 85px;
+  top: 243px;
+  width: 377px;
+  height: 236px;
+}
+.customize-columns-guide-class {
+  right: 8px;
+  top: 249px;
+  width: 694px;
+  height: 474px;
+}
+.tab-filter-guide-class {
+  left: 248px;
+  top: 118px;
+  height: 42px;
+  z-index: 20000;
+}
+
+.Title {
+  display: flex;
+  height: 68px;
+  border-bottom: 1px solid var(--color-border);
+  font-size: var(--font-size-6);
+  font-weight: 700;
+  padding: 0 24px;
+  align-items: center;
+}
+.display {
+  border: 1px solid var(--color-border);
+  border-width: 0 0 1px 0;
+  padding: 0 24px;
+}
+.heaer_top {
+  margin-top: 6.57px;
+  display: flex;
+}
+.search {
+  width: 400px;
+  height: 32px;
+}
+.filtersTag {
+  margin-top: 8px;
+  margin-bottom: 4px;
+  display: inline-flex;
+  align-items: center;
+  flex-wrap: wrap;
+}
+.tag {
+  border-radius: var(--border-radius-22);
+  margin: 0 8px 8px 0;
+  color: var(--color-neutral-1);
+  font-weight: 600;
+  font-size: var(--font-size-2);
+  border-color: var(--tag-boder-color);
+  background-color: var(--tag-bg-color) !important;
+}
+.iconfont_icon_tip {
+  margin-left: 8px;
+  width: 16px;
+  height: 16px;
+  display: flex;
+  align-items: center;
+}
+.icon_search {
+  fill: var(--color-neutral-1);
+}
+@media only screen and (min-width: 1280px) {
+  .search {
+    width: 480px;
+  }
+}
+@media only screen and (min-width: 1440px) {
+  .search {
+    width: 740px;
+  }
+}
+:deep(.log_input .el-input__wrapper) {
+  box-shadow: 0 0 0 1px var(--color-select-border) inset;
+  border-radius: 6px;
+}
+</style>

+ 1650 - 0
src/views/Dashboard/src/DashboardView.new.vue

@@ -0,0 +1,1650 @@
+<script lang="ts" setup>
+import { ref, onMounted, reactive } from 'vue'
+import QuickCalendarDate from '@/components/DateRange/src/components/QuickCalendarDate.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'
+
+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
+      }
+    })
+    .finally(() => {
+      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 startyear = ref()
+const startmonth = ref()
+const startday = ref()
+const endyear = ref()
+const endmonth = ref()
+const endday = ref()
+//处理跳转数据
+const handleTurnData = (startdate: any, enddata: any, name: any) => {
+  if (name == 'Container') {
+    if (startdate != '') {
+      startmonth.value = startdate.split('/')[0]
+      startyear.value = startdate.split('/')[1]
+    }
+    if (enddata != '') {
+      endmonth.value = enddata.split('/')[0]
+      endyear.value = enddata.split('/')[1]
+    }
+  } else {
+    if (startdate != '') {
+      startmonth.value = startdate.split('/')[0]
+      startyear.value = startdate.split('/')[2]
+      startday.value = startdate.split('/')[1]
+    }
+    if (enddata != '') {
+      endmonth.value = enddata.split('/')[0]
+      endyear.value = enddata.split('/')[2]
+      endday.value = enddata.split('/')[1]
+    }
+  }
+}
+const ClickParams = (val: any) => {
+  const currentDate = new Date()
+  let tenyear = currentDate.getFullYear()
+  let tenmonth = currentDate.getMonth() - 11
+  if (tenmonth < 0) {
+    tenyear -= 1
+    tenmonth += 11
+  }
+  const reportList: any = {}
+  const handlereportlist = (transportation: any, type: any, name: any) => {
+    if (transportation.includes('All')) {
+      reportList.transport_mode = ['All']
+    } else {
+      reportList.transport_mode = transportation
+    }
+    if (name == 'Container') {
+      if (type == 'ETA') {
+        if (startyear.value) {
+          reportList.eta_start = startmonth.value + '/01/' + startyear.value
+          reportList.eta_end =
+            endmonth.value +
+            '/' +
+            new Date(endyear.value, endmonth.value, 0).getDate() +
+            '/' +
+            endyear.value
+        }
+      } else {
+        if (startyear.value) {
+          reportList.etd_start = startmonth.value + '/01/' + startyear.value
+          reportList.etd_end =
+            endmonth.value +
+            '/' +
+            new Date(endyear.value, endmonth.value, 0).getDate() +
+            '/' +
+            endyear.value
+        }
+      }
+    } else {
+      if (type == 'ETA') {
+        if (startyear.value) {
+          reportList.eta_start = startmonth.value + '/' + startday.value + '/' + startyear.value
+          reportList.eta_end = endmonth.value + '/' + endday.value + '/' + endyear.value
+        }
+      } else {
+        if (startyear.value) {
+          reportList.etd_start = startmonth.value + '/' + startday.value + '/' + startyear.value
+          reportList.etd_end = endmonth.value + '/' + endday.value + '/' + endyear.value
+        }
+      }
+    }
+  }
+  // ETD to ETA(DAYS)点击跳转
+  if (val == 'ETD to ETA (Days)') {
+    handleTurnData(
+      dashboardObj.ETDDefaultData.date_start,
+      dashboardObj.ETDDefaultData.date_end,
+      'Container'
+    )
+    reportList._reportRef = pie_chart_ETD.value[0].paramsdata.name
+    reportList._reportRefe_date = currentDate.getMonth() + 1 + '/' + currentDate.getFullYear()
+    reportList._reportType = 'r1'
+    reportList._reportRefb_date = tenmonth + '/' + tenyear
+    handlereportlist(
+      dashboardObj.ETDDefaultData.transportation,
+      dashboardObj.ETDDefaultData.date_type,
+      'Container'
+    )
+    sessionStorage.setItem('clickParams', 'clickParams')
+    sessionStorage.setItem('reportList', JSON.stringify(reportList))
+    let obj: any = {}
+    obj.title = 'ETD to ETA (Days)'
+    obj.name = pie_chart_ETD.value[0].paramsdata.name
+    sessionStorage.setItem('tagsList', JSON.stringify(obj))
+    router.push({
+      path: '/tracking'
+    })
+  }
+  //  PendingArrival点击跳转
+  else if (val == 'Pending1') {
+    handleTurnData('', '', '') // 因为Pending没有时间筛选,所以传空
+    reportList._reportRef = pie_chart_pending_arrival.value[0].paramsdata.name
+    reportList._reportType = 'r3'
+    handlereportlist(
+      dashboardObj.PendingDefaultData.transportation,
+      dashboardObj.PendingDefaultData.date_type,
+      ''
+    )
+    sessionStorage.setItem('clickParams', 'clickParams')
+    sessionStorage.setItem('reportList', JSON.stringify(reportList))
+    let obj: any = {}
+    obj.title = 'Pending Arrival'
+    obj.name = pie_chart_pending_arrival.value[0].paramsdata.name
+    sessionStorage.setItem('tagsList', JSON.stringify(obj))
+    router.push({
+      path: '/tracking'
+    })
+  }
+  // PendingDeparture点击跳转
+  else if (val == 'Pending0') {
+    handleTurnData('', '', '') // 因为Pending没有时间筛选,所以传空
+    reportList._reportType = 'r4'
+    reportList._reportRef = pie_chart_pending_departure.value[0].paramsdata.name
+    handlereportlist(
+      dashboardObj.PendingDefaultData.transportation,
+      dashboardObj.PendingDefaultData.date_type,
+      ''
+    )
+    sessionStorage.setItem('clickParams', 'clickParams')
+    sessionStorage.setItem('reportList', JSON.stringify(reportList))
+    let obj: any = {}
+    obj.title = 'Pending Departure'
+    obj.name = pie_chart_pending_departure.value[0].paramsdata.name
+    sessionStorage.setItem('tagsList', JSON.stringify(obj))
+    router.push({
+      path: '/tracking'
+    })
+  }
+  // KPIDeparture点击跳转
+  else if (val == 'KPI0') {
+    handleTurnData(
+      dashboardObj.KPIDefaulteData.date_start,
+      dashboardObj.KPIDefaulteData.date_end,
+      ''
+    )
+    reportList._reportRef = pie_chart_kpi_departure.value[0].paramsdata.name
+    reportList._reportType = 'atd_r4'
+    handlereportlist(
+      dashboardObj.KPIDefaulteData.transportation,
+      dashboardObj.KPIDefaulteData.date_type,
+      ''
+    )
+    sessionStorage.setItem('clickParams', 'clickParams')
+    sessionStorage.setItem('reportList', JSON.stringify(reportList))
+    let obj: any = {}
+    obj.title = 'KPI Departure'
+    obj.name = pie_chart_kpi_departure.value[0].paramsdata.name
+    sessionStorage.setItem('tagsList', JSON.stringify(obj))
+    router.push({
+      path: '/tracking'
+    })
+  }
+  // KPIArrival点击跳转
+  else if (val == 'KPI1') {
+    handleTurnData(
+      dashboardObj.KPIDefaulteData.date_start,
+      dashboardObj.KPIDefaulteData.date_end,
+      ''
+    )
+    reportList._reportRef = pie_chart_kpi_arrival.value[0]?.paramsdata?.name || ''
+    reportList._reportType = 'ata_r3'
+    handlereportlist(
+      dashboardObj.KPIDefaulteData.transportation,
+      dashboardObj.KPIDefaulteData.date_type,
+      ''
+    )
+    sessionStorage.setItem('clickParams', 'clickParams')
+    sessionStorage.setItem('reportList', JSON.stringify(reportList))
+    let obj: any = {}
+    obj.title = 'KPI Arrival'
+    obj.name = pie_chart_kpi_arrival.value[0]?.paramsdata?.name || ''
+    sessionStorage.setItem('tagsList', JSON.stringify(obj))
+    router.push({
+      path: '/tracking'
+    })
+  }
+  // Top10 origin点击跳转
+  else if (val == 'Top 10 Origin') {
+    handleTurnData(dashboardObj.Top10faultData.date_start, dashboardObj.Top10faultData.date_end, '')
+    reportList._reportRef = seller_chart_top10_origin.value[0].paramsdata
+    reportList._reportType = 'top'
+    reportList._reportStationType = toporiginType.value
+    reportList._city_name = seller_chart_top10_origin.value[0].paramscityname
+    handlereportlist(
+      dashboardObj.Top10faultData.transportation,
+      dashboardObj.Top10faultData.date_type,
+      ''
+    )
+    sessionStorage.setItem('clickParams', 'clickParams')
+    sessionStorage.setItem('reportList', JSON.stringify(reportList))
+    let obj: any = {}
+    obj.title = 'Top 10 Origin'
+    obj.name = seller_chart_top10_origin.value[0].paramsdata
+    obj.data = seller_chart_top10_origin.value[0].paramscityname
+    sessionStorage.setItem('tagsList', JSON.stringify(obj))
+    router.push({
+      path: '/tracking'
+    })
+  }
+  // Top10 destination点击跳转
+  else if (val == 'Top 10 Destination') {
+    handleTurnData(dashboardObj.Top10faultData.date_start, dashboardObj.Top10faultData.date_end, '')
+    reportList._reportRef = seller_chart_top10_destination.value[0].paramsdata
+    reportList._reportStationType = topdestinationinType.value
+    reportList._reportType = 'top'
+    reportList._city_name = seller_chart_top10_destination.value[0].paramscityname
+    handlereportlist(
+      dashboardObj.Top10faultData.transportation,
+      dashboardObj.Top10faultData.date_type,
+      ''
+    )
+    sessionStorage.setItem('clickParams', 'clickParams')
+    sessionStorage.setItem('reportList', JSON.stringify(reportList))
+    let obj: any = {}
+    obj.title = 'Top 10 Destination'
+    obj.name = seller_chart_top10_destination.value[0].paramsdata
+    obj.data = seller_chart_top10_destination.value[0].paramscityname
+    sessionStorage.setItem('tagsList', JSON.stringify(obj))
+    router.push({
+      path: '/tracking'
+    })
+  }
+  // CO2e Emission by Origin (Top 10)点击跳转
+  else if (val == 'CO2e Emission by Origin (Top 10)') {
+    handleTurnData(
+      dashboardObj.OriginCo2Top10faultData.date_start,
+      dashboardObj.OriginCo2Top10faultData.date_end,
+      ''
+    )
+    reportList._reportRef = seller_chart_CO2_origin.value[0].paramsdata.name
+    reportList._reportDataType = seller_chart_CO2_origin.value[0].paramsdata.type
+    reportList._reportStationType = 'origin'
+    reportList._reportType = 'co2e'
+    handlereportlist(
+      dashboardObj.OriginCo2Top10faultData.transportation,
+      dashboardObj.OriginCo2Top10faultData.date_type,
+      ''
+    )
+    sessionStorage.setItem('clickParams', 'clickParams')
+    sessionStorage.setItem('reportList', JSON.stringify(reportList))
+    let obj: any = {}
+    obj.title = 'CO2e Emission by Origin (Top 10)'
+    obj.name = seller_chart_CO2_origin.value[0].paramsdata.name
+    sessionStorage.setItem('tagsList', JSON.stringify(obj))
+    router.push({
+      path: '/tracking'
+    })
+  }
+  // CO2e Emission by Origin (Top 10)点击跳转
+  else if (val == 'CO2e Emission by Destination (Top 10)') {
+    handleTurnData(
+      dashboardObj.DestinationCo2Top10faultData.date_start,
+      dashboardObj.DestinationCo2Top10faultData.date_end,
+      ''
+    )
+    reportList._reportRef = seller_chart_CO2_destination.value[0].paramsdata.name
+    reportList._reportDataType = seller_chart_CO2_destination.value[0].paramsdata.type
+    reportList._reportType = 'co2e'
+    reportList._reportStationType = 'agent'
+    handlereportlist(
+      dashboardObj.DestinationCo2Top10faultData.transportation,
+      dashboardObj.DestinationCo2Top10faultData.date_type,
+      ''
+    )
+    sessionStorage.setItem('clickParams', 'clickParams')
+    sessionStorage.setItem('reportList', JSON.stringify(reportList))
+    let obj: any = {}
+    obj.title = 'CO2e Emission by Destination (Top 10)'
+    obj.name = seller_chart_CO2_destination.value[0].paramsdata.name
+    sessionStorage.setItem('tagsList', JSON.stringify(obj))
+    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'
+
+// ====== 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" 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>
+            <el-divider />
+            <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',
+            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>
+                  <!-- <el-tooltip
+                    effect="dark"
+                    :offset="6"
+                    :content="item.text"
+                    placement="bottom-start"
+                  >
+                    <span class="iconfont_icon iconfont_icon_tip">
+                      <svg class="iconfont" aria-hidden="true">
+                        <use xlink:href="#icon-icon_info_b"></use>
+                      </svg>
+                    </span>
+                  </el-tooltip> -->
+                </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-y: hidden;
+  border-radius: 12px;
+  background-color: var(--management-bg-color);
+}
+.Management:hover {
+  overflow-y: scroll;
+}
+.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_content {
+  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);
+}
+.el-divider--horizontal {
+  margin: 8px 0;
+}
+.Save_filters {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  height: 40px;
+  font-size: var(--font-size-3);
+  width: 126px;
+  margin: 4px 0;
+  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;
+}
+.KPI_title {
+  border-bottom: 1px solid var(--color-border);
+  height: 48px;
+  line-height: 48px;
+  align-items: center;
+  justify-content: space-between;
+  display: flex;
+  padding-left: 16px;
+  font-weight: 700;
+  font-size: var(--font-size-5);
+}
+.tips_filter {
+  margin-right: 8px;
+  height: 32px;
+}
+.filters_right {
+  width: 251px;
+  height: 32px;
+  margin-bottom: 8px;
+}
+: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: #fff;
+  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;
+}
+.container-type {
+  font-size: 14px;
+  font-weight: 400;
+  margin-right: 4px;
+}
+.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;
+}
+.iconfont_icon_tip {
+  margin-left: 8px;
+  width: 16px;
+  height: 16px;
+  display: flex;
+  align-items: center;
+}
+.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>

+ 920 - 0
src/views/Tracking/src/TrackingView.new.vue

@@ -0,0 +1,920 @@
+<script setup lang="ts">
+import FilterTags from '@/components/FliterTags'
+import emitter from '@/utils/bus'
+import TransportMode from '@/components/TransportMode'
+import TrackingTable from './components/TrackingTable'
+import DateRange from '@/components/DateRange'
+import MoreFilters from '@/components/MoreFilters'
+import { ref, reactive, onMounted } from 'vue'
+import { useCalculatingHeight } from '@/hooks/calculatingHeight'
+import { useHeaderSearch } from '@/stores/modules/headerSearch'
+import { useUserStore } from '@/stores/modules/user'
+import dayjs from 'dayjs'
+import {
+  FiltersType,
+  updateFilter,
+  deleteFilter,
+  getFilterIndex,
+  getFitler,
+  getTags
+} from '@/utils/filters'
+
+const userStore = useUserStore()
+const formatDate = userStore.dateFormat
+const valueFormatDate = 'MM/DD/YYYY'
+
+const filtersList = ref<FiltersType[]>([])
+
+const initPage = () => {
+  if (sessionStorage.getItem('trackingFilters') != null) {
+    filtersList.value = getTags(
+      JSON.parse(sessionStorage.getItem('trackingFilters') as string)
+    ) as unknown as FiltersType[]
+  }
+}
+
+const headerSearch = useHeaderSearch()
+const filterRef: Ref<HTMLElement | null> = ref(null)
+
+const containerHeight = useCalculatingHeight(document.documentElement, 246, [filterRef])
+
+const TrackingSearch = ref()
+const tableLoadingTableData = ref(false)
+let searchTableQeuryTracking: any = {}
+const filterData = reactive({
+  filtersTagData: [] as Array<string>,
+  transportData: [] as Array<string>,
+  daterangeData: [] as Array<string>,
+  morefiltersData: [] as Array<string>,
+  dashboardData: [] as Array<string>
+})
+const tagsData: any = ref([])
+const handleClose = (tag: any) => {
+  emitter.emit('clearTag', tag)
+  tagsData.value.splice(tagsData.value.indexOf(tag), 1)
+  if (
+    sessionStorage.getItem('reportList') != null ||
+    sessionStorage.getItem('reportList') != '{}'
+  ) {
+    const reportList = JSON.parse(sessionStorage.getItem('reportList') as string) || {}
+    let data = JSON.parse(sessionStorage.getItem('tagsList') as string) || {}
+    if (tag.includes('Transport')) {
+      delete reportList.transport_mode
+    } else if (tag.includes('Day') || tag.includes('CO2e')) {
+      delete reportList._reportRef
+      delete reportList._reportType
+      delete reportList._reportRefe_date
+      delete reportList._reportRefb_date
+      delete reportList._reportStationType
+      delete reportList._reportDataType
+      delete reportList._reportStationType
+      filterData.dashboardData = []
+      data = {}
+    } else if (tag.includes('ETD')) {
+      filterData.daterangeData.forEach((item: any, index: any) => {
+        if (item.includes('ETD')) {
+          filterData.daterangeData.splice(index, 1)
+        }
+      })
+      delete reportList.etd_start
+      delete reportList.etd_end
+    } else if (tag.includes('ETA')) {
+      filterData.daterangeData.forEach((item: any, index: any) => {
+        if (item.includes('ETA')) {
+          filterData.daterangeData.splice(index, 1)
+        }
+      })
+      delete reportList.eta_start
+      delete reportList.eta_end
+    } else if (tag.includes('Origin')) {
+      delete reportList.shipper_city
+      delete reportList._city_name
+      filterData.dashboardData = []
+    } else if (tag.includes('Destination')) {
+      delete reportList.consignee_city
+    }
+    sessionStorage.setItem('reportList', JSON.stringify(reportList))
+    sessionStorage.setItem('tagsList', JSON.stringify(data))
+  }
+  if (tag.includes('Transport')) {
+    delete searchTableQeuryTracking.transport_mode
+  } else if (tag.includes('Day') || tag.includes('CO2e')) {
+    delete searchTableQeuryTracking._reportRef
+    delete searchTableQeuryTracking._reportType
+    delete searchTableQeuryTracking._reportRefe_date
+    delete searchTableQeuryTracking._reportRefb_date
+    delete searchTableQeuryTracking._reportStationType
+    delete searchTableQeuryTracking._reportDataType
+    delete searchTableQeuryTracking._reportStationType
+    filterData.dashboardData = []
+  } else if (tag.includes('ETD')) {
+    filterData.daterangeData.forEach((item: any, index: any) => {
+      if (item.includes('ETD')) {
+        filterData.daterangeData.splice(index, 1)
+      }
+    })
+    delete searchTableQeuryTracking.etd_start
+    delete searchTableQeuryTracking.etd_end
+  } else if (tag.includes('ETA')) {
+    filterData.daterangeData.forEach((item: any, index: any) => {
+      if (item.includes('ETA')) {
+        filterData.daterangeData.splice(index, 1)
+      }
+    })
+    delete searchTableQeuryTracking.eta_start
+    delete searchTableQeuryTracking.eta_end
+  } else if (tag.includes('Creation')) {
+    delete searchTableQeuryTracking.created_time_start
+    delete searchTableQeuryTracking.created_time_end
+  } else if (tag.includes('Shippername')) {
+    delete searchTableQeuryTracking.shipper
+  } else if (tag.includes('Consigneename')) {
+    delete searchTableQeuryTracking.consignee
+  } else if (tag.includes('Service')) {
+    delete searchTableQeuryTracking.service
+  } else if (tag.includes('Incoterms')) {
+    delete searchTableQeuryTracking.incoterms
+  } else if (tag.includes('Notify Party')) {
+    delete searchTableQeuryTracking.notify_party
+  } else if (tag.includes('Bill to')) {
+    delete searchTableQeuryTracking.billto
+  } else if (tag.includes('Origin Agent')) {
+    delete searchTableQeuryTracking.origin
+  } else if (tag.includes('Destination Agent')) {
+    delete searchTableQeuryTracking.agent
+  } else if (tag.includes('Destination Operator')) {
+    delete searchTableQeuryTracking.dest_op
+  } else if (tag.includes('Sales')) {
+    delete searchTableQeuryTracking.sales_rep
+  } else if (tag.includes('Origin')) {
+    delete searchTableQeuryTracking.shipper_city
+    delete searchTableQeuryTracking._city_name
+    filterData.dashboardData = []
+  } else if (tag.includes('Destination')) {
+    delete searchTableQeuryTracking.consignee_city
+  } else if (tag.includes('Place of Receipt')) {
+    delete searchTableQeuryTracking.place_of_receipt_exp
+  } else if (tag.includes('Port of Loading')) {
+    delete searchTableQeuryTracking.port_of_loading
+  } else if (tag.includes('Place of delivery')) {
+    delete searchTableQeuryTracking.place_of_delivery_exp
+  } else if (tag.includes('Place of Discharge')) {
+    delete searchTableQeuryTracking.port_of_discharge
+  } else if (tag.includes('Vessel')) {
+    delete searchTableQeuryTracking['f_vessel/vessel']
+  } else if (tag.includes('Voyage')) {
+    delete searchTableQeuryTracking['f_voyage/voyage']
+  }
+
+  sessionStorage.setItem('searchTableQeuryTracking', JSON.stringify(searchTableQeuryTracking))
+  getTrackingData()
+}
+// 筛选框查询
+const FiltersSeach = (val: any, value: any) => {
+  searchTableQeuryTracking[val] = value
+
+  sessionStorage.setItem('searchTableQeuryTracking', JSON.stringify(searchTableQeuryTracking))
+  getTrackingData()
+}
+//TransportSearch
+const TransportSearch = (val: any) => {
+  filterData.transportData = []
+  if (val.data.length != 0) {
+    let str = `${val.title}:${val.data}`
+    filterData.transportData.push(str)
+  }
+  FiltersSeach('transport_mode', val.data)
+  renderTagsData()
+}
+// defaultTransport
+const defaultTransport = (val: any, value: any) => {
+  filterData.transportData = []
+  if (val.data.length != 0) {
+    let str = `${val.title}:${val.data}`
+    filterData.transportData.push(str)
+  }
+  if (sessionStorage.getItem('searchTableQeuryTracking') == null) {
+    if (
+      sessionStorage.getItem('clickParams') === null ||
+      sessionStorage.getItem('clickParams') === '{}'
+    ) {
+      searchTableQeuryTracking.transport_mode = val.data
+    }
+  } else {
+    searchTableQeuryTracking = value
+  }
+}
+const setFilterData = (dateRangeData: any) => {
+  filterData.daterangeData = []
+  for (const key in dateRangeData) {
+    const startEnd = dateRangeData[key].data[0] + ' To ' + dateRangeData[key].data[1]
+    let str = `${key}:${startEnd}`
+    filterData.daterangeData.push(str)
+  }
+}
+//defaultDate
+const defaultDate = (dateRangeData: any, data: any) => {
+  setFilterData(dateRangeData)
+
+  if (sessionStorage.getItem('searchTableQeuryTracking') == null) {
+    if (
+      sessionStorage.getItem('clickParams') === null ||
+      sessionStorage.getItem('clickParams') === '{}'
+    ) {
+      if (Object.keys(dateRangeData).length == 0) {
+        delete searchTableQeuryTracking.etd_start
+        delete searchTableQeuryTracking.etd_end
+      }
+      for (const key in dateRangeData) {
+        searchTableQeuryTracking.etd_start = dateRangeData[key].data[0]
+
+        searchTableQeuryTracking.etd_end = dateRangeData[key].data[1]
+      }
+    }
+  } else {
+    searchTableQeuryTracking = data
+    if (searchTableQeuryTracking._textSearch) {
+      TrackingSearch.value = searchTableQeuryTracking._textSearch
+    }
+  }
+
+  const rawData = localStorage.getItem('searchData')
+  const trackingData = rawData ? JSON.parse(rawData) : null
+  if (trackingData) {
+    // 根据顶部搜索框的搜索结果赋值
+    initDataByHeaderSearch()
+  } else if (!trackingData && !sessionStorage.getItem('clickParams')) {
+    getTrackingData()
+  }
+
+  renderTagsData()
+}
+//DateRangeSearch
+const DateRangeSearch = (dateRangeData: any) => {
+  setFilterData(dateRangeData)
+  if (Object.keys(dateRangeData).length == 0) {
+    delete searchTableQeuryTracking.etd_start
+    delete searchTableQeuryTracking.etd_end
+    delete searchTableQeuryTracking.eta_start
+    delete searchTableQeuryTracking.eta_end
+    delete searchTableQeuryTracking.created_time_start
+    delete searchTableQeuryTracking.created_time_end
+  }
+  const fieldList = [
+    {
+      title: 'ETD',
+      keys: ['etd_start', 'etd_end']
+    },
+    { title: 'ETA', keys: ['eta_start', 'eta_end'] },
+    { title: 'Creation Time', keys: ['created_time_start', 'created_time_end'] }
+  ]
+  fieldList.forEach((item) => {
+    if (!dateRangeData.hasOwnProperty(item.title)) {
+      // 删除不存在的字段
+      searchTableQeuryTracking[item.keys[0]] = undefined
+      searchTableQeuryTracking[item.keys[1]] = undefined
+    }
+  })
+  for (const key in dateRangeData) {
+    if (key == 'ETD') {
+      searchTableQeuryTracking.etd_start = dateRangeData[key].data[0]
+      searchTableQeuryTracking.etd_end = dateRangeData[key].data[1]
+    } else if (key == 'ETA') {
+      searchTableQeuryTracking.eta_start = dateRangeData[key].data[0]
+      searchTableQeuryTracking.eta_end = dateRangeData[key].data[1]
+    } else {
+      searchTableQeuryTracking.created_time_start = dateRangeData[key].data[0]
+      searchTableQeuryTracking.created_time_end = dateRangeData[key].data[1]
+    }
+  }
+  sessionStorage.setItem('searchTableQeuryTracking', JSON.stringify(searchTableQeuryTracking))
+  getTrackingData()
+  renderTagsData()
+}
+//MoreFiltersSearch
+const MoreFiltersSearch = (val: any, value: any) => {
+  filterData.morefiltersData = []
+  if (Object.keys(value).length == 0) {
+    delete searchTableQeuryTracking.shipper
+    delete searchTableQeuryTracking.consignee
+    delete searchTableQeuryTracking.service
+    delete searchTableQeuryTracking.incoterms
+    delete searchTableQeuryTracking.notify_party
+    delete searchTableQeuryTracking.billto
+    delete searchTableQeuryTracking.origin
+    delete searchTableQeuryTracking.agent
+    delete searchTableQeuryTracking.sales_rep
+    delete searchTableQeuryTracking.dest_op
+    delete searchTableQeuryTracking.consignee_city
+    delete searchTableQeuryTracking.place_of_receipt_exp
+    delete searchTableQeuryTracking.place_of_delivery_exp
+    delete searchTableQeuryTracking.port_of_discharge
+    delete searchTableQeuryTracking.shipper_city
+    delete searchTableQeuryTracking['port_of_loading/fport_of_loading_un']
+    delete searchTableQeuryTracking['f_vessel/vessel']
+    delete searchTableQeuryTracking['f_voyage/voyage']
+  }
+  for (const key in val) {
+    let str = `${key}:${val[key]}`
+    filterData.morefiltersData.push(str)
+    if (key == 'Shippername') {
+      searchTableQeuryTracking.shipper = value[key]
+    } else if (key == 'Consigneename') {
+      searchTableQeuryTracking.consignee = value[key]
+    } else if (key == 'Service') {
+      searchTableQeuryTracking.service = value[key]
+    } else if (key == 'Incoterms') {
+      searchTableQeuryTracking.incoterms = value[key]
+    } else if (key == 'Notify Party') {
+      searchTableQeuryTracking.notify_party = value[key]
+    } else if (key == 'Bill to') {
+      searchTableQeuryTracking.billto = value[key]
+    } else if (key == 'Origin Agent') {
+      searchTableQeuryTracking.origin = value[key]
+    } else if (key == 'Destination Agent') {
+      searchTableQeuryTracking.agent = value[key]
+    } else if (key == 'Destination Operator') {
+      searchTableQeuryTracking.dest_op = value[key]
+    } else if (key == 'Sales') {
+      searchTableQeuryTracking.sales_rep = value[key]
+    } else if (key == 'Destination') {
+      searchTableQeuryTracking.consignee_city = value[key]
+    } else if (key == 'Place of Receipt') {
+      searchTableQeuryTracking.place_of_receipt_exp = value[key]
+    } else if (key == 'Origin') {
+      searchTableQeuryTracking.shipper_city = value[key]
+    } else if (key == 'Port of Loading') {
+      searchTableQeuryTracking['port_of_loading/fport_of_loading_un'] = value[key]
+    } else if (key == 'Place of delivery') {
+      searchTableQeuryTracking.place_of_delivery_exp = value[key]
+    } else if (key == 'Port of Discharge') {
+      searchTableQeuryTracking.port_of_discharge = value[key]
+    } else if (key == 'Vessel') {
+      searchTableQeuryTracking['f_vessel/vessel'] = value[key]
+    } else if (key == 'Voyage') {
+      searchTableQeuryTracking['f_voyage/voyage'] = value[key]
+    }
+  }
+  sessionStorage.setItem('searchTableQeuryTracking', JSON.stringify(searchTableQeuryTracking))
+  getTrackingData()
+  renderTagsData()
+}
+const defaultMorefilters = (val: any, value: any, data: any) => {
+  filterData.morefiltersData = []
+  for (const key in val) {
+    let str = `${key}:${val[key]}`
+    filterData.morefiltersData.push(str)
+    for (const key in val) {
+      if (key == 'Shippername') {
+        searchTableQeuryTracking.shipper = value[key]
+      } else if (key == 'Consigneename') {
+        searchTableQeuryTracking.consignee = value[key]
+      } else if (key == 'Service') {
+        searchTableQeuryTracking.service = value[key]
+      } else if (key == 'Incoterms') {
+        searchTableQeuryTracking.incoterms = value[key]
+      } else if (key == 'Notify Party') {
+        searchTableQeuryTracking.notify_party = value[key]
+      } else if (key == 'Bill to') {
+        searchTableQeuryTracking.billto = value[key]
+      } else if (key == 'Destination Operator') {
+        searchTableQeuryTracking.dest_op = value[key]
+      } else if (key == 'Origin Agent') {
+        searchTableQeuryTracking.origin = value[key]
+      } else if (key == 'Destination Agent') {
+        searchTableQeuryTracking.agent = value[key]
+      } else if (key == 'Sales') {
+        searchTableQeuryTracking.sales_rep = value[key]
+      } else if (key == 'Origin') {
+        searchTableQeuryTracking.shipper_city = value[key]
+      } else if (key == 'Destination') {
+        searchTableQeuryTracking.consignee_city = value[key]
+      } else if (key == 'Place of Receipt') {
+        searchTableQeuryTracking.place_of_receipt_exp = value[key]
+      } else if (key == 'Port of Loading') {
+        searchTableQeuryTracking.port_of_loading = value[key]
+      } else if (key == 'Place of delivery') {
+        searchTableQeuryTracking.place_of_delivery_exp = value[key]
+      } else if (key == 'Place of Discharge') {
+        searchTableQeuryTracking.port_of_discharge = value[key]
+      } else if (key == 'Vessel') {
+        searchTableQeuryTracking['f_vessel/vessel'] = value[key]
+      } else if (key == 'Voyage') {
+        searchTableQeuryTracking['f_voyage/voyage'] = value[key]
+      }
+    }
+    if (sessionStorage.getItem('searchTableQeuryTracking') != null) {
+      searchTableQeuryTracking = data
+    }
+  }
+}
+const clearfilters = () => {
+  TrackingSearch.value = ''
+  filterData.filtersTagData = []
+  tagsData.value = []
+  let str = 'Shipment status: All'
+  filterData.filtersTagData.push(str)
+  filterData.transportData = []
+  filterData.daterangeData = []
+  filterData.morefiltersData = []
+  filterData.dashboardData = []
+  emitter.emit('clearTag', 'Shipment status')
+  emitter.emit('clearTag', 'Transport Mode')
+  emitter.emit('clearTag', 'ETD')
+  emitter.emit('clearTag', 'ETA')
+  emitter.emit('clearTag', 'Creation Time')
+  emitter.emit('clearTag', 'Shippername')
+  emitter.emit('clearTag', 'Consigneename')
+  emitter.emit('clearTag', 'Service')
+  emitter.emit('clearTag', 'Incoterms')
+  emitter.emit('clearTag', 'Notify Party')
+  emitter.emit('clearTag', 'Bill to')
+  emitter.emit('clearTag', 'Origin Agent')
+  emitter.emit('clearTag', 'Destination Agent')
+  emitter.emit('clearTag', 'Destination Operator')
+  emitter.emit('clearTag', 'Sales')
+  emitter.emit('clearTag', 'Origin')
+  emitter.emit('clearTag', 'Destination')
+  emitter.emit('clearTag', 'Place of Receipt')
+  emitter.emit('clearTag', 'Port of Loading')
+  emitter.emit('clearTag', 'Place of delivery')
+  emitter.emit('clearTag', 'Port of Discharge')
+  emitter.emit('clearTag', 'Vessel')
+  emitter.emit('clearTag', 'Voyage')
+  searchTableQeuryTracking = {}
+  searchTableQeuryTracking.filterTag = ['All']
+  sessionStorage.setItem('searchTableQeuryTracking', JSON.stringify(searchTableQeuryTracking))
+  if (
+    sessionStorage.getItem('reportList') != null ||
+    sessionStorage.getItem('reportList') != '{}'
+  ) {
+    // sessionStorage.removeItem('reportList')
+    sessionStorage.removeItem('tagsList')
+  }
+  getTrackingData()
+  renderTagsData()
+}
+const renderTagsData = () => {
+  const data = JSON.parse(sessionStorage.getItem('tagsList') as string) || {}
+  if (Object.keys(data).length != 0) {
+    let str = `${data.title}:${data.name}`
+    !filterData.dashboardData.includes(str) && filterData.dashboardData.push(str)
+  }
+  tagsData.value = []
+  if (filterData.transportData.length) {
+    tagsData.value.push(filterData.transportData[0])
+  }
+  if (filterData.daterangeData.length) {
+    filterData.daterangeData.forEach((item) => {
+      tagsData.value.push(item)
+    })
+  }
+  if (filterData.morefiltersData.length) {
+    filterData.morefiltersData.forEach((item) => {
+      tagsData.value.push(item)
+    })
+  }
+  if (filterData.dashboardData.length) {
+    filterData.dashboardData.forEach((item) => {
+      tagsData.value.push(item)
+    })
+  }
+  if (filterData.filtersTagData.length) {
+    filterData.filtersTagData.forEach((item) => {
+      tagsData.value.push(item)
+    })
+  }
+}
+// 清除 Transport Tags
+const clearTransportTags = () => {
+  filterData.transportData = []
+}
+// 清除 Daterange Tags
+const clearDaterangeTags = () => {
+  filterData.daterangeData = []
+}
+// 清除 MoreFilters Tags
+const clearMoreFiltersTags = () => {
+  filterData.morefiltersData = []
+}
+
+const initDataByHeaderSearch = () => {
+  const data = JSON.parse(localStorage.getItem('searchData'))
+  if (data) {
+    // 更新搜索框的值
+    TrackingSearch.value = data.searchValue
+    // 更新表格数据
+    TrackingTable_ref.value.getSharedTableData()
+    // 更新tagsList和TransportList
+    TransportListItem.value = data.trackingData.TransportList
+    TagsList.value = data.trackingData.tagsList
+    let obj = {
+      IncotermsList: data.trackingData.IncotermsList,
+      ServiceList: data.trackingData.ServiceList
+    }
+    sessionStorage.setItem('incotermsList', JSON.stringify(obj))
+    headerSearch.clearSearchData()
+    tagsData.value = []
+    filterData.transportData = []
+    filterData.daterangeData = []
+    filterData.morefiltersData = []
+    filterData.dashboardData = []
+    filterData.filtersTagData = []
+    let str = 'Shipment status: All'
+    filterData.filtersTagData.push(str)
+    searchTableQeuryTracking = {}
+    sessionStorage.removeItem('searchTableQeuryTracking')
+    searchTableQeuryTracking._textSearch = TrackingSearch.value
+    searchTableQeuryTracking.filterTag = ['All']
+
+    sessionStorage.setItem('searchTableQeuryTracking', JSON.stringify(searchTableQeuryTracking))
+    setTimeout(() => {
+      emitter.emit('clearTag', 'Shipment status')
+      emitter.emit('clearTag', 'Transport Mode')
+      emitter.emit('clearTag', 'ETD')
+      emitter.emit('clearTag', 'ETA')
+      emitter.emit('clearTag', 'Creation Time')
+      emitter.emit('clearTag', 'Shippername')
+      emitter.emit('clearTag', 'Consigneename')
+      emitter.emit('clearTag', 'Service')
+      emitter.emit('clearTag', 'Incoterms')
+      emitter.emit('clearTag', 'Notify Party')
+      emitter.emit('clearTag', 'Bill to')
+      emitter.emit('clearTag', 'Origin Agent')
+      emitter.emit('clearTag', 'Destination Agent')
+      emitter.emit('clearTag', 'Destination Operator')
+      emitter.emit('clearTag', 'Sales')
+      emitter.emit('clearTag', 'Origin')
+      emitter.emit('clearTag', 'Destination')
+      emitter.emit('clearTag', 'Place of Receipt')
+      emitter.emit('clearTag', 'Port of Loading')
+      emitter.emit('clearTag', 'Place of delivery')
+      emitter.emit('clearTag', 'Port of Discharge')
+      emitter.emit('clearTag', 'Vessel')
+      emitter.emit('clearTag', 'Voyage')
+    }, 2000)
+    renderTagsData()
+  }
+}
+
+// 从 store 中获取数据并绑定到输入框
+const headerSearchdData = computed(() => headerSearch.searchValue)
+// 监听顶部搜索结果的变化
+watch(
+  () => headerSearchdData.value,
+  (newData) => {
+    if (newData) {
+      initDataByHeaderSearch()
+    }
+  }
+)
+
+const TrackingTable_ref = ref()
+const TransportListItem = ref()
+interface ListItem {
+  name: string
+  number: number
+  type: string
+  checked: boolean
+}
+const TagsList = ref<ListItem[]>([])
+const filterTag = ref(['All'])
+const isShowAlertIcon = ref(false)
+const getTrackingData = () => {
+  const dateRangeKeys = [
+    'etd_start',
+    'etd_end',
+    'eta_start',
+    'eta_end',
+    'created_time_start',
+    'created_time_end'
+  ]
+  const curRangeData = {}
+  for (const key of dateRangeKeys) {
+    if (searchTableQeuryTracking[key]) {
+      curRangeData[key] = dayjs(searchTableQeuryTracking[key], formatDate).format(valueFormatDate)
+    }
+  }
+
+  tableLoadingTableData.value = true
+  TrackingTable_ref.value.getLoadingData(tableLoadingTableData.value)
+  $api
+    .getTrackingTableData({
+      cp: TrackingTable_ref.value.pageInfo.pageNo,
+      ps: TrackingTable_ref.value.pageInfo.pageSize,
+      rc: -1,
+      other_filed: '',
+      ...searchTableQeuryTracking,
+      ...curRangeData
+    })
+    .then((res: any) => {
+      if (res.code === 200) {
+        TransportListItem.value = res.data.TransportList
+        TagsList.value = res.data.tagsList
+        let obj = {
+          IncotermsList: res.data.IncotermsList,
+          ServiceList: res.data.ServiceList
+        }
+        let taglist: any = []
+        if (Object.keys(filterData.filtersTagData).length == 0) {
+          TagsList.value.forEach((item: any) => {
+            if (item.checked == true) {
+              taglist.push(item.name)
+            }
+          })
+          let str = 'Shipment status: ' + taglist.toString()
+          filterData.filtersTagData.push(str)
+          filterData.filtersTagData.forEach((item) => {
+            tagsData.value.push(item)
+          })
+        }
+        sessionStorage.setItem('incotermsList', JSON.stringify(obj))
+        sessionStorage.setItem('TrackingData', JSON.stringify(res.data))
+        TrackingTable_ref.value.searchTableData(searchTableQeuryTracking)
+        // 查询没结果的话显示icon
+        if (TrackingSearch.value != '' && TrackingSearch.value != undefined) {
+          if (res.data.searchData.length == 0) {
+            isShowAlertIcon.value = true
+          }
+        } else {
+          isShowAlertIcon.value = false
+        }
+      }
+    })
+    .finally(() => {
+      sessionStorage.removeItem('clickParams')
+    })
+}
+onMounted(() => {
+  if (
+    sessionStorage.getItem('clickParams') != null &&
+    sessionStorage.getItem('clickParams') != '{}'
+  ) {
+    const reportList = JSON.parse(sessionStorage.getItem('reportList') as string) || {}
+    for (const key in reportList) {
+      let str = ''
+      switch (key) {
+        case 'etd_start':
+          const startDate = dayjs(reportList['etd_start'], valueFormatDate).format(formatDate)
+          searchTableQeuryTracking['etd_start'] = startDate
+          const endDate = dayjs(reportList['etd_end'], valueFormatDate).format(formatDate)
+          searchTableQeuryTracking['etd_end'] = endDate
+          const startEnd = startDate + ' To ' + endDate
+          str = `ETD:${startEnd}`
+          // filterData.daterangeData.push(str)
+          break
+
+        case 'etd_end':
+          break
+        case 'eta_start':
+          const etaStart = dayjs(reportList['eta_start'], valueFormatDate).format(formatDate)
+          searchTableQeuryTracking['eta_start'] = etaStart
+          const etaEnd = dayjs(reportList['eta_end'], valueFormatDate).format(formatDate)
+          searchTableQeuryTracking['eta_end'] = etaEnd
+          str = `ETA:${etaStart} To ${etaEnd}`
+          // filterData.daterangeData.push(str)
+          break
+
+        case 'eta_end':
+          break
+        case 'created_time_start':
+          const createdTimeStart = dayjs(reportList['created_time_start'], valueFormatDate).format(
+            formatDate
+          )
+          searchTableQeuryTracking['created_time_start'] = createdTimeStart
+          const createdTimeEnd = dayjs(reportList['created_time_end'], valueFormatDate).format(
+            formatDate
+          )
+          searchTableQeuryTracking['created_time_end'] = createdTimeEnd
+          str = `Creation Time:${createdTimeStart} To ${createdTimeEnd}`
+          // filterData.daterangeData.push(str)
+          break
+        case 'created_time_end':
+          break
+        default:
+          searchTableQeuryTracking[key] = reportList[key]
+      }
+    }
+
+    // sessionStorage.removeItem('reportList')
+    sessionStorage.setItem('searchTableQeuryTracking', JSON.stringify(searchTableQeuryTracking))
+    getTrackingData()
+  }
+  renderTagsData()
+})
+const changeTag = (val: any, boolean: any) => {
+  filterData.filtersTagData = []
+  searchTableQeuryTracking.filterTag = val
+  let str = 'Shipment status: ' + val
+  filterData.filtersTagData.push(str)
+  filterTag.value = val
+
+  sessionStorage.setItem('searchTableQeuryTracking', JSON.stringify(searchTableQeuryTracking))
+  if (boolean) {
+    getTrackingData()
+  }
+  renderTagsData()
+}
+// 点击search按钮
+const SearchInput = () => {
+  searchTableQeuryTracking._textSearch = TrackingSearch.value
+
+  sessionStorage.setItem('searchTableQeuryTracking', JSON.stringify(searchTableQeuryTracking))
+  getTrackingData()
+}
+
+import TrackingGuide from './components/TrackingGuide.vue'
+import { useGuideStore } from '@/stores/modules/guide'
+
+const guideStore = useGuideStore()
+const trackingGuideRef = ref()
+const handleGuide = () => {
+  trackingGuideRef.value.startGuide() // 开始引导
+}
+</script>
+
+<template>
+  <div class="Title">
+    <span>Tracking</span>
+    <VDriverGuide @click="handleGuide"></VDriverGuide>
+  </div>
+  <TrackingGuide ref="trackingGuideRef"></TrackingGuide>
+  <div class="display" ref="filterRef">
+    <div class="filter-box">
+      <div class="filters-container" id="filters-container-guide">
+        <FilterTags :TagsListItem="TagsList" @changeTag="changeTag"></FilterTags>
+        <div class="heaer_top">
+          <div class="search">
+            <el-input
+              placeholder="Enter Booking/HBL/PO/Container/Carrier Booking No. "
+              v-model="TrackingSearch"
+              class="log_input"
+              @keyup.enter="SearchInput"
+            >
+              <template #prefix>
+                <span class="iconfont_icon">
+                  <svg class="iconfont icon_search" aria-hidden="true">
+                    <use xlink:href="#icon-icon_search_b"></use>
+                  </svg>
+                </span>
+              </template>
+              <template #suffix>
+                <el-tooltip
+                  v-if="isShowAlertIcon"
+                  :offset="6"
+                  popper-class="ShowAlerIcon"
+                  effect="dark"
+                  content="We support the following references number to find bookings:· Booking No./HAWB No./MAWB No./PO No./Carrier Booking No./Contract No./File No./Quote No."
+                  placement="bottom"
+                >
+                  <span class="iconfont_icon iconfont_icon_tip">
+                    <svg class="iconfont icon_search" aria-hidden="true">
+                      <use xlink:href="#icon-icon_info_b"></use>
+                    </svg>
+                  </span>
+                </el-tooltip>
+              </template>
+            </el-input>
+          </div>
+
+          <TransportMode
+            :isShipment="true"
+            :TransportListItem="TransportListItem"
+            @TransportSearch="TransportSearch"
+            @defaultTransport="defaultTransport"
+            @clearTransportTags="clearTransportTags"
+          ></TransportMode>
+          <DateRange
+            :isShipment="true"
+            @DateRangeSearch="DateRangeSearch"
+            @clearDaterangeTags="clearDaterangeTags"
+            @defaultDate="defaultDate"
+          ></DateRange>
+        </div>
+      </div>
+      <MoreFilters
+        :isShipment="true"
+        :searchTableQeury="searchTableQeuryTracking"
+        @MoreFiltersSearch="MoreFiltersSearch"
+        @clearMoreFiltersTags="clearMoreFiltersTags"
+        @defaultMorefilters="defaultMorefilters"
+        :isShowMoreFiltersGuidePhoto="guideStore.tracking.isShowMoreFiltersGuidePhoto"
+        :pageMode="'tracking'"
+      ></MoreFilters>
+      <el-button class="el-button--dark" style="margin-left: 8px" @click="SearchInput"
+        >Search</el-button
+      >
+    </div>
+    <!-- 筛选项 -->
+    <div class="filtersTag" v-if="tagsData.length" id="filter-tag-guide">
+      <el-tag
+        :key="tag"
+        class="tag"
+        v-for="tag in tagsData"
+        :closable="!tag.includes('Shipment')"
+        :disable-transitions="false"
+        @close="handleClose(tag)"
+        color="#EFEFF0"
+      >
+        <el-tooltip
+          class="box-item"
+          effect="dark"
+          :content="tag"
+          placement="top"
+          v-if="tag.length > 39"
+        >
+          {{ tag.length > 39 ? tag.substr(0, 39) + '...' : tag }}
+        </el-tooltip>
+        <div v-else>{{ tag }}</div>
+      </el-tag>
+      <div class="text_button" @click="clearfilters">Clear Filters</div>
+    </div>
+  </div>
+  <TrackingTable
+    :height="containerHeight"
+    :tagsData="tagsData"
+    ref="TrackingTable_ref"
+  ></TrackingTable>
+</template>
+
+<style lang="scss" scoped>
+.filter-box {
+  width: 100%;
+  display: flex;
+  flex-direction: row;
+  align-items: flex-end;
+  height: 100%;
+}
+.filters-container {
+  max-width: 1426px;
+  width: 80%;
+  display: flex;
+  flex-direction: column;
+}
+
+.Title {
+  display: flex;
+  height: 68px;
+  border: 1px solid var(--color-border);
+  border-top: none;
+  border-width: 1px 0 1px 0;
+  font-size: var(--font-size-6);
+  font-weight: 700;
+  padding: 0 24px;
+  align-items: center;
+}
+.display {
+  border: 1px solid var(--color-border);
+  border-width: 0 0 1px 0;
+  padding: 0 24px;
+}
+.heaer_top {
+  position: relative;
+  margin-top: 6.57px;
+  display: flex;
+}
+.search {
+  // width: 400px;
+  height: 32px;
+}
+.filtersTag {
+  margin-top: 8px;
+  margin-bottom: 4px;
+  display: inline-flex;
+  align-items: center;
+  flex-wrap: wrap;
+}
+.tag {
+  border-radius: var(--border-radius-22);
+  margin: 0 8px 8px 0;
+  color: var(--color-neutral-1);
+  font-weight: 600;
+  font-size: var(--font-size-2);
+  border-color: var(--tag-boder-color);
+  background-color: var(--tag-bg-color) !important;
+}
+.iconfont_icon_tip {
+  margin-left: 8px;
+  width: 16px;
+  height: 16px;
+  display: flex;
+  align-items: center;
+}
+.icon_search {
+  fill: var(--color-neutral-1);
+}
+@media only screen and (min-width: 1280px) {
+  .search {
+    width: 480px;
+  }
+}
+@media only screen and (min-width: 1440px) {
+  .search {
+    width: 740px;
+  }
+}
+:deep(.log_input .el-input__wrapper) {
+  box-shadow: 0 0 0 1px var(--color-select-border) inset;
+  border-radius: 6px;
+}
+</style>