Browse Source

✨ feat:

修改图表组件方法, 趋势图提供数据给表格
WanGxC 1 năm trước cách đây
mục cha
commit
b74c57d30d

+ 7 - 2
src/views/productCenter/productAnalysis/api.ts

@@ -5,7 +5,6 @@ import emitter from '/@/utils/emitter'
 
 export const apiPrefix = '/api/sellers/product/trend/daily/'
 export function getCardData(query: UserPageQuery) {
-
   return request({
     url: '/api/sellers/product/trend/total/',
     method: 'GET',
@@ -20,7 +19,6 @@ export function getLineData(query: UserPageQuery) {
     params: query,
   })
 }
-
 export function getLineWeekData(query: UserPageQuery) {
   query['dateRangeType'] = 'W'
   return request({
@@ -74,3 +72,10 @@ export function getDetail(query) {
     params: query,
   })
 }
+export function getListData(query) {
+  return request({
+    url: '/api/sellers/product/trend/daily/',
+    method: 'GET',
+    params: query,
+  })
+}

+ 91 - 0
src/views/productCenter/productAnalysis/components/DataTable/index.vue

@@ -0,0 +1,91 @@
+<template>
+  <div style="overflow: hidden; width: 100%; height: 800px" v-loading="tableLoading">
+    <vxe-grid v-bind="gridOptions">
+      <template v-for="col in universalColumns" #[`${col.field}_default`]="{ row }">
+        <div>
+          {{ row[col.field] }}
+        </div>
+      </template>
+      <!-- <template v-for="col in dynamicCols" #[`${col.field}_footer`]="{ items, _columnIndex }">
+        <CustomFooterCell :totalValue="items[_columnIndex].totalValue" :gapValue="items[_columnIndex].gapValue" :isCompare="isCompare" :columnIndex="_columnIndex" />
+      </template> -->
+      <!-- <template #pager>
+        <vxe-pager
+          :layouts="['Sizes', 'PrevJump', 'PrevPage', 'Number', 'NextPage', 'NextJump', 'FullJump', 'Total']"
+          v-model:current-page="tablePage.currentPage"
+          v-model:page-size="tablePage.pageSize"
+          :total="tablePage.total"
+          @page-change="handlePageChange">
+        </vxe-pager>
+      </template> -->
+    </vxe-grid>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { inject, onMounted, reactive, ref, watch } from 'vue'
+import { VXETable } from 'vxe-table'
+import { getListData } from '../../api'
+import { universalColumns } from '../../utils/columns'
+
+const profile = <any>inject('profile')
+const dateRange = <any>inject('dateRange')
+const tableData = <any>inject('tableData')
+
+const tableLoading = ref(false)
+
+// const tablePage = reactive({
+//   total: 0,
+//   currentPage: 1,
+//   pageSize: 15,
+// })
+
+const gridOptions = reactive({
+  height: 'auto',
+  border: false,
+  round: true,
+  showFooter: true,
+
+  columnConfig: {
+    resizable: true,
+  },
+  toolbarConfig: {
+    custom: true,
+    // slots: {
+    //   buttons: 'toolbar_buttons',
+    // },
+  },
+  columns: [],
+  data: [],
+})
+
+async function fetchListData() {
+  tableLoading.value = true
+  const query = {
+    profileId: profile.value.profile_id,
+    startDate: dateRange.value[0],
+    endDate: dateRange.value[1],
+    // dateRangeType: 'D'
+  }
+  try {
+    const res = await getListData(query)
+    gridOptions.columns = universalColumns
+    gridOptions.data = res.data
+  } catch (error) {
+    console.log('error:', error)
+  } finally {
+    tableLoading.value = false
+  }
+}
+
+watch(tableData, () => {
+  // console.log('tableData.value', tableData.value)
+  gridOptions.data = tableData.value
+})
+
+onMounted(() => {
+  fetchListData()
+})
+</script>
+
+<style scoped></style>

+ 4 - 1
src/views/productCenter/productAnalysis/components/DateTendency/index.vue

@@ -278,6 +278,7 @@ const changeMetric = () => {
   chartObj.setOption(opt)
 }
 
+const emit = defineEmits(['changeStatDim'])
 const changeStatDim = async () => {
   loading.value = true
   let source = await getDataset()
@@ -285,10 +286,12 @@ const changeStatDim = async () => {
     chartObj.setOption({ dataset: { source: source } })
   }
   loading.value = false
+  emit('changeStatDim', source);
 }
 
+
 watch(props.query, async () => {
-  console.log("------watch-----queryParams", props.query)
+  // console.log("------watch-----queryParams", props.query)
   loading.value = true
   await getMetricsItems()
   const items = await getDataset()

+ 1 - 0
src/views/productCenter/productAnalysis/components/TopParentAsin/index.vue

@@ -59,6 +59,7 @@ const parentAsin = ref('')
 const childAsin = ref('')
 const sku = ref('')
 
+// 根据不同的点击事件发送请求获取数据
 emitter.on('useSelectItem-clickParentAsinBtn', (value: any) => {
   parentAsin.value = value.selectedParentAsin
   fetchDetail()

+ 16 - 3
src/views/productCenter/productAnalysis/components/TrendOverview/index.vue

@@ -1,12 +1,14 @@
 <template>
   <el-card>
     <!-- <p>{{ queryParams }}</p> -->
-    <DataTendencyChart :metricEnum="productListMetricsEnum" 
-      :query="queryParams" 
+    <DataTendencyChart
+      :metricEnum="productListMetricsEnum"
+      :query="queryParams"
       :fetchCard="getCardData"
       :fetchLine="getLineData"
       :fetch-line-month="getLineMonthData"
-      :fetch-line-week="getLineWeekData">
+      :fetch-line-week="getLineWeekData"
+      @changeStatDim="update">
     </DataTendencyChart>
   </el-card>
 </template>
@@ -26,6 +28,8 @@ const profile = <any>inject('profile')
 const publicData = usePublicData()
 const { dateRange } = storeToRefs(publicData)
 
+const listData = ref([])
+
 const parentAsin = ref('')
 const childAsin = ref('')
 const sku = ref('')
@@ -53,6 +57,15 @@ const queryParams = ref({
   sku,
 })
 
+const emit = defineEmits(['updateList'])
+
+function update(value) {
+  listData.value = value
+  emit('updateList', value)
+}
+
+
+
 onBeforeUnmount(() => {
   emitter.all.clear()
 })

+ 15 - 3
src/views/productCenter/productAnalysis/index.vue

@@ -4,7 +4,7 @@
     <div class="filters">
       <DateRangePicker v-model="dateRange"></DateRangePicker>
       <div v-show="activeName == 'trendOverview'">
-        <el-select v-model="filter1" placeholder="Select" style="width: 240px; margin-right: 8px;;">
+        <el-select v-model="filter1" placeholder="Select" style="width: 240px; margin-right: 8px">
           <el-option v-for="item in options1" :key="item.value" :label="item.label" :value="item.value" />
         </el-select>
         <el-select v-model="filter2" placeholder="Select" style="width: 240px">
@@ -15,7 +15,8 @@
     <div>
       <el-tabs v-model="activeName" type="border-card" class="chart-tabs">
         <el-tab-pane label="趋势总览" name="trendOverview">
-          <TrendOverview></TrendOverview>
+          <TrendOverview @updateList="handleUpdate"></TrendOverview>
+          <DataTable></DataTable>
         </el-tab-pane>
         <el-tab-pane label="广告优化" name="adOptimization">广告优化</el-tab-pane>
         <el-tab-pane label="销售概览" name="salesOverview">销售概览</el-tab-pane>
@@ -27,12 +28,13 @@
 
 <script setup lang="ts">
 import { storeToRefs } from 'pinia'
-import { provide, ref } from 'vue'
+import { provide, ref, watch } from 'vue'
 import TopParentAsin from './components/TopParentAsin/index.vue'
 import TrendOverview from './components/TrendOverview/index.vue'
 import DateRangePicker from '/@/components/DateRangePicker/index.vue'
 import { usePublicData } from '/@/stores/publicData'
 import { useShopInfo } from '/@/stores/shopInfo'
+import DataTable from './components/DataTable/index.vue'
 
 // 店铺信息
 const shopInfo = useShopInfo()
@@ -68,6 +70,16 @@ const options2 = [
     label: 'Option2',
   },
 ]
+
+const updatedData = ref([])
+provide('tableData', updatedData)
+
+function handleUpdate(value) {
+  updatedData.value = value
+}
+
+
+
 </script>
 
 <style scoped>

+ 57 - 53
src/views/productCenter/productAnalysis/utils/columns.ts

@@ -1,58 +1,62 @@
-const universal = [
-  { field: 'TotalSales', title: '总销售额', align: 'right', width: 130, sortable: true, slots: { default: 'TotalSales_default', footer: 'TotalSales_footer' } },
-  { field: 'TotalOrderItems', title: '总订单数', align: 'right', width: 130, sortable: true, slots: { default: 'TotalOrderItems_default', footer: 'TotalOrderItems_footer' } },
-  { field: 'TotalUnitOrdered', title: '总销量', align: 'right', width: 130, sortable: true, slots: { default: 'TotalUnitOrdered_default', footer: 'TotalUnitOrdered_footer' } },
-  { field: 'SAP', title: '单均价', align: 'right', width: 130, sortable: true, slots: { default: 'SAP_default', footer: 'SAP_footer' } },
-  { field: 'TotalAdSales', title: '广告销售额', align: 'right', width: 130, sortable: true, slots: { default: 'TotalAdSales_default', footer: 'TotalAdSales_footer' } },
-  { field: 'TotalAdSalesSameSKU', title: '本商品广告销售额', align: 'right', width: 180, sortable: true, slots: { default: 'TotalAdSalesSameSKU_default', footer: 'TotalAdSalesSameSKU_footer' } },
-  { field: 'TotalAdPurchases', title: '广告订单数', align: 'right', width: 130, sortable: true, slots: { default: 'TotalAdPurchases_default', footer: 'TotalAdPurchases_footer' } },
-  { field: 'TotalAdPurchasesSameSKU', title: '本商品广告订单数', align: 'right', width: 180, sortable: true, slots: { default: 'TotalAdPurchasesSameSKU_default', footer: 'TotalAdPurchasesSameSKU_footer' } },
-  { field: 'TotalAdUnitOrdered', title: '广告销量', align: 'right', width: 130, sortable: true, slots: { default: 'TotalAdUnitOrdered_default', footer: 'TotalAdUnitOrdered_footer' } },
-  { field: 'TotalAdUnitOrderedSameSKU', title: '本商品广告销量', align: 'right', width: 180, sortable: true, slots: { default: 'TotalAdUnitOrderedSameSKU_default', footer: 'TotalAdUnitOrderedSameSKU_footer' } },
-  { field: 'Spend', title: '花费', align: 'right', width: 130, sortable: true, showOverflow: true, slots: { default: 'Spend_default', footer: 'Spend_footer' } },
-  { field: 'ACOS', title: 'ACOS', align: 'right', width: 130, sortable: true, slots: { default: 'ACOS_default', footer: 'ACOS_footer' } },
-  { field: 'ROAS', title: 'ROAS', align: 'right', width: 130, sortable: true, slots: { default: 'ROAS_default', footer: 'ROAS_footer' } },
-  { field: 'TACOS', title: 'TACOS', align: 'right', width: 130, sortable: true, slots: { default: 'TACOS_default', footer: 'TACOS_footer' } },
-  { field: 'CR', title: '转化率', align: 'right', width: 130, sortable: true, slots: { default: 'CR_default', footer: 'CR_footer' } },
-  { field: 'CTR', title: '点击率', align: 'right', width: 130, sortable: true, slots: { default: 'CTR_default', footer: 'CTR_footer' } },
-  { field: 'CPC', title: '点击成本', align: 'right', width: 130, sortable: true, slots: { default: 'CPC_default', footer: 'CPC_footer' } },
-  { field: 'CPO', title: '总订单成本', align: 'right', width: 130, sortable: true, slots: { default: 'CPO_default', footer: 'CPO_footer' } },
-  { field: 'CPA', title: '广告订单成本', align: 'right', width: 180, sortable: true, slots: { default: 'CPA_default', footer: 'CPA_footer' } },
-  { field: 'Impression', title: '曝光量', align: 'right', width: 130, sortable: true, slots: { default: 'Impression_default', footer: 'Impression_footer' } },
-  { field: 'Click', title: '点击量', align: 'right', width: 130, sortable: true, slots: { default: 'Click_default', footer: 'Click_footer' } },
-  { field: 'Sessions', title: '会话次数', align: 'right', width: 150, sortable: true, slots: { default: 'Sessions_default', footer: 'Sessions_footer' } },
-  { field: 'ProductCr', title: '商品会话百分比', align: 'right', width: 150, sortable: true, slots: { default: 'ProductCr_default', footer: 'ProductCr_footer' } },
-  { field: 'PageViews', title: '页面浏览量', align: 'right', width: 130, sortable: true, slots: { default: 'PageViews_default', footer: 'PageViews_footer' } },
-  { field: 'BuyBoxPercentage', title: '推荐报价(购买按钮)百分比', align: 'right', width: 180, sortable: true, showHeaderOverflow: true, slots: { default: 'BuyBoxPercentage_default', footer: 'BuyBoxPercentage_footer' } },
-  { field: 'FBAQuantity', title: 'FBA库存', align: 'right', width: 130, sortable: true, slots: { footer: 'FBAQuantity_footer' } },
-  { field: 'FBMQuantity', title: 'FBM库存', align: 'right', width: 130, sortable: true, showHeaderOverflow: true, slots: { footer: 'FBMQuantity_footer' } },
+export const universalColumns = [
+  { field: 'Name', title: '日期', align: 'right', width: 130 },
+  { field: 'TotalSales', title: '总销售额', align: 'right', width: 130, sortable: true, slots: { default: 'TotalSales_default' } },
+  { field: 'TotalOrderItems', title: '总订单数', align: 'right', width: 130, sortable: true, slots: { default: 'TotalOrderItems_default' } },
+  { field: 'TotalUnitOrdered', title: '总销量', align: 'right', width: 130, sortable: true, slots: { default: 'TotalUnitOrdered_default' } },
+  { field: 'SAP', title: '单均价', align: 'right', width: 130, sortable: true, slots: { default: 'SAP_default' } },
+  { field: 'TotalAdSales', title: '广告销售额', align: 'right', width: 130, sortable: true, slots: { default: 'TotalAdSales_default' } },
+  { field: 'TotalAdSalesSameSKU', title: '本商品广告销售额', align: 'right', width: 180, sortable: true, slots: { default: 'TotalAdSalesSameSKU_default' } },
+  { field: 'TotalAdPurchases', title: '广告订单数', align: 'right', width: 130, sortable: true, slots: { default: 'TotalAdPurchases_default' } },
+  { field: 'TotalAdPurchasesSameSKU', title: '本商品广告订单数', align: 'right', width: 180, sortable: true, slots: { default: 'TotalAdPurchasesSameSKU_default' } },
+  { field: 'TotalAdUnitOrdered', title: '广告销量', align: 'right', width: 130, sortable: true, slots: { default: 'TotalAdUnitOrdered_default' } },
+  { field: 'TotalAdUnitOrderedSameSKU', title: '本商品广告销量', align: 'right', width: 180, sortable: true, slots: { default: 'TotalAdUnitOrderedSameSKU_default' } },
+  { field: 'Spend', title: '花费', align: 'right', width: 130, sortable: true, showOverflow: true, slots: { default: 'Spend_default' } },
+  { field: 'ACOS', title: 'ACOS', align: 'right', width: 130, sortable: true, slots: { default: 'ACOS_default' } },
+  { field: 'ROAS', title: 'ROAS', align: 'right', width: 130, sortable: true, slots: { default: 'ROAS_default' } },
+  { field: 'TACOS', title: 'TACOS', align: 'right', width: 130, sortable: true, slots: { default: 'TACOS_default' } },
+  { field: 'CR', title: '转化率', align: 'right', width: 130, sortable: true, slots: { default: 'CR_default' } },
+  { field: 'CTR', title: '点击率', align: 'right', width: 130, sortable: true, slots: { default: 'CTR_default' } },
+  { field: 'CPC', title: '点击成本', align: 'right', width: 130, sortable: true, slots: { default: 'CPC_default' } },
+  { field: 'CPO', title: '总订单成本', align: 'right', width: 130, sortable: true, slots: { default: 'CPO_default' } },
+  { field: 'CPA', title: '广告订单成本', align: 'right', width: 180, sortable: true, slots: { default: 'CPA_default' } },
+  { field: 'Impression', title: '曝光量', align: 'right', width: 130, sortable: true, slots: { default: 'Impression_default' } },
+  { field: 'Click', title: '点击量', align: 'right', width: 130, sortable: true, slots: { default: 'Click_default' } },
+  { field: 'Sessions', title: '会话次数', align: 'right', width: 150, sortable: true, slots: { default: 'Sessions_default' } },
+  { field: 'ProductCr', title: '商品会话百分比', align: 'right', width: 150, sortable: true, slots: { default: 'ProductCr_default' } },
+  { field: 'PageViews', title: '页面浏览量', align: 'right', width: 130, sortable: true, slots: { default: 'PageViews_default' } },
+  { field: 'BuyBoxPercentage', title: '推荐报价(购买按钮)百分比', align: 'right', width: 180, sortable: true, showHeaderOverflow: true, slots: { default: 'BuyBoxPercentage_default' } },
+  { field: 'FBAQuantity', title: 'FBA库存', align: 'right', width: 130, sortable: true },
+  { field: 'FBMQuantity', title: 'FBM库存', align: 'right', width: 130, sortable: true, showHeaderOverflow: true },
 ]
 
-export const productLineColumns = [{ field: 'productlineName', title: '产品线', align: 'left', fixed: 'left', width: 180, sortable: true, slots: { default: 'productlineName_default', footer: 'productlineName_footer' } }, ...universal]
+// export const productLineColumns = [
+//   { field: 'productlineName', title: '产品线', align: 'left', fixed: 'left', width: 180, sortable: true, slots: { default: 'productlineName_default', footer: 'productlineName_footer' } },
+//   ...universal,
+// ]
 
-export const parentAsinColumns = [
-  { field: 'parentAsin', title: '父ASIN', align: 'left', fixed: 'left', width: 180, sortable: true, slots: { default: 'parentAsin_default', footer: 'parentAsin_footer' } },
-  { field: 'bestSku', title: '最佳SKU', align: 'right', width: 260, sortable: true, slots: { default: 'bestSku_default', footer: 'bestSku_footer' } },
-  // { field: 'TACOS', title: '预警TACOS', align: 'right', width: 130, slots: { default: 'TACOS_default', footer: 'TACOS_footer' } },
-  ...universal,
-]
+// export const parentAsinColumns = [
+//   { field: 'parentAsin', title: '父ASIN', align: 'left', fixed: 'left', width: 180, sortable: true, slots: { default: 'parentAsin_default', footer: 'parentAsin_footer' } },
+//   { field: 'bestSku', title: '最佳SKU', align: 'right', width: 260, sortable: true, slots: { default: 'bestSku_default', footer: 'bestSku_footer' } },
+//   // { field: 'TACOS', title: '预警TACOS', align: 'right', width: 130, slots: { default: 'TACOS_default', footer: 'TACOS_footer' } },
+//   ...universal,
+// ]
 
-export const asinColumns = [
-  { field: 'Asin', title: 'ASIN', align: 'left', fixed: 'left', width: 180, sortable: true, slots: { default: 'Asin_default', footer: 'Asin_footer' } },
-  { field: 'productlineName', title: '产品线', align: 'left', fixed: 'left', width: 180, sortable: true, slots: { default: 'productlineName_default', footer: 'productlineName_footer' } },
-  { field: 'rank', title: '排名', align: 'left', fixed: 'left', width: 120, sortable: true, slots: { default: 'rank_default', footer: 'rank_footer' } },
-  // { field: 'TACOS', title: '预警TACOS', align: 'right', width: 130, slots: { default: 'TACOS_default', footer: 'TACOS_footer' } },
-  ...universal,
-]
+// export const asinColumns = [
+//   { field: 'Asin', title: 'ASIN', align: 'left', fixed: 'left', width: 180, sortable: true, slots: { default: 'Asin_default', footer: 'Asin_footer' } },
+//   { field: 'productlineName', title: '产品线', align: 'left', fixed: 'left', width: 180, sortable: true, slots: { default: 'productlineName_default', footer: 'productlineName_footer' } },
+//   { field: 'rank', title: '排名', align: 'left', fixed: 'left', width: 120, sortable: true, slots: { default: 'rank_default', footer: 'rank_footer' } },
+//   // { field: 'TACOS', title: '预警TACOS', align: 'right', width: 130, slots: { default: 'TACOS_default', footer: 'TACOS_footer' } },
+//   ...universal,
+// ]
 
-export const skuColumns = [
-  { field: 'sku', title: 'SKU', align: 'left', fixed: 'left', width: 260, slots: { default: 'sku_default', footer: 'sku_footer' } },
-  { field: 'productlineName', title: '产品线', align: 'left', width: 180, slots: { default: 'productlineName_default', footer: 'productlineName_footer' } },
-  { field: 'status', title: '商品状态', align: 'center', width: 80, slots: { default: 'status_default', footer: 'status_footer' } },
-  { field: 'rank', title: '排名', align: 'left', width: 130, slots: { default: 'rank_default', footer: 'rank_footer' } },
-  { field: 'parentAsin', title: '父ASIN', align: 'left', width: 130, slots: { default: 'parentAsin_default', footer: 'parentAsin_footer' } },
-  { field: 'launchDatetime', title: '上架时间', align: 'center', width: 120, sortable: true, slots: { default: 'launchDatetime_default', footer: 'launchDatetime_footer' } },
-  ...universal,
-  // { field: 'ABP', title: '异常推广', align: 'right', width: 130, slots: { default: 'ABP_default', footer: 'ABP_footer' } },
-  // { field: 'TACOS', title: '预警TACOS', align: 'right', width: 130, slots: { default: 'TACOS_default', footer: 'TACOS_footer' } },
-]
+// export const skuColumns = [
+//   { field: 'sku', title: 'SKU', align: 'left', fixed: 'left', width: 260, slots: { default: 'sku_default', footer: 'sku_footer' } },
+//   { field: 'productlineName', title: '产品线', align: 'left', width: 180, slots: { default: 'productlineName_default', footer: 'productlineName_footer' } },
+//   { field: 'status', title: '商品状态', align: 'center', width: 80, slots: { default: 'status_default', footer: 'status_footer' } },
+//   { field: 'rank', title: '排名', align: 'left', width: 130, slots: { default: 'rank_default', footer: 'rank_footer' } },
+//   { field: 'parentAsin', title: '父ASIN', align: 'left', width: 130, slots: { default: 'parentAsin_default', footer: 'parentAsin_footer' } },
+//   { field: 'launchDatetime', title: '上架时间', align: 'center', width: 120, sortable: true, slots: { default: 'launchDatetime_default', footer: 'launchDatetime_footer' } },
+//   ...universal,
+//   // { field: 'ABP', title: '异常推广', align: 'right', width: 130, slots: { default: 'ABP_default', footer: 'ABP_footer' } },
+//   // { field: 'TACOS', title: '预警TACOS', align: 'right', width: 130, slots: { default: 'TACOS_default', footer: 'TACOS_footer' } },
+// ]