Sfoglia il codice sorgente

feat:添加查询接口/添加图表数据获取接口/添加横幅评分

AmandaG 1 anno fa
parent
commit
bf1d4cefa9

+ 1 - 0
package.json

@@ -23,6 +23,7 @@
     "element-plus": "^2.8.1",
     "exceljs": "^4.4.0",
     "js-md5": "^0.8.3",
+    "leaflet": "^1.9.4",
     "lodash": "^4.17.21",
     "mitt": "^3.0.1",
     "moment": "^2.30.1",

+ 149 - 0
src/api/module/common.ts

@@ -24,3 +24,152 @@ export const saveTableSettingColumns = (params: any, config: any) => {
     config
   )
 }
+/**
+ * 获取日志列
+ */
+export const getOperationTableColumns = (params: any, config: any) => {
+  return HttpAxios.get(
+    `${baseUrl}`,
+    {
+      action: 'opreation_log',
+    },
+    config
+  )
+}
+/**
+ * 查询日志
+ */
+export const SearchOperationLog = (params: any, config: any) => {
+  return HttpAxios.post(
+    `${baseUrl}`,
+    {
+      action: 'opreation_log',
+      operate: 'search',
+      ...params
+    },
+    config
+  )
+}
+/**
+ * 获取首页数据
+ */
+export const GetDashboardData = (params: any, config: any) => {
+  return HttpAxios.post(
+    `${baseUrl}`,
+    {
+      action: 'main_welcome',
+      ...params
+    },
+    config
+  )
+}
+/**
+ * 获取ETD to ETA (Days)
+ */
+export const GetETDEcharts = (params: any, config: any) => {
+  return HttpAxios.get(
+    `${baseUrl}`,
+    {
+      action: 'main_report',
+      r_type: 'r1',
+      ...params
+    },
+    config
+  )
+}
+/**
+ * 获取KPI Echarts
+ */
+export const GetKPIEcharts = (params: any, config: any) => {
+  return HttpAxios.get(
+    `${baseUrl}`,
+    {
+      action: 'main_report_kpi',
+      ...params
+    },
+    config
+  )
+}
+/**
+ * 获取Pending Echarts
+ */
+export const GetPendingEcharts = (params: any, config: any) => {
+  return HttpAxios.get(
+    `${baseUrl}`,
+    {
+      action: 'main_report',
+      ...params
+    },
+    config
+  )
+}
+/**
+ * 获取ContainerCount Echarts
+ */
+export const GetContainerCountEcharts = (params: any, config: any) => {
+  return HttpAxios.get(
+    `${baseUrl}`,
+    {
+      action: 'main_report_container_bar',
+      r_type: 'r2',
+      ...params
+    },
+    config
+  )
+}
+/**
+ * 获取CO2 Emission
+ */
+export const GetCo2EmissionEcharts = (params: any, config: any) => {
+  return HttpAxios.get(
+    `${baseUrl}`,
+    {
+      action: 'main_report_co2e_bar',
+      r_type: 'co2e_orgin',
+      ...params
+    },
+    config
+  )
+}
+/**
+ * 获取CO2 Destination
+ */
+export const GetCo2DestinationEcharts = (params: any, config: any) => {
+  return HttpAxios.get(
+    `${baseUrl}`,
+    {
+      action: 'main_report_co2e_bar',
+      r_type: 'co2e_destination',
+      ...params
+    },
+    config
+  )
+}
+/**
+ * Top10 Origin/Destination
+ */
+export const GetTop10ODEcharts = (params: any, config: any) => {
+  return HttpAxios.get(
+    `${baseUrl}`,
+    {
+      action: 'main_report_top10_bar',
+      r_type: 'top',
+      ...params
+    },
+    config
+  )
+}
+/**
+ * Save Layout
+ */
+export const SaveLayout = (params: any, config: any) => {
+  return HttpAxios.post(
+    `${baseUrl}`,
+    {
+      action: 'save_layout',
+      ...params
+    },
+    config
+  )
+}
+

+ 7 - 2
src/components/DateRange/src/DateRange.vue

@@ -3,6 +3,7 @@ import emitter from '@/utils/bus'
 import { ref, computed, onMounted, onBeforeMount } from 'vue'
 import IconDropDown from '@/components/IconDropDown'
 import CalendarDate from './components/CalendarDate.vue'
+import moment from 'moment'
 
 onMounted(() => {
   emitter.on('clearTag', (tag: any) => {
@@ -50,12 +51,16 @@ const DateEnd = ref()
 const DateCreation = ref()
 const daterangedata = ref()
 daterangedata.value = []
+let daterangeObj2: any = {}
 const DateRangeChange = (val: any) => {
-  daterangeObj[val.title] = val.data[0] + ' To ' + val.data[1]
+  const date1 = moment(String(val.data[0])).format('MMM-DD-YYYY')
+  const date2 = moment(String(val.data[1])).format('MMM-DD-YYYY')
+  daterangeObj[val.title] = date1 + ' To ' + date2
+  daterangeObj2[val.title] = val
 }
 const emit = defineEmits(['DateRangeSearch', 'clearDaterangeTags'])
 const DateRangeSearch = () => {
-  emit('DateRangeSearch', daterangeObj)
+  emit('DateRangeSearch', daterangeObj, daterangeObj2)
   Date_visible.value = false
 }
 const CalendarTitle = computed(() => {

+ 3 - 2
src/components/DateRange/src/components/CalendarDate.vue

@@ -23,7 +23,7 @@ watch(
     ETDDate.value = current
   }
 )
-const emit = defineEmits(['DateRangeChange'])
+const emit = defineEmits(['DateRangeChange', 'DateChange'])
 const open = ref(false)
 const Disabled = ref([false, false])
 const isShowExtra = ref(true)
@@ -58,6 +58,7 @@ const changeRangeData = (value: any) => {
       data: value
     }
     emit('DateRangeChange', rangedata)
+    emit('DateChange', value)
   }
 }
 const handlePanelChange = (value: any, mode: any) => {
@@ -81,7 +82,7 @@ const handlePanelChange = (value: any, mode: any) => {
       @change="changeRangeData"
       :placeholder="['Start Time', 'End Time']"
       format="MMM-DD-YYYY"
-      valueFormat="MMM-DD-YYYY"
+      valueFormat="MM/DD/YYYY"
       @openChange="handleCalendarOpen"
       @panelChange="handlePanelChange"
       v-model:value="ETDDate"

+ 32 - 8
src/components/ScoringGrade/components/DialogUe.vue

@@ -5,20 +5,31 @@ const props = defineProps({
   content: String,
   dialogWidth: String,
   isShowAngry: Boolean,
-  isShowSmile: Boolean
+  isShowSmile: Boolean,
+  isShowHappy: Boolean
 })
 const checkboxGroup1 = ref([])
 const evaluate = [
+  'Lacking in functionality',
+  'Inaccurate data',
+  'Unclear information',
+  'Difficult to use',
+  'Poor system performance'
+]
+const happyevaluate = [
   'Complete funtionality',
-  'Accurate information',
-  'Visualization of shipments',
+  'Accurate data',
+  'Clear information',
   'Easy to use',
-  'Performance'
+  'Good performance'
 ]
-const emits = defineEmits(['changeAngryDetails', 'changeSmileRadio'])
+const emits = defineEmits(['changeAngryDetails', 'changeSmileRadio', 'changeHappybuttonbox'])
 const changebuttonbox = () => {
   emits('changeAngryDetails')
 }
+const changeHappybuttonbox = () => {
+  emits('changeHappybuttonbox')
+}
 const Aspects = ref([
   'Highly Dissatisfied',
   'Dissatisfied',
@@ -40,12 +51,12 @@ smileAspects.value = [
     radio: ''
   },
   {
-    title: 'Accurate information',
+    title: 'Accurate data',
     proposal: ['Highly Dissatisfied', 'Dissatisfied', 'Neutral', 'Satisfied', 'Highly Satisfied'],
     radio: ''
   },
   {
-    title: 'Visualization of shipments',
+    title: 'Clear information',
     proposal: ['Highly Dissatisfied', 'Dissatisfied', 'Neutral', 'Satisfied', 'Highly Satisfied'],
     radio: ''
   },
@@ -55,7 +66,7 @@ smileAspects.value = [
     radio: ''
   },
   {
-    title: 'Performance',
+    title: 'System Performance',
     proposal: ['Highly Dissatisfied', 'Dissatisfied', 'Neutral', 'Satisfied', 'Highly Satisfied'],
     radio: ''
   }
@@ -82,6 +93,18 @@ const changeSmileRadio = (title: any, value: any) => {
           </el-checkbox-button>
         </el-checkbox-group>
       </div>
+      <div v-if="props.isShowHappy" class="dialogflex">
+        <el-checkbox-group v-model="checkboxGroup1" size="large">
+          <el-checkbox-button
+            @change="changeHappybuttonbox"
+            v-for="item in happyevaluate"
+            :key="item"
+            :value="item"
+          >
+            {{ item }}
+          </el-checkbox-button>
+        </el-checkbox-group>
+      </div>
       <div v-if="props.isShowSmile">
         <div class="smile_flex">
           <div class="smile_title_left"></div>
@@ -197,6 +220,7 @@ const changeSmileRadio = (title: any, value: any) => {
   height: 41px;
   background-color: #fff;
   font-weight: 400;
+  border: 1px solid var(--color-border);
   font-size: var(--font-size-3);
   border-radius: 6px 0 0 6px;
   display: flex;

+ 20 - 1
src/components/ScoringGrade/src/ScoringGrade.vue

@@ -7,6 +7,7 @@ const isShow = ref(true)
 const visible = ref(false)
 const isLoaded = ref(false)
 const isShowAngry = ref(false)
+const isShowHappy = ref(false)
 const isShowSmile = ref(false)
 const isLoaded_share = ref(false)
 const isshowexpression = ref(true)
@@ -91,7 +92,7 @@ const showScore = (item: any) => {
       }, 1500)
     } else {
       setTimeout(() => {
-        isShowAngry.value = true
+        isShowHappy.value = true
         angryproposal.value = item.proposal
       }, 1500)
     }
@@ -107,6 +108,7 @@ const closeDialog = () => {
   isLoaded.value = false
   isLoaded_share.value = false
   isShowAngry.value = false
+  isShowHappy.value = false
   isshowDetails.value = false
   isShowSmile.value = false
   isshowexpression_details.value = false
@@ -120,6 +122,15 @@ const changeAngryDetails = () => {
     }, 1500)
   }, 1500)
 }
+//开心表情,选择建议后显示对话
+const changeHappybuttonbox = () => {
+  setTimeout(() => {
+    isLoaded_share.value = true
+    setTimeout(() => {
+      isshowexpression_details.value = true
+    }, 1500)
+  }, 1500)
+}
 // smile提交后显示对话
 const changeSmileRadio = (val: any) => {
   if (Object.keys(val).length == 5) {
@@ -197,6 +208,14 @@ const submitDetails = (val: any) => {
             dialogWidth="573px"
           ></DialogUe>
         </transition>
+        <transition name="fade" v-if="isShowHappy">
+          <DialogUe
+            :content="angryproposal"
+            :isShowHappy="isShowHappy"
+            @changeHappybuttonbox="changeHappybuttonbox"
+            dialogWidth="573px"
+          ></DialogUe>
+        </transition>
         <transition name="fade" v-if="isShowSmile">
           <DialogUe
             :isShowSmile="isShowSmile"

BIN
src/styles/images/dashboard_scoring.png


+ 53 - 19
src/views/Booking/src/BookingView.vue

@@ -14,6 +14,7 @@ const filterRef: Ref<HTMLElement | null> = ref(null)
 const containerHeight = useCalculatingHeight(document.documentElement, 246, [filterRef])
 
 const BookingSearch = ref()
+let searchTableQeury: any = {}
 const filterData = reactive({
   transportData: [] as Array<string>,
   daterangeData: [] as Array<string>,
@@ -24,6 +25,11 @@ const handleClose = (tag: any) => {
   emitter.emit('clearTag', tag)
   tagsData.value.splice(tagsData.value.indexOf(tag), 1)
 }
+// 筛选框查询
+const FiltersSeach = (val: any, value: any) => {
+  searchTableQeury[val] = value
+  BookingTable_ref.value.searchTableData(searchTableQeury)
+}
 //TransportSearch
 const TransportSearch = (val: any) => {
   filterData.transportData = []
@@ -31,15 +37,29 @@ const TransportSearch = (val: any) => {
     let str = `${val.title}:${val.data}`
     filterData.transportData.push(str)
   }
+  FiltersSeach('transport_mode', val.data)
   renderTagsData()
 }
 //DateRangeSearch
-const DateRangeSearch = (val: any) => {
+const DateRangeSearch = (val: any, value: any) => {
   filterData.daterangeData = []
   for (const key in val) {
     let str = `${key}:${val[key]}`
     filterData.daterangeData.push(str)
   }
+  for (const key in value) {
+    if (key == 'ETD') {
+      searchTableQeury.m_etd_start = value[key].data[0]
+      searchTableQeury.m_etd_end = value[key].data[1]
+    } else if (key == 'ETA') {
+      searchTableQeury.f_eta_start = value[key].data[0]
+      searchTableQeury.f_eta_end = value[key].data[1]
+    } else {
+      searchTableQeury.created_time_start = value[key].data[0]
+      searchTableQeury.created_time_end = value[key].data[1]
+    }
+  }
+  BookingTable_ref.value.searchTableData(searchTableQeury)
   renderTagsData()
 }
 //MoreFiltersSearch
@@ -48,7 +68,31 @@ const MoreFiltersSearch = (val: any) => {
   for (const key in val) {
     let str = `${key}:${val[key]}`
     filterData.morefiltersData.push(str)
+    if (key == 'shippername') {
+      searchTableQeury.shipper = val[key]
+    } else if (key == 'consigneename') {
+      searchTableQeury.consignee = val[key]
+    } else if (key == 'Origin Agent') {
+      searchTableQeury.origin = val[key]
+    } else if (key == 'Destination Agent') {
+      searchTableQeury.agent = val[key]
+    } else if (key == 'Sales') {
+      searchTableQeury.sales_rep = val[key]
+    } else if (key == 'destination') {
+      searchTableQeury['final_desination/final_desination_exp'] = val[key]
+    } else if (key == 'Place of Receipt') {
+      searchTableQeury.place_of_receipt = val[key]
+    } else if (key == 'Port of Loading') {
+      searchTableQeury['fport_of_loading/fport_of_loading_exp'] = val[key]
+    } else if (key == 'Port of delivery') {
+      searchTableQeury['place_of_delivery/place_of_delivery_exp'] = val[key]
+    } else if (key == 'vessel') {
+      searchTableQeury.vessel = val[key]
+    } else if (key == 'voyage') {
+      searchTableQeury['f_voyage/m_voyage'] = val[key]
+    }
   }
+  BookingTable_ref.value.searchTableData(searchTableQeury)
   renderTagsData()
 }
 const clearfilters = () => {
@@ -101,34 +145,22 @@ interface ListItem {
 }
 const TagsList = ref<ListItem[]>([])
 const filterTag = ref(['All'])
-// const getTableData = async () => {
-//   await $api
-//     .getBookingTableData({
-//       ...BookingTable_ref.value.querydata,
-//       other_filed: '',
-//       _textSearch: '',
-//       filterTag: filterTag.value
-//     })
-//     .then((res: any) => {
-//       if (res.code === 200) {
-//         TransportListItem.value = res.data.TransportList
-//         TagsList.value = res.data.tagsList
-//       }
-//     })
-// }
 onMounted(() => {
-  // getTableData()
   setTimeout(() => {
     TransportListItem.value = BookingTable_ref.value.TransportListItem
     TagsList.value = BookingTable_ref.value.TagsList
   }, 1000)
 })
-let searchTableQeury: any = {}
 const changeTag = (val: any) => {
   searchTableQeury.filterTag = val
   BookingTable_ref.value.searchTableData(searchTableQeury)
   filterTag.value = val
 }
+// 点击search按钮
+const SearchInput = () => {
+  searchTableQeury._textSearch = BookingSearch.value
+  BookingTable_ref.value.searchTableData(searchTableQeury)
+}
 </script>
 
 <template>
@@ -164,7 +196,9 @@ const changeTag = (val: any) => {
         @MoreFiltersSearch="MoreFiltersSearch"
         @clearMoreFiltersTags="clearMoreFiltersTags"
       ></MoreFilters>
-      <el-button class="el-button--dark" style="margin-left: 8px">Search</el-button>
+      <el-button class="el-button--dark" style="margin-left: 8px" @click="SearchInput"
+        >Search</el-button
+      >
     </div>
     <!-- 筛选项 -->
     <div class="filtersTag" v-if="tagsData.length">

+ 7 - 7
src/views/Booking/src/components/BookingTable/src/BookingTable.vue

@@ -3,6 +3,7 @@ import { type VxeGridInstance, type VxeGridProps } from 'vxe-table'
 import DownloadDialog from './components/DownloadDialog.vue'
 import { autoWidth } from '@/utils/table'
 import { useRowClickStyle } from '@/hooks/rowClickStyle'
+import { ref, onMounted, nextTick } from 'vue'
 import dayjs from 'dayjs'
 import { useRouter } from 'vue-router'
 
@@ -82,22 +83,21 @@ const getTableColumns = async (isInit: boolean) => {
 }
 
 const pageInfo = ref({ pageNo: 1, pageSize: 100, total: 0 })
-const querydata = ref()
 const TransportListItem = ref()
 const TagsList = ref()
 
 // 获取表格数据
+let filterdataobj: any = {}
 const getTableData = async (isInit: boolean, isPageChange?: boolean) => {
   const rc = isPageChange ? pageInfo.value.total : -1
   tableLoading.value = true
-  querydata.value = { cp: pageInfo.value.pageNo, ps: pageInfo.value.pageSize, rc: rc }
   await $api
     .getBookingTableData({
       cp: pageInfo.value.pageNo,
       ps: pageInfo.value.pageSize,
       rc,
       other_filed: '',
-      _textSearch: ''
+      ...filterdataobj
     })
     .then((res: any) => {
       if (res.code === 200) {
@@ -124,19 +124,20 @@ const getTableData = async (isInit: boolean, isPageChange?: boolean) => {
 const searchTableData = (data: any) => {
   tableLoading.value = true
   console.log(data)
+  filterdataobj = data
   $api
     .getBookingTableData({
       cp: pageInfo.value.pageNo,
       ps: pageInfo.value.pageSize,
-      rc: pageInfo.value.total,
+      rc: -1,
       other_filed: '',
       _textSearch: '',
-      filterTag: data.filterTag ? data.filterTag : ['All']
+      ...data
     })
     .then((res: any) => {
       if (res.code === 200) {
-        console.log(res.data)
         bookingTable.value.data = res.data.searchData
+        pageInfo.value.total = Number(res.data.rc)
         tableLoading.value = false
       }
     })
@@ -325,7 +326,6 @@ const handleCheckAllChange = ({ records }: any) => {
   selectedNumber.value = records.length
 }
 defineExpose({
-  querydata,
   searchTableData,
   TransportListItem,
   TagsList

File diff suppressed because it is too large
+ 671 - 648
src/views/Dashboard/src/DashboardView.vue


+ 29 - 16
src/views/Dashboard/src/components/BarChart.vue

@@ -3,18 +3,19 @@
 import * as echarts from 'echarts'
 import { onMounted, ref, reactive, watch, computed } from 'vue'
 const props = defineProps({
-  BarData: Array,
-  BarSeries: Array,
-  barHeight: Object,
-  barTitle: String
+  BarData: Object,
+  barHeight: Object
 })
 const bar_data = ref(props.BarData)
-const bar_series = ref(props.BarSeries)
 const bar_ref = ref()
 watch(
   () => props.BarData,
   (current) => {
     bar_data.value = current
+    initOption.title.text = bar_title.value
+    initOption.xAxis.data = barName.value
+    initOption.series = bar_series.value
+    initOption.legend.data = Name.value
     initChart()
   },
   {
@@ -23,19 +24,31 @@ watch(
 )
 // x轴值
 const barName = computed(() => {
-  return bar_data.value
+  return bar_data.value?.barList
 })
-// 标题
+// title
+const bar_title = computed(() => {
+  return bar_data.value?.bar_title
+})
+// series
+const bar_series = computed(() => {
+  return bar_data.value?.barSeries
+})
+// legend标题
 const Name = computed(() => {
-  return bar_series.value?.map((item: any) => {
-    return item.name
-  })
+  if (bar_data.value?.barSeries) {
+    return bar_data.value?.barSeries.map((item: any) => {
+      return item.name
+    })
+  } else {
+    return []
+  }
 })
 // 数额
 const initOption = reactive({
   //标题
   title: {
-    text: [props.barTitle] || '', //主标题
+    text: bar_title.value || '', //主标题
     left: 19,
     top: 9.5,
     textStyle: {
@@ -101,7 +114,7 @@ const initOption = reactive({
   },
   xAxis: {
     type: 'category',
-    data: barName,
+    data: barName.value,
     axisTick: {
       show: false
     },
@@ -138,12 +151,12 @@ const initOption = reactive({
     max: 3000, // 最大值
     interval: 500 // 刻度
   },
-  series: props.BarSeries,
+  series: bar_series.value,
   legend: {
-    data: Name,
-    top: props.barTitle ? '3.5%' : '2%',
+    data: Name.value,
+    top: '3%',
     itemGap: 30,
-    left: props.barTitle ? '18%' : '8.5px',
+    left: '40%',
     itemHeight: 8.5, //修改icon图形大小
     itemWidth: 8.5, //修改icon图形大小
     textStyle: {

+ 27 - 16
src/views/Dashboard/src/components/PieChart.vue

@@ -3,34 +3,45 @@
 import * as echarts from 'echarts'
 import { onMounted, ref, reactive, watch, computed } from 'vue'
 const props = defineProps({
-  PieData: Array,
-  PieTitle: String,
-  pieRadius: Array
+  PieData: Object
 })
-const pie_data = ref(props.PieData)
-const pie_ref = ref()
-
-// 标题
-const Name = computed(() => {
-  return pie_data.value?.map((item: any) => {
-    return item.name
-  })
-})
-
 watch(
   () => props.PieData,
   (current) => {
     pie_data.value = current
+    initOption.title.text = pie_title.value
     initChart()
   },
   {
     deep: true
   }
 )
+const pie_data = ref(props.PieData)
+const pie_ref = ref()
+
+// legend
+const Name = computed(() => {
+  return pie_data.value?.ETDList.map((item: any) => {
+    return item.name
+  })
+})
+// title标题
+const pie_title = computed(() => {
+  return pie_data.value?.ETD_Title
+})
+// 圆弧大小
+const pie_radius = computed(() => {
+  return pie_data.value?.ETD_Radius
+})
+// 数据
+const pie_series = computed(() => {
+  return pie_data.value?.ETDList
+})
+
 const initOption: any = reactive({
   //标题
   title: {
-    text: [props.PieTitle] || '', //主标题
+    text: pie_title.value || '', //主标题
     left: 19,
     top: 9.5,
     textStyle: {
@@ -92,9 +103,9 @@ const initOption: any = reactive({
   },
   series: {
     type: 'pie', // 饼状图
-    data: pie_data,
+    data: pie_series,
     // radius: ['30%', '50%'],
-    radius: props.pieRadius,
+    radius: pie_radius,
     minAngle: 20, // 设置每块扇形的最小占比
     avoidLabelOverlap: false,
     label: {

+ 566 - 0
src/views/Dashboard/src/components/ScoringSystem.vue

@@ -0,0 +1,566 @@
+<script setup lang="ts">
+import { ref } from 'vue'
+const dialogVisible = ref(false)
+const innerVisible = ref(false)
+const isShowAngry = ref(false)
+const isShowSmile = ref(false)
+const isShowHappy = ref(false)
+const isshowDetails_submit = ref(false)
+const buttonDisabled = ref(true)
+const isshowDetails = ref(true)
+const isShowScoring = ref(true)
+interface AvaterItem {
+  src: string
+  src1: string
+  itemsrc: string
+  itemtext: string
+  expression: string
+  proposal: string
+  itemtitle: string
+  changecolortext: boolean
+}
+const avater = ref<AvaterItem[]>([])
+const inputdetails = ref('')
+avater.value = [
+  {
+    src: '/src/styles/images/score_angry.png',
+    src1: '/src/styles/images/score_angry.png',
+    itemsrc: '/src/styles/images/angry_2.png',
+    itemtext: 'We are so sorry for the inconveniences. We value your experience immensely. ',
+    expression: 'angry',
+    proposal: 'Could you please tell us which aspects of the system you are dissatisfied with?',
+    itemtitle: 'Highly dissatisfied',
+    changecolortext: false
+  },
+  {
+    src: '/src/styles/images/score_sad.png',
+    src1: '/src/styles/images/score_sad.png',
+    itemsrc: '/src/styles/images/sad_2.png',
+    itemtext: 'We are so sorry for the inconveniences. We value your experience immensely. ',
+    expression: 'angry',
+    proposal: 'Could you please tell us which aspects of the system you are dissatisfied with?',
+    itemtitle: 'Dissatisfied',
+    changecolortext: false
+  },
+  {
+    src: '/src/styles/images/score_smile.png',
+    src1: '/src/styles/images/score_smile.png',
+    itemsrc: '/src/styles/images/smile_2.png',
+    itemtext: 'Thank you for sharing your thoughts with us. We value your experience greatly.',
+    expression: 'smile',
+    proposal: 'Could you share what aspects you liked and what could be improved ?',
+    itemtitle: 'Neutral',
+    changecolortext: false
+  },
+  {
+    src: '/src/styles/images/score_hhh.png',
+    src1: '/src/styles/images/score_hhh.png',
+    itemsrc: '/src/styles/images/hhh_2.png',
+    itemtext: 'Thank you very much for giving us a satisfied rating on our service or system.',
+    expression: 'happy',
+    proposal: 'We are curious to learn more about what specifically made you feel satisfied. ',
+    itemtitle: 'Satisfied',
+    changecolortext: false
+  },
+  {
+    src: '/src/styles/images/score_happy.png',
+    src1: '/src/styles/images/score_happy.png',
+    itemsrc: '/src/styles/images/happy_2.png',
+    itemtext: 'Thank you very much for giving us a satisfied rating on our service or system.',
+    expression: 'happy',
+    proposal: 'We are curious to learn more about what specifically made you feel satisfied. ',
+    itemtitle: 'Highly satisfied',
+    changecolortext: false
+  }
+]
+const checkboxGroup1 = ref([])
+const evaluate = [
+  'Lacking in functionality',
+  'Inaccurate data',
+  'Unclear information',
+  'Difficult to use',
+  'Poor system performance'
+]
+const happyevaluate = [
+  'Complete funtionality',
+  'Accurate data',
+  'Clear information',
+  'Easy to use',
+  'Good performance'
+]
+const Aspects = ref([
+  'Highly Dissatisfied',
+  'Dissatisfied',
+  'Neutral',
+  'Satisfied',
+  'Highly Satisfied'
+])
+interface smileAspectsItem {
+  title: string
+  proposal: Array<string>
+  radio: string
+}
+const smileAspects = ref<smileAspectsItem[]>([])
+smileAspects.value = [
+  {
+    title: 'Complete funtionality',
+    proposal: ['Highly Dissatisfied', 'Dissatisfied', 'Neutral', 'Satisfied', 'Highly Satisfied'],
+    radio: ''
+  },
+  {
+    title: 'Accurate data',
+    proposal: ['Highly Dissatisfied', 'Dissatisfied', 'Neutral', 'Satisfied', 'Highly Satisfied'],
+    radio: ''
+  },
+  {
+    title: 'Clear information',
+    proposal: ['Highly Dissatisfied', 'Dissatisfied', 'Neutral', 'Satisfied', 'Highly Satisfied'],
+    radio: ''
+  },
+  {
+    title: 'Easy to use',
+    proposal: ['Highly Dissatisfied', 'Dissatisfied', 'Neutral', 'Satisfied', 'Highly Satisfied'],
+    radio: ''
+  },
+  {
+    title: 'System Performance',
+    proposal: ['Highly Dissatisfied', 'Dissatisfied', 'Neutral', 'Satisfied', 'Highly Satisfied'],
+    radio: ''
+  }
+]
+const closeDialog = () => {
+  isShowAngry.value = false
+  isShowHappy.value = false
+  isShowSmile.value = false
+  isshowDetails_submit.value = false
+  isshowDetails.value = true
+}
+const mouseenter = (item: any) => {
+  item.src = item.itemsrc
+  item.changecolortext = true
+}
+const mouseout = (item: any) => {
+  item.src = item.src1
+  item.changecolortext = false
+}
+const InnerTitle = ref()
+const InnerTileQues = ref()
+const OpenScoring = (item: any) => {
+  dialogVisible.value = false
+  innerVisible.value = true
+  InnerTitle.value = item.itemtext
+  InnerTileQues.value = item.proposal
+  if (item.expression == 'angry') {
+    isShowAngry.value = true
+  } else if (item.expression == 'smile') {
+    isShowSmile.value = true
+  } else {
+    isShowHappy.value = true
+  }
+}
+const previous = () => {
+  dialogVisible.value = true
+  innerVisible.value = false
+  isShowAngry.value = false
+  isShowSmile.value = false
+  isShowHappy.value = false
+}
+// 选择后button变为可选择
+const changeAngryDetails = () => {
+  buttonDisabled.value = false
+}
+// 选择后button变为可选择
+const changeHappyDetails = () => {
+  buttonDisabled.value = false
+}
+let SmileObj: any = {}
+const changeSmileRadio = (title: any, value: any) => {
+  SmileObj[title] = value
+  console.log(Object.keys(SmileObj).length)
+  if (Object.keys(SmileObj).length == Aspects.value.length) {
+    buttonDisabled.value = false
+  }
+}
+// 提交details
+const submitDetails = (val: any) => {
+  console.log(val)
+  isshowDetails_submit.value = true
+  isshowDetails.value = false
+}
+</script>
+
+<template>
+  <div class="scoring_dashboard" v-if="isShowScoring">
+    <div class="scoring_left">
+      <img class="scoring_img" src="/src/styles/images/dashboard_scoring.png" />
+      <div>How satisfied are you with this system ?</div>
+      <div class="das_share" @click="dialogVisible = true">Share Your Feedback</div>
+      <el-dialog
+        v-model="dialogVisible"
+        :destroy-on-close="true"
+        width="640"
+        :modal="false"
+        custom-class="my-dialog"
+        :close-on-click-modal="false"
+      >
+        <div class="das_title">How satisfied are you with this system ?</div>
+        <div class="das_flex">
+          <div class="das_score" v-for="(item, index) in avater" :key="index">
+            <el-avatar
+              :size="40"
+              @mouseenter="mouseenter(item)"
+              @mouseout="mouseout(item)"
+              shape="square"
+              :src="item.src"
+              @click="OpenScoring(item)"
+            />
+            <div class="das_itemtitle" :class="item.changecolortext ? 'changecolortext' : ''">
+              {{ item.itemtitle }}
+            </div>
+          </div>
+        </div>
+      </el-dialog>
+      <el-dialog
+        v-model="innerVisible"
+        width="640"
+        :modal="false"
+        :destroy-on-close="true"
+        @close="closeDialog"
+      >
+        <div class="dialog" v-if="isshowDetails">
+          <div class="das_in_title">
+            {{ InnerTitle }}
+          </div>
+          <div class="das_in_ques">
+            <div class="typography">*</div>
+            {{ InnerTileQues }}
+          </div>
+          <div v-if="isShowAngry" class="dialogflex">
+            <el-checkbox-group v-model="checkboxGroup1" size="large">
+              <el-checkbox-button
+                @change="changeAngryDetails"
+                v-for="item in evaluate"
+                :key="item"
+                :value="item"
+              >
+                {{ item }}
+              </el-checkbox-button>
+            </el-checkbox-group>
+          </div>
+          <div v-if="isShowSmile" style="margin-bottom: 48px">
+            <div class="smile_flex">
+              <div class="smile_title_left"></div>
+              <div class="smile_title_right">
+                <div class="smile_title" v-for="item in Aspects" :key="item">
+                  {{ item }}
+                </div>
+              </div>
+            </div>
+            <div class="smile_content_flex" v-for="(item, index) in smileAspects" :key="index">
+              <div class="smile_title_left content_left">{{ item.title }}</div>
+              <div class="smile_title_right content_right">
+                <el-radio-group
+                  v-model="item.radio"
+                  @change="changeSmileRadio(item.title, item.radio)"
+                >
+                  <el-radio
+                    class="smile_radio"
+                    v-for="proposal in item.proposal"
+                    :value="proposal"
+                    :key="proposal"
+                  ></el-radio>
+                </el-radio-group>
+              </div>
+            </div>
+          </div>
+          <div v-if="isShowHappy" style="margin-bottom: 48px">
+            <el-checkbox-group v-model="checkboxGroup1" size="large">
+              <el-checkbox-button
+                @change="changeHappyDetails"
+                v-for="item in happyevaluate"
+                :key="item"
+                :value="item"
+              >
+                {{ item }}
+              </el-checkbox-button>
+            </el-checkbox-group>
+          </div>
+          <div class="das_in_ques" style="margin: 0">
+            Would you like to share more details with us?
+          </div>
+          <div>
+            <el-input
+              class="inputdetails"
+              v-model="inputdetails"
+              style="width: 592px"
+              :rows="4"
+              type="textarea"
+              placeholder="We look forward to hearing from you.  thank you for helping to build a better customer system"
+            />
+          </div>
+          <div class="buttom">
+            <div class="previous" @click="previous">
+              <span class="iconfont_icon">
+                <svg class="iconfont" aria-hidden="true">
+                  <use xlink:href="#icon-icon_back_b"></use>
+                </svg>
+              </span>
+              Previous
+            </div>
+            <div class="button_submit">
+              <el-button
+                :disabled="buttonDisabled"
+                class="submit_button el-button--dark"
+                @click="submitDetails(inputdetails)"
+                >Submit</el-button
+              >
+            </div>
+          </div>
+        </div>
+        <el-result
+          class="result"
+          v-if="isshowDetails_submit"
+          icon="success"
+          title="Submit Successful"
+        >
+          <template #icon>
+            <el-image src="/src/styles/images/submit_successful.png" />
+          </template>
+          <template #sub-title>
+            <div class="sub_title_text">Apologize once again for your experience.</div>
+            <div class="sub_title_text">
+              We are committed to working hard to provide better services.
+            </div>
+          </template>
+        </el-result>
+      </el-dialog>
+    </div>
+    <div @click="isShowScoring = false" style="cursor: pointer">
+      <span class="iconfont_icon">
+        <svg class="iconfont" aria-hidden="true">
+          <use xlink:href="#icon-icon_reject_b"></use>
+        </svg>
+      </span>
+    </div>
+  </div>
+</template>
+
+<style lang="scss" scoped>
+.scoring_dashboard {
+  display: flex;
+  justify-content: space-between;
+  padding-right: 24px;
+  align-items: center;
+  background: linear-gradient(
+    251deg,
+    rgba(255, 255, 255, 0.3),
+    rgba(255, 244, 235, 0.5) 22.66%,
+    rgba(240, 243, 255, 0.5) 44.57%,
+    rgba(224, 247, 249, 0.6) 80.46%,
+    rgba(255, 255, 255, 0.3)
+  );
+  height: 48px;
+}
+.scoring_img {
+  margin-right: 8px;
+  width: 24px;
+  height: 24px;
+}
+.scoring_left {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  width: 90%;
+}
+.das_share {
+  color: #ed6d00;
+  font-size: 12px;
+  font-weight: 400;
+  margin-left: 8px;
+  text-decoration: underline;
+  text-underline-offset: 3px;
+  cursor: pointer;
+}
+.das_title {
+  font-weight: 700;
+  font-size: 18px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+.das_flex {
+  display: flex;
+  height: 64px;
+  align-items: center;
+  justify-content: center;
+  margin-top: 24px;
+}
+.das_score {
+  width: 104px;
+  text-align: center;
+}
+.das_score:last-child {
+  margin-right: 0;
+}
+.das_itemtitle {
+  font-size: 12px;
+  margin-top: 9px;
+}
+.changecolortext {
+  color: #ed6d00;
+}
+.das_in_title {
+  font-weight: 700;
+  font-size: 18px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  text-align: center;
+  color: #ed6d00;
+  width: 480px;
+}
+.dialog {
+  display: flex;
+  align-items: center;
+  flex-direction: column;
+}
+.buttom {
+  display: flex;
+  width: 540px;
+  align-items: end;
+  justify-content: space-between;
+}
+.submit_button {
+  width: 180px;
+  height: 40px;
+}
+.button_submit {
+  margin-top: 9.51px;
+  display: flex;
+  justify-content: end;
+}
+:deep(.el-button > span) {
+  color: #ffffff !important;
+  font-weight: 400;
+  font-size: var(--font-size-3);
+}
+:deep(.el-button.is-disabled) {
+  background-color: #bfc1c3;
+}
+.previous {
+  cursor: pointer;
+  display: flex;
+}
+.das_in_ques {
+  font-size: 16px;
+  font-weight: 700;
+  width: 592px;
+  margin: 40px 0 16px 0;
+  display: flex;
+}
+.typography {
+  color: #c9353f;
+}
+.dialogflex {
+  display: flex;
+  margin-bottom: 40px;
+}
+:deep(.el-checkbox-button__inner) {
+  color: var(--tag-info-text-color);
+  font-size: var(--font-size-3);
+  font-weight: 400;
+  padding: 0;
+  width: 180px !important;
+  height: 40px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  border: 1px solid var(--color-border);
+  border-radius: var(--border-radius-6);
+  margin-bottom: 8px;
+}
+:deep(.el-checkbox-button__inner:hover) {
+  color: var(--color-theme);
+  background-color: var(--color-btn-default-bg-hover);
+  border-color: var(--color-btn-default-bg-hover);
+}
+:deep(.el-checkbox-button.is-focus .el-checkbox-button__inner) {
+  border-color: transparent;
+}
+:deep(.el-checkbox-button:first-child .el-checkbox-button__inner) {
+  border-left: 1px solid var(--color-border);
+  border-top-left-radius: var(--border-radius-6);
+  border-bottom-left-radius: var(--border-radius-6);
+}
+:deep(.el-checkbox-button:last-child .el-checkbox-button__inner) {
+  border-top-right-radius: var(--border-radius-6);
+  border-bottom-right-radius: var(--border-radius-6);
+}
+:deep(.el-checkbox-button:nth-child(3n + 1)) {
+  margin-right: 8px;
+}
+:deep(.el-checkbox-button:nth-child(3n + 2)) {
+  margin-right: 8px;
+}
+:deep(.el-checkbox-button.is-checked .el-checkbox-button__inner) {
+  color: #ffffff;
+  background-color: var(--color-theme);
+  border-color: var(--color-theme);
+}
+.inputdetails {
+  margin-top: 8px;
+}
+:deep(.el-textarea) {
+  .el-textarea__inner {
+    resize: none; // 去除右下角图标
+    padding: 5px 7px 5px 10px;
+  }
+}
+.smile_flex {
+  display: flex;
+}
+.smile_title_left {
+  width: 176px;
+}
+.smile_title_right {
+  display: flex;
+  width: 414px;
+}
+.smile_title {
+  width: 75.4px;
+  font-size: var(--font-size-2);
+  line-height: 16px;
+  font-weight: 400;
+  display: flex;
+  justify-content: center;
+  align-items: end;
+  text-align: center;
+}
+.smile_content_flex {
+  display: flex;
+  margin-top: 8px;
+}
+.content_left {
+  height: 41px;
+  background-color: #fff;
+  font-weight: 400;
+  border: 1px solid var(--color-border);
+  font-size: var(--font-size-3);
+  border-radius: 6px 0 0 6px;
+  display: flex;
+  align-items: center;
+  padding-left: 7px;
+}
+.smile_radio {
+  width: 75.4px;
+  display: flex;
+  justify-content: center;
+}
+.content_right {
+  background-color: #e0e2e6;
+  border-radius: 0 6px 6px 0;
+}
+.el-radio {
+  margin-right: 0;
+}
+</style>

+ 25 - 3
src/views/Dashboard/src/components/SellerChart.vue

@@ -3,9 +3,11 @@
 import * as echarts from 'echarts'
 import { onMounted, ref, reactive, watch, computed } from 'vue'
 const props = defineProps({
-  SellerData: Array
+  SellerData: Array,
+  Interval: Object
 })
 const seller_data = ref(props.SellerData)
+const seller_interval = ref(props.Interval)
 const seller_ref = ref()
 watch(
   () => props.SellerData,
@@ -17,6 +19,26 @@ watch(
     deep: true
   }
 )
+watch(
+  () => props.Interval,
+  (current) => {
+    seller_interval.value = current
+    initOption.xAxis.max = Max.value
+    initOption.xAxis.interval = interval.value
+    initChart()
+  },
+  {
+    deep: true
+  }
+)
+// 最大值
+const Max = computed(() => {
+  return seller_interval.value?.Max
+})
+// 刻度
+const interval = computed(() => {
+  return seller_interval.value?.interval
+})
 // y轴值
 const sellerName = computed(() => {
   return seller_data.value?.map((item: any) => {
@@ -77,8 +99,8 @@ const initOption = reactive({
       color: '#B5B9BF'
     },
     min: 0, // 最小值
-    max: 1000, // 最大值
-    interval: 200 // 刻度
+    max: Max.value, // 最大值
+    interval: interval.value // 刻度
   },
   // y轴
   yAxis: {

+ 19 - 0
src/views/Dashboard/src/components/TopMap.vue

@@ -0,0 +1,19 @@
+<script setup lang="ts">
+import { onMounted, ref } from 'vue'
+import L from 'leaflet'
+import 'leaflet/dist/leaflet.css'
+onMounted(() => {
+  init()
+})
+const map = ref(null)
+const init = () => {
+  map.value = L.map('map').setView([51.505, -0.09], 13)
+
+  L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
+    attribution: '&copy; OpenStreetMap contributors'
+  }).addTo(map.value)
+}
+</script>
+<template>
+  <div id="map" style="height: 272px"></div>
+</template>

+ 93 - 53
src/views/OperationLog/src/OperationLog.vue

@@ -145,67 +145,102 @@ const handlePageChange = (value: any) => {
     return item.page == value
   })
   selectedOperation.value = newOperationList.value[0].value
+  searchLogData.page = value
+  searchLogData.operation = newOperationList.value[0].value
+  BookingTable_ref.value.SearchOperationLog(searchLogData)
+}
+const BookingTable_ref = ref()
+let searchLogData: any = {}
+const changeUserType = (val: any) => {
+  Search('user_type', val)
+}
+const handleOperationChange = (val: any) => {
+  Search('operation', val)
+}
+const Search = (tag: any, value: any) => {
+  if (OperationSearch.value) {
+    searchLogData.user_name = OperationSearch.value
+  }
+  searchLogData[tag] = value
+  BookingTable_ref.value.SearchOperationLog(searchLogData)
+}
+const DateChange = (date: any) => {
+  searchLogData.operation_date_start = date[0]
+  searchLogData.operation_date_end = date[1]
+  BookingTable_ref.value.SearchOperationLog(searchLogData)
 }
 </script>
 <template>
-  <div class="Title">Operation Log</div>
-  <div class="display">
-    <div class="heaer_top">
-      <div class="search tips_filter">
-        <el-input placeholder="Search user name" v-model="OperationSearch">
-          <template #prefix>
-            <span class="iconfont_icon">
-              <svg class="iconfont" aria-hidden="true">
-                <use xlink:href="#icon-icon_search_b"></use>
-              </svg>
-            </span>
-          </template>
-        </el-input>
-      </div>
-      <div class="tips_filter">
-        <el-select v-model="UserType" placeholder="User Type" style="width: 144px">
-          <el-option
-            v-for="item in usertypeoptions"
-            :key="item.value"
-            :label="item.label"
-            :value="item.value"
-          />
-        </el-select>
-      </div>
-      <div class="tips_filter">
-        <CalendarDate></CalendarDate>
-      </div>
-      <div class="tips_filter">
-        <el-select
-          style="width: 144px"
-          v-model="selectedPage"
-          placeholder="Page"
-          @change="handlePageChange"
-        >
-          <el-option
-            v-for="province in Page"
-            :key="province.value"
-            :label="province.label"
-            :value="province.value"
+  <div class="dashboard">
+    <div class="Title">Operation Log</div>
+    <div class="display">
+      <div class="heaer_top">
+        <div class="search tips_filter">
+          <el-input placeholder="Search user name" v-model="OperationSearch">
+            <template #prefix>
+              <span class="iconfont_icon">
+                <svg class="iconfont" aria-hidden="true">
+                  <use xlink:href="#icon-icon_search_b"></use>
+                </svg>
+              </span>
+            </template>
+          </el-input>
+        </div>
+        <div class="tips_filter">
+          <el-select
+            v-model="UserType"
+            placeholder="User Type"
+            style="width: 144px"
+            @change="changeUserType"
           >
-          </el-option>
-        </el-select>
-      </div>
-      <div class="tips_filter">
-        <el-select style="width: 144px" v-model="selectedOperation" placeholder="Operation">
-          <el-option
-            v-for="city in newOperationList"
-            :key="city.value"
-            :label="city.label"
-            :value="city.value"
+            <el-option
+              v-for="item in usertypeoptions"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value"
+            />
+          </el-select>
+        </div>
+        <div class="tips_filter">
+          <CalendarDate @DateChange="DateChange"></CalendarDate>
+        </div>
+        <div class="tips_filter">
+          <el-select
+            style="width: 144px"
+            v-model="selectedPage"
+            placeholder="Page"
+            @change="handlePageChange"
           >
-          </el-option>
-        </el-select>
+            <el-option
+              v-for="province in Page"
+              :key="province.value"
+              :label="province.label"
+              :value="province.value"
+            >
+            </el-option>
+          </el-select>
+        </div>
+        <div class="tips_filter">
+          <el-select
+            style="width: 144px"
+            v-model="selectedOperation"
+            placeholder="Operation"
+            @change="handleOperationChange"
+          >
+            <el-option
+              v-for="city in newOperationList"
+              :key="city.value"
+              :label="city.label"
+              :value="city.value"
+            >
+            </el-option>
+          </el-select>
+        </div>
+        <el-button class="el-button--dark" @click="Search">Search</el-button>
       </div>
-      <el-button class="el-button--dark">Search</el-button>
     </div>
+    <BookingTable :height="containerHeight" ref="BookingTable_ref"></BookingTable>
   </div>
-  <BookingTable :height="containerHeight" ref="BookingTable_ref"></BookingTable>
 </template>
 
 <style lang="scss" scoped>
@@ -246,4 +281,9 @@ const handlePageChange = (value: any) => {
 .tips_filter {
   margin-right: 8px;
 }
+.dashboard {
+  z-index: 2014;
+  position: relative;
+  background-color: white;
+}
 </style>

+ 31 - 28
src/views/OperationLog/src/components/BookingTable/src/BookingTable.vue

@@ -1,12 +1,11 @@
 <script setup lang="ts">
+import { ref, nextTick, onMounted } from 'vue'
 import { type VxeGridInstance, type VxeGridProps } from 'vxe-table'
 import DownloadDialog from './components/DownloadDialog.vue'
 import { autoWidth } from '@/utils/table'
 import { useRowClickStyle } from '@/hooks/rowClickStyle'
 import dayjs from 'dayjs'
-import { useRouter } from 'vue-router'
 
-const router = useRouter()
 const props = defineProps({
   height: {
     type: Number,
@@ -62,13 +61,13 @@ const handleColumns = (columns: any) => {
 // 获取表格列
 const getTableColumns = async (isInit: boolean) => {
   tableLoading.value = true
-  await $api.getBookingTableColumns().then((res: any) => {
+  await $api.getOperationTableColumns().then((res: any) => {
     if (res.code === 200) {
       bookingTable.value.columns = [
         { type: 'checkbox', width: 50, fixed: 'left' },
-        ...handleColumns(res.data.BookingTableColumns)
+        ...handleColumns(res.data.OperationTableColumns)
       ]
-      tableOriginColumnsField.value = res.data.BookingTableColumns
+      tableOriginColumnsField.value = res.data.OperationTableColumns
     }
   })
   nextTick(() => {
@@ -76,24 +75,23 @@ const getTableColumns = async (isInit: boolean) => {
   })
 }
 
-const pageInfo = ref({ pageNo: 1, pageSize: 200, total: 0 })
-const querydata = ref()
+const pageInfo = ref({ pageNo: 1, pageSize: 20, total: 0 })
 
+let searchdata: any = {}
 // 获取表格数据
 const getTableData = async (isInit: boolean, isPageChange?: boolean) => {
   const rc = isPageChange ? pageInfo.value.total : -1
   tableLoading.value = true
-  querydata.value = { cp: pageInfo.value.pageNo, ps: pageInfo.value.pageSize, rc: rc }
   await $api
-    .getBookingTableData({
+    .SearchOperationLog({
       cp: pageInfo.value.pageNo,
       ps: pageInfo.value.pageSize,
       rc,
-      other_filed: '',
-      _textSearch: ''
+      ...searchdata
     })
     .then((res: any) => {
       if (res.code === 200) {
+        console.log(res.data)
         bookingTable.value.data = res.data.searchData
         pageInfo.value.total = Number(res.data.rc)
       }
@@ -102,6 +100,26 @@ const getTableData = async (isInit: boolean, isPageChange?: boolean) => {
     !isInit && (tableLoading.value = false)
   })
 }
+const SearchOperationLog = (val: any) => {
+  console.log(val)
+  searchdata = val
+  tableLoading.value = true
+  $api
+    .SearchOperationLog({
+      cp: pageInfo.value.pageNo,
+      ps: pageInfo.value.pageSize,
+      rc: -1,
+      ...val
+    })
+    .then((res: any) => {
+      if (res.code === 200) {
+        console.log(res.data)
+        bookingTable.value.data = res.data.searchData
+        pageInfo.value.total = Number(res.data.rc)
+        tableLoading.value = false
+      }
+    })
+}
 onMounted(() => {
   tableLoading.value = true
   Promise.all([getTableColumns(true), getTableData(true)]).finally(() => {
@@ -204,13 +222,6 @@ const exportTable = () => {
 }
 
 const tableLoading = ref(false)
-// 双击表格跳转详情页
-const handleCellDblclick = ({ row }: any) => {
-  router.push({
-    path: '/booking/detail',
-    query: { id: row.booking_no }
-  })
-}
 
 const selectedNumber = ref(0)
 // 复选框选中事件
@@ -221,7 +232,7 @@ const handleCheckAllChange = ({ records }: any) => {
   selectedNumber.value = records.length
 }
 defineExpose({
-  querydata
+  SearchOperationLog
 })
 </script>
 
@@ -239,11 +250,9 @@ defineExpose({
     <vxe-grid
       ref="tableRef"
       v-vloading="tableLoading"
-      isLoadingBackground="true"
       :height="props.height"
       :style="{ border: 'none' }"
       v-bind="bookingTable"
-      @cell-dblclick="handleCellDblclick"
       @checkbox-change="handleCheckboxChange"
       @checkbox-all="handleCheckAllChange"
     >
@@ -271,12 +280,6 @@ defineExpose({
       <template #status="{ row, column }">
         <VTag :type="row[column.field]">{{ row[column.field] }}</VTag>
       </template>
-      <!-- Booking No字段的插槽 -->
-      <template #bookingNo="{ row, column }">
-        <span style="color: var(--color-theme); cursor: pointer" @click="handleCellDblclick">
-          {{ row[column.field] }}
-        </span>
-      </template>
     </vxe-grid>
     <div class="bottom-pagination">
       <div class="left-total-records">Total {{ pageInfo.total }}</div>
@@ -284,7 +287,7 @@ defineExpose({
         <el-pagination
           v-model:current-page="pageInfo.pageNo"
           v-model:page-size="pageInfo.pageSize"
-          :page-sizes="[100, 200, 300, 400]"
+          :page-sizes="[20, 50, 100, 150]"
           :pager-count="3"
           background
           layout="sizes, prev, pager, next"

+ 59 - 21
src/views/Tracking/src/TrackingView.vue

@@ -14,6 +14,7 @@ const filterRef: Ref<HTMLElement | null> = ref(null)
 const containerHeight = useCalculatingHeight(document.documentElement, 246, [filterRef])
 
 const TrackingSearch = ref()
+let searchTableQeury: any = {}
 const filterData = reactive({
   transportData: [] as Array<string>,
   daterangeData: [] as Array<string>,
@@ -24,6 +25,11 @@ const handleClose = (tag: any) => {
   emitter.emit('clearTag', tag)
   tagsData.value.splice(tagsData.value.indexOf(tag), 1)
 }
+// 筛选框查询
+const FiltersSeach = (val: any, value: any) => {
+  searchTableQeury[val] = value
+  TrackingTable_ref.value.searchTableData(searchTableQeury)
+}
 //TransportSearch
 const TransportSearch = (val: any) => {
   filterData.transportData = []
@@ -31,15 +37,29 @@ const TransportSearch = (val: any) => {
     let str = `${val.title}:${val.data}`
     filterData.transportData.push(str)
   }
+  FiltersSeach('transport_mode', val.data)
   renderTagsData()
 }
 //DateRangeSearch
-const DateRangeSearch = (val: any) => {
+const DateRangeSearch = (val: any, value: any) => {
   filterData.daterangeData = []
   for (const key in val) {
     let str = `${key}:${val[key]}`
     filterData.daterangeData.push(str)
   }
+  for (const key in value) {
+    if (key == 'ETD') {
+      searchTableQeury.m_etd_start = value[key].data[0]
+      searchTableQeury.m_etd_end = value[key].data[1]
+    } else if (key == 'ETA') {
+      searchTableQeury.f_eta_start = value[key].data[0]
+      searchTableQeury.f_eta_end = value[key].data[1]
+    } else {
+      searchTableQeury.created_time_start = value[key].data[0]
+      searchTableQeury.created_time_end = value[key].data[1]
+    }
+  }
+  TrackingTable_ref.value.searchTableData(searchTableQeury)
   renderTagsData()
 }
 //MoreFiltersSearch
@@ -48,7 +68,31 @@ const MoreFiltersSearch = (val: any) => {
   for (const key in val) {
     let str = `${key}:${val[key]}`
     filterData.morefiltersData.push(str)
+    if (key == 'shippername') {
+      searchTableQeury.shipper = val[key]
+    } else if (key == 'consigneename') {
+      searchTableQeury.consignee = val[key]
+    } else if (key == 'Origin Agent') {
+      searchTableQeury.origin = val[key]
+    } else if (key == 'Destination Agent') {
+      searchTableQeury.agent = val[key]
+    } else if (key == 'Sales') {
+      searchTableQeury.sales_rep = val[key]
+    } else if (key == 'destination') {
+      searchTableQeury['final_desination/final_desination_exp'] = val[key]
+    } else if (key == 'Place of Receipt') {
+      searchTableQeury.place_of_receipt = val[key]
+    } else if (key == 'Port of Loading') {
+      searchTableQeury['fport_of_loading/fport_of_loading_exp'] = val[key]
+    } else if (key == 'Port of delivery') {
+      searchTableQeury['place_of_delivery/place_of_delivery_exp'] = val[key]
+    } else if (key == 'vessel') {
+      searchTableQeury.vessel = val[key]
+    } else if (key == 'voyage') {
+      searchTableQeury['f_voyage/m_voyage'] = val[key]
+    }
   }
+  TrackingTable_ref.value.searchTableData(searchTableQeury)
   renderTagsData()
 }
 const clearfilters = () => {
@@ -101,29 +145,21 @@ interface ListItem {
 }
 const TagsList = ref<ListItem[]>([])
 const filterTag = ref(['All'])
-const getTableData = async () => {
-  await $api
-    .getBookingTableData({
-      ...TrackingTable_ref.value.querydata,
-      other_filed: '',
-      _textSearch: '',
-      filterTag: filterTag.value
-    })
-    .then((res: any) => {
-      if (res.code === 200) {
-        TransportListItem.value = res.data.TransportList
-        TagsList.value = res.data.tagsList
-      }
-    })
-}
 onMounted(() => {
-  console.log(filterTag.value)
-  getTableData()
+  setTimeout(() => {
+    TransportListItem.value = TrackingTable_ref.value.TransportListItem
+    TagsList.value = TrackingTable_ref.value.TagsList
+  }, 1000)
 })
 const changeTag = (val: any) => {
-  console.log(filterTag.value)
+  searchTableQeury.filterTag = val
+  TrackingTable_ref.value.searchTableData(searchTableQeury)
   filterTag.value = val
-  getTableData()
+}
+// 点击search按钮
+const SearchInput = () => {
+  searchTableQeury._textSearch = TrackingSearch.value
+  TrackingTable_ref.value.searchTableData(searchTableQeury)
 }
 </script>
 
@@ -160,7 +196,9 @@ const changeTag = (val: any) => {
         @MoreFiltersSearch="MoreFiltersSearch"
         @clearMoreFiltersTags="clearMoreFiltersTags"
       ></MoreFilters>
-      <el-button class="el-button--dark" style="margin-left: 8px">Search</el-button>
+      <el-button class="el-button--dark" style="margin-left: 8px" @click="SearchInput"
+        >Search</el-button
+      >
     </div>
     <!-- 筛选项 -->
     <div class="filtersTag" v-if="tagsData.length">

+ 34 - 1
src/views/Tracking/src/components/TrackingTable/src/TrackingTable.vue

@@ -82,8 +82,11 @@ const getTableColumns = async (isInit: boolean) => {
 }
 
 const pageInfo = ref({ pageNo: 1, pageSize: 200, total: 0 })
+const TransportListItem = ref()
+const TagsList = ref()
 
 // 获取表格数据
+let filterdataobj: any = {}
 const getTableData = async (isInit: boolean, isPageChange?: boolean) => {
   const rc = isPageChange ? pageInfo.value.total : -1
   tableLoading.value = true
@@ -93,12 +96,14 @@ const getTableData = async (isInit: boolean, isPageChange?: boolean) => {
       ps: pageInfo.value.pageSize,
       rc,
       other_filed: '',
-      _textSearch: ''
+      ...filterdataobj
     })
     .then((res: any) => {
       if (res.code === 200) {
         trackingTable.value.data = res.data.searchData
         pageInfo.value.total = Number(res.data.rc)
+        TransportListItem.value = res.data.TransportList
+        TagsList.value = res.data.tagsList
 
         // 拥有所有字段的表格
         setTimeout(() => {
@@ -114,6 +119,29 @@ const getTableData = async (isInit: boolean, isPageChange?: boolean) => {
     !isInit && (tableLoading.value = false)
   })
 }
+// 查询列表数据
+const searchTableData = (data: any) => {
+  tableLoading.value = true
+  console.log(data)
+  filterdataobj = data
+  $api
+    .getBookingTableData({
+      cp: pageInfo.value.pageNo,
+      ps: pageInfo.value.pageSize,
+      rc: -1,
+      other_filed: '',
+      _textSearch: '',
+      ...data
+    })
+    .then((res: any) => {
+      if (res.code === 200) {
+        trackingTable.value.data = res.data.searchData
+        pageInfo.value.total = Number(res.data.rc)
+        tableLoading.value = false
+      }
+    })
+}
+
 onMounted(() => {
   tableLoading.value = true
   Promise.all([getTableColumns(true), getTableData(true)]).finally(() => {
@@ -263,6 +291,11 @@ const handleCheckboxChange = ({ records }: any) => {
 const handleCheckAllChange = ({ records }: any) => {
   selectedNumber.value = records.length
 }
+defineExpose({
+  searchTableData,
+  TransportListItem,
+  TagsList
+})
 </script>
 
 <template>

Some files were not shown because too many files changed in this diff