|
@@ -1,186 +1,194 @@
|
|
|
<!-- src/views/adweb/data/components/HsCodeAnalysis.vue -->
|
|
|
<template>
|
|
|
- <a-card title="产品">
|
|
|
- <div>
|
|
|
- <div class="switch-view">
|
|
|
- <a-radio-group v-model:value="viewType" button-style="solid">
|
|
|
- <a-radio-button value="chart">图表</a-radio-button>
|
|
|
- <a-radio-button value="table">列表</a-radio-button>
|
|
|
- </a-radio-group>
|
|
|
- </div>
|
|
|
-
|
|
|
- <!-- 图表视图 -->
|
|
|
- <div v-show="viewType === 'chart'" ref="chartRef" :style="{ height, width }"></div>
|
|
|
-
|
|
|
- <!-- 列表视图 -->
|
|
|
- <div v-show="viewType === 'table'">
|
|
|
- <a-table :columns="columns" :data-source="tableData" :pagination="false">
|
|
|
- <template #bodyCell="{ column, record }">
|
|
|
- <template v-if="column.dataIndex === 'val'">
|
|
|
- {{ record.val }}
|
|
|
- </template>
|
|
|
+ <a-card title="产品">
|
|
|
+ <template #extra>
|
|
|
+ <a-radio-group v-model:value="sortMode" button-style="solid" style="margin-left: 16px;">
|
|
|
+ <a-radio-button value="count">交易次数</a-radio-button>
|
|
|
+ <a-radio-button value="sum_weight">交易重量</a-radio-button>
|
|
|
+ <a-radio-button value="sum_amount">交易金额</a-radio-button>
|
|
|
+ </a-radio-group>
|
|
|
+ </template>
|
|
|
+ <div>
|
|
|
+ <div class="switch-view">
|
|
|
+ <a-radio-group v-model:value="viewType" button-style="solid">
|
|
|
+ <a-radio-button value="chart">图表</a-radio-button>
|
|
|
+ <a-radio-button value="table">列表</a-radio-button>
|
|
|
+ </a-radio-group>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 图表视图 -->
|
|
|
+ <div v-show="viewType === 'chart'" ref="chartRef" :style="{ height, width }"></div>
|
|
|
+
|
|
|
+ <!-- 列表视图 -->
|
|
|
+ <div v-show="viewType === 'table'">
|
|
|
+ <a-table :columns="columns" :data-source="tableData" :pagination="false">
|
|
|
+ <template #bodyCell="{ column, record }">
|
|
|
+ <template v-if="column.dataIndex === 'val'">
|
|
|
+ {{ record.val }}
|
|
|
</template>
|
|
|
- </a-table>
|
|
|
- </div>
|
|
|
+ </template>
|
|
|
+ </a-table>
|
|
|
</div>
|
|
|
- </a-card>
|
|
|
- </template>
|
|
|
-
|
|
|
- <script lang="ts">
|
|
|
- import { defineComponent, PropType, ref, Ref, onMounted, watch, computed } from 'vue';
|
|
|
- import { useECharts } from '/@/hooks/web/useECharts';
|
|
|
-
|
|
|
- export default defineComponent({
|
|
|
- props: {
|
|
|
- width: {
|
|
|
- type: String as PropType<string>,
|
|
|
- default: '100%',
|
|
|
+ </div>
|
|
|
+ </a-card>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script lang="ts">
|
|
|
+import { defineComponent, PropType, ref, Ref, onMounted, watch, computed } from 'vue';
|
|
|
+import { useECharts } from '/@/hooks/web/useECharts';
|
|
|
+
|
|
|
+export default defineComponent({
|
|
|
+ props: {
|
|
|
+ width: {
|
|
|
+ type: String as PropType<string>,
|
|
|
+ default: '100%',
|
|
|
+ },
|
|
|
+ height: {
|
|
|
+ type: String as PropType<string>,
|
|
|
+ default: '350px',
|
|
|
+ },
|
|
|
+ hsCodeData: {
|
|
|
+ default: () => ({}),
|
|
|
+ },
|
|
|
+ },
|
|
|
+ setup(props) {
|
|
|
+ const chartRef = ref<HTMLDivElement | null>(null);
|
|
|
+ const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>);
|
|
|
+ const viewType = ref<'chart' | 'table'>('chart');
|
|
|
+ const sortMode = ref('count');
|
|
|
+
|
|
|
+ // 格式化函数
|
|
|
+ const formatNumber = (value: string | number) => {
|
|
|
+ if (!value) return '0.00';
|
|
|
+ return Number(value).toLocaleString('en-US', {
|
|
|
+ minimumFractionDigits: 2,
|
|
|
+ maximumFractionDigits: 2,
|
|
|
+ });
|
|
|
+ };
|
|
|
+
|
|
|
+ // 表格列定义
|
|
|
+ const columns = [
|
|
|
+ {
|
|
|
+ title: 'HS编码',
|
|
|
+ dataIndex: 'val',
|
|
|
+ key: 'val',
|
|
|
},
|
|
|
- height: {
|
|
|
- type: String as PropType<string>,
|
|
|
- default: '350px',
|
|
|
+ {
|
|
|
+ title: '重量(KG)',
|
|
|
+ dataIndex: 'sum_weight',
|
|
|
+ key: 'sum_weight',
|
|
|
+ customRender: ({ text }) => formatNumber(text),
|
|
|
},
|
|
|
- hsCodeData: {
|
|
|
- default: () => ({}),
|
|
|
+ {
|
|
|
+ title: '金额($)',
|
|
|
+ dataIndex: 'sum_amount',
|
|
|
+ key: 'sum_amount',
|
|
|
+ customRender: ({ text }) => formatNumber(text),
|
|
|
},
|
|
|
- },
|
|
|
- setup(props) {
|
|
|
- const chartRef = ref<HTMLDivElement | null>(null);
|
|
|
- const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>);
|
|
|
- const viewType = ref<'chart' | 'table'>('chart');
|
|
|
-
|
|
|
- // 格式化函数
|
|
|
- const formatNumber = (value: string | number) => {
|
|
|
- if (!value) return '0.00';
|
|
|
- return Number(value).toLocaleString('en-US', {
|
|
|
- minimumFractionDigits: 2,
|
|
|
- maximumFractionDigits: 2,
|
|
|
- });
|
|
|
- };
|
|
|
-
|
|
|
- // 表格列定义
|
|
|
- const columns = [
|
|
|
- {
|
|
|
- title: 'HS编码',
|
|
|
- dataIndex: 'val',
|
|
|
- key: 'val',
|
|
|
+ {
|
|
|
+ title: '交易次数',
|
|
|
+ dataIndex: 'count',
|
|
|
+ key: 'count',
|
|
|
+ customRender: ({ text }) => {
|
|
|
+ return text ? Number(text).toLocaleString('en-US') : '0';
|
|
|
},
|
|
|
- {
|
|
|
- title: '重量(KG)',
|
|
|
- dataIndex: 'sum_weight',
|
|
|
- key: 'sum_weight',
|
|
|
- customRender: ({ text }) => formatNumber(text),
|
|
|
+ },
|
|
|
+ ];
|
|
|
+
|
|
|
+ // 计算表格数据
|
|
|
+ const tableData = computed(() => {
|
|
|
+ return props.hsCodeData?.buckets || [];
|
|
|
+ });
|
|
|
+
|
|
|
+ const updateChart = () => {
|
|
|
+ const chartData = tableData.value;
|
|
|
+ if (!chartData.length) return;
|
|
|
+
|
|
|
+ // 取前10条数据展示
|
|
|
+ const top10Data = chartData.slice(0, 10);
|
|
|
+
|
|
|
+ const colors = ['#53A2D3', '#FF6B6B', '#4ECDC4', '#45B7AF', '#96CEB4', '#FFEEAD', '#D4A5A5', '#9B59B6', '#3498DB', '#E67E22'];
|
|
|
+
|
|
|
+ setOptions({
|
|
|
+ tooltip: {
|
|
|
+ trigger: 'axis',
|
|
|
+ axisPointer: {
|
|
|
+ type: 'shadow',
|
|
|
+ },
|
|
|
},
|
|
|
- {
|
|
|
- title: '金额($)',
|
|
|
- dataIndex: 'sum_amount',
|
|
|
- key: 'sum_amount',
|
|
|
- customRender: ({ text }) => formatNumber(text),
|
|
|
+
|
|
|
+ grid: {
|
|
|
+ left: '3%',
|
|
|
+ right: '4%',
|
|
|
+ bottom: '3%',
|
|
|
+ containLabel: true,
|
|
|
},
|
|
|
- {
|
|
|
- title: '交易次数',
|
|
|
- dataIndex: 'count',
|
|
|
- key: 'count',
|
|
|
- customRender: ({ text }) => {
|
|
|
- return text ? Number(text).toLocaleString('en-US') : '0';
|
|
|
+ xAxis: {
|
|
|
+ type: 'category',
|
|
|
+ data: top10Data.map(item => item.val),
|
|
|
+ axisLabel: {
|
|
|
+ rotate: 45,
|
|
|
},
|
|
|
- },
|
|
|
- ];
|
|
|
-
|
|
|
- // 计算表格数据
|
|
|
- const tableData = computed(() => {
|
|
|
- return props.hsCodeData?.buckets || [];
|
|
|
- });
|
|
|
-
|
|
|
- const updateChart = () => {
|
|
|
- const chartData = tableData.value;
|
|
|
- if (!chartData.length) return;
|
|
|
-
|
|
|
- // 取前10条数据展示
|
|
|
- const top10Data = chartData.slice(0, 10);
|
|
|
-
|
|
|
- const colors = ['#53A2D3', '#FF6B6B', '#4ECDC4', '#45B7AF', '#96CEB4', '#FFEEAD', '#D4A5A5', '#9B59B6', '#3498DB', '#E67E22'];
|
|
|
-
|
|
|
- setOptions({
|
|
|
- tooltip: {
|
|
|
- trigger: 'axis',
|
|
|
- axisPointer: {
|
|
|
- type: 'shadow',
|
|
|
+ axisLine: {
|
|
|
+ lineStyle: {
|
|
|
+ color: '#ccc',
|
|
|
},
|
|
|
},
|
|
|
-
|
|
|
- grid: {
|
|
|
- left: '3%',
|
|
|
- right: '4%',
|
|
|
- bottom: '3%',
|
|
|
- containLabel: true,
|
|
|
- },
|
|
|
- xAxis: {
|
|
|
- type: 'category',
|
|
|
- data: top10Data.map(item => item.val),
|
|
|
- axisLabel: {
|
|
|
- rotate: 45,
|
|
|
- },
|
|
|
+ },
|
|
|
+ yAxis: [
|
|
|
+ {
|
|
|
+ type: 'value',
|
|
|
+ name: '交易次数',
|
|
|
+ position: 'left',
|
|
|
axisLine: {
|
|
|
lineStyle: {
|
|
|
- color: '#ccc',
|
|
|
+ color: '#53A2D3',
|
|
|
},
|
|
|
},
|
|
|
- },
|
|
|
- yAxis: [
|
|
|
- {
|
|
|
- type: 'value',
|
|
|
- name: '交易次数',
|
|
|
- position: 'left',
|
|
|
- axisLine: {
|
|
|
- lineStyle: {
|
|
|
- color: '#53A2D3',
|
|
|
- },
|
|
|
- },
|
|
|
- }
|
|
|
- ],
|
|
|
- series: [
|
|
|
- {
|
|
|
- name: '交易次数',
|
|
|
- type: 'bar',
|
|
|
- yAxisIndex: 0,
|
|
|
- data: top10Data.map((item, index) => ({
|
|
|
- value: Number(item.count),
|
|
|
- itemStyle: {
|
|
|
- color: colors[index]
|
|
|
- }
|
|
|
- })),
|
|
|
- }
|
|
|
- ],
|
|
|
- });
|
|
|
- };
|
|
|
-
|
|
|
- watch(
|
|
|
- () => props.hsCodeData,
|
|
|
- () => {
|
|
|
- updateChart();
|
|
|
- },
|
|
|
- { deep: true }
|
|
|
- );
|
|
|
-
|
|
|
- onMounted(() => {
|
|
|
- updateChart();
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ series: [
|
|
|
+ {
|
|
|
+ name: '交易次数',
|
|
|
+ type: 'bar',
|
|
|
+ yAxisIndex: 0,
|
|
|
+ data: top10Data.map((item, index) => ({
|
|
|
+ value: Number(item.count),
|
|
|
+ itemStyle: {
|
|
|
+ color: colors[index]
|
|
|
+ }
|
|
|
+ })),
|
|
|
+ }
|
|
|
+ ],
|
|
|
});
|
|
|
-
|
|
|
- return {
|
|
|
- chartRef,
|
|
|
- viewType,
|
|
|
- columns,
|
|
|
- tableData,
|
|
|
- formatNumber,
|
|
|
- };
|
|
|
- },
|
|
|
- });
|
|
|
- </script>
|
|
|
-
|
|
|
- <style scoped>
|
|
|
- .switch-view {
|
|
|
- text-align: right;
|
|
|
- margin-bottom: 16px;
|
|
|
- }
|
|
|
- </style>
|
|
|
+ };
|
|
|
+
|
|
|
+ watch(
|
|
|
+ () => props.hsCodeData,
|
|
|
+ () => {
|
|
|
+ updateChart();
|
|
|
+ },
|
|
|
+ { deep: true }
|
|
|
+ );
|
|
|
+
|
|
|
+ onMounted(() => {
|
|
|
+ updateChart();
|
|
|
+ });
|
|
|
+
|
|
|
+ return {
|
|
|
+ chartRef,
|
|
|
+ viewType,
|
|
|
+ sortMode,
|
|
|
+ columns,
|
|
|
+ tableData,
|
|
|
+ formatNumber,
|
|
|
+ };
|
|
|
+ },
|
|
|
+});
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+.switch-view {
|
|
|
+ margin-bottom: 16px;
|
|
|
+}
|
|
|
+</style>
|