|
@@ -1,4 +1,4 @@
|
|
|
-<script setup lang="ts">
|
|
|
+<script lang="ts" setup>
|
|
|
/**
|
|
|
* @Name: index.vue
|
|
|
* @Description: 搜索词-TopSearchTerm Table
|
|
@@ -14,9 +14,12 @@ import { useRouter } from 'vue-router';
|
|
|
import { ElMessage } from 'element-plus';
|
|
|
import dayjs from 'dayjs';
|
|
|
import enLocale from 'element-plus/es/locale/lang/en';
|
|
|
+import { useTableHeight } from '/@/utils/useTableHeight';
|
|
|
+import { useCustomHeight } from '/@/utils/useCustomHeight';
|
|
|
+
|
|
|
|
|
|
const router = useRouter();
|
|
|
-const { tableData, total, currentPage, pageSize, handlePageChange } = usePagination(fetchTableData);
|
|
|
+const { tableData, total, currentPage, pageSize } = usePagination(fetchTableData);
|
|
|
const marketplaceSelect = ref(marketplaceIdEnum[0].value); // 当前只有美国区 默认第一个为美国
|
|
|
const marketplaceOptions = marketplaceIdEnum;
|
|
|
const reportTypeSelect = ref('weekly');
|
|
@@ -27,8 +30,15 @@ const downloadLoading = ref(false);
|
|
|
const date = ref(calculateLastWeek()); // 设置默认日期为上周的周日到周六
|
|
|
const dateDimension = ref(date.value[0]);
|
|
|
|
|
|
+const titleContainer = ref();
|
|
|
+const queryContainer = ref();
|
|
|
+const heightObj = {
|
|
|
+ a: 32 + 13 + 40 + 70 + 40 + 48 + 95
|
|
|
+}
|
|
|
+const { tableHeight } = useCustomHeight(heightObj);
|
|
|
+
|
|
|
onBeforeMount(() => {
|
|
|
- pageSize.value = 21; // 将usePagination中的pageSize默认修改每页显示21条
|
|
|
+ pageSize.value = 7; // 将usePagination中的pageSize默认修改每页显示21条
|
|
|
fetchTableData();
|
|
|
});
|
|
|
|
|
@@ -59,7 +69,7 @@ function calculateLastWeek() {
|
|
|
const today = dayjs();
|
|
|
const lastSaturday = today.subtract(today.day() + 1, 'day'); // 上周六
|
|
|
const lastSunday = lastSaturday.subtract(6, 'day'); // 上周日
|
|
|
- return [lastSunday.format('YYYY-MM-DD'), lastSaturday.format('YYYY-MM-DD')];
|
|
|
+ return [ lastSunday.format('YYYY-MM-DD'), lastSaturday.format('YYYY-MM-DD') ];
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -72,7 +82,7 @@ function calculateEndDate(startDate: string) {
|
|
|
|
|
|
async function refreshTable() {
|
|
|
currentPage.value = 1;
|
|
|
- pageSize.value = 21;
|
|
|
+ pageSize.value = 7;
|
|
|
asinInp.value = '';
|
|
|
searchTermInp.value = '';
|
|
|
reportTypeSelect.value = 'weekly';
|
|
@@ -80,17 +90,22 @@ async function refreshTable() {
|
|
|
await fetchTableData();
|
|
|
}
|
|
|
|
|
|
-async function fetchTableData() {
|
|
|
+async function fetchTableData(isQuery = false) {
|
|
|
tableLoading.value = true;
|
|
|
+
|
|
|
+ if (isQuery) {
|
|
|
+ currentPage.value = 1;
|
|
|
+ }
|
|
|
+
|
|
|
const query = {
|
|
|
page: currentPage.value,
|
|
|
- limit: pageSize.value,
|
|
|
+ limit: pageSize.value * 3,
|
|
|
asin: asinInp.value,
|
|
|
search_term: searchTermInp.value,
|
|
|
report_type: reportTypeSelect.value,
|
|
|
marketplace_Ids: marketplaceSelect.value,
|
|
|
date_start: date.value[0],
|
|
|
- date_end: date.value[1],
|
|
|
+ date_end: date.value[1]
|
|
|
};
|
|
|
try {
|
|
|
const response = await getTopSearchTermTable(query);
|
|
@@ -109,9 +124,9 @@ async function fetchTableData() {
|
|
|
/**
|
|
|
* 下拉框值改变和input清空事件触发
|
|
|
*/
|
|
|
-async function handleSelectChange() {
|
|
|
+function handleSelectChange() {
|
|
|
calculateDate();
|
|
|
- await fetchTableData();
|
|
|
+ // await fetchTableData();
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -165,12 +180,12 @@ async function handleDownload() {
|
|
|
date_end: date.value[1],
|
|
|
search_term: searchTermInp.value,
|
|
|
marketplace_Ids: marketplaceSelect.value,
|
|
|
- report_type: reportTypeSelect.value,
|
|
|
+ report_type: reportTypeSelect.value
|
|
|
};
|
|
|
|
|
|
const response = await postDownload(body);
|
|
|
|
|
|
- const blob = new Blob([response.data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
|
|
|
+ const blob = new Blob([ response.data ], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
|
|
|
|
|
|
// 创建一个临时 URL
|
|
|
const url = window.URL.createObjectURL(blob);
|
|
@@ -181,7 +196,7 @@ async function handleDownload() {
|
|
|
|
|
|
// 设置文件名
|
|
|
const currentTime = dayjs().format('YYYY-MM-DD_HH_mm_ss');
|
|
|
- const filename = `TopSearchTerm_${currentTime}.xlsx`;
|
|
|
+ const filename = `TopSearchTerm_${ currentTime }.xlsx`;
|
|
|
|
|
|
link.setAttribute('download', filename);
|
|
|
|
|
@@ -202,151 +217,156 @@ async function handleDownload() {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-function getTagStyle(clickShareRank: number): Record<string, string> {
|
|
|
- switch (clickShareRank) {
|
|
|
- case 1:
|
|
|
- return { backgroundColor: '#fbbf24', color: '#fff', border: '1px solid #fbbf24' }; // 金色
|
|
|
- case 2:
|
|
|
- return { backgroundColor: '#C0C0C0', color: '#fff', border: '1px solid #C0C0C0' }; // 银色
|
|
|
- case 3:
|
|
|
- return { backgroundColor: '#CD7F32', color: '#fff', border: '1px solid #CD7F32' }; // 铜色
|
|
|
- default:
|
|
|
- return { backgroundColor: '#f0f0f0', color: '#000', border: '1px solid #e0e0e0' };
|
|
|
- }
|
|
|
-}
|
|
|
+// function getTagStyle(clickShareRank: number): Record<string, string> {
|
|
|
+// switch (clickShareRank) {
|
|
|
+// case 1:
|
|
|
+// return { backgroundColor: '#fbbf24', color: '#fff', border: '1px solid #fbbf24' }; // 金色
|
|
|
+// case 2:
|
|
|
+// return { backgroundColor: '#C0C0C0', color: '#fff', border: '1px solid #C0C0C0' }; // 银色
|
|
|
+// case 3:
|
|
|
+// return { backgroundColor: '#CD7F32', color: '#fff', border: '1px solid #CD7F32' }; // 铜色
|
|
|
+// default:
|
|
|
+// return { backgroundColor: '#f0f0f0', color: '#000', border: '1px solid #e0e0e0' };
|
|
|
+// }
|
|
|
+// }
|
|
|
|
|
|
function arraySpanMethod({ row, column, rowIndex, columnIndex }) {
|
|
|
// 每三个合并为一个单元格
|
|
|
if (columnIndex >= 0 && columnIndex <= 4) {
|
|
|
if (rowIndex % 3 === 0) {
|
|
|
- return [3, 1]; // 跨越三行
|
|
|
+ return [ 3, 1 ]; // 跨越三行
|
|
|
} else {
|
|
|
- return [0, 0]; // 被合并的单元格
|
|
|
+ return [ 0, 0 ]; // 被合并的单元格
|
|
|
}
|
|
|
}
|
|
|
- return [1, 1];
|
|
|
+ return [ 1, 1 ];
|
|
|
+}
|
|
|
+
|
|
|
+async function handlePageChange(newPage: number, newSize: number) {
|
|
|
+ currentPage.value = newPage;
|
|
|
+ pageSize.value = newSize;
|
|
|
+ await fetchTableData();
|
|
|
}
|
|
|
</script>
|
|
|
|
|
|
<template>
|
|
|
- <div class="mx-3">
|
|
|
+ <div ref="titleContainer" class="mx-3">
|
|
|
<el-divider>
|
|
|
<div class="font-bold text-xl">
|
|
|
<el-icon style="top: 3px">
|
|
|
- <DataAnalysis />
|
|
|
+ <DataAnalysis/>
|
|
|
</el-icon>
|
|
|
Top Search Term - Table
|
|
|
</div>
|
|
|
</el-divider>
|
|
|
</div>
|
|
|
- <el-card class="mx-3 mb-2.5" v-loading="tableLoading" style="border: none;">
|
|
|
+ <el-card v-loading="tableLoading" class="mx-3 mb-2.5" style="border: none;">
|
|
|
<!-- table筛选栏 -->
|
|
|
- <div class="flex justify-between">
|
|
|
+ <div ref="queryContainer" class="flex justify-between">
|
|
|
<div class="flex gap-5 flex-wrap">
|
|
|
<div>
|
|
|
- <span class="font-medium mr-0.5">市场 </span>
|
|
|
- <el-select v-model="marketplaceSelect" @change="handleSelectChange" style="width: 90px">
|
|
|
+ <span class="font-medium mr-0.5">市 场 </span>
|
|
|
+ <el-select v-model="marketplaceSelect" style="width: 90px" @change="handleSelectChange">
|
|
|
<el-option
|
|
|
- v-for="item in marketplaceOptions"
|
|
|
- :disabled="item.disabled"
|
|
|
- :key="item.value"
|
|
|
- :value="item.value"
|
|
|
- :label="item.label" />
|
|
|
+ v-for="item in marketplaceOptions"
|
|
|
+ :key="item.value"
|
|
|
+ :disabled="item.disabled"
|
|
|
+ :label="item.label"
|
|
|
+ :value="item.value"/>
|
|
|
</el-select>
|
|
|
</div>
|
|
|
<div>
|
|
|
<span class="font-medium mr-0.5">报告类型 </span>
|
|
|
- <el-select v-model="reportTypeSelect" @change="handleSelectChange" style="width: 90px">
|
|
|
- <el-option label="周度" value="weekly" />
|
|
|
- <el-option label="月度" value="monthly" />
|
|
|
+ <el-select v-model="reportTypeSelect" style="width: 90px" @change="handleSelectChange">
|
|
|
+ <el-option label="周度" value="weekly"/>
|
|
|
+ <el-option label="月度" value="monthly"/>
|
|
|
</el-select>
|
|
|
</div>
|
|
|
<div>
|
|
|
<span class="font-medium mr-0.5">搜索词 </span>
|
|
|
<el-input
|
|
|
- v-model="searchTermInp"
|
|
|
- @keyup.enter="handleQueryChange"
|
|
|
- :prefix-icon="Search"
|
|
|
- placeholder="输入后回车查询"
|
|
|
- clearable
|
|
|
- @clear="handleSelectChange"
|
|
|
- style="width: 240px" />
|
|
|
+ v-model="searchTermInp"
|
|
|
+ :prefix-icon="Search"
|
|
|
+ clearable
|
|
|
+ placeholder="请输入"
|
|
|
+ style="width: 240px" />
|
|
|
</div>
|
|
|
<div>
|
|
|
<span class="font-medium mr-0.5">ASIN </span>
|
|
|
<el-input
|
|
|
- v-model="asinInp"
|
|
|
- @keyup.enter="handleQueryChange"
|
|
|
- :prefix-icon="Search"
|
|
|
- placeholder="输入后回车查询"
|
|
|
- clearable
|
|
|
- @clear="handleSelectChange"
|
|
|
- style="width: 180px" />
|
|
|
+ v-model="asinInp"
|
|
|
+ :prefix-icon="Search"
|
|
|
+ clearable
|
|
|
+ placeholder="请输入"
|
|
|
+ style="width: 180px" />
|
|
|
</div>
|
|
|
<div>
|
|
|
<span class="font-medium mr-0.5">报告日期 </span>
|
|
|
- <el-config-provider :locale="enLocale">
|
|
|
- <el-date-picker
|
|
|
- v-if="reportTypeSelect === 'weekly'"
|
|
|
- v-model="dateDimension"
|
|
|
- type="week"
|
|
|
- value-format="YYYY-MM-DD"
|
|
|
- :format="`${date[0]} To ${date[1]}`"
|
|
|
- :popper-options="{ placement: 'bottom-end' }"
|
|
|
- :disabled-date="(time: Date) => time > new Date()"
|
|
|
- :clearable="false" />
|
|
|
+ <el-config-provider v-if="reportTypeSelect === 'weekly'" :locale="enLocale">
|
|
|
<el-date-picker
|
|
|
+ v-model="dateDimension"
|
|
|
+ :clearable="false"
|
|
|
+ :disabled-date="(time: Date) => time > new Date()"
|
|
|
+ :format="`${date[0]} To ${date[1]}`"
|
|
|
+ :popper-options="{ placement: 'bottom-end' }"
|
|
|
+ type="week"
|
|
|
+ value-format="YYYY-MM-DD"/>
|
|
|
+ </el-config-provider>
|
|
|
+ <el-date-picker
|
|
|
v-else
|
|
|
v-model="dateDimension"
|
|
|
- type="month"
|
|
|
- value-format="YYYY-MM"
|
|
|
+ :clearable="false"
|
|
|
+ :disabled-date="(time: Date) => time > new Date()"
|
|
|
:format="`${date[0]} To ${date[1]}`"
|
|
|
:popper-options="{ placement: 'bottom-end' }"
|
|
|
- :disabled-date="(time: Date) => time > new Date()"
|
|
|
- :clearable="false">
|
|
|
- <template #default> 123</template>
|
|
|
- </el-date-picker>
|
|
|
- </el-config-provider>
|
|
|
+ type="month"
|
|
|
+ value-format="YYYY-MM">
|
|
|
+ <!--<template #default> 123</template>-->
|
|
|
+ </el-date-picker>
|
|
|
</div>
|
|
|
</div>
|
|
|
<div class="flex">
|
|
|
- <el-button type="primary" plain @click="handleJump" :icon="TopRight">搜索词管理</el-button>
|
|
|
- <el-button
|
|
|
- type="success"
|
|
|
- plain
|
|
|
- @click="handleDownload"
|
|
|
+ <el-button :icon="Search" type="primary" @click="fetchTableData(true)">查 询</el-button>
|
|
|
+ <el-button :icon="Refresh" @click="refreshTable">刷 新</el-button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="mt-6">
|
|
|
+ <el-button :icon="TopRight" plain type="primary" @click="handleJump">搜索词管理</el-button>
|
|
|
+ <el-button
|
|
|
+ :disabled="!tableData.length"
|
|
|
:icon="Download"
|
|
|
- round
|
|
|
:loading="downloadLoading"
|
|
|
- :disabled="!tableData.length"
|
|
|
- >下载表格
|
|
|
- </el-button>
|
|
|
- <el-button @click="refreshTable" :icon="Refresh" circle></el-button>
|
|
|
- </div>
|
|
|
+ plain
|
|
|
+ round
|
|
|
+ type="success"
|
|
|
+ @click="handleDownload"
|
|
|
+ >下载表格
|
|
|
+ </el-button>
|
|
|
</div>
|
|
|
<!-- table -->
|
|
|
- <el-card shadow="never" class="mt-5">
|
|
|
- <div style="height: 100%; overflow: auto">
|
|
|
- <el-table :data="tableData" :span-method="arraySpanMethod" height="920" stripe style="width: 100%">
|
|
|
+ <el-card class="mt-5" shadow="never">
|
|
|
+ <div>
|
|
|
+ <el-table :data="tableData" :span-method="arraySpanMethod" :height="tableHeight" stripe style="width: 100%">
|
|
|
<!-- 保持索引是1, 2, 3的顺序 不会收到合并单元格的影响 -->
|
|
|
- <el-table-column fixed type="index" width="50" :index="(index) => Math.floor(index / 3) + 1" />
|
|
|
- <el-table-column prop="searchTerm" label="搜索词" width="260">
|
|
|
+ <el-table-column :index="(index) => Math.floor(index / 3) + (currentPage - 1) * pageSize + 1" fixed
|
|
|
+ label="No." type="index" width="80"/>
|
|
|
+ <el-table-column label="搜索词" prop="searchTerm">
|
|
|
<template #header>
|
|
|
<el-icon style="top: 2px; margin-right: 3px">
|
|
|
- <Key />
|
|
|
+ <Key/>
|
|
|
</el-icon>
|
|
|
<span>搜索词</span>
|
|
|
</template>
|
|
|
<template #default="{ row }">
|
|
|
- <el-link :underline="false" target="_blank" style="color: #5a6fc0"
|
|
|
- >{{ row.searchTerm }}
|
|
|
+ <el-link :underline="false" style="font-size: 18px;" target="_blank" type="primary">
|
|
|
+ {{ row.searchTerm }}
|
|
|
</el-link>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
- <el-table-column prop="searchFrequencyRank" label="搜索词搜索排名" align="center" width="150">
|
|
|
+ <el-table-column align="center" label="搜索词搜索排名" prop="searchFrequencyRank" width="90">
|
|
|
<template #header>
|
|
|
<el-icon style="top: 2px; margin-right: 4px">
|
|
|
- <Rank />
|
|
|
+ <Rank/>
|
|
|
</el-icon>
|
|
|
<span>搜索词搜索排名</span>
|
|
|
</template>
|
|
@@ -354,10 +374,10 @@ function arraySpanMethod({ row, column, rowIndex, columnIndex }) {
|
|
|
<span class="font-medium">{{ row.searchFrequencyRank }}</span>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
- <el-table-column prop="clickShareSummary" label="点击分享率(SUM)" align="center" width="150">
|
|
|
+ <el-table-column align="center" label="点击分享率(SUM)" prop="clickShareSummary" width="90">
|
|
|
<template #header>
|
|
|
<el-icon style="top: 2px; margin-right: 4px">
|
|
|
- <Star />
|
|
|
+ <Star/>
|
|
|
</el-icon>
|
|
|
<span>点击分享率汇总</span>
|
|
|
</template>
|
|
@@ -365,10 +385,10 @@ function arraySpanMethod({ row, column, rowIndex, columnIndex }) {
|
|
|
<span class="font-medium">{{ row.clickShareSummary }}</span>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
- <el-table-column prop="conversionShareSummary" label="转化分享率(SUM)" align="center" width="150">
|
|
|
+ <el-table-column align="center" label="转化分享率(SUM)" prop="conversionShareSummary" width="90">
|
|
|
<template #header>
|
|
|
<el-icon style="top: 2px; margin-right: 4px">
|
|
|
- <Star />
|
|
|
+ <Star/>
|
|
|
</el-icon>
|
|
|
<span>转化分享率汇总</span>
|
|
|
</template>
|
|
@@ -376,10 +396,10 @@ function arraySpanMethod({ row, column, rowIndex, columnIndex }) {
|
|
|
<span class="font-medium">{{ row.conversionShareSummary }}</span>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
- <el-table-column prop="clickedAsin" label="Asin" align="center">
|
|
|
+ <el-table-column align="center" label="Asin" prop="clickedAsin" width="160">
|
|
|
<template #header>
|
|
|
<el-icon style="top: 2px; margin-right: 5px">
|
|
|
- <Goods />
|
|
|
+ <Goods/>
|
|
|
</el-icon>
|
|
|
<span>Asin</span>
|
|
|
</template>
|
|
@@ -395,16 +415,17 @@ function arraySpanMethod({ row, column, rowIndex, columnIndex }) {
|
|
|
<!--</div>-->
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
- <el-table-column prop="clickedItemName" label="标题">
|
|
|
+ <el-table-column label="标 题" prop="clickedItemName">
|
|
|
<template #header>
|
|
|
<el-icon style="top: 2px; margin-right: 5px">
|
|
|
- <Reading />
|
|
|
+ <Reading/>
|
|
|
</el-icon>
|
|
|
- <span>标题</span>
|
|
|
+ <span>标 题</span>
|
|
|
</template>
|
|
|
<template #default="{ row }">
|
|
|
<div class="text-sm text-left">
|
|
|
- <el-tooltip class="box-item" effect="dark" :content="row.clickedItemName" placement="top" :show-after="500">
|
|
|
+ <el-tooltip :content="row.clickedItemName" :show-after="500" class="box-item" effect="dark"
|
|
|
+ placement="top">
|
|
|
<div class="tooltip-text">
|
|
|
{{ row.clickedItemName }}
|
|
|
</div>
|
|
@@ -412,23 +433,23 @@ function arraySpanMethod({ row, column, rowIndex, columnIndex }) {
|
|
|
</div>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
- <el-table-column prop="clickShareRank" label="点击分享率排名" align="center" width="150">
|
|
|
+ <el-table-column align="center" label="点击分享率排名" prop="clickShareRank" width="90">
|
|
|
<template #header>
|
|
|
<el-icon style="top: 2px; margin-right: 4px">
|
|
|
- <Medal />
|
|
|
+ <Medal/>
|
|
|
</el-icon>
|
|
|
<span>点击分享率排名</span>
|
|
|
</template>
|
|
|
<template #default="{ row }">
|
|
|
- <el-tag :style="getTagStyle(row.clickShareRank)">
|
|
|
- {{ row.clickShareRank }}
|
|
|
- </el-tag>
|
|
|
+ <!--<el-tag :style="getTagStyle(row.clickShareRank)">-->
|
|
|
+ {{ row.clickShareRank }}
|
|
|
+ <!--</el-tag>-->
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
- <el-table-column prop="clickShare" align="center" label="点击分享率">
|
|
|
+ <el-table-column align="center" label="点击分享率" prop="clickShare" width="90">
|
|
|
<template #header>
|
|
|
<el-icon style="top: 2px; margin-right: 4px">
|
|
|
- <Pointer />
|
|
|
+ <Pointer/>
|
|
|
</el-icon>
|
|
|
<span>点击分享率</span>
|
|
|
</template>
|
|
@@ -436,10 +457,10 @@ function arraySpanMethod({ row, column, rowIndex, columnIndex }) {
|
|
|
<span class="font-semibold">{{ row.clickShare }}</span>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
- <el-table-column prop="conversionShare" align="center" label="转化分享率">
|
|
|
+ <el-table-column align="center" label="转化分享率" prop="conversionShare" width="90">
|
|
|
<template #header>
|
|
|
<el-icon style="top: 2px; margin-right: 5px">
|
|
|
- <Switch />
|
|
|
+ <Switch/>
|
|
|
</el-icon>
|
|
|
<span>转化分享率</span>
|
|
|
</template>
|
|
@@ -451,12 +472,12 @@ function arraySpanMethod({ row, column, rowIndex, columnIndex }) {
|
|
|
</div>
|
|
|
<div class="mt-3.5 flex justify-end">
|
|
|
<el-pagination
|
|
|
- v-model:current-page="currentPage"
|
|
|
- v-model:page-size="pageSize"
|
|
|
- :page-sizes="[21, 42, 72, 102, 132, 162]"
|
|
|
- layout="sizes, prev, pager, next, total"
|
|
|
- :total="total"
|
|
|
- @change="handlePageChange" />
|
|
|
+ v-model:current-page="currentPage"
|
|
|
+ v-model:page-size="pageSize"
|
|
|
+ :page-sizes="[7, 14, 21, 28, 35]"
|
|
|
+ :total="Math.floor(total / 3)"
|
|
|
+ layout="prev, pager, next, sizes, total"
|
|
|
+ @change="handlePageChange"/>
|
|
|
</div>
|
|
|
</el-card>
|
|
|
</el-card>
|