Parcourir la source

feat: delivery 列表页查看详情弹窗中的表格表头改为接口调用动态设置

Jack Zhou il y a 2 semaines
Parent
commit
311bddbeed

+ 2 - 1
src/views/DestinationDelivery/src/components/CreateNewBooking/src/components/NewbookingTable.vue

@@ -58,8 +58,9 @@ const handleColumns = (columns: any) => {
       curColumn = {
         ...curColumn,
         formatter: ({ cellValue }: any) => {
+          if (!cellValue) return '--'
           const array = cellValue.split('-')
-          return `${formatTimezone(array[0])} - ${formatTimezone(array[1])}`
+          return `${formatTimezone(array[0])} -- ${formatTimezone(array[1])}`
         }
       }
     } else if (item.type === 'download') {

+ 1 - 1
src/views/DestinationDelivery/src/components/TableView/src/TableView.vue

@@ -273,7 +273,7 @@ const tableData = ref<VxeGridProps<any>>({
     }
   },
   columnConfig: { resizable: true, useKey: true },
-  rowConfig: { isHover: true, isCurrent: true },
+  rowConfig: { isHover: true },
   exportConfig: {
     types: ['csv', 'html', 'txt', 'xlsx'],
     modes: ['current', 'selected', 'all']

+ 112 - 48
src/views/DestinationDelivery/src/components/TableView/src/components/ShipmentInforTable.vue

@@ -2,6 +2,7 @@
 import { type VxeGridInstance, type VxeGridProps } from 'vxe-table'
 import { useRowClickStyle } from '@/hooks/rowClickStyle'
 import { formatTimezone, formatNumber } from '@/utils/tools'
+import { autoWidth } from '@/utils/table'
 
 const props = defineProps({
   data: Object
@@ -11,40 +12,7 @@ const tableData = ref<VxeGridProps<any>>({
   minHeight: 70,
   border: true,
   round: true,
-  columns: [
-    {
-      field: 'HBOL No.',
-      title: 'HBOL No.',
-      width: 120
-    },
-    {
-      field: 'Container No.',
-      title: 'Container No.'
-    },
-    {
-      field: 'Service Type',
-      title: 'Service Type'
-    },
-    {
-      field: 'ETA',
-      title: 'ETA',
-      minWidth: 100,
-      formatter: ({ cellValue }: any) => formatTimezone(cellValue)
-    },
-
-    {
-      field: 'Recommended Delivery Date',
-      title: 'Recommended Delivery Date',
-      width: 220,
-      formatter: ({ cellValue }: any) => {
-        if (!cellValue) return '--'
-        const rangeData = cellValue.split(';')
-        const leftDate = rangeData[0] ? formatTimezone(rangeData[0]) : '_'
-        const rightDate = rangeData[1] ? formatTimezone(rangeData[0]) : '_'
-        return leftDate + ' -- ' + rightDate
-      }
-    }
-  ],
+  columns: [],
   data: [],
   scrollY: { enabled: true, oSize: 20, gt: 30 },
   emptyText: ' ',
@@ -56,10 +24,74 @@ const tableData = ref<VxeGridProps<any>>({
   columnConfig: { resizable: true, useKey: true },
   rowConfig: { isHover: true }
 })
+const tableLoadingColumn = ref()
+
+const handleColumns = (columns: any) => {
+  const newColumns = columns.map((item: any) => {
+    let curColumn: any = {
+      title: item.title,
+      field: item.field,
+      width: '150px'
+    }
+    // 格式化
+    if (item.formatter === 'date') {
+      curColumn = {
+        ...curColumn,
+        formatter: ({ cellValue }: any) => formatTimezone(cellValue)
+      }
+    } else if (item.type === 'link') {
+      curColumn = {
+        ...curColumn,
+        slots: { default: 'trackingNo' }
+      }
+    } else if (item.type == 'recommend') {
+      curColumn = {
+        ...curColumn,
+        formatter: ({ cellValue }: any) => {
+          if (!cellValue) return '--'
+          const array = cellValue.split('-')
+          return `${formatTimezone(array[0])} -- ${formatTimezone(array[1])}`
+        }
+      }
+    } else if (item.type === 'download') {
+      curColumn = {
+        ...curColumn,
+        slots: { default: 'download' }
+      }
+    }
+    return curColumn
+  })
+  return newColumns
+}
+// 获取表格列
+const getTableColumns = async () => {
+  tableLoadingColumn.value = true
+  await $api.BookingTableColumn().then((res: any) => {
+    if (res.code === 200) {
+      tableData.value.columns = [...handleColumns(res.data.TrackingTableColumns)]
+    }
+  })
+  nextTick(() => {
+    tableLoadingColumn.value = false
+    tableRef.value &&
+      autoWidth(tableData.value, tableRef.value, {
+        packing_list: 190,
+        commercial_invoice: 180
+      })
+  })
+}
+onMounted(() => {
+  getTableColumns()
+})
 
 // 获得表格数据后赋值
 const assignTableData = (data: any) => {
   tableData.value.data = data || []
+  tableRef.value &&
+    autoWidth(tableData.value, tableRef.value, {
+      packing_list: 190,
+      commercial_invoice: 180
+    })
 }
 watch(
   () => props.data,
@@ -74,25 +106,48 @@ const tableLoadingTable = ref()
 
 let searchdata: any = {}
 
-// 获取表格数据
-const getTableData = async () => {
-  const rc = -1
-  tableLoadingTable.value = true
-  await $api
-    .SearchOperationLog({
-      cp: 1,
-      ps: 6,
-      rc,
-      ...searchdata
+function base64ToBlob(base64, mimeType) {
+  const byteString = atob(base64.split(',')[0].startsWith('data:') ? base64.split(',')[1] : base64)
+  const ab = new ArrayBuffer(byteString.length)
+  const ia = new Uint8Array(ab)
+  for (let i = 0; i < byteString.length; i++) {
+    ia[i] = byteString.charCodeAt(i)
+  }
+  return new Blob([ia], { type: mimeType })
+}
+
+const handleDownload = (serialNo: string, field: string) => {
+  const fileType = field === 'commercial_invoice' ? 'C/I' : 'Packing List'
+  $api
+    .downloadBookingTableFile({
+      serial_no: serialNo,
+      file_type: fileType
     })
     .then((res: any) => {
       if (res.code === 200) {
-        assignTableData(res.data)
+        // 使用
+        const base64 = res.data.data // 纯 base64 字符串,不含 data: 前缀
+        const mimeType = 'application/octet-stream'
+        const fileName = res.data.filename || 'download'
+
+        const blob = base64ToBlob(base64, mimeType)
+        const url = URL.createObjectURL(blob)
+
+        const link = document.createElement('a')
+        link.href = url
+        link.download = fileName
+        document.body.appendChild(link)
+        link.click()
+        document.body.removeChild(link)
+
+        // 可选:下载完成后释放内存
+        link.onclick = () => {
+          setTimeout(() => {
+            URL.revokeObjectURL(url) // 释放对象 URL
+          }, 100)
+        }
       }
     })
-    .finally(() => {
-      tableLoadingTable.value = false
-    })
 }
 
 // 实现行点击样式
@@ -109,6 +164,15 @@ useRowClickStyle(tableRef)
       max-height="240"
       min-height="120"
     >
+      <template #download="{ row, column }">
+        <div class="download-btn" @click="handleDownload(row.h_serial_no, column.field)">
+          <span class="font_family icon-icon_download_b icon-style"> </span>
+          <span
+            >{{ row.h_bol
+            }}{{ column.field === 'commercial_invoice' ? '.CI.zip' : '._PL.zip' }}</span
+          >
+        </div>
+      </template>
       <template #empty v-if="!tableLoadingTable && tableData.data.length === 0">
         <div class="empty">No data</div>
       </template>

+ 1 - 1
src/views/Tracking/src/TrackingView.vue

@@ -255,7 +255,7 @@ const clearMoreFiltersTags = () => {
 
 onBeforeRouteLeave((route: any) => {
   // guideStore.clearGuide()
-  const whiteList = ['Booking Detail', 'Tracking Detail']
+  const whiteList = ['Booking Detail', 'Tracking Detail', 'Add VGM']
   if (!whiteList.includes(route?.name)) {
     filtersStore.clearFilters()
   }