Browse Source

修改浏览器标签显示logo

zq940222 3 months ago
parent
commit
054fd518c2

+ 14 - 2
index.html

@@ -10,14 +10,26 @@
     />
 
     <title><%= title %></title>
-    <link rel="icon" href="/logo.png" />
     <!-- 全局配置 -->
     <script>
+      // 检查域名是否包含 "soho"
+      var isSohoDomain = window.location.hostname.includes('sohoeb2b');
+
+      // 根据条件设置图标链接
+      var iconLink = isSohoDomain ? '/soho_logo.png' : '/adweb_logo.png';
+
+      // 创建或更新 <link> 标签
+      var linkElement = document.createElement('link');
+      linkElement.rel = 'icon';
+      linkElement.href = iconLink;
+
+      // 将新的 <link> 标签添加到 head 中
+      document.head.appendChild(linkElement);
       window._CONFIG = {};
     </script>
   </head>
   <body>
-    <script>
+  <script>
       (() => {
         var htmlRoot = document.getElementById('htmlRoot');
         var theme = window.localStorage.getItem('__APP__DARK__MODE__');

BIN
public/adweb_logo.png


BIN
public/soho_logo.png


+ 0 - 1
src/hooks/setting/index.ts

@@ -1,7 +1,6 @@
 import type { GlobConfig } from '/#/config';
 
 import { getAppEnvConfig } from '/@/utils/env';
-import { windows } from "rimraf";
 
 export const useGlobSetting = (): Readonly<GlobConfig> => {
   const {

+ 212 - 0
src/views/adweb/data/components/DestPortAnalysis.vue

@@ -0,0 +1,212 @@
+<template>
+    <a-card title="目的港" :loading="loading">
+        <template #extra>
+            <a-radio-group v-model:value="viewMode" button-style="solid">
+                <a-radio-button value="chart">图表</a-radio-button>
+                <a-radio-button value="table">列表</a-radio-button>
+            </a-radio-group>
+        </template>
+
+        <div v-show="viewMode === 'chart'" ref="chartRef" style="height: 400px"></div>
+
+        <a-table
+            v-show="viewMode === 'table'"
+            :columns="columns"
+            :data-source="tableData"
+            :pagination="false"
+            size="middle"
+        >
+            <template #bodyCell="{ column, record }">
+                <template v-if="column.dataIndex === 'count' || column.dataIndex === 'num_buyer'">
+                    {{ formatNumber(record[column.dataIndex]) }}
+                </template>
+                <template v-if="column.dataIndex === 'sum_weight' || column.dataIndex === 'sum_amount'">
+                    {{ formatDecimal(record[column.dataIndex]) }}
+                </template>
+            </template>
+        </a-table>
+    </a-card>
+</template>
+
+<script setup lang="ts">
+import { ref, onMounted, watch, computed, nextTick, onUnmounted } from 'vue';
+import * as echarts from 'echarts';
+
+const props = defineProps({
+    destPortData: {
+        type: Object,
+        required: true
+    }
+});
+
+const chartRef = ref(null);
+const loading = ref(false);
+const viewMode = ref('chart');
+let chart = null;
+
+const columns = [
+    {
+        title: '目的港',
+        dataIndex: 'val',
+        key: 'val',
+    },
+    {
+        title: '采购商数量',
+        dataIndex: 'num_buyer',
+        key: 'num_buyer',
+        sorter: (a, b) => Number(a.num_buyer) - Number(b.num_buyer),
+    },
+    {
+        title: '重量(KG)',
+        dataIndex: 'sum_weight',
+        key: 'sum_weight',
+        sorter: (a, b) => Number(a.sum_weight) - Number(b.sum_weight),
+    },
+    {
+        title: '金额($)',
+        dataIndex: 'sum_amount',
+        key: 'sum_amount',
+        sorter: (a, b) => Number(a.sum_amount) - Number(b.sum_amount),
+    },
+    {
+        title: '交易次数',
+        dataIndex: 'count',
+        key: 'count',
+    }
+];
+
+const formatNumber = (num: string | number) => {
+    return Number(num).toLocaleString();
+};
+
+const formatDecimal = (num: string | number) => {
+    return Number(num).toLocaleString(undefined, {
+        minimumFractionDigits: 2,
+        maximumFractionDigits: 2
+    });
+};
+
+const tableData = computed(() => {
+    if (!props.destPortData?.buckets) return [];
+    
+    return props.destPortData.buckets.map((item, index) => ({
+        key: index,
+        val: item.val,
+        count: item.count,
+        num_buyer: item.num_buyer,
+        sum_weight: item.sum_weight,
+        sum_amount: item.sum_amount
+    }));
+});
+
+const initChart = () => {
+    if (!chartRef.value) return;
+    
+    chart = echarts.init(chartRef.value);
+    updateChart();
+};
+
+const updateChart = () => {
+    if (!chart || !props.destPortData?.buckets) return;
+
+    const data = props.destPortData.buckets
+        .sort((a, b) => Number(b.count) - Number(a.count))
+        .slice(0, 10);
+    
+    const total = data.reduce((sum, item) => sum + Number(item.count), 0);
+
+    const option = {
+        tooltip: {
+            trigger: 'item',
+            formatter: (params) => {
+                const percent = ((params.value / total) * 100).toFixed(2);
+                return `${params.name}<br/>交易次数: ${formatNumber(params.value)}<br/>占比: ${percent}%`;
+            }
+        },
+        legend: {
+            orient: 'vertical',
+            right: 10,
+            top: 'center',
+            type: 'scroll'
+        },
+        series: [
+            {
+                name: '交易次数',
+                type: 'pie',
+                radius: ['40%', '70%'],
+                avoidLabelOverlap: true,
+                itemStyle: {
+                    borderRadius: 10,
+                    borderColor: '#fff',
+                    borderWidth: 2
+                },
+                label: {
+                    show: true,
+                    formatter: (params) => {
+                        const percent = ((params.value / total) * 100).toFixed(2);
+                        return `${params.name}\n${percent}%`;
+                    }
+                },
+                emphasis: {
+                    label: {
+                        show: true,
+                        fontSize: 14,
+                        fontWeight: 'bold'
+                    }
+                },
+                data: data.map(item => ({
+                    name: item.val_cn || item.val,
+                    value: Number(item.count)
+                }))
+            }
+        ]
+    };
+
+    chart.setOption(option);
+};
+
+watch(
+    () => props.destPortData,
+    () => {
+        updateChart();
+    },
+    { deep: true }
+);
+
+watch(viewMode, (newValue) => {
+    if (newValue === 'chart') {
+        nextTick(() => {
+            initChart();
+        });
+    }
+});
+
+onMounted(() => {
+    if (viewMode.value === 'chart') {
+        initChart();
+    }
+});
+
+window.addEventListener('resize', () => {
+    if (viewMode.value === 'chart') {
+        chart?.resize();
+    }
+});
+
+onUnmounted(() => {
+    chart?.dispose();
+    window.removeEventListener('resize', () => {
+        chart?.resize();
+    });
+});
+</script>
+
+<style scoped>
+.ant-card {
+    margin-bottom: 24px;
+}
+
+:deep(.ant-table-pagination) {
+    margin: 16px 0;
+}
+</style> 

+ 218 - 0
src/views/adweb/data/components/IncotermsAnalysis.vue

@@ -0,0 +1,218 @@
+<template>
+    <a-card title="成交方式" :loading="loading">
+        <!-- 添加切换按钮组 -->
+        <template #extra>
+            <a-radio-group v-model:value="viewMode" button-style="solid">
+                <a-radio-button value="chart">图表</a-radio-button>
+                <a-radio-button value="table">列表</a-radio-button>
+            </a-radio-group>
+        </template>
+
+        <!-- 图表视图 -->
+        <div v-show="viewMode === 'chart'" ref="chartRef" style="height: 400px"></div>
+
+        <!-- 表格视图 -->
+        <a-table
+            v-show="viewMode === 'table'"
+            :columns="columns"
+            :data-source="tableData"
+            :pagination="false"
+            size="middle"
+        >
+            <template #bodyCell="{ column, record }">
+                <template v-if="column.dataIndex === 'count' || column.dataIndex === 'num_supplier'">
+                    {{ formatNumber(record[column.dataIndex]) }}
+                </template>
+                <template v-if="column.dataIndex === 'sum_weight' || column.dataIndex === 'sum_amount'">
+                    {{ formatDecimal(record[column.dataIndex]) }}
+                </template>
+            </template>
+        </a-table>
+    </a-card>
+</template>
+
+<script setup lang="ts">
+import { ref, onMounted, watch, computed, nextTick, onUnmounted } from 'vue';
+import * as echarts from 'echarts';
+
+const props = defineProps({
+    incotermsData: {  // 修改属性名
+        type: Object,
+        required: true
+    }
+});
+
+const chartRef = ref(null);
+const loading = ref(false);
+const viewMode = ref('chart');
+let chart = null;
+
+// 定义表格列
+const columns = [
+    {
+        title: '成交方式',  
+        dataIndex: 'val',
+        key: 'val',
+    },
+    {
+        title: '重量(KG)',
+        dataIndex: 'sum_weight',
+        key: 'sum_weight',
+        sorter: (a, b) => Number(a.sum_weight) - Number(b.sum_weight),
+    },
+    {
+        title: '金额($)',
+        dataIndex: 'sum_amount',
+        key: 'sum_amount',
+        sorter: (a, b) => Number(a.sum_amount) - Number(b.sum_amount),
+    },
+    {
+        title: '交易次数',
+        dataIndex: 'count',
+        key: 'count',
+    }
+];
+
+// 格式化整数
+const formatNumber = (num: string | number) => {
+    return Number(num).toLocaleString();
+};
+
+// 格式化小数(保留两位)
+const formatDecimal = (num: string | number) => {
+    return Number(num).toLocaleString(undefined, {
+        minimumFractionDigits: 2,
+        maximumFractionDigits: 2
+    });
+};
+
+// 计算表格数据
+const tableData = computed(() => {
+    if (!props.incotermsData?.buckets) return [];  // 修改属性名
+    
+    return props.incotermsData.buckets.map((item, index) => ({
+        key: index,
+        val: item.val,
+        count: item.count,
+        num_supplier: item.num_supplier,
+        sum_weight: item.sum_weight,
+        sum_amount: item.sum_amount
+    }));
+});
+
+const initChart = () => {
+    if (!chartRef.value) return;
+    
+    chart = echarts.init(chartRef.value);
+    updateChart();
+};
+
+const updateChart = () => {
+    if (!chart || !props.incotermsData?.buckets) return;  // 修改属性名
+
+    // 获取前10个数据并计算总数
+    const data = props.incotermsData.buckets  // 修改属性名
+        .sort((a, b) => Number(b.count) - Number(a.count))
+        .slice(0, 10);
+    
+    const total = data.reduce((sum, item) => sum + Number(item.count), 0);
+
+    const option = {
+        tooltip: {
+            trigger: 'item',
+            formatter: (params) => {
+                const percent = ((params.value / total) * 100).toFixed(2);
+                return `${params.name}<br/>交易次数: ${formatNumber(params.value)}<br/>占比: ${percent}%`;
+            }
+        },
+        legend: {
+            orient: 'vertical',
+            right: 10,
+            top: 'center',
+            type: 'scroll'
+        },
+        series: [
+            {
+                name: '交易次数',
+                type: 'pie',
+                radius: ['40%', '70%'],
+                avoidLabelOverlap: true,
+                itemStyle: {
+                    borderRadius: 10,
+                    borderColor: '#fff',
+                    borderWidth: 2
+                },
+                label: {
+                    show: true,
+                    formatter: (params) => {
+                        const percent = ((params.value / total) * 100).toFixed(2);
+                        return `${params.name}\n${percent}%`;
+                    }
+                },
+                emphasis: {
+                    label: {
+                        show: true,
+                        fontSize: 14,
+                        fontWeight: 'bold'
+                    }
+                },
+                data: data.map(item => ({
+                    name: item.val_cn || item.val,
+                    value: Number(item.count)
+                }))
+            }
+        ]
+    };
+
+    chart.setOption(option);
+};
+
+// 监听数据变化
+watch(
+    () => props.incotermsData,  // 修改属性名
+    () => {
+        updateChart();
+    },
+    { deep: true }
+);
+
+// 监听视图模式变化
+watch(viewMode, (newValue) => {
+    if (newValue === 'chart') {
+        nextTick(() => {
+            initChart();
+        });
+    }
+});
+
+onMounted(() => {
+    if (viewMode.value === 'chart') {
+        initChart();
+    }
+});
+
+// 监听窗口大小变化
+window.addEventListener('resize', () => {
+    if (viewMode.value === 'chart') {
+        chart?.resize();
+    }
+});
+
+// 组件卸载时清理
+onUnmounted(() => {
+    chart?.dispose();
+    window.removeEventListener('resize', () => {
+        chart?.resize();
+    });
+});
+</script>
+
+<style scoped>
+.ant-card {
+    margin-bottom: 24px;
+}
+
+:deep(.ant-table-pagination) {
+    margin: 16px 0;
+}
+</style>

+ 225 - 0
src/views/adweb/data/components/OrigPortAnalysis.vue

@@ -0,0 +1,225 @@
+<!-- src/views/adweb/data/components/OrigPortAnalysis.vue -->
+<template>
+    <a-card title="起运港" :loading="loading">
+        <!-- 添加切换按钮组 -->
+        <template #extra>
+            <a-radio-group v-model:value="viewMode" button-style="solid">
+                <a-radio-button value="chart">图表</a-radio-button>
+                <a-radio-button value="table">列表</a-radio-button>
+            </a-radio-group>
+        </template>
+
+        <!-- 图表视图 -->
+        <div v-show="viewMode === 'chart'" ref="chartRef" style="height: 400px"></div>
+
+        <!-- 表格视图 -->
+        <a-table
+            v-show="viewMode === 'table'"
+            :columns="columns"
+            :data-source="tableData"
+            :pagination="false"
+            size="middle"
+        >
+            <template #bodyCell="{ column, record }">
+                <template v-if="column.dataIndex === 'count' || column.dataIndex === 'num_supplier'">
+                    {{ formatNumber(record[column.dataIndex]) }}
+                </template>
+                <template v-if="column.dataIndex === 'sum_weight' || column.dataIndex === 'sum_amount'">
+                    {{ formatDecimal(record[column.dataIndex]) }}
+                </template>
+            </template>
+        </a-table>
+    </a-card>
+</template>
+
+<script setup lang="ts">
+import { ref, onMounted, watch, computed, nextTick, onUnmounted } from 'vue';
+import * as echarts from 'echarts';
+
+const props = defineProps({
+    origPortData: {  // 修改属性名
+        type: Object,
+        required: true
+    }
+});
+
+const chartRef = ref(null);
+const loading = ref(false);
+const viewMode = ref('chart');
+let chart = null;
+
+// 定义表格列
+const columns = [
+    {
+        title: '起运港',  
+        dataIndex: 'val',
+        key: 'val',
+    },
+    {
+        title: '供应商数量',
+        dataIndex: 'num_supplier',
+        key: 'num_supplier',
+        sorter: (a, b) => Number(a.num_supplier) - Number(b.num_supplier),
+    },
+    {
+        title: '重量(KG)',
+        dataIndex: 'sum_weight',
+        key: 'sum_weight',
+        sorter: (a, b) => Number(a.sum_weight) - Number(b.sum_weight),
+    },
+    {
+        title: '金额($)',
+        dataIndex: 'sum_amount',
+        key: 'sum_amount',
+        sorter: (a, b) => Number(a.sum_amount) - Number(b.sum_amount),
+    },
+    {
+        title: '交易次数',
+        dataIndex: 'count',
+        key: 'count',
+    }
+];
+
+// 格式化整数
+const formatNumber = (num: string | number) => {
+    return Number(num).toLocaleString();
+};
+
+// 格式化小数(保留两位)
+const formatDecimal = (num: string | number) => {
+    return Number(num).toLocaleString(undefined, {
+        minimumFractionDigits: 2,
+        maximumFractionDigits: 2
+    });
+};
+
+// 计算表格数据
+const tableData = computed(() => {
+    if (!props.origPortData?.buckets) return [];  // 修改属性名
+    
+    return props.origPortData.buckets.map((item, index) => ({
+        key: index,
+        val: item.val,
+        count: item.count,
+        num_supplier: item.num_supplier,
+        sum_weight: item.sum_weight,
+        sum_amount: item.sum_amount
+    }));
+});
+
+const initChart = () => {
+    if (!chartRef.value) return;
+    
+    chart = echarts.init(chartRef.value);
+    updateChart();
+};
+
+const updateChart = () => {
+    if (!chart || !props.origPortData?.buckets) return;  // 修改属性名
+
+    // 获取前10个数据并计算总数
+    const data = props.origPortData.buckets  // 修改属性名
+        .sort((a, b) => Number(b.count) - Number(a.count))
+        .slice(0, 10);
+    
+    const total = data.reduce((sum, item) => sum + Number(item.count), 0);
+
+    const option = {
+        tooltip: {
+            trigger: 'item',
+            formatter: (params) => {
+                const percent = ((params.value / total) * 100).toFixed(2);
+                return `${params.name}<br/>交易次数: ${formatNumber(params.value)}<br/>占比: ${percent}%`;
+            }
+        },
+        legend: {
+            orient: 'vertical',
+            right: 10,
+            top: 'center',
+            type: 'scroll'
+        },
+        series: [
+            {
+                name: '交易次数',
+                type: 'pie',
+                radius: ['40%', '70%'],
+                avoidLabelOverlap: true,
+                itemStyle: {
+                    borderRadius: 10,
+                    borderColor: '#fff',
+                    borderWidth: 2
+                },
+                label: {
+                    show: true,
+                    formatter: (params) => {
+                        const percent = ((params.value / total) * 100).toFixed(2);
+                        return `${params.name}\n${percent}%`;
+                    }
+                },
+                emphasis: {
+                    label: {
+                        show: true,
+                        fontSize: 14,
+                        fontWeight: 'bold'
+                    }
+                },
+                data: data.map(item => ({
+                    name: item.val_cn || item.val,
+                    value: Number(item.count)
+                }))
+            }
+        ]
+    };
+
+    chart.setOption(option);
+};
+
+// 监听数据变化
+watch(
+    () => props.origPortData,  // 修改属性名
+    () => {
+        updateChart();
+    },
+    { deep: true }
+);
+
+// 监听视图模式变化
+watch(viewMode, (newValue) => {
+    if (newValue === 'chart') {
+        nextTick(() => {
+            initChart();
+        });
+    }
+});
+
+onMounted(() => {
+    if (viewMode.value === 'chart') {
+        initChart();
+    }
+});
+
+// 监听窗口大小变化
+window.addEventListener('resize', () => {
+    if (viewMode.value === 'chart') {
+        chart?.resize();
+    }
+});
+
+// 组件卸载时清理
+onUnmounted(() => {
+    chart?.dispose();
+    window.removeEventListener('resize', () => {
+        chart?.resize();
+    });
+});
+</script>
+
+<style scoped>
+.ant-card {
+    margin-bottom: 24px;
+}
+
+:deep(.ant-table-pagination) {
+    margin: 16px 0;
+}
+</style>

+ 57 - 0
src/views/adweb/data/components/SupplierDetails.vue

@@ -0,0 +1,57 @@
+<template>
+  <div inert="true">
+    <a-range-picker v-model:value="date" />
+    <div v-if="supplier">
+      <h1>{{ supplier.name }}</h1> <!-- 添加企业名称 -->
+      <p>地址: {{ supplier.address }}</p> <!-- 添加企业地址 -->
+      <p>联系方式: {{ supplier.contact }}</p> <!-- 添加联系方式 -->
+    </div>
+  </div>
+  
+</template>
+
+<script lang="ts" setup>
+import { ref, watch } from 'vue';
+import { getCompanyInfo } from '../customsData.api'; // Adjust the import based on your API structure
+import type { Dayjs } from 'dayjs';
+type RangeValue = [Dayjs, Dayjs];
+const date = ref<RangeValue>();
+
+const props = defineProps({
+  supplierId: {
+    type: String,
+    required: true,
+  },
+});
+
+const supplier = ref<{ name: string; address: string; contact: string } | null>(null);
+const loading = ref(true);
+
+const fetchSupplierDetails = async () => {
+  loading.value = true;
+  const params = {
+    source_type: 1,
+    data_source: ['IMP_AMERICA_BL_SEA'],
+    date: [20230101, 20230630],
+    com_id:props.supplierId,
+    com_role: 2,
+  }
+  const response = await getCompanyInfo(params);
+  supplier.value = response.result.data.result; // Adjust based on your API response structure
+  loading.value = false;
+};
+
+// Watch for changes in supplierId prop
+watch(() => props.supplierId, (newId) => {
+  if (newId) {
+    fetchSupplierDetails();
+  }
+});
+</script>
+
+<style scoped lang="less">
+.supplier-details {
+  padding: 20px;
+}
+
+</style> 

+ 219 - 0
src/views/adweb/data/components/TransTypeAnalysis.vue

@@ -0,0 +1,219 @@
+<!-- src/views/adweb/data/components/TransTypeAnalysis.vue -->
+<template>
+    <a-card title="运输方式" :loading="loading">
+        <!-- 添加切换按钮组 -->
+        <template #extra>
+            <a-radio-group v-model:value="viewMode" button-style="solid">
+                <a-radio-button value="chart">图表</a-radio-button>
+                <a-radio-button value="table">列表</a-radio-button>
+            </a-radio-group>
+        </template>
+
+        <!-- 图表视图 -->
+        <div v-show="viewMode === 'chart'" ref="chartRef" style="height: 400px"></div>
+
+        <!-- 表格视图 -->
+        <a-table
+            v-show="viewMode === 'table'"
+            :columns="columns"
+            :data-source="tableData"
+            :pagination="false"
+            size="middle"
+        >
+            <template #bodyCell="{ column, record }">
+                <template v-if="column.dataIndex === 'count' || column.dataIndex === 'num_supplier'">
+                    {{ formatNumber(record[column.dataIndex]) }}
+                </template>
+                <template v-if="column.dataIndex === 'sum_weight' || column.dataIndex === 'sum_amount'">
+                    {{ formatDecimal(record[column.dataIndex]) }}
+                </template>
+            </template>
+        </a-table>
+    </a-card>
+</template>
+
+<script setup lang="ts">
+import { ref, onMounted, watch, computed, nextTick, onUnmounted } from 'vue';
+import * as echarts from 'echarts';
+
+const props = defineProps({
+    transTypeData: {  // 修改属性名
+        type: Object,
+        required: true
+    }
+});
+
+const chartRef = ref(null);
+const loading = ref(false);
+const viewMode = ref('chart');
+let chart = null;
+
+// 定义表格列
+const columns = [
+    {
+        title: '运输方式',  
+        dataIndex: 'val',
+        key: 'val',
+    },
+    {
+        title: '重量(KG)',
+        dataIndex: 'sum_weight',
+        key: 'sum_weight',
+        sorter: (a, b) => Number(a.sum_weight) - Number(b.sum_weight),
+    },
+    {
+        title: '金额($)',
+        dataIndex: 'sum_amount',
+        key: 'sum_amount',
+        sorter: (a, b) => Number(a.sum_amount) - Number(b.sum_amount),
+    },
+    {
+        title: '交易次数',
+        dataIndex: 'count',
+        key: 'count',
+    }
+];
+
+// 格式化整数
+const formatNumber = (num: string | number) => {
+    return Number(num).toLocaleString();
+};
+
+// 格式化小数(保留两位)
+const formatDecimal = (num: string | number) => {
+    return Number(num).toLocaleString(undefined, {
+        minimumFractionDigits: 2,
+        maximumFractionDigits: 2
+    });
+};
+
+// 计算表格数据
+const tableData = computed(() => {
+    if (!props.transTypeData?.buckets) return [];  // 修改属性名
+    
+    return props.transTypeData.buckets.map((item, index) => ({
+        key: index,
+        val: item.val,
+        count: item.count,
+        num_supplier: item.num_supplier,
+        sum_weight: item.sum_weight,
+        sum_amount: item.sum_amount
+    }));
+});
+
+const initChart = () => {
+    if (!chartRef.value) return;
+    
+    chart = echarts.init(chartRef.value);
+    updateChart();
+};
+
+const updateChart = () => {
+    if (!chart || !props.transTypeData?.buckets) return;  // 修改属性名
+
+    // 获取前10个数据并计算总数
+    const data = props.transTypeData.buckets  // 修改属性名
+        .sort((a, b) => Number(b.count) - Number(a.count))
+        .slice(0, 10);
+    
+    const total = data.reduce((sum, item) => sum + Number(item.count), 0);
+
+    const option = {
+        tooltip: {
+            trigger: 'item',
+            formatter: (params) => {
+                const percent = ((params.value / total) * 100).toFixed(2);
+                return `${params.name}<br/>交易次数: ${formatNumber(params.value)}<br/>占比: ${percent}%`;
+            }
+        },
+        legend: {
+            orient: 'vertical',
+            right: 10,
+            top: 'center',
+            type: 'scroll'
+        },
+        series: [
+            {
+                name: '交易次数',
+                type: 'pie',
+                radius: ['40%', '70%'],
+                avoidLabelOverlap: true,
+                itemStyle: {
+                    borderRadius: 10,
+                    borderColor: '#fff',
+                    borderWidth: 2
+                },
+                label: {
+                    show: true,
+                    formatter: (params) => {
+                        const percent = ((params.value / total) * 100).toFixed(2);
+                        return `${params.name}\n${percent}%`;
+                    }
+                },
+                emphasis: {
+                    label: {
+                        show: true,
+                        fontSize: 14,
+                        fontWeight: 'bold'
+                    }
+                },
+                data: data.map(item => ({
+                    name: item.val_cn || item.val,
+                    value: Number(item.count)
+                }))
+            }
+        ]
+    };
+
+    chart.setOption(option);
+};
+
+// 监听数据变化
+watch(
+    () => props.transTypeData,  // 修改属性名
+    () => {
+        updateChart();
+    },
+    { deep: true }
+);
+
+// 监听视图模式变化
+watch(viewMode, (newValue) => {
+    if (newValue === 'chart') {
+        nextTick(() => {
+            initChart();
+        });
+    }
+});
+
+onMounted(() => {
+    if (viewMode.value === 'chart') {
+        initChart();
+    }
+});
+
+// 监听窗口大小变化
+window.addEventListener('resize', () => {
+    if (viewMode.value === 'chart') {
+        chart?.resize();
+    }
+});
+
+// 组件卸载时清理
+onUnmounted(() => {
+    chart?.dispose();
+    window.removeEventListener('resize', () => {
+        chart?.resize();
+    });
+});
+</script>
+
+<style scoped>
+.ant-card {
+    margin-bottom: 24px;
+}
+
+:deep(.ant-table-pagination) {
+    margin: 16px 0;
+}
+</style>

+ 113 - 0
src/views/adweb/data/customsData.api.ts

@@ -9,6 +9,11 @@ enum Api {
     origCountry = '/tradesparq/cds_v2/old_api/report/orig_country', // 原产地分析接口
     supplierReport = '/tradesparq/cds_v2/old_api/report/supplier_report', // 新增供应商报告接口
     buyerReport = '/tradesparq/cds_v2/old_api/report/buyer_report', // 采购商分析接口
+    origPort = '/tradesparq/cds_v2/old_api/report/orig_port', // 起运港分析
+    destPort = '/tradesparq/cds_v2/old_api/report/dest_port', // 目的港分析
+    transType = '/tradesparq/cds_v2/old_api/report/trans_type', // 新增交易类型分析接口
+    incoterms = '/tradesparq/cds_v2/old_api/report/incoterms',  // 添加新的 API 路径
+    companyInfo = '/tradesparq/cds_v2/old_api/company/info', //企业基本信息
 }
 
 // 定义请求参数类型
@@ -222,6 +227,35 @@ export interface BuyerReportResponse {
     };
 }
 
+// 定义原产地港口请求参数类型
+export interface OrigPortParams {
+    source_type?: number;
+    data_source?: string[];
+    date?: number[];
+    hs_code?: string;
+    supplier_t?: string;
+    buyer_t?: string;
+    [key: string]: any;
+}
+
+// 定义原产地港口响应数据类型
+export interface OrigPortResponse {
+    status_code: number;
+    data: {
+        result: {
+            buckets: Array<{
+                val: string;           // 港口名称
+                code: string;          // 港口代码
+                num_supplier: string;  // 供应商数量
+                sum_amount: string;    // 总金额
+                sum_weight: string;    // 总重量
+                count: string;         // 交易次数
+            }>;
+            numBuckets: number;        // 总bucket数量
+        };
+    };
+}
+
 /**
  * 获取交易详单列表及总数
  */
@@ -338,4 +372,83 @@ export const getBuyerReport = (params: BuyerReportParams) => {
     );
 };
 
+/**
+ * 获取原产地港口统计数据
+ */
+export const getOrigPortReport = (params: OrigPortParams) => {
+    return defHttp.post<OrigPortResponse>(
+        {
+            url: Api.origPort,
+            params
+        },
+        {
+            errorMessageMode: 'message',
+            isTransformResponse: false,
+        }
+    );
+};
+
+/**
+ * 获取目的港统计数据
+ */
+export const getDestPortReport = (params: OrigPortParams) => {
+    return defHttp.post(
+        {
+            url: Api.destPort,
+            params
+        },
+        {
+            errorMessageMode: 'message',
+            isTransformResponse: false,
+        }
+    );
+};
+
+/**
+ * 获取交易类型统计数据
+ */
+export const getTransTypeReport = (params: any) => {  // 根据需要定义参数类型
+    return defHttp.post<any>(  // 根据需要定义响应类型
+        {
+            url: Api.transType,
+            params
+        },
+        {
+            errorMessageMode: 'message',
+            isTransformResponse: false,
+        }
+    );
+};
+
+/**
+ * 获取成交方式统计数据
+ */
+export const getIncotermsReport = (params: any) => {  // 根据需要定义参数类型
+    return defHttp.post<any>(  // 根据需要定义响应类型
+        {
+            url: Api.incoterms,
+            params
+        },
+        {
+            errorMessageMode: 'message',
+            isTransformResponse: false,
+        }
+    );
+};
+
+/**
+ * 获取企业基本信息数据
+ */
+export const getCompanyInfo = (params: any) => {
+    return defHttp.post<any>(
+        {
+            url: Api.companyInfo,
+            params
+        },
+        {
+            errorMessageMode: 'message',
+            isTransformResponse: false,
+        }
+    )
+}
 

+ 2 - 0
src/views/adweb/data/customsData.data.ts

@@ -6,12 +6,14 @@ export const columns: BasicColumn[] = [
         title: "供应商",
         align: "center",
         dataIndex: "supplier_t",
+        key:"supplier_t",
         width: 100,
     },
     {
         title: "采购商",
         align: "center",
         dataIndex: "buyer_t",
+        key:"buyer_t",
         width: 100,
     },
     {

+ 591 - 453
src/views/adweb/data/customsData.vue

@@ -210,27 +210,52 @@
 
   <!-- 使用 v-show 控制数据展示区域的显示/隐藏 -->
   <div v-show="showDataContent" class="table-container">
-    <a-tabs v-model:activeKey="activeTabKey" @change="handleTabChange" class="custom-tabs">
+    <a-tabs v-model:activeKey="activeTabKey" @change="handleTabChange" class="custom-tabs" type="card">
       <a-tab-pane key="transaction" tab="交易信息">
-        <div class="table-toolbar">
-          <a-button type="primary" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出 </a-button>
+        <a-table :columns="columns" :data-source="tableData" :loading="loading" :pagination="{
+          current: pagination.current,
+          pageSize: pagination.pageSize,
+          total: pagination.total,
+          showSizeChanger: true,
+          showQuickJumper: true,
+          showTotal: (total) => `共 ${total} 条`,
+          onChange: handleTableChange,
+          onShowSizeChange: handleTableChange,
+        }" @change="handleTableChange">
+
+          <template #bodyCell="{ column, record, text }">
+            <template v-if="column.key === 'supplier_t'">
+              <a @click="handleSupplierClick(record.supplier_id)">{{ text }}</a>
+            </template>
+          </template>
+        </a-table>
+        <div :inert="isModalVisible">
+          <!-- 其他内容 -->
+          <a-modal v-model:open="isModalVisible" title="企业详情">
+            <div>
+              <div v-if="supplier">
+                <h1>{{ supplier.name }}</h1> <!-- 添加企业名称 -->
+                <p><strong>地址:</strong> {{ supplier.address }}</p> <!-- 添加企业地址 -->
+                <p><strong>联系方式:</strong> postal code:{{ supplier.postal_code }}</p> <!-- 添加联系方式 -->
+              </div>
+            </div>
+            <!-- 新增选项卡 -->
+            <a-tabs v-model:activeKey="activeTabKey" @change="handleTabChange"  type="card">
+              <a-tab-pane key="tradeOverview" tab="贸易总览">
+                <!-- 贸易总览内容 -->
+              </a-tab-pane>
+              <a-tab-pane key="exportDetails" tab="出口详单">
+                <!-- 出口详单内容 -->
+              </a-tab-pane>
+              <a-tab-pane key="exportTradingPartners" tab="出口贸易伙伴">
+                <!-- 出口贸易伙伴内容 -->
+              </a-tab-pane>
+              <a-tab-pane key="enterpriseAtlas" tab="企业图谱">
+                <!-- 企业图谱内容 -->
+              </a-tab-pane>
+            </a-tabs>
+          </a-modal>
         </div>
-        <a-table
-          :columns="columns"
-          :data-source="tableData"
-          :loading="loading"
-          :pagination="{
-            current: pagination.current,
-            pageSize: pagination.pageSize,
-            total: pagination.total,
-            showSizeChanger: true,
-            showQuickJumper: true,
-            showTotal: (total) => `共 ${total} 条`,
-            onChange: handleTableChange,
-            onShowSizeChange: handleTableChange,
-          }"
-          @change="handleTableChange"
-        />
       </a-tab-pane>
 
       <a-tab-pane key="companies" tab="企业列表">
@@ -270,40 +295,186 @@
       </a-tab-pane>
 
       <a-tab-pane key="shippingAnalysis" tab="航运类分析报告">
-        <div class="analysis-content"> 航运类分析报告内容 </div>
+        <div class="analysis-content">
+          <div class="analysis-item">
+            <OrigPortAnalysis :origPortData="origPortData"></OrigPortAnalysis>
+          </div>
+          <div class="analysis-item">
+            <DestPortAnalysis :destPortData="destPortData"></DestPortAnalysis>
+          </div>
+
+          <div class="analysis-item">
+            <TransTypeAnalysis :transTypeData="transTypeData"></TransTypeAnalysis>
+          </div>
+
+          <div class="analysis-item">
+            <IncotermsAnalysis :incotermsData="incotermsData"></IncotermsAnalysis>
+          </div>
+        </div>
       </a-tab-pane>
     </a-tabs>
   </div>
 </template>
 
 <script lang="ts" setup>
-  import { reactive, ref, onMounted } from 'vue';
-  import {
-    list,
-    listCompanies,
-    getTrendReport,
-    getHsCodeReport,
-    getOrigCountryReport,
-    getDestCountryReport,
-    getSupplierReport,
-    getBuyerReport,
-  } from './customsData.api';
-  import { columns } from './customsData.data';
-  import CompanyList from './components/CompanyList.vue';
-  import TradeAnalysis from './components/TradeAnalysis.vue';
-  import HsCodeAnalysis from './components/HsCodeAnalysis.vue';
-  import OriginCountryAnalysis from './components/OriginCountryAnalysis.vue';
-  import DestinationCountryAnalysis from './components/DestinationCountryAnalysis.vue';
-  import SupplierList from './components/SupplierList.vue';
-  import BuyerList from './components/BuyerList.vue';
-
-  // 当前激活的标签页
-  const activeTabKey = ref('transaction');
-
-  // 查询参数
-  const queryParam = reactive<any>({});
-
-  const form = ref({
+import { reactive, ref, onMounted } from 'vue';
+import {
+  list,
+  listCompanies,
+  getTrendReport,
+  getHsCodeReport,
+  getOrigCountryReport,
+  getDestCountryReport,
+  getSupplierReport,
+  getBuyerReport,
+  getOrigPortReport,
+  getDestPortReport,
+  getTransTypeReport,
+  getIncotermsReport,
+  getCompanyInfo
+} from './customsData.api';
+import { columns } from './customsData.data';
+import CompanyList from './components/CompanyList.vue';
+import TradeAnalysis from './components/TradeAnalysis.vue';
+import HsCodeAnalysis from './components/HsCodeAnalysis.vue';
+import OriginCountryAnalysis from './components/OriginCountryAnalysis.vue';
+import DestinationCountryAnalysis from './components/DestinationCountryAnalysis.vue';
+import SupplierList from './components/SupplierList.vue';
+import BuyerList from './components/BuyerList.vue';
+import OrigPortAnalysis from './components/OrigPortAnalysis.vue';
+import DestPortAnalysis from './components/DestPortAnalysis.vue';
+import TransTypeAnalysis from './components/TransTypeAnalysis.vue';
+import IncotermsAnalysis from './components/IncotermsAnalysis.vue';
+import { Dayjs } from 'dayjs';
+
+const supplier = ref<{ name: string; address: string; postal_code: string } | null>(null);
+type RangeValue = [Dayjs, Dayjs];
+const date = ref<RangeValue>();
+
+// 当前激活的标签页
+const activeTabKey = ref('transaction');
+
+// 查询参数
+const queryParam = reactive<any>({});
+
+const form = ref({
+  product: '',
+  hsCode: '',
+  startDate: null,
+  endDate: null,
+  supplier: '',
+  supplierReg: '',
+  supplierAddress: '',
+  options: ['excludeNVL'],
+  buyer: '',
+  buyerReg: '',
+  buyerAddress: '',
+  buyerOptions: ['excludeNVL'],
+  originCountry: '',
+  destinationCountry: '',
+  port: '',
+  transportMode: '',
+  weightMin: null,
+  weightMax: null,
+  quantityMin: null,
+  quantityMax: null,
+  amountMin: null,
+  amountMax: null,
+  teuMin: null,
+  teuMax: null,
+  origPort: '',
+  destPort: '',
+  customs: '',
+  incoterms: '',
+  mainOrderNo: '',
+  subOrderNo: '',
+  containerNo: '',
+  carrier: '',
+  shipName: '',
+  brand: '',
+  other: '',
+});
+
+// 添加控制数据展示的状态
+const showDataContent = ref(false);
+
+// ���改 handleSearch 方法
+const handleSearch = async () => {
+  showDataContent.value = true;
+
+  // 构建查询参数
+  const params = {
+    // 固定参数
+    source_type: 1,
+    data_source: ['IMP_AMERICA_BL_SEA'],
+
+    // 表单参数
+    prod_desc: form.value.product,
+    hs_code: form.value.hsCode,
+    supplier: form.value.supplier,
+    supplier_reg: form.value.supplierReg,
+    supplier_address: form.value.supplierAddress,
+    buyer: form.value.buyer,
+    buyer_reg: form.value.buyerReg,
+    buyer_address: form.value.buyerAddress,
+    origin_country: form.value.originCountry,
+    destination_country: form.value.destinationCountry,
+    orig_port: form.value.origPort,
+    dest_port: form.value.destPort,
+    customs: form.value.customs,
+    transport_mode: form.value.transportMode,
+    incoterms: form.value.incoterms,
+    main_order_no: form.value.mainOrderNo,
+    sub_order_no: form.value.subOrderNo,
+    container_no: form.value.containerNo,
+    carrier: form.value.carrier,
+    ship_name: form.value.shipName,
+    brand: form.value.brand,
+
+    // 日期处理
+    date: form.value.startDate && form.value.endDate ? [form.value.startDate.format('YYYYMMDD'), form.value.endDate.format('YYYYMMDD')] : undefined,
+
+    // 范围值处理
+    weight: form.value.weightMin || form.value.weightMax ? [form.value.weightMin || '', form.value.weightMax || ''] : undefined,
+    quantity: form.value.quantityMin || form.value.quantityMax ? [form.value.quantityMin || '', form.value.quantityMax || ''] : undefined,
+    amount: form.value.amountMin || form.value.amountMax ? [form.value.amountMin || '', form.value.amountMax || ''] : undefined,
+    teu: form.value.teuMin || form.value.teuMax ? [form.value.teuMin || '', form.value.teuMax || ''] : undefined,
+
+    // 选项处理
+    supplier_ex_log: form.value.options?.includes('excludeLogistics'),
+    supplier_ex_nvl: form.value.options?.includes('excludeNVL'),
+    buyer_ex_log: form.value.buyerOptions?.includes('excludeLogistics'),
+    buyer_ex_nvl: form.value.buyerOptions?.includes('excludeNVL'),
+  };
+
+  // 移除所有 undefined 和空字符串的属性
+  Object.keys(params).forEach((key) => {
+    if (params[key] === undefined || params[key] === '') {
+      delete params[key];
+    }
+  });
+
+  // 将参数保存到 queryParam 以供其他地方使用
+  Object.assign(queryParam, params);
+  if (activeTabKey.value === 'transaction') {
+    pagination.value.current = 1; // Reset to first page
+    await handleTableChange(pagination.value);
+  } else if (activeTabKey.value === 'companies') {
+    await handleTabChange('companies'); // Load companies data
+  } else if (activeTabKey.value === 'tradeAnalysis') {
+    await handleTabChange('tradeAnalysis'); // Load trade analysis data
+  } else if (activeTabKey.value === 'shippingAnalysis') {
+    await handleTabChange('shippingAnalysis'); // Load shipping analysis data
+  }
+};
+
+// 修改重置方法
+const handleReset = () => {
+  // 隐藏数据内容
+  showDataContent.value = false;
+
+  // 重置表单
+  form.value = {
     product: '',
     hsCode: '',
     startDate: null,
@@ -316,478 +487,445 @@
     buyerReg: '',
     buyerAddress: '',
     buyerOptions: ['excludeNVL'],
-    originCountry: '',
-    destinationCountry: '',
-    port: '',
-    transportMode: '',
-    weightMin: null,
-    weightMax: null,
-    quantityMin: null,
-    quantityMax: null,
-    amountMin: null,
-    amountMax: null,
-    teuMin: null,
-    teuMax: null,
-    origPort: '',
-    destPort: '',
-    customs: '',
-    incoterms: '',
-    mainOrderNo: '',
-    subOrderNo: '',
-    containerNo: '',
-    carrier: '',
-    shipName: '',
-    brand: '',
-    other: '',
+    // ... 其他字段重置
+  };
+
+  // 重置查询参数,但保留基础参数
+  Object.assign(queryParam, {
+    source_type: 1,
+    data_source: ['IMP_AMERICA_BL_SEA'],
+    date: [20230101, 20230630],
   });
 
-  // 添加控制数据展示的状态
-  const showDataContent = ref(false);
+  // 重新加载数据
+  if (activeTabKey.value === 'transaction') {
+    reloadTransaction();
+  }
+};
+
+const showAdvancedSearch = ref(false);
 
-  // 修改 handleSearch 方法
-  const handleSearch = async () => {
-    showDataContent.value = true;
+const toggleAdvancedSearch = () => {
+  showAdvancedSearch.value = !showAdvancedSearch.value;
+};
 
-    // 构建查询参数
+// 修改 onMounted,不再自动加载数据
+onMounted(() => {
+  Object.assign(queryParam, {
+    source_type: 1,
+    data_source: ['IMP_AMERICA_BL_SEA'],
+    date: [20230101, 20230630],
+  });
+});
+
+// Add these new variables
+const tableData = ref([]);
+const loading = ref(false);
+const pagination = ref({
+  current: 1,
+  pageSize: 10,
+  total: 0,
+});
+
+// Replace registerTransactionTable with this new method
+const handleTableChange = async (pag, filters, sorter) => {
+  loading.value = true;
+  try {
     const params = {
-      // 固定参数
+      page: pag.current,
+      page_size: pag.pageSize,
+      sortField: sorter?.field,
+      sortOrder: sorter?.order,
       source_type: 1,
       data_source: ['IMP_AMERICA_BL_SEA'],
-
-      // 表单参数
-      prod_desc: form.value.product,
-      hs_code: form.value.hsCode,
-      supplier: form.value.supplier,
-      supplier_reg: form.value.supplierReg,
-      supplier_address: form.value.supplierAddress,
-      buyer: form.value.buyer,
-      buyer_reg: form.value.buyerReg,
-      buyer_address: form.value.buyerAddress,
-      origin_country: form.value.originCountry,
-      destination_country: form.value.destinationCountry,
-      orig_port: form.value.origPort,
-      dest_port: form.value.destPort,
-      customs: form.value.customs,
-      transport_mode: form.value.transportMode,
-      incoterms: form.value.incoterms,
-      main_order_no: form.value.mainOrderNo,
-      sub_order_no: form.value.subOrderNo,
-      container_no: form.value.containerNo,
-      carrier: form.value.carrier,
-      ship_name: form.value.shipName,
-      brand: form.value.brand,
-
-      // 日期处理
-      date: form.value.startDate && form.value.endDate ? [form.value.startDate.format('YYYYMMDD'), form.value.endDate.format('YYYYMMDD')] : undefined,
-
-      // 范围值处理
-      weight: form.value.weightMin || form.value.weightMax ? [form.value.weightMin || '', form.value.weightMax || ''] : undefined,
-      quantity: form.value.quantityMin || form.value.quantityMax ? [form.value.quantityMin || '', form.value.quantityMax || ''] : undefined,
-      amount: form.value.amountMin || form.value.amountMax ? [form.value.amountMin || '', form.value.amountMax || ''] : undefined,
-      teu: form.value.teuMin || form.value.teuMax ? [form.value.teuMin || '', form.value.teuMax || ''] : undefined,
-
-      // 选项处理
-      supplier_ex_log: form.value.options?.includes('excludeLogistics'),
-      supplier_ex_nvl: form.value.options?.includes('excludeNVL'),
-      buyer_ex_log: form.value.buyerOptions?.includes('excludeLogistics'),
-      buyer_ex_nvl: form.value.buyerOptions?.includes('excludeNVL'),
-    };
-
-    // 移除所有 undefined 和空字符串的属性
-    Object.keys(params).forEach((key) => {
-      if (params[key] === undefined || params[key] === '') {
-        delete params[key];
-      }
-    });
-
-    // 将参数保存到 queryParam 以供其他地方使用
-    Object.assign(queryParam, params);
-    if (activeTabKey.value === 'transaction') {
-      pagination.value.current = 1; // Reset to first page
-      await handleTableChange(pagination.value);
-    }
-  };
-
-  // 修改重置方法
-  const handleReset = () => {
-    // 隐藏数据内容
-    showDataContent.value = false;
-
-    // 重置表单
-    form.value = {
-      product: '',
-      hsCode: '',
-      startDate: null,
-      endDate: null,
-      supplier: '',
-      supplierReg: '',
-      supplierAddress: '',
-      options: ['excludeNVL'],
-      buyer: '',
-      buyerReg: '',
-      buyerAddress: '',
-      buyerOptions: ['excludeNVL'],
-      // ... 其他字段重置
+      ...queryParam,
     };
 
-    // 重置查询参数,但保留基础参数
-    Object.assign(queryParam, {
-      source_type: 1,
-      data_source: ['IMP_AMERICA_BL_SEA'],
-      date: [20230101, 20230630],
-    });
-
-    // 重新加载数据
-    if (activeTabKey.value === 'transaction') {
-      reloadTransaction();
+    const res = await list(params);
+    if (res.result.data.result && res.result.data.result.docs) {
+      // 处理日期格式
+      tableData.value = res.result.data.result.docs.map((item) => ({
+        ...item,
+        date: item.date ? item.date.split(' ')[0] : '', // 只保留日期部分
+      }));
+      pagination.value = {
+        current: pag.current,
+        pageSize: pag.pageSize,
+        total: res.result.data.result.numFound || 0,
+      };
     }
-  };
-
-  const onExportXls = () => {
-    console.log('导出');
-  };
-
-  const showAdvancedSearch = ref(false);
-
-  const toggleAdvancedSearch = () => {
-    showAdvancedSearch.value = !showAdvancedSearch.value;
-  };
-
-  // 修改 onMounted,不再自动加载数据
-  onMounted(() => {
-    Object.assign(queryParam, {
-      source_type: 1,
-      data_source: ['IMP_AMERICA_BL_SEA'],
-      date: [20230101, 20230630],
-    });
-  });
-
-  // Add these new variables
-  const tableData = ref([]);
-  const loading = ref(false);
-  const pagination = ref({
-    current: 1,
-    pageSize: 10,
-    total: 0,
-  });
-
-  // Replace registerTransactionTable with this new method
-  const handleTableChange = async (pag, filters, sorter) => {
-    loading.value = true;
+  } catch (error) {
+    console.error('Failed to fetch data:', error);
+  } finally {
+    loading.value = false;
+  }
+};
+
+// 企业列表数据
+const companiesData = ref([]);
+
+// 处理企业列表数据
+const handleCompaniesData = (companies) => {
+  companiesData.value = companies.map((company) => ({
+    name: company.name,
+    totalRecords: company.total_records,
+    matchedRecords: company.matched_records,
+    address: company.address,
+    phone: company.phone,
+    email: company.email,
+  }));
+};
+
+// 处理对比点击
+const handleCompareClick = (company) => {
+  console.log('Compare clicked for company:', company.name);
+};
+
+// 在 handleTabChange 中添加企业列表数据加载逻辑
+const handleTabChange = async (key: string) => {
+  activeTabKey.value = key;
+  if (key === 'companies') {
     try {
-      const params = {
-        page: pag.current,
-        page_size: pag.pageSize,
-        sortField: sorter?.field,
-        sortOrder: sorter?.order,
-        source_type: 1,
-        data_source: ['IMP_AMERICA_BL_SEA'],
-        ...queryParam,
-      };
-
-      const res = await list(params);
-      if (res.result.data.result && res.result.data.result.docs) {
-        // 处理日期格式
-        tableData.value = res.result.data.result.docs.map((item) => ({
-          ...item,
-          date: item.date ? item.date.split(' ')[0] : '', // 只保留日期部分
-        }));
-        pagination.value = {
-          current: pag.current,
-          pageSize: pag.pageSize,
-          total: res.result.data.result.numFound || 0,
-        };
+      const res = await listCompanies(queryParam);
+      if (res.result && res.result.companies) {
+        handleCompaniesData(res.result.companies);
       }
     } catch (error) {
-      console.error('Failed to fetch data:', error);
-    } finally {
-      loading.value = false;
+      console.error('Failed to fetch companies:', error);
     }
-  };
-
-  // 企业列表数据
-  const companiesData = ref([]);
-
-  // 处理企业列表数据
-  const handleCompaniesData = (companies) => {
-    companiesData.value = companies.map((company) => ({
-      name: company.name,
-      totalRecords: company.total_records,
-      matchedRecords: company.matched_records,
-      address: company.address,
-      phone: company.phone,
-      email: company.email,
-    }));
-  };
-
-  // 处理对比点击
-  const handleCompareClick = (company) => {
-    console.log('Compare clicked for company:', company.name);
-  };
-
-  // 在 handleTabChange 中添加企业列表数据加载逻辑
-  const handleTabChange = async (key: string) => {
-    activeTabKey.value = key;
-    if (key === 'companies') {
-      try {
-        const res = await listCompanies(queryParam);
-        if (res.result && res.result.companies) {
-          handleCompaniesData(res.result.companies);
-        }
-      } catch (error) {
-        console.error('Failed to fetch companies:', error);
-      }
-    } else if (key === 'tradeAnalysis') {
-      // 当切换到贸易类分析报告标签页时,加载月度趋势数据
-      try {
-        await Promise.all([
-          loadMonthlyTrendData(),
-          fetchHsCodeData(),
-          fetchOriginCountryData(),
-          fetchDestinationCountryData(),
-          fetchSupplierData(),
-          fetchBuyerData(),
-        ]);
-      } catch (error) {
-        console.error('Failed to load analysis data:', error);
-      }
+  } else if (key === 'tradeAnalysis') {
+    // 当切换到贸易类分析报告标签页时,加载月度趋势数据
+    try {
+      await Promise.all([
+        loadMonthlyTrendData(),
+        fetchHsCodeData(),
+        fetchOriginCountryData(),
+        fetchDestinationCountryData(),
+        fetchSupplierData(),
+        fetchBuyerData(),
+      ]);
+    } catch (error) {
+      console.error('Failed to load analysis data:', error);
     }
-  };
-
-  // 月度趋势分析数据
-  const monthlyTrendData = ref([]);
-
-  // 加载月度趋势分析数据
-  const loadMonthlyTrendData = async () => {
+  } else if (key === 'shippingAnalysis') {
     try {
-      const params = {
-        source_type: 1,
-        data_source: ['IMP_AMERICA_BL_SEA'],
-        ...queryParam,
-      };
-
-      const res = await getTrendReport(params);
-      if (res.result.data.result && res.result.data.result) {
-        // 处理日期格式
-        monthlyTrendData.value = res.result.data.result.map((item) => ({
-          ...item,
-        }));
-      }
-      console.log(monthlyTrendData.value);
+      await Promise.all([
+        fetchOrigPortData(),
+        fetchDestPortData(),
+        fetchTransTypeData(),
+        fetchIncotermsData()
+      ])
     } catch (error) {
-      console.error('Failed to fetch data:', error);
-    } finally {
-      loading.value = false;
+      console.error('Failed to load analysis data:', error);
     }
-  };
+  }
+};
 
-  const hsCodeData = ref({});
+// 月度趋势分析数据
+const monthlyTrendData = ref([]);
 
-  // 获取HS编码数据
-  const fetchHsCodeData = async () => {
+// 加载月度趋势分析数据
+const loadMonthlyTrendData = async () => {
+  try {
     const params = {
       source_type: 1,
       data_source: ['IMP_AMERICA_BL_SEA'],
       ...queryParam,
     };
-    const res = await getHsCodeReport(params);
-    hsCodeData.value = res.result.data.result;
-  };
-
-  const originCountryData = ref({});
 
-  // 获取原产国数据
-  const fetchOriginCountryData = async () => {
-    const params = {
-      source_type: 1,
-      data_source: ['IMP_AMERICA_BL_SEA'],
-      ...queryParam,
-    };
-    const res = await getOrigCountryReport(params);
-    originCountryData.value = res.result.data.result;
-  };
+    const res = await getTrendReport(params);
+    if (res.result.data.result && res.result.data.result) {
+      // 处理日期格式
+      monthlyTrendData.value = res.result.data.result.map((item) => ({
+        ...item,
+      }));
+    }
+    console.log(monthlyTrendData.value);
+  } catch (error) {
+    console.error('Failed to fetch data:', error);
+  } finally {
+    loading.value = false;
+  }
+};
 
-  const destinationCountryData = ref({});
+const hsCodeData = ref({});
 
-  // 获取目的国数据
-  const fetchDestinationCountryData = async () => {
-    const params = {
-      source_type: 1,
-      data_source: ['IMP_AMERICA_BL_SEA'],
-      ...queryParam,
-    };
-    const res = await getDestCountryReport(params);
-    destinationCountryData.value = res.result.data.result;
+// 获取HS编码数据
+const fetchHsCodeData = async () => {
+  const params = {
+    source_type: 1,
+    data_source: ['IMP_AMERICA_BL_SEA'],
+    ...queryParam,
   };
-
-  const supplierData = ref({});
-
-  // 获取供应商数据
-  const fetchSupplierData = async () => {
-    const params = {
-      source_type: 1,
-      data_source: ['IMP_AMERICA_BL_SEA'],
-      ...queryParam,
-    };
-    const res = await getSupplierReport(params);
-    supplierData.value = res.result.data.result;
+  const res = await getHsCodeReport(params);
+  hsCodeData.value = res.result.data.result;
+};
+
+const originCountryData = ref({});
+
+// 获取原产国数据
+const fetchOriginCountryData = async () => {
+  const params = {
+    source_type: 1,
+    data_source: ['IMP_AMERICA_BL_SEA'],
+    ...queryParam,
   };
-
-  const buyerData = ref({});
-
-  // 获取采购商数据
-  const fetchBuyerData = async () => {
-    const params = {
-      source_type: 1,
-      data_source: ['IMP_AMERICA_BL_SEA'],
-      ...queryParam,
-    };
-    const res = await getBuyerReport(params);
-    buyerData.value = res.result.data.result;
+  const res = await getOrigCountryReport(params);
+  originCountryData.value = res.result.data.result;
+};
+
+const destinationCountryData = ref({});
+
+// 获取目的国数据
+const fetchDestinationCountryData = async () => {
+  const params = {
+    source_type: 1,
+    data_source: ['IMP_AMERICA_BL_SEA'],
+    ...queryParam,
+  };
+  const res = await getDestCountryReport(params);
+  destinationCountryData.value = res.result.data.result;
+};
+
+const supplierData = ref({});
+
+// 获取供应商数据
+const fetchSupplierData = async () => {
+  const params = {
+    source_type: 1,
+    data_source: ['IMP_AMERICA_BL_SEA'],
+    ...queryParam,
+  };
+  const res = await getSupplierReport(params);
+  supplierData.value = res.result.data.result;
+};
+
+const buyerData = ref({});
+
+// 获取采购商数据
+const fetchBuyerData = async () => {
+  const params = {
+    source_type: 1,
+    data_source: ['IMP_AMERICA_BL_SEA'],
+    ...queryParam,
+  };
+  const res = await getBuyerReport(params);
+  buyerData.value = res.result.data.result;
+};
+
+const origPortData = ref({});
+// 获取起运港数据
+const fetchOrigPortData = async () => {
+  const params = {
+    source_type: 1,
+    data_source: ['IMP_AMERICA_BL_SEA'],
+    ...queryParam,
+  };
+  const res = await getOrigPortReport(params);
+  origPortData.value = res.result.data.result;
+}
+
+const destPortData = ref({});
+// 获取起运港数据
+const fetchDestPortData = async () => {
+  const params = {
+    source_type: 1,
+    data_source: ['IMP_AMERICA_BL_SEA'],
+    ...queryParam,
   };
-  onMounted(() => {});
+  const res = await getDestPortReport(params);
+  destPortData.value = res.result.data.result;
+}
+
+const transTypeData = ref({});
+// 获取运输方式数据
+const fetchTransTypeData = async () => {
+  const params = {
+    source_type: 1,
+    data_source: ['IMP_AMERICA_BL_SEA'],
+    ...queryParam,
+  };
+  const res = await getTransTypeReport(params);
+  transTypeData.value = res.result.data.result;
+}
+
+const incotermsData = ref({});
+// 获取成交方式数据
+const fetchIncotermsData = async () => {
+  const params = {
+    source_type: 1,
+    data_source: ['IMP_AMERICA_BL_SEA'],
+    ...queryParam,
+  };
+  const res = await getIncotermsReport(params);
+  incotermsData.value = res.result.data.result;
+}
+
+const isModalVisible = ref(false);
+
+// 修改供应商名称的点击事件
+const handleSupplierClick = async (supplierId) => {
+  loading.value = true;
+  const params = {
+    source_type: 1,
+    data_source: ['IMP_AMERICA_BL_SEA'],
+    date: [20230101, 20230630],
+    com_id:supplierId,
+    com_role: 2,
+  }
+  const response = await getCompanyInfo(params);
+  supplier.value = {
+    ...response.result.data.result,
+    postal_code: response.result.data.result.postal_code ? response.result.data.result.postal_code.join(',') : '' // 检查 postal_code 是否为 null
+  }; // Adjust based on your API response structure
+  loading.value = false; // 请求供应商详细信息
+  isModalVisible.value = true; // 显示弹窗
+};
+
+onMounted(() => { });
 </script>
 
 <style scoped lang="less">
-  .search-form {
-    padding: 20px;
-    background-color: #f5f5f5;
-    border-radius: 8px;
-    margin-bottom: 16px;
-
-    .query-container {
-      background-color: #fff;
-      padding: 16px;
-      border-radius: 4px;
-      box-shadow: 0 1px 4px rgba(0, 0, 0, 0.05);
-
-      .ant-row {
-        padding: 12px 0;
-
-        &:not(:last-child) {
-          border-bottom: 1px solid #e8e8e8;
-        }
-      }
 
-      .button-row {
-        padding: 16px 0 0;
-        border-bottom: none !important;
-        background-color: transparent !important;
-      }
+.search-form {
+  padding: 20px;
+  background-color: #f5f5f5;
+  border-radius: 8px;
+  margin-bottom: 16px;
+
+  .query-container {
+    background-color: #fff;
+    padding: 16px;
+    border-radius: 4px;
+    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.05);
 
-      .checkbox-group {
-        display: flex;
-        align-items: center;
-        height: 100%;
+    .ant-row {
+      padding: 12px 0;
+
+      &:not(:last-child) {
+        border-bottom: 1px solid #e8e8e8;
       }
     }
-  }
 
-  // 添加新的样式
-  .table-container {
-    background-color: #fff;
-    border-radius: 8px;
-    padding: 16px 24px;
-    margin: 0 20px;
-    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
-    transition: opacity 0.3s ease-in-out;
-
-    .custom-tabs {
-      :deep(.ant-tabs-nav) {
-        margin-bottom: 24px;
-
-        &::before {
-          border-bottom: 1px solid #f0f0f0;
-        }
+    .button-row {
+      padding: 16px 0 0;
+      border-bottom: none !important;
+      background-color: transparent !important;
+    }
 
-        .ant-tabs-tab {
-          padding: 12px 24px;
-          font-size: 14px;
-          transition: all 0.3s;
+    .checkbox-group {
+      display: flex;
+      align-items: center;
+      height: 100%;
+    }
+  }
+}
+
+// 添加新的样式
+.table-container {
+  background-color: #fff;
+  border-radius: 8px;
+  padding: 16px 24px;
+  margin: 0 20px;
+  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
+  transition: opacity 0.3s ease-in-out;
+
+  .custom-tabs {
+    :deep(.ant-tabs-nav) {
+      margin-bottom: 24px;
+
+      &::before {
+        border-bottom: 1px solid #f0f0f0;
+      }
 
-          &:hover {
-            color: @primary-color;
-          }
+      .ant-tabs-tab {
+        padding: 12px 24px;
+        font-size: 14px;
+        transition: all 0.3s;
 
-          &.ant-tabs-tab-active {
-            .ant-tabs-tab-btn {
-              font-weight: 500;
-            }
-          }
+        &:hover {
+          color: @primary-color;
         }
 
-        .ant-tabs-ink-bar {
-          height: 3px;
-          border-radius: 3px 3px 0 0;
+        &.ant-tabs-tab-active {
+          .ant-tabs-tab-btn {
+            font-weight: 500;
+          }
         }
       }
 
-      :deep(.ant-tabs-content) {
-        padding: 8px 0;
+      .ant-tabs-ink-bar {
+        height: 3px;
+        border-radius: 3px 3px 0 0;
       }
     }
+
+    :deep(.ant-tabs-content) {
+      padding: 8px 0;
+    }
   }
+}
 
-  // 分析报告内容样式
-  .analysis-content {
-    background: #fff;
+// 分析报告内容样式
+.analysis-content {
+  background: #fff;
 
-    .analysis-item {
-      margin-bottom: 24px; // 添加组件之间的间距
+  .analysis-item {
+    margin-bottom: 24px; // 添加组件之间的间距
 
-      &:last-child {
-        margin-bottom: 0; // 最后一个组件不需要底部间距
-      }
+    &:last-child {
+      margin-bottom: 0; // 最后一个组件不需要底部间距
+    }
 
-      :deep(.ant-card) {
-        transition: all 0.3s ease;
-        box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
+    :deep(.ant-card) {
+      transition: all 0.3s ease;
+      box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
 
-        &:hover {
-          box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
-        }
+      &:hover {
+        box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
       }
     }
   }
+}
 
-  // 表格工具栏样式
-  :deep(.ant-table-wrapper) {
-    .ant-table-title {
-      padding: 16px 0;
-    }
+// 表格工具栏样式
+:deep(.ant-table-wrapper) {
+  .ant-table-title {
+    padding: 16px 0;
   }
+}
 
-  // 按钮样式优化
-  :deep(.ant-btn) {
-    height: 32px;
-    padding: 0 16px;
-    border-radius: 4px;
+// 按钮样式优化
+:deep(.ant-btn) {
+  height: 32px;
+  padding: 0 16px;
+  border-radius: 4px;
 
-    &.ant-btn-primary {
-      box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
-    }
+  &.ant-btn-primary {
+    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
   }
+}
 
-  // 表格内容样式优化
-  :deep(.ant-table) {
-    .ant-table-thead > tr > th {
-      background: #fafafa;
-      font-weight: 500;
-    }
-
-    .ant-table-tbody > tr > td {
-      transition: background 0.3s;
-    }
+// 表格内容样式优化
+:deep(.ant-table) {
+  .ant-table-thead>tr>th {
+    background: #fafafa;
+    font-weight: 500;
+  }
 
-    .ant-table-tbody > tr:hover > td {
-      background: #f5f5f5;
-    }
+  .ant-table-tbody>tr>td {
+    transition: background 0.3s;
   }
 
-  // Add these new styles
-  .table-toolbar {
-    margin-bottom: 16px;
-    display: flex;
-    justify-content: flex-end;
+  .ant-table-tbody>tr:hover>td {
+    background: #f5f5f5;
   }
+}
+
+// Add these new styles
+.table-toolbar {
+  margin-bottom: 16px;
+  display: flex;
+  justify-content: flex-end;
+}
 </style>