Browse Source

✨ feat: 下拉框和按钮全局联动

WanGxC 1 year ago
parent
commit
0caba42165

+ 25 - 9
src/views/productCenter/productList/api.ts

@@ -1,8 +1,11 @@
 import { request } from '/@/utils/service'
 import { UserPageQuery, AddReq, DelReq, EditReq, InfoReq } from '@fast-crud/fast-crud'
+import emitter from '/@/utils/emitter'
 
-export const apiPrefix = '/api/ad_manage/sbcampaigns/'
+
+export const apiPrefix = '/api/sellers/home/daily/'
 export function getCardData(query: UserPageQuery) {
+
   return request({
     url: '/api/sellers/home/total/',
     method: 'GET',
@@ -12,7 +15,7 @@ export function getCardData(query: UserPageQuery) {
 export function getLineData(query: UserPageQuery) {
   query['dateRangeType'] = 'D'
   return request({
-    url: apiPrefix + 'daily/',
+    url: apiPrefix,
     method: 'GET',
     params: query,
   })
@@ -21,7 +24,7 @@ export function getLineData(query: UserPageQuery) {
 export function getLineWeekData(query: UserPageQuery) {
   query['dateRangeType'] = 'W'
   return request({
-    url: apiPrefix + 'daily/',
+    url: apiPrefix,
     method: 'GET',
     params: query,
   })
@@ -30,7 +33,7 @@ export function getLineWeekData(query: UserPageQuery) {
 export function getLineMonthData(query: UserPageQuery) {
   query['dateRangeType'] = 'M'
   return request({
-    url: apiPrefix + 'daily/',
+    url: apiPrefix,
     method: 'GET',
     params: query,
   })
@@ -54,28 +57,41 @@ export function postCreateProductLine(body) {
   return request({
     url: '/api/sellers/productline/create/',
     method: 'POST',
-    data: body
+    data: body,
   })
 }
 export function getProductCardData(query) {
   return request({
     url: '/api/sellers/productline/sales/',
     method: 'GET',
-    params: query
+    params: query,
   })
 }
 export function getProductDetail(query) {
   return request({
     url: '/api/sellers/productlinedetail/',
     method: 'GET',
-    params: query
+    params: query,
   })
 }
 export function postUpdateProductLine(body) {
   return request({
     url: '/api/sellers/productlinedetail/update/',
     method: 'POST',
-    data: body
+    data: body,
+  })
+}
+export function getTableDataForSKU(query) {
+  return request({
+    url: '/api/sellers/home/sku/list/',
+    method: 'GET',
+    params: query,
+  })
+}
+export function getTableDataForProductLine(query) {
+  return request({
+    url: '/api/sellers/home/productline/list/',
+    method: 'GET',
+    params: query,
   })
 }
-

+ 96 - 48
src/views/productCenter/productList/components/DataTable/index.vue

@@ -1,5 +1,5 @@
 <template>
-  <div style="overflow: hidden; width: 100%; height: 600px">
+  <div style="overflow: hidden; width: 100%; height: 600px" v-loading="tableLoading">
     <vxe-grid v-bind="gridOptions">
       <template #toolbar_buttons>
         <span>
@@ -18,8 +18,16 @@
 </template>
 
 <script setup>
-import { reactive, ref } from 'vue'
+import { reactive, ref, inject, onBeforeUnmount, onMounted,watch } from 'vue'
 import { VXETable } from 'vxe-table'
+import { getTableDataForSKU, getTableDataForProductLine } from '/@/views/productCenter/productList/api'
+import emitter from '/@/utils/emitter'
+import { skuColumns, productLineColumns } from '/@/views/productCenter/productList/utils/index'
+
+const profile = inject('profile')
+const dateRange = inject('dateRange')
+
+const tableLoading = ref(false)
 
 const gridOptions = reactive({
   height: 'auto',
@@ -34,53 +42,22 @@ const gridOptions = reactive({
       buttons: 'toolbar_buttons',
     },
   },
-  columns: [
-    { field: 'name', title: 'Name', align: 'center', width: 130, slots: { default: 'name_default' } },
-    { field: 'sex', title: 'Sex', align: 'center', width: 80, slots: { default: 'sex_default' } },
-    { field: 'name', title: '产品线', align: 'left', fixed: 'left', width: 180, sortable: true },
-    { field: 'sex', title: '总销售额', align: 'right', width: 130, sortable: true },
-    { field: 'age', title: '总订单数', align: 'right', width: 130, sortable: true },
-    { field: 'time', title: '总销量', align: 'right', width: 130, sortable: true },
-    { field: 'address', title: '单均价', align: 'right', width: 130, sortable: true },
-    { field: 'address', title: '广告销售额', align: 'right', width: 130, sortable: true },
-    { field: 'address', title: '本商品广告销售额', align: 'right', width: 180, sortable: true },
-    { field: 'address', title: '广告订单数', align: 'right', width: 130, sortable: true },
-    { field: 'address', title: '本商品广告订单数', align: 'right', width: 180, sortable: true },
-    { field: 'address', title: '广告销量', align: 'right', width: 130, sortable: true },
-    { field: 'address', title: '本商品广告销量', align: 'right', width: 180, sortable: true },
-    { field: 'address', title: '花费', align: 'right', width: 130, sortable: true, showOverflow: true },
-    { field: 'address', title: 'ACOS', align: 'right', width: 130, sortable: true },
-    { field: 'address', title: 'ROAS', align: 'right', width: 130, sortable: true },
-    { field: 'address', title: 'TACOS', align: 'right', width: 130, sortable: true },
-    { field: 'address', title: '转化率', align: 'right', width: 130, sortable: true },
-    { field: 'address', title: '点击率', align: 'right', width: 130, sortable: true },
-    { field: 'address', title: '点击成本', align: 'right', width: 130, sortable: true },
-    { field: 'address', title: '总订单成本', align: 'right', width: 130, sortable: true },
-    { field: 'address', title: '广告订单成本', align: 'right', width: 180, sortable: true },
-    { field: 'address', title: '曝光量', align: 'right', width: 130, sortable: true },
-    { field: 'address', title: '点击量', align: 'right', width: 130, sortable: true },
-    { field: 'address', title: '会话次数', align: 'right', width: 150, sortable: true },
-    { field: 'address', title: '商品会话百分比', align: 'right', width: 150, sortable: true },
-    { field: 'address', title: '页面浏览量', align: 'right', width: 130, sortable: true },
-    { field: 'address', title: '推荐报价(购买按钮)百分比', align: 'right', width: 180, sortable: true, showHeaderOverflow: true },
-    { field: 'address', title: 'FBA库存', align: 'right', width: 130, sortable: true },
-    { field: 'address', title: 'FBM库存', align: 'right', width: 130, sortable: true, showHeaderOverflow: true },
-  ],
+  columns: [],
   data: [
-    { id: 10001, name: 'Test1', role: 'Develop', sex: '0', age: 28, num: 234, address: 'test abc' },
-    { id: 10002, name: 'Test2', role: 'Test', sex: '1', age: 22, num: 34, address: 'Guangzhou' },
-    { id: 10003, name: 'Test3', role: 'PM', sex: '0', age: 32, num: 12, address: 'Shanghai' },
-    { id: 10003, name: 'Test3', role: 'PM', sex: '0', age: 32, num: 12, address: 'Shanghai' },
-    { id: 10003, name: 'Test3', role: 'PM', sex: '0', age: 32, num: 12, address: 'Shanghai' },
-    { id: 10003, name: 'Test3', role: 'PM', sex: '0', age: 32, num: 12, address: 'Shanghai' },
-    { id: 10003, name: 'Test3', role: 'PM', sex: '0', age: 32, num: 12, address: 'Shanghai' },
-    { id: 10003, name: 'Test3', role: 'PM', sex: '0', age: 32, num: 12, address: 'Shanghai' },
-    { id: 10003, name: 'Test3', role: 'PM', sex: '0', age: 32, num: 12, address: 'Shanghai' },
-    { id: 10003, name: 'Test3', role: 'PM', sex: '0', age: 32, num: 12, address: 'Shanghai' },
-    { id: 10003, name: 'Test3', role: 'PM', sex: '0', age: 32, num: 12, address: 'Shanghai' },
-    { id: 10003, name: 'Test3', role: 'PM', sex: '0', age: 32, num: 12, address: 'Shanghai' },
-    { id: 10003, name: 'Test3', role: 'PM', sex: '0', age: 32, num: 12, address: 'Shanghai' },
-    { id: 10003, name: 'TestLast', role: 'PM', sex: '0', age: 32, num: 12, address: 'Shanghai' },
+    // { id: 10001, name: 'Test1', role: 'Develop', sex: '0', age: 28, num: 234, address: 'test abc' },
+    // { id: 10002, name: 'Test2', role: 'Test', sex: '1', age: 22, num: 34, address: 'Guangzhou' },
+    // { id: 10003, name: 'Test3', role: 'PM', sex: '0', age: 32, num: 12, address: 'Shanghai' },
+    // { id: 10003, name: 'Test3', role: 'PM', sex: '0', age: 32, num: 12, address: 'Shanghai' },
+    // { id: 10003, name: 'Test3', role: 'PM', sex: '0', age: 32, num: 12, address: 'Shanghai' },
+    // { id: 10003, name: 'Test3', role: 'PM', sex: '0', age: 32, num: 12, address: 'Shanghai' },
+    // { id: 10003, name: 'Test3', role: 'PM', sex: '0', age: 32, num: 12, address: 'Shanghai' },
+    // { id: 10003, name: 'Test3', role: 'PM', sex: '0', age: 32, num: 12, address: 'Shanghai' },
+    // { id: 10003, name: 'Test3', role: 'PM', sex: '0', age: 32, num: 12, address: 'Shanghai' },
+    // { id: 10003, name: 'Test3', role: 'PM', sex: '0', age: 32, num: 12, address: 'Shanghai' },
+    // { id: 10003, name: 'Test3', role: 'PM', sex: '0', age: 32, num: 12, address: 'Shanghai' },
+    // { id: 10003, name: 'Test3', role: 'PM', sex: '0', age: 32, num: 12, address: 'Shanghai' },
+    // { id: 10003, name: 'Test3', role: 'PM', sex: '0', age: 32, num: 12, address: 'Shanghai' },
+    // { id: 10003, name: 'TestLast', role: 'PM', sex: '0', age: 32, num: 12, address: 'Shanghai' },
   ],
 })
 
@@ -95,7 +72,78 @@ function openDetail(row) {
   })
 }
 
+const activeButton = inject('activeButton')
+
+watch(activeButton, () => {
+  console.log('value', activeButton.value)
+  switch (activeButton.value) {
+    case '产品线':
+      fetchTableDataForProductLine()
+      break
+    case '父ASIN':
+      console.log('case:父ASIN')
+      break
+    case 'ASIN':
+      console.log('case:ASIN')
+      break
+    case 'SKU':
+      fetchTableDataForSKU()
+      break
+
+    default:
+      break
+  }
+})
+
+async function fetchTableDataForProductLine() {
+  tableLoading.value = true
+  const query = {
+    startDate: dateRange.value[0],
+    endDate: dateRange.value[1],
+    profileId: profile.value.profile_id,
+  }
+  gridOptions.columns = productLineColumns
+  try {
+    const response = await getTableDataForProductLine(query)
+    gridOptions.data = response.data
+  } catch (error) {
+    console.log('error:', error)
+  } finally {
+    tableLoading.value = false
+  }
+}
+
+async function fetchTableDataForSKU() {
+  tableLoading.value = true
+  const query = {
+    startDate: dateRange.value[0],
+    endDate: dateRange.value[1],
+    profileId: profile.value.profile_id,
+  }
+  gridOptions.columns = skuColumns
+  try {
+    const response = await getTableDataForSKU(query)
+    gridOptions.data = response.data
+  } catch (error) {
+    console.log('error:', error)
+  } finally {
+    tableLoading.value = false
+  }
+}
+
 const isCompare = ref(false)
+
+onMounted(() => {
+  fetchTableDataForProductLine()
+})
+
+// onUnBeforeMount(() => {
+//   emitter.all.clear()
+// })
+onBeforeUnmount(() => {
+  emitter.all.clear()
+})
+
 </script>
 
 <style scoped></style>

+ 2 - 0
src/views/productCenter/productList/components/DateTendency/index.vue

@@ -239,6 +239,7 @@ const initLine = async () => {
   chartObj.setOption(option)
   loading.value = false
 }
+
 const getDataset = async () => {
   if (statDim.value === 'week') {
     if (props.fetchLineWeek) {
@@ -255,6 +256,7 @@ const getDataset = async () => {
     return resp.data
   }
 }
+
 const getMetricsItems = async () => {
   const resp = await props.fetchCard(queryParams.value)
   const data = resp.data

+ 27 - 4
src/views/productCenter/productList/components/ProductDialog/ProductList.vue

@@ -4,7 +4,7 @@
       <el-tabs v-model="activeName">
         <el-tab-pane label="搜索" name="search">
           <div class="product-search">
-            <vxe-input v-model="searchInp" placeholder="请输入商品名称" type="search" class="search-input" />
+            <vxe-input v-model="searchInp" @search-click="handleSearch" @keydown="handleKeydown" placeholder="请输入商品名称" type="search" class="search-input" />
           </div>
           <div class="padding-0-10">
             <div class="list-bar">
@@ -128,7 +128,6 @@ const activeName = ref('search')
 
 const searchInp = ref('')
 const textarea = ref('')
-function handleSearch() {}
 
 const data = ref([])
 const selectedData = ref([])
@@ -138,6 +137,31 @@ let currentPage = 1
 let total = 0
 let limit = 10
 
+async function handleSearch() {
+  infiniteLoad.value = true
+  const query = {
+    profile_id: profile.value.profile_id,
+    asin: searchInp.value,
+  }
+  try { 
+    const response = await getAllProduct(query)
+    console.log('🚀 ~ response', response.data)
+    data.value = response.data
+  } catch (error) {
+    console.log('error:', error)
+  } finally {
+    checkParentItems()
+    infiniteLoad.value = false
+  }
+}
+
+function handleKeydown(event) {
+  if (event.$event.key === 'Enter') {
+    handleSearch()
+    console.log(111)
+  }
+}
+
 function load() {
   if (currentPage * limit < total) {
     currentPage++
@@ -164,12 +188,11 @@ async function fetchAllProduct() {
       }
       total = res.total
     }
-    checkParentItems()
   } catch (error) {
     console.log('error:', error)
   } finally {
     infiniteLoad.value = false
-    // checkParentItems()
+    checkParentItems()
     activeNames.value = data.value.map((_, index) => String(index))
   }
 }

+ 3 - 3
src/views/productCenter/productList/components/ProductDialog/index.vue

@@ -14,7 +14,7 @@
         <template #label>
           <span class="form-label"> 产品线名称: </span>
         </template>
-        <el-input v-model="ruleForm.productLineName" placeholder="请输入产品线名称" maxlength="150" show-word-limit style="width: 500px;" />
+        <el-input v-model="ruleForm.productLineName" show-word-limit placeholder="请输入产品线名称" maxlength="150" style="width: 500px;" />
       </el-form-item>
       <el-form-item required>
         <template #label>
@@ -24,8 +24,8 @@
       </el-form-item>
       <el-form-item>
         <div style="display: flex; flex-direction: row-reverse">
-          <el-button v-if="!isUpdate" style="margin-left: 10px;" color="#3c59b0;" @click="submitForm(ruleFormRef)"> 创建 </el-button>
-          <el-button v-if="isUpdate" style="margin-left: 10px;" color="#3c59b0;" @click="updateForm(ruleFormRef)"> 确定 </el-button>
+          <el-button v-if="!isUpdate" style="margin-left: 10px;" color="#3c59b0" @click="submitForm(ruleFormRef)"> 创建 </el-button>
+          <el-button v-if="isUpdate" style="margin-left: 10px;" color="#3c59b0" @click="updateForm(ruleFormRef)"> 确定 </el-button>
           <el-button plain @click="createProductDialog = false">取消</el-button>
         </div>
       </el-form-item>

+ 2 - 2
src/views/productCenter/productList/components/ProductSelectCard/index.vue

@@ -10,13 +10,13 @@
           :class="{ selected: selectedCardIndex === index }"
           @click="selectCard(index, item)">
           <div class="pct-chart" :id="`chart${index}-${item.productlineId}`"></div>
-          <el-popover placement="bottom" :width="150" trigger="click">
+          <el-popover v-if="index !== 0" placement="bottom" :width="150" trigger="click">
             <template #reference>
               <el-icon class="custom-icon" @click.stop=""><MoreFilled /></el-icon>
             </template>
             <div class="custom-popoer">
               <el-button :icon="Edit" text size="small" @click="editCard(item)">编辑</el-button>
-              <el-button :icon="Delete" text size="small" style="margin-left: 0">删除</el-button>
+              <el-button :icon="Delete" text size="small" style="margin-left: 0;">删除</el-button>
             </div>
           </el-popover>
           <div class="left-part-container">

+ 6 - 4
src/views/productCenter/productList/components/TopFilters/index.vue

@@ -2,7 +2,7 @@
   <div class="filters">
     <el-input placeholder="ASIN/父ASIN/标题/SKU"></el-input>
     <el-select v-model="selectValue" class="filter-select">
-      <el-option v-for="item in options" :key="item.productlineId" :label="item.productlinename" :value="item.productlineId" />
+      <el-option v-for="item in options" :key="item.productlineId" :label="item.productlineName" :value="item.productlineId" />
     </el-select>
     <DateRangePicker v-model="dateRange"></DateRangePicker>
   </div>
@@ -12,8 +12,8 @@
 import DateRangePicker from '/@/components/DateRangePicker/index.vue'
 import { usePublicData } from '/@/stores/publicData'
 import { storeToRefs } from 'pinia'
-import { getProductLineSelect } from '/@/views/productCenter/productList/api'
-import { inject, onBeforeUnmount, onMounted, ref,watch } from 'vue'
+import { getProductLineSelect, getCardData } from '/@/views/productCenter/productList/api'
+import { inject, onBeforeUnmount, onMounted, ref, watch } from 'vue'
 import emitter from '/@/utils/emitter'
 
 const publicData = usePublicData()
@@ -37,8 +37,10 @@ emitter.on('ProductSelectCard-cardId', (value: any) => {
   selectValue.value = value.productlineId
 })
 
-watch(selectValue, ()=> {
+watch(selectValue, () => {
   emitter.emit('TopFilters-selectValue', { selectValue: selectValue.value })
+  // getCardData({ productlineId: selectValue.value, profileId: profile.value.profile_id, startDate: dateRange.value[0], endDate: dateRange.value[1] })
+  console.log('selectValue.value', selectValue.value)
 })
 
 onMounted(() => {

+ 1 - 2
src/views/productCenter/productList/hooks/useButton.ts

@@ -1,4 +1,4 @@
-import { ref } from 'vue'
+import { ref,watch } from 'vue'
 
 export default function useButtonGroup() {
   const buttons = ['产品线', '父ASIN', 'ASIN', 'SKU'] // 按钮列表
@@ -10,7 +10,6 @@ export default function useButtonGroup() {
 
   function handleClickBtn(buttonName) {
     activeButton.value = buttonName // 更新当前激活的按钮
-    console.log('🚀 ~ activeButton.value', activeButton.value)
   }
 
   // 返回需要在模板中使用的响应式数据和方法

+ 9 - 2
src/views/productCenter/productList/index.vue

@@ -33,7 +33,6 @@
           </el-button>
         </el-button-group>
       </div>
-      
       <DataTable></DataTable>
     </div>
   </div>
@@ -45,7 +44,7 @@ import ProductSelectCard from './components/ProductSelectCard/index.vue'
 import ProductLineDialog from './components/ProductDialog/index.vue'
 import TopFilters from './components/TopFilters/index.vue'
 import DataTable from './components/DataTable/index.vue'
-import { ref, provide } from 'vue'
+import { ref, provide, watch } from 'vue'
 import { storeToRefs } from 'pinia'
 import { usePublicData } from '/@/stores/publicData'
 import DataTendencyChart from './components/DateTendency/index.vue'
@@ -55,6 +54,11 @@ import { productListMetricsEnum } from '../utils/enum'
 import useButtonGroup from './hooks/useButton'
 import emitter from '/@/utils/emitter'
 
+const productlineId = ref('ALL')
+emitter.on('TopFilters-selectValue', (value) => {
+  // console.log('value', value.selectValue)
+  productlineId.value = value.selectValue
+})
 
 // 店铺信息
 const shopInfo = useShopInfo()
@@ -65,6 +69,7 @@ const { dateRange } = storeToRefs(publicData)
 const queryParams = ref({
   profileId: profile.value.profile_id,
   dateRange,
+  productlineId,
 })
 
 provide('dateRange', dateRange)
@@ -72,6 +77,8 @@ provide('profile', profile)
 
 // 按钮组
 const { buttons, activeButton, activeStyle, handleClickBtn } = useButtonGroup()
+provide('activeButton', activeButton)
+
 
 // 控制创建产品线弹窗
 function handleProductlog() {

+ 70 - 0
src/views/productCenter/productList/utils/index.ts

@@ -0,0 +1,70 @@
+export const productLineColumns = [
+  // { field: 'name', title: 'Name', align: 'center', width: 130, slots: { default: 'name_default' } },
+  //   { field: 'sex', title: 'Sex', align: 'center', width: 80, slots: { default: 'sex_default' } },
+    { field: 'productlineName', title: '产品线', align: 'left', fixed: 'left', width: 180, sortable: true },
+    { field: 'sex', title: '总销售额', align: 'right', width: 130, sortable: true },
+    { field: 'age', title: '总订单数', align: 'right', width: 130, sortable: true },
+    { field: 'time', title: '总销量', align: 'right', width: 130, sortable: true },
+    { field: 'address', title: '单均价', align: 'right', width: 130, sortable: true },
+    { field: 'address', title: '广告销售额', align: 'right', width: 130, sortable: true },
+    { field: 'address', title: '本商品广告销售额', align: 'right', width: 180, sortable: true },
+    { field: 'address', title: '广告订单数', align: 'right', width: 130, sortable: true },
+    { field: 'address', title: '本商品广告订单数', align: 'right', width: 180, sortable: true },
+    { field: 'address', title: '广告销量', align: 'right', width: 130, sortable: true },
+    { field: 'address', title: '本商品广告销量', align: 'right', width: 180, sortable: true },
+    { field: 'address', title: '花费', align: 'right', width: 130, sortable: true, showOverflow: true },
+    { field: 'ACOS', title: 'ACOS', align: 'right', width: 130, sortable: true },
+    { field: 'ROAS', title: 'ROAS', align: 'right', width: 130, sortable: true },
+    { field: 'TACOS', title: 'TACOS', align: 'right', width: 130, sortable: true },
+    { field: 'address', title: '转化率', align: 'right', width: 130, sortable: true },
+    { field: 'address', title: '点击率', align: 'right', width: 130, sortable: true },
+    { field: 'address', title: '点击成本', align: 'right', width: 130, sortable: true },
+    { field: 'address', title: '总订单成本', align: 'right', width: 130, sortable: true },
+    { field: 'address', title: '广告订单成本', align: 'right', width: 180, sortable: true },
+    { field: 'address', title: '曝光量', align: 'right', width: 130, sortable: true },
+    { field: 'address', title: '点击量', align: 'right', width: 130, sortable: true },
+    { field: 'address', title: '会话次数', align: 'right', width: 150, sortable: true },
+    { field: 'address', title: '商品会话百分比', align: 'right', width: 150, sortable: true },
+    { field: 'address', title: '页面浏览量', align: 'right', width: 130, sortable: true },
+    { field: 'address', title: '推荐报价(购买按钮)百分比', align: 'right', width: 180, sortable: true, showHeaderOverflow: true },
+    { field: 'address', title: 'FBA库存', align: 'right', width: 130, sortable: true },
+    { field: 'address', title: 'FBM库存', align: 'right', width: 130, sortable: true, showHeaderOverflow: true }
+]
+
+export const skuColumns = [
+  { field: 'sku', title: 'SKU', align: 'left', fixed: 'left', width: 130 },
+  { field: 'name', title: '产品线', align: 'left', width: 180 },
+  { field: 'sex', title: '总销售额', align: 'right', width: 130, sortable: true },
+  { field: 'age', title: '总订单数', align: 'right', width: 130, sortable: true },
+  { field: 'status', title: '商品状态', align: 'right', width: 130 },
+  { field: 'time', title: '总销量', align: 'right', width: 130, sortable: true },
+  { field: 'time', title: '排名', align: 'right', width: 130 },
+  { field: 'time', title: '单均价', align: 'right', width: 130, sortable: true },
+  { field: 'time', title: '父ASIN', align: 'right', width: 130 },
+  { field: 'address', title: '广告销售额', align: 'right', width: 130, sortable: true },
+  { field: 'address', title: '上架时间', align: 'right', width: 130, sortable: true },
+  { field: 'address', title: '本商品广告销售额', align: 'right', width: 180, sortable: true },
+  { field: 'time', title: '异常推广', align: 'right', width: 130 },
+  { field: 'address', title: '广告订单数', align: 'right', width: 130, sortable: true },
+  { field: 'address', title: '本商品广告订单数', align: 'right', width: 180, sortable: true },
+  { field: 'address', title: '广告销量', align: 'right', width: 130, sortable: true },
+  { field: 'address', title: '本商品广告销量', align: 'right', width: 180, sortable: true },
+  { field: 'address', title: '花费', align: 'right', width: 130, sortable: true, showOverflow: true },
+  { field: 'address', title: 'ACOS', align: 'right', width: 130, sortable: true },
+  { field: 'address', title: 'ROAS', align: 'right', width: 130, sortable: true },
+  { field: 'address', title: 'TACOS', align: 'right', width: 130, sortable: true },
+  { field: 'address', title: '转化率', align: 'right', width: 130, sortable: true },
+  { field: 'address', title: '点击率', align: 'right', width: 130, sortable: true },
+  { field: 'address', title: '点击成本', align: 'right', width: 130, sortable: true },
+  { field: 'address', title: '总订单成本', align: 'right', width: 130, sortable: true },
+  { field: 'address', title: '广告订单成本', align: 'right', width: 180, sortable: true },
+  { field: 'address', title: '曝光量', align: 'right', width: 130, sortable: true },
+  { field: 'address', title: '点击量', align: 'right', width: 130, sortable: true },
+  { field: 'address', title: '预警TACOS', align: 'right', width: 130 },
+  { field: 'address', title: '会话次数', align: 'right', width: 150, sortable: true },
+  { field: 'address', title: '商品会话百分比', align: 'right', width: 150, sortable: true },
+  { field: 'address', title: '页面浏览量', align: 'right', width: 130, sortable: true },
+  { field: 'address', title: '推荐报价(购买按钮)百分比', align: 'right', width: 180, sortable: true, showHeaderOverflow: true },
+  { field: 'address', title: 'FBA库存', align: 'right', width: 130, sortable: true },
+  { field: 'address', title: 'FBM库存', align: 'right', width: 130, sortable: true, showHeaderOverflow: true },
+]