|  | @@ -4,19 +4,282 @@
 | 
											
												
													
														|  |   * @Description: 关键词-TopSearchTerm Table
 |  |   * @Description: 关键词-TopSearchTerm Table
 | 
											
												
													
														|  |   * @Author: Cheney
 |  |   * @Author: Cheney
 | 
											
												
													
														|  |   */
 |  |   */
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +import { onMounted, ref, watch } from 'vue';
 | 
											
												
													
														|  | 
 |  | +import { usePagination } from '/@/utils/usePagination';
 | 
											
												
													
														|  | 
 |  | +import { getTopSearchTermTable } from './api';
 | 
											
												
													
														|  | 
 |  | +import { marketplaceIdEnum } from '/@/utils/marketplaceIdEnum';
 | 
											
												
													
														|  | 
 |  | +import { RefreshRight, Search } from '@element-plus/icons-vue';
 | 
											
												
													
														|  | 
 |  | +import { useRouter } from 'vue-router';
 | 
											
												
													
														|  | 
 |  | +import { ElMessage } from 'element-plus';
 | 
											
												
													
														|  | 
 |  | +import dayjs from 'dayjs';
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +const router = useRouter();
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +const { tableData, total, currentPage, pageSize, handlePageChange } = usePagination(fetchTableData);
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +const date = ref([dayjs().subtract(7, 'day').format('YYYY-MM-DD'), dayjs().subtract(1, 'day').format('YYYY-MM-DD')]);
 | 
											
												
													
														|  | 
 |  | +const searchTermInp = ref('');
 | 
											
												
													
														|  | 
 |  | +const asinInp = ref('');
 | 
											
												
													
														|  | 
 |  | +const marketplaceSelect = ref(marketplaceIdEnum[0].value); // 当前只有美国区 默认第一个为美国
 | 
											
												
													
														|  | 
 |  | +const marketplaceOptions = marketplaceIdEnum;
 | 
											
												
													
														|  | 
 |  | +const reportTypeSelect = ref('weekly');
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +const tableLoading = ref(false);
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +onMounted(() => {
 | 
											
												
													
														|  | 
 |  | +  fetchTableData();
 | 
											
												
													
														|  | 
 |  | +});
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +watch(date, () => {
 | 
											
												
													
														|  | 
 |  | +  fetchTableData();
 | 
											
												
													
														|  | 
 |  | +});
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +async function refreshTable() {
 | 
											
												
													
														|  | 
 |  | +  currentPage.value = 1;
 | 
											
												
													
														|  | 
 |  | +  pageSize.value = 10;
 | 
											
												
													
														|  | 
 |  | +  asinInp.value = '';
 | 
											
												
													
														|  | 
 |  | +  searchTermInp.value = '';
 | 
											
												
													
														|  | 
 |  | +  reportTypeSelect.value = 'weekly';
 | 
											
												
													
														|  | 
 |  | +  marketplaceSelect.value = marketplaceIdEnum[0].value;
 | 
											
												
													
														|  | 
 |  | +  await fetchTableData();
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +async function fetchTableData() {
 | 
											
												
													
														|  | 
 |  | +  tableLoading.value = true;
 | 
											
												
													
														|  | 
 |  | +  const query = {
 | 
											
												
													
														|  | 
 |  | +    page: currentPage.value,
 | 
											
												
													
														|  | 
 |  | +    limit: pageSize.value,
 | 
											
												
													
														|  | 
 |  | +    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],
 | 
											
												
													
														|  | 
 |  | +  };
 | 
											
												
													
														|  | 
 |  | +  const response = await getTopSearchTermTable(query);
 | 
											
												
													
														|  | 
 |  | +  total.value = response.total;
 | 
											
												
													
														|  | 
 |  | +  tableData.value = response.data;
 | 
											
												
													
														|  | 
 |  | +  tableLoading.value = false;
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +async function handleQueryChange() {
 | 
											
												
													
														|  | 
 |  | +  if (!validateSearchTermInput(searchTermInp.value)) {
 | 
											
												
													
														|  | 
 |  | +    ElMessage.warning({ message: '关键词只能输入数字和英文字母', plain: true });
 | 
											
												
													
														|  | 
 |  | +    return;
 | 
											
												
													
														|  | 
 |  | +  }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +  if (!validateAsinInput(asinInp.value)) {
 | 
											
												
													
														|  | 
 |  | +    if (asinInp.value.length == 0) return;
 | 
											
												
													
														|  | 
 |  | +    else {
 | 
											
												
													
														|  | 
 |  | +      ElMessage.warning({ message: '不符合匹配规范', plain: true });
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +    return;
 | 
											
												
													
														|  | 
 |  | +  }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +  await fetchTableData();
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +function handleJump() {
 | 
											
												
													
														|  | 
 |  | +  // console.log('All defined routes:', router.getRoutes());
 | 
											
												
													
														|  | 
 |  | +  router.push({ path: '/keyword/rootWordManage' });
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +/**
 | 
											
												
													
														|  | 
 |  | + * 校验SearchTerm输入是否合法
 | 
											
												
													
														|  | 
 |  | + * @param input 输入的字符串
 | 
											
												
													
														|  | 
 |  | + */
 | 
											
												
													
														|  | 
 |  | +function validateSearchTermInput(input: string) {
 | 
											
												
													
														|  | 
 |  | +  const regex = /^[a-zA-Z0-9\s]*$/;
 | 
											
												
													
														|  | 
 |  | +  return regex.test(input);
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +/**
 | 
											
												
													
														|  | 
 |  | + * 校验Asin输入是否合法
 | 
											
												
													
														|  | 
 |  | + * @param input 输入的字符串
 | 
											
												
													
														|  | 
 |  | + */
 | 
											
												
													
														|  | 
 |  | +function validateAsinInput(input: string) {
 | 
											
												
													
														|  | 
 |  | +  const regex = /^[Bb]0[A-Za-z0-9\s]+$/i;
 | 
											
												
													
														|  | 
 |  | +  return regex.test(input);
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  |  </script>
 |  |  </script>
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  <template>
 |  |  <template>
 | 
											
												
													
														|  | -<div style="background-color: #f7f7f7;">
 |  | 
 | 
											
												
													
														|  | -  <div class="flex justify-between mt-1.5 mx-2">
 |  | 
 | 
											
												
													
														|  | -    <span class="font-bold text-lg">
 |  | 
 | 
											
												
													
														|  | -      Top Search Term - Table
 |  | 
 | 
											
												
													
														|  | -    </span>
 |  | 
 | 
											
												
													
														|  | -    <el-button type="info">关键词管理</el-button>
 |  | 
 | 
											
												
													
														|  | 
 |  | +  <div class="mt-3 mx-1.5" style="background-color: #f7f7f7">
 | 
											
												
													
														|  | 
 |  | +    <div class="flex justify-between mt-1.5 mx-2">
 | 
											
												
													
														|  | 
 |  | +      <div class="font-bold text-lg">
 | 
											
												
													
														|  | 
 |  | +        <el-icon style="top: 3px">
 | 
											
												
													
														|  | 
 |  | +          <Memo />
 | 
											
												
													
														|  | 
 |  | +        </el-icon>
 | 
											
												
													
														|  | 
 |  | +        Top Search Term - Table
 | 
											
												
													
														|  | 
 |  | +      </div>
 | 
											
												
													
														|  | 
 |  | +      <div>
 | 
											
												
													
														|  | 
 |  | +        <el-button type="primary" plain @click="handleJump">关键词管理</el-button>
 | 
											
												
													
														|  | 
 |  | +        <el-button type="success" plain round>下载表格</el-button>
 | 
											
												
													
														|  | 
 |  | +      </div>
 | 
											
												
													
														|  | 
 |  | +    </div>
 | 
											
												
													
														|  | 
 |  | +  </div>
 | 
											
												
													
														|  | 
 |  | +  <div class="mx-3" style="margin-top: -8px">
 | 
											
												
													
														|  | 
 |  | +    <el-divider>
 | 
											
												
													
														|  | 
 |  | +      <el-icon>
 | 
											
												
													
														|  | 
 |  | +        <star-filled />
 | 
											
												
													
														|  | 
 |  | +      </el-icon>
 | 
											
												
													
														|  | 
 |  | +    </el-divider>
 | 
											
												
													
														|  |    </div>
 |  |    </div>
 | 
											
												
													
														|  | -</div>
 |  | 
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +  <el-card class="mx-3" v-loading="tableLoading" style="border: none">
 | 
											
												
													
														|  | 
 |  | +    <!-- table筛选栏 -->
 | 
											
												
													
														|  | 
 |  | +    <div class="flex justify-between">
 | 
											
												
													
														|  | 
 |  | +      <div class="flex gap-6 flex-wrap">
 | 
											
												
													
														|  | 
 |  | +        <div>
 | 
											
												
													
														|  | 
 |  | +          <span class="font-medium mr-0.5">市场 </span>
 | 
											
												
													
														|  | 
 |  | +          <el-select v-model="marketplaceSelect" @change="handleQueryChange" style="width: 130px">
 | 
											
												
													
														|  | 
 |  | +            <el-option
 | 
											
												
													
														|  | 
 |  | +              v-for="item in marketplaceOptions"
 | 
											
												
													
														|  | 
 |  | +              :disabled="item.disabled"
 | 
											
												
													
														|  | 
 |  | +              :key="item.value"
 | 
											
												
													
														|  | 
 |  | +              :value="item.value"
 | 
											
												
													
														|  | 
 |  | +              :label="item.label" />
 | 
											
												
													
														|  | 
 |  | +          </el-select>
 | 
											
												
													
														|  | 
 |  | +        </div>
 | 
											
												
													
														|  | 
 |  | +        <div>
 | 
											
												
													
														|  | 
 |  | +          <span class="font-medium mr-0.5">报告类型 </span>
 | 
											
												
													
														|  | 
 |  | +          <el-select v-model="reportTypeSelect" @change="handleQueryChange" style="width: 100px">
 | 
											
												
													
														|  | 
 |  | +            <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
 | 
											
												
													
														|  | 
 |  | +            style="width: 300px"></el-input>
 | 
											
												
													
														|  | 
 |  | +        </div>
 | 
											
												
													
														|  | 
 |  | +        <div>
 | 
											
												
													
														|  | 
 |  | +          <span class="font-medium mr-0.5">ASIN </span>
 | 
											
												
													
														|  | 
 |  | +          <el-input
 | 
											
												
													
														|  | 
 |  | +            v-model="asinInp"
 | 
											
												
													
														|  | 
 |  | +            @keyup.enter="handleQueryChange"
 | 
											
												
													
														|  | 
 |  | +            :prefix-icon="Search"
 | 
											
												
													
														|  | 
 |  | +            placeholder="输入后回车查询"
 | 
											
												
													
														|  | 
 |  | +            clearable
 | 
											
												
													
														|  | 
 |  | +            style="width: 180px"></el-input>
 | 
											
												
													
														|  | 
 |  | +        </div>
 | 
											
												
													
														|  | 
 |  | +        <div>
 | 
											
												
													
														|  | 
 |  | +          <span class="font-medium mr-0.5">报告日期 </span>
 | 
											
												
													
														|  | 
 |  | +          <el-date-picker
 | 
											
												
													
														|  | 
 |  | +            v-model="date"
 | 
											
												
													
														|  | 
 |  | +            type="daterange"
 | 
											
												
													
														|  | 
 |  | +            value-format="YYYY-MM-DD"
 | 
											
												
													
														|  | 
 |  | +            :popper-options="{ placement: 'bottom-end' }"
 | 
											
												
													
														|  | 
 |  | +            :clearable="false"
 | 
											
												
													
														|  | 
 |  | +            range-separator="至"
 | 
											
												
													
														|  | 
 |  | +            start-placeholder="开始日期"
 | 
											
												
													
														|  | 
 |  | +            end-placeholder="结束日期" />
 | 
											
												
													
														|  | 
 |  | +        </div>
 | 
											
												
													
														|  | 
 |  | +      </div>
 | 
											
												
													
														|  | 
 |  | +      <el-button @click="refreshTable" :icon="RefreshRight" circle></el-button>
 | 
											
												
													
														|  | 
 |  | +    </div>
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    <!-- table -->
 | 
											
												
													
														|  | 
 |  | +    <el-card shadow="never" class="mt-5">
 | 
											
												
													
														|  | 
 |  | +      <div style="height: 765px">
 | 
											
												
													
														|  | 
 |  | +        <el-table :data="tableData" stripe height="765px" style="width: 100%">
 | 
											
												
													
														|  | 
 |  | +          <el-table-column fixed prop="searchTerm" label="关键词" width="260">
 | 
											
												
													
														|  | 
 |  | +            <template #header>
 | 
											
												
													
														|  | 
 |  | +              <el-icon style="top: 2px; margin-right: 3px">
 | 
											
												
													
														|  | 
 |  | +                <Key />
 | 
											
												
													
														|  | 
 |  | +              </el-icon>
 | 
											
												
													
														|  | 
 |  | +              <span>关键词</span>
 | 
											
												
													
														|  | 
 |  | +            </template>
 | 
											
												
													
														|  | 
 |  | +            <template #default="{ row }">
 | 
											
												
													
														|  | 
 |  | +              <span class="font-medium text-lg" style="color: #0b3289">{{ row.searchTerm }}</span>
 | 
											
												
													
														|  | 
 |  | +            </template>
 | 
											
												
													
														|  | 
 |  | +          </el-table-column>
 | 
											
												
													
														|  | 
 |  | +          <el-table-column prop="searchFrequencyRank" label="关键词搜索排名" align="center" width="150">
 | 
											
												
													
														|  | 
 |  | +            <template #header>
 | 
											
												
													
														|  | 
 |  | +              <el-icon style="top: 2px; margin-right: 4px">
 | 
											
												
													
														|  | 
 |  | +                <Rank />
 | 
											
												
													
														|  | 
 |  | +              </el-icon>
 | 
											
												
													
														|  | 
 |  | +              <span>关键词搜索排名</span>
 | 
											
												
													
														|  | 
 |  | +            </template>
 | 
											
												
													
														|  | 
 |  | +            <template #default="{ row }">
 | 
											
												
													
														|  | 
 |  | +              <span class="font-medium">{{ row.searchFrequencyRank }}</span>
 | 
											
												
													
														|  | 
 |  | +            </template>
 | 
											
												
													
														|  | 
 |  | +          </el-table-column>
 | 
											
												
													
														|  | 
 |  | +          <el-table-column prop="clickedAsin" align="center" label="Asin">
 | 
											
												
													
														|  | 
 |  | +            <template #header>
 | 
											
												
													
														|  | 
 |  | +              <el-icon style="top: 2px; margin-right: 5px">
 | 
											
												
													
														|  | 
 |  | +                <Goods />
 | 
											
												
													
														|  | 
 |  | +              </el-icon>
 | 
											
												
													
														|  | 
 |  | +              <span>Asin</span>
 | 
											
												
													
														|  | 
 |  | +            </template>
 | 
											
												
													
														|  | 
 |  | +            <template #default="{ row }">
 | 
											
												
													
														|  | 
 |  | +              <span class="font-medium">{{ row.clickedAsin }}</span>
 | 
											
												
													
														|  | 
 |  | +            </template>
 | 
											
												
													
														|  | 
 |  | +          </el-table-column>
 | 
											
												
													
														|  | 
 |  | +          <el-table-column prop="clickedItemName" label="标题">
 | 
											
												
													
														|  | 
 |  | +            <template #header>
 | 
											
												
													
														|  | 
 |  | +              <el-icon style="top: 2px; margin-right: 5px">
 | 
											
												
													
														|  | 
 |  | +                <Reading />
 | 
											
												
													
														|  | 
 |  | +              </el-icon>
 | 
											
												
													
														|  | 
 |  | +              <span>标题</span>
 | 
											
												
													
														|  | 
 |  | +            </template>
 | 
											
												
													
														|  | 
 |  | +          </el-table-column>
 | 
											
												
													
														|  | 
 |  | +          <el-table-column prop="clickShareRank" label="点击分享率排名" align="center" width="150">
 | 
											
												
													
														|  | 
 |  | +            <template #header>
 | 
											
												
													
														|  | 
 |  | +              <el-icon style="top: 2px; margin-right: 4px">
 | 
											
												
													
														|  | 
 |  | +                <Medal />
 | 
											
												
													
														|  | 
 |  | +              </el-icon>
 | 
											
												
													
														|  | 
 |  | +              <span>点击分享率排名</span>
 | 
											
												
													
														|  | 
 |  | +            </template>
 | 
											
												
													
														|  | 
 |  | +            <template #default="{ row }">
 | 
											
												
													
														|  | 
 |  | +              <span class="font-semibold">{{ row.clickShareRank }}</span>
 | 
											
												
													
														|  | 
 |  | +            </template>
 | 
											
												
													
														|  | 
 |  | +          </el-table-column>
 | 
											
												
													
														|  | 
 |  | +          <el-table-column prop="clickShare" align="center" label="点击分享率">
 | 
											
												
													
														|  | 
 |  | +            <template #header>
 | 
											
												
													
														|  | 
 |  | +              <el-icon style="top: 2px; margin-right: 4px">
 | 
											
												
													
														|  | 
 |  | +                <Pointer />
 | 
											
												
													
														|  | 
 |  | +              </el-icon>
 | 
											
												
													
														|  | 
 |  | +              <span>点击分享率</span>
 | 
											
												
													
														|  | 
 |  | +            </template>
 | 
											
												
													
														|  | 
 |  | +            <template #default="{ row }">
 | 
											
												
													
														|  | 
 |  | +              <span class="font-semibold">{{ row.clickShare }}</span>
 | 
											
												
													
														|  | 
 |  | +            </template>
 | 
											
												
													
														|  | 
 |  | +          </el-table-column>
 | 
											
												
													
														|  | 
 |  | +          <el-table-column prop="conversionShare" align="center" label="转化分享率">
 | 
											
												
													
														|  | 
 |  | +            <template #header>
 | 
											
												
													
														|  | 
 |  | +              <el-icon style="top: 2px; margin-right: 5px">
 | 
											
												
													
														|  | 
 |  | +                <Switch />
 | 
											
												
													
														|  | 
 |  | +              </el-icon>
 | 
											
												
													
														|  | 
 |  | +              <span>转化分享率</span>
 | 
											
												
													
														|  | 
 |  | +            </template>
 | 
											
												
													
														|  | 
 |  | +            <template #default="{ row }">
 | 
											
												
													
														|  | 
 |  | +              <span class="font-semibold">{{ row.conversionShare }}</span>
 | 
											
												
													
														|  | 
 |  | +            </template>
 | 
											
												
													
														|  | 
 |  | +          </el-table-column>
 | 
											
												
													
														|  | 
 |  | +        </el-table>
 | 
											
												
													
														|  | 
 |  | +      </div>
 | 
											
												
													
														|  | 
 |  | +      <div class="mt-3.5 flex justify-end">
 | 
											
												
													
														|  | 
 |  | +        <el-pagination
 | 
											
												
													
														|  | 
 |  | +          v-model:current-page="currentPage"
 | 
											
												
													
														|  | 
 |  | +          v-model:page-size="pageSize"
 | 
											
												
													
														|  | 
 |  | +          :page-sizes="[10, 20, 30, 50]"
 | 
											
												
													
														|  | 
 |  | +          layout="sizes, prev, pager, next"
 | 
											
												
													
														|  | 
 |  | +          :total="total"
 | 
											
												
													
														|  | 
 |  | +          @change="handlePageChange" />
 | 
											
												
													
														|  | 
 |  | +      </div>
 | 
											
												
													
														|  | 
 |  | +    </el-card>
 | 
											
												
													
														|  | 
 |  | +  </el-card>
 | 
											
												
													
														|  |  </template>
 |  |  </template>
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  <style scoped>
 |  |  <style scoped>
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | 
 |  | +:deep(.el-divider__text.is-center.el-divider__text) {
 | 
											
												
													
														|  | 
 |  | +  background-color: #f8f8f8;
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  |  </style>
 |  |  </style>
 |