浏览代码

✨ feat: 新增商品列表表格细化, 组件数据模块化

WanGxC 1 年之前
父节点
当前提交
1ea87ac560

+ 8 - 0
src/views/productCenter/productList/api.ts

@@ -35,3 +35,11 @@ export function getLineMonthData(query: UserPageQuery) {
     params: query,
   })
 }
+
+export function getProductLineSelect(query) {
+  return request({
+    url: '/api/sellers/productline/',
+    method: 'GET',
+    params: query,
+  })
+}

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

@@ -1,18 +1,42 @@
 <template>
   <div class="filters">
-      <el-input placeholder="ASIN/父ASIN/标题/SKU"></el-input>
-      <el-select style="width: 300px"></el-select>
-      <DateRangePicker v-model="dateRange"></DateRangePicker>
-    </div>
+    <el-input placeholder="ASIN/父ASIN/标题/SKU"></el-input>
+    <el-select v-model="value" style="width: 300px">
+      <el-option v-for="item in options" :key="item.id" :label="item.productlinename" :value="item.id" />
+    </el-select>
+    <DateRangePicker v-model="dateRange"></DateRangePicker>
+  </div>
 </template>
 
 <script setup lang="ts">
 import DateRangePicker from '/@/components/DateRangePicker/index.vue'
-import { storeToRefs } from 'pinia'
 import { usePublicData } from '/@/stores/publicData'
+import { storeToRefs } from 'pinia'
+import { useShopInfo } from '/@/stores/shopInfo'
+import { getProductLineSelect } from '../api'
+import { onMounted, ref } from 'vue'
 
 const publicData = usePublicData()
 const { dateRange } = storeToRefs(publicData)
+const shopInfo = useShopInfo()
+const { profile } = storeToRefs(shopInfo)
+
+const value = ref('')
+const options = ref([])
+
+async function getSelectData() {
+  const query = { profile_id: profile.value.profile_id }
+  try {
+    const response = await getProductLineSelect(query)
+    options.value = response.data
+  } catch (error) {
+    console.error('error:', error)
+  }
+}
+
+onMounted(()=>{
+  getSelectData()
+})
 </script>
 
 <style scoped>
@@ -21,4 +45,4 @@ const { dateRange } = storeToRefs(publicData)
   justify-content: space-between;
   gap: 10px;
 }
-</style>
+</style>

+ 0 - 241
src/views/productCenter/productList/crud.tsx

@@ -1,241 +0,0 @@
-import * as api from './api'
-import {AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery} from '@fast-crud/fast-crud'
-import {inject} from 'vue'
-import {SbBaseColumn} from '/@/views/adManage/utils/commonTabColumn.js'
-import {parseQueryParams} from '/@/views/adManage/utils/tools.js'
-import XEUtils from 'xe-utils'
-import { useRouter } from 'vue-router'
-
-export const createCrudOptions = function ({crudExpose, context}: CreateCrudOptionsProps): CreateCrudOptionsRet {
-  const pageRequest = async (query: UserPageQuery) => {
-    const params = parseQueryParams(context.value)
-    XEUtils.assign(query, params)
-    return await api.GetList(query)
-  }
-  const editRequest = async ({form, row}: EditReq) => {
-    form.id = row.id
-    return await api.UpdateObj(form)
-  }
-  const delRequest = async ({row}: DelReq) => {
-    return await api.DelObj(row.id)
-  }
-  const addRequest = async ({form}: AddReq) => {
-    return await api.AddObj(form)
-  }
-
-  const router = useRouter()
-
-  //权限判定
-  const hasPermissions = inject('$hasPermissions')
-
-  return {
-    crudOptions: {
-      table: {
-        height: 800,
-        headerCellStyle: {
-          backgroundColor: '#f6f7fa', // 直接设置背景颜色
-          height: '20px',
-          borderRight: 'none'
-        },
-        cellStyle: {
-          border: 'none',
-          borderBottom: '0.5px solid #ddd',
-        },
-        stripe: false,
-        showSummary: true,
-      },
-      container: {
-        fixedHeight: false
-      },
-      // actionbar: {
-      //   show: true,
-      //   color: "#626aef",
-      //   buttons: {
-      //     add: {
-      //       show: false
-      //     },
-      //     create: {
-      //       text: '新建广告活动',
-      //       // type: 'primary',
-      //       color: "#626aef",
-      //       plain: true,
-      //       show: true,
-      //       click() {
-
-      //       }
-      //     },
-      //   }
-      // },
-      actionbar: {
-        show: true,
-        buttons: {
-          add: {
-            show: false,
-          },
-          create: {
-            text: '新建广告活动',
-            type: 'primary',
-            show: true,
-            color: "#626aef",
-            plain: true,
-            click() {
-              router.push({
-                name: 'SbCreateCampaigns',
-                query: { campaignId: 123, tagsViewName: '新建广告活动' },
-              })
-            
-            },
-          },
-        },
-      },
-      search: {
-        show: false
-      },
-      toolbar: {
-        buttons: {
-          search: {
-            show: true
-          },
-          compact: {
-            show: false
-          }
-        }
-      },
-      request: {
-        pageRequest,
-        addRequest,
-        editRequest,
-        delRequest,
-      },
-      rowHandle: {
-        fixed: 'right',
-        width: 100,
-        align: 'center',
-        buttons: {
-          view: {
-            show: false,
-          },
-          edit: {
-            iconRight: 'Edit',
-            type: 'text',
-            text: null
-            // show: hasPermissions('dictionary:Update'),
-          },
-          remove: {
-            show: false
-            // iconRight: 'Delete',
-            // type: 'text',
-            // text: null
-            // show: hasPermissions('dictionary:Delete'),
-          },
-        },
-      },
-      columns: {
-        id: {
-          title: 'ID',
-          column: {
-            show: false
-          },
-          form: {
-            show: false
-          }
-        },
-        campaignName: {
-          title: '广告活动名称',
-          sortable: true,
-          column: {
-            fixed: 'left',
-            width: 180,
-            // showOverflowTooltip: true,
-          },
-        },
-        state: {
-          title: '状态',
-          sortable: true,
-          column: {
-            width: '90px',
-            align: 'center'
-          },
-          type: 'dict-select',
-          search: {
-            show: true
-          },
-          dict: dict({
-            data: [
-              {value: 'PAUSED', label: '已暂停', color: 'warning'},
-              {value: 'ENABLED', label: '投放中', color: 'success'},
-            ]
-          })
-        },
-        bidOptimization: {
-          title: '竞价',
-          form: {
-            show: false,
-          },
-          column: {
-            width: '100px',
-            sortable: true,
-            align: 'center',
-            formatter: (row) => {
-              switch (row.value) {
-                case 1:
-                  return '自动竞价'
-                case 0:
-                  return '自定义竞价'
-                default:
-                  return '-'
-              }
-            }
-          },
-        },
-        startDate: {
-          title: '开始日期',
-          column: {
-            width: '120px',
-            align: 'center',
-            sortable: true,
-          },
-        },
-        endDate: {
-          title: '结束日期',
-          column: {
-            width: '120px',
-            align: 'center',
-            sortable: true,
-            formatter: (row) => {
-              if (row.value !== null) {
-                return row.value
-              } else {
-                return '--'
-              }
-            }
-          },
-        },
-        portfolioName: {
-          title: '广告组合',
-          type: 'text',
-          column: {
-            width: '120px',
-            align: 'center',
-            formatter: (row) => {
-              if (row.value !== null) {
-                return row.value
-              } else {
-                return '--'
-              }
-            }
-          }
-        },
-        dailyBudget: {
-          title: '预算',
-          column: {
-            sortable: true,
-            width: '120px',
-            align: 'right',
-          }
-        },
-        ...SbBaseColumn
-      }
-    }
-  }
-}

+ 21 - 12
src/views/productCenter/productList/index.vue

@@ -36,19 +36,26 @@
           <template #buttons>
             <vxe-button type="text" status="primary" content="创建产品线" icon="vxe-icon-add" @click="visibleDialog"></vxe-button>
           </template>
-          <template #tools>
+          <!-- <template #tools>
             <vxe-button type="text" icon="vxe-icon-undo" class="tool-btn"></vxe-button>
             <vxe-button type="text" icon="vxe-icon-funnel" class="tool-btn" @click="funnelEvent"></vxe-button>
-          </template>
+          </template> -->
         </vxe-toolbar>
       </div>
       <div style="overflow: hidden; width: 100%; height: 600px">
-        <vxe-table ref="tableRef" round height="auto" :data="tableData" :column-config="{ resizable: true }" :row-config="{ isHover: true }">
-          <vxe-column field="name" title="Name" width="300"></vxe-column>
-          <vxe-column field="sex" title="最小列宽" min-width="300"></vxe-column>
-          <vxe-column field="age" title="Age"></vxe-column>
-          <vxe-column field="time" title="Time"></vxe-column>
-          <vxe-column field="address" title="Address" show-overflow></vxe-column>
+        <vxe-table ref="tableRef" round height="auto" show-overflow :data="tableData" :column-config="{ resizable: true }" :row-config="{ isHover: true }">
+          <vxe-column
+            v-for="(column, index) in columns"
+            :key="index"
+            :field="column.field"
+            :title="column.title"
+            :align="column.align"
+            :fixed="column.fixed"
+            :width="column.width"
+            :sortable="column.sortable"
+            :show-overflow="column.showOverflow"
+            :show-header-overflow="column.showHeaderOverflow"
+            :formatter="column.formatter"></vxe-column>
         </vxe-table>
       </div>
       <div>
@@ -56,7 +63,7 @@
       </div>
     </div>
   </div>
-<ProductLineDialog></ProductLineDialog>
+  <ProductLineDialog></ProductLineDialog>
 </template>
 
 <script setup>
@@ -64,14 +71,17 @@ import ProductTab from './components/ProductTab.vue'
 import ProductLineDialog from './components/ProductLineDialog.vue'
 import TopFilters from './components/TopFilters.vue'
 import { ref, reactive, nextTick } from 'vue'
+import { VXETable } from 'vxe-table'
 import { storeToRefs } from 'pinia'
 import { usePublicData } from '/@/stores/publicData'
 import DataTendencyChart from '/@/views/adManage/sb/chartComponents/dataTendency.vue'
 import { useShopInfo } from '/@/stores/shopInfo'
 import { getCardData, getLineData, getLineMonthData, getLineWeekData } from './api'
-import { useButtonGroup } from './hooks/index'
+import { useButtonGroup } from './utils/button'
+import { tableColumns } from './utils/tableColumns'
 import emitter from '/@/utils/emitter'
 
+const columns = tableColumns
 const publicData = usePublicData()
 const { dateRange } = storeToRefs(publicData)
 const shopInfo = useShopInfo()
@@ -123,7 +133,7 @@ const tableData = ref([
 
 // 激活弹窗
 function visibleDialog() {
-  emitter.emit('create-product-dialog', {isVisible: true})
+  emitter.emit('create-product-dialog', { isVisible: true })
 }
 </script>
 
@@ -154,5 +164,4 @@ function visibleDialog() {
   margin-bottom: 12px;
   align-items: center;
 }
-
 </style>

+ 1 - 1
src/views/productCenter/productList/hooks/index.ts → src/views/productCenter/productList/utils/button.ts

@@ -2,7 +2,7 @@ import { ref } from 'vue'
 
 export function useButtonGroup() {
   const buttons = ['产品线', '父ASIN', 'ASIN', 'SKU'] // 按钮列表
-  const activeButton = ref('')
+  const activeButton = ref('产品线')
   const activeStyle = {
     color: '#3a83f7',
     backgroundColor: '#ebeef5',

+ 38 - 0
src/views/productCenter/productList/utils/tableColumns.ts

@@ -0,0 +1,38 @@
+export const tableColumns = [
+  { 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: 150, 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, formatter: formatTalk },
+  { field: 'address', title: '页面浏览量', align: "right", width: 180, sortable: true },
+  { field: 'address', title: '推荐报价(购买按钮)百分比', align: "right", width: 180, sortable: true, showHeaderOverflow: true, formatter: formatPrice },
+  { field: 'address', title: 'FBA库存', align: "right", width: 130, sortable: true },
+  { field: 'address', title: 'FBM库存', align: "right", width: 130, sortable: true, showHeaderOverflow: true },
+]
+
+function formatTalk({ cellValue }) {
+  const item = cellValue + "万"
+  return item
+}
+export function formatPrice({ cellValue }) {
+  // console.log('cellValue', cellValue)
+}