Explorar o código

✨ feat: 商品分析: 完善切换商品功能

WanGxC hai 1 ano
pai
achega
0c70b4d7f5

+ 68 - 108
src/views/productCenter/productAnalysis/components/TopParentAsin/ExchangeProduct.vue

@@ -6,11 +6,14 @@
         切换商品
       </span>
     </template>
-    <div class="exchange-popover__title">切换商品</div>
+    <div class="custom-top">
+      <div class="exchange-popover__title">切换商品</div>
+      <el-icon @click="visible = false" style="cursor: pointer"><CloseBold /></el-icon>
+    </div>
     <div class="filter-bar">
       <el-input v-model="searchInp" style="max-width: 600px" placeholder="请输入标题/父ASIN/ASIN/SKU查询商品">
         <template #prepend>
-          <el-select v-model="select" style="width: 80px">
+          <el-select v-model="filterSelect" style="width: 80px">
             <el-option label="模糊" value="vague" />
             <el-option label="精确" value="accurate" />
           </el-select>
@@ -19,16 +22,16 @@
           <el-button :icon="Search" />
         </template>
       </el-input>
-      <el-select v-if="select == 'vague'" v-model="selectValue" class="filter-select">
+      <el-select v-if="filterSelect == 'vague'" v-model="productSelect" class="filter-select">
         <el-option v-for="item in options" :key="item.productlineId" :label="item.productlineName" :value="item.productlineId" />
       </el-select>
-      <el-button @click="visible = false">关闭</el-button>
     </div>
     <div class="asin-selector">
       <div class="asin-selector__part" v-loading="parentloading">
         <div class="part-title">父ASIN</div>
         <ul v-infinite-scroll="load" class="infinite-list" style="overflow: auto">
           <li v-for="(item, index) in allData" :key="index" class="infinite-list-item" @click="selectPaAsin(index)" :class="{ selected: index === selectedIndex }">
+            <el-button color="#3c58af" size="small" class="view-btn" @click.stop="clickParentAsinBtn">查看</el-button>
             <div class="list-content">
               <img :src="item.Image" class="list-item-image" />
               <div>
@@ -81,6 +84,9 @@
                   {{ item.skuNumbers ? item.skuNumbers : '--' }}
                 </div>
               </div>
+              <div>
+                <el-button color="#3c58af" size="small" class="view-btn" @click.stop="clickAsinBtn">查看</el-button>
+              </div>
               <div style="position: relative">
                 <el-icon><ArrowRight /></el-icon>
               </div>
@@ -92,7 +98,7 @@
         <div class="part-title">SKU</div>
         <el-scrollbar height="450px">
           <li v-for="(item, index) in skuData" :key="index" class="sku-list-item" @click="selectSku(index)" :class="{ selected: index === selectedSkuIndex }">
-              <div>{{ item.sku ? item.sku : '--' }}</div>
+            <div>{{ item.sku ? item.sku : '--' }}</div>
           </li>
         </el-scrollbar>
       </div>
@@ -102,136 +108,75 @@
 
 <script setup lang="ts">
 import { Search } from '@element-plus/icons-vue'
-import { inject, onMounted, ref } from 'vue'
-import { getProductLineSelect, getProduct } from '../../api'
+import { inject, onBeforeUnmount, onMounted, ref, watch } from 'vue'
+import { getProductLineSelect } from '../../api'
+import emitter from '/@/utils/emitter'
+import useSelectItem from '../../hooks/useSelectItem'
+import useInfiniteScroll from '../../hooks/useInfiniteScroll'
 
 const profile = <any>inject('profile')
+const { allData, parentloading, currentPage, load, fetchProduct } = useInfiniteScroll()
+const { skuData, asinData, selectedIndex, selectedAsinIndex, selectedSkuIndex, selectPaAsin, selectAsin, selectSku, clickParentAsinBtn, clickAsinBtn } = useSelectItem()
+
 const visible = ref(false)
-const parentloading = ref(false)
 
 const searchInp = ref('')
-const select = ref('vague')
+const filterSelect = ref('vague')
 
-const selectValue = ref('')
+const productSelect = ref('ALL')
 const options = ref([])
 
-const allData = ref([])
-let currentPage = 1
-let total = 0
-let limit = 10
-
-const selectedIndex = ref(-1)
-const selectedParentAsin = ref('')
-const asinData = ref([])
-
-const selectedAsinIndex = ref(-1)
-const selectedAsin = ref('')
-const skuData = ref([])
+emitter.on('useSelectItem-clickParentAsinBtn', () => {
+  visible.value = false
+})
 
-const selectedSkuIndex = ref(-1)
-const selectedSku = ref('')
+emitter.on('useSelectItem-clickAsinBtn', () => {
+  visible.value = false
+})
 
-function load() {
-  if (currentPage * limit < total) {
-    currentPage++
-    fetchProduct()
-  }
-}
+emitter.on('useSelectItem-clickSkuItem', () => {
+  visible.value = false
+})
 
 async function fetchProductLine() {
   try {
     const resp = await getProductLineSelect({ profileId: profile.value.profile_id })
     options.value = resp.data
-    selectValue.value = options.value[0].productlineId
-  } catch (error) {
-    console.log('error:', error)
-  }
-}
-
-async function fetchProduct() {
-  parentloading.value = true
-  const query = {
-    profileId: profile.value.profile_id,
-    productlineId: 'ALL',
-    page: currentPage,
-    limit: limit,
-  }
-  try {
-    const res = await getProduct(query)
-    if (res && res.data) {
-      const newData = res.data
-      if (currentPage > 1) {
-        allData.value.push(...newData)
-      } else {
-        allData.value = newData
-      }
-      total = res.total
-    }
-  } catch (error) {
-    console.log('error:', error)
-  } finally {
-    parentloading.value = false
-  }
-}
-
-function selectPaAsin(index) {
-  selectedIndex.value = index
-  const selectedItem = allData.value[index]
-  selectedParentAsin.value = selectedItem.parentAsin
-  fetchAsin()
-}
-
-async function fetchAsin() {
-  const query = {
-    profileId: profile.value.profile_id,
-    productlineId: 'ALL',
-    parentAsin: selectedParentAsin.value,
-  }
-  try {
-    const res = await getProduct(query)
-    asinData.value = res.data
+    productSelect.value = options.value[0].productlineId
   } catch (error) {
     console.log('error:', error)
   }
 }
 
-function selectAsin(index) {
-  selectedAsinIndex.value = index
-  const selectedItem = asinData.value[index]
-  selectedAsin.value = selectedItem.Asin
-  fetchSku()
-}
-
-async function fetchSku() {
-  const query = {
-    profileId: profile.value.profile_id,
-    productlineId: 'ALL',
-    parentAsin: selectedParentAsin.value,
-    childAsin: selectedAsin.value,
-  }
-  try {
-    const res = await getProduct(query)
-    skuData.value = res.data
-  } catch (error) {
-    console.log('error:', error)
-  }
-}
+// 若产品选择改变则 重置分页并清空其他的数据
+watch(
+  productSelect,
+  (value) => {
+    emitter.emit('ExchangeProduct-productSelect', value)
 
-function selectSku(index) {
-  selectedSkuIndex.value = index
-  const selectedItem = skuData.value[index]
-  selectedSku.value = selectedItem.sku
-  console.log('🚀 ~ selectedSku.value', selectedSku.value)
-  // fetchSku()
-}
+    currentPage.value = 1
+    fetchProduct()
+    asinData.value = []
+    skuData.value = []
+    selectedIndex.value = -1
+  },
+  { immediate: true }
+)
 
 onMounted(() => {
-  fetchProduct()
   fetchProductLine()
 })
+
+onBeforeUnmount(() => {
+  emitter.all.clear()
+})
 </script>
 
 <style scoped>
+.custom-top {
+  display: flex;
+  justify-content: space-between;
+}
 .exchange-btn {
   color: #3359b5;
   font-weight: 700;
@@ -278,6 +223,7 @@ onMounted(() => {
   height: 80px;
   border: 1px solid transparent;
   cursor: pointer;
+  position: relative;
 }
 .infinite-list-item:hover {
   background-color: #ecf5ff;
@@ -317,7 +263,7 @@ onMounted(() => {
 .list-content {
   display: flex;
   align-items: center;
-  border-bottom: 8px;
+  /* margin-bottom: 8px; */
 }
 .li-label {
   color: #6b7785;
@@ -332,5 +278,19 @@ onMounted(() => {
   margin-bottom: 8px;
   border: 1px solid transparent;
   cursor: pointer;
+  border-bottom: 1px solid #e5e6eb;
+}
+.view-btn {
+  position: absolute;
+  right: 5%;
+  top: 34%;
+  display: none; /* 默认隐藏按钮 */
+}
+
+.infinite-list-item:hover .view-btn {
+  display: block; /* 鼠标悬浮时显示按钮 */
+}
+.sku-list-item:hover {
+  background-color: #ecf5ff;
 }
 </style>

+ 62 - 0
src/views/productCenter/productAnalysis/hooks/useInfiniteScroll.ts

@@ -0,0 +1,62 @@
+import { inject, onBeforeUnmount, onMounted, ref, watch } from 'vue'
+import { getProduct } from '../api'
+import emitter from '/@/utils/emitter'
+
+export default function useInfiniteScroll() {
+  const profile = <any>inject('profile')
+  const parentloading = ref(false)
+
+  const productSelect = ref('')
+  emitter.on('ExchangeProduct-productSelect', (value: any) => {
+    productSelect.value = value
+  })
+
+  const allData = ref([])
+  let currentPage = ref(1)
+  let total = 0
+  let limit = 10
+
+  function load() {
+    if (currentPage.value * limit < total) {
+      currentPage.value++
+      fetchProduct()
+    }
+  }
+
+  async function fetchProduct() {
+    parentloading.value = true
+    const query = {
+      profileId: profile.value.profile_id,
+      productlineId: productSelect.value,
+      page: currentPage.value,
+      limit: limit,
+    }
+    try {
+      const res = await getProduct(query)
+      if (res && res.data) {
+        const newData = res.data
+        if (currentPage.value > 1) {
+          allData.value.push(...newData)
+        } else {
+          allData.value = newData
+        }
+        total = res.total
+      }
+    } catch (error) {
+      console.log('error:', error)
+    } finally {
+      parentloading.value = false
+      emitter.emit('ExchangeProduct-allData', allData)
+    }
+  }
+
+  onMounted(() => {
+    fetchProduct()
+  })
+
+  onBeforeUnmount(() => {
+    emitter.all.clear()
+  })
+
+  return { allData, parentloading, currentPage, load, fetchProduct }
+}

+ 94 - 0
src/views/productCenter/productAnalysis/hooks/useSelectItem.ts

@@ -0,0 +1,94 @@
+import { inject, ref, onBeforeUnmount } from 'vue'
+import emitter from '/@/utils/emitter'
+import { getProduct } from '../api'
+
+export default function useSelectItem() {
+  const profile = <any>inject('profile')
+
+  const productSelect = ref('')
+  emitter.on('ExchangeProduct-productSelect', (value: any) => {
+    productSelect.value = value
+  })
+
+  const allData = ref([])
+  emitter.on('ExchangeProduct-allData', (value: any) => {
+    allData.value = value.value
+  })
+
+  const selectedIndex = ref(-1)
+  const selectedParentAsin = ref('')
+  const asinData = ref([])
+
+  const selectedAsinIndex = ref(-1)
+  const selectedAsin = ref('')
+  const skuData = ref([])
+
+  const selectedSkuIndex = ref(-1)
+  const selectedSku = ref('')
+
+  function selectPaAsin(index) {
+    selectedIndex.value = index
+    const selectedItem = allData.value[index]
+    selectedParentAsin.value = selectedItem.parentAsin
+    fetchAsin()
+    selectedAsinIndex.value = -1
+    skuData.value = []
+  }
+
+  async function fetchAsin() {
+    const query = {
+      profileId: profile.value.profile_id,
+      productlineId: productSelect.value,
+      parentAsin: selectedParentAsin.value,
+    }
+    try {
+      const res = await getProduct(query)
+      asinData.value = res.data
+    } catch (error) {
+      console.log('error:', error)
+    }
+  }
+
+  function selectAsin(index) {
+    selectedAsinIndex.value = index
+    const selectedItem = asinData.value[index]
+    selectedAsin.value = selectedItem.Asin
+    fetchSku()
+  }
+
+  async function fetchSku() {
+    const query = {
+      profileId: profile.value.profile_id,
+      productlineId: productSelect.value,
+      parentAsin: selectedParentAsin.value,
+      childAsin: selectedAsin.value,
+    }
+    try {
+      const res = await getProduct(query)
+      skuData.value = res.data
+    } catch (error) {
+      console.log('error:', error)
+    }
+  }
+
+  function selectSku(index) {
+    emitter.emit('useSelectItem-clickSkuItem')
+    selectedSkuIndex.value = index
+    const selectedItem = skuData.value[index]
+    selectedSku.value = selectedItem.sku
+  }
+
+  function clickParentAsinBtn() {
+    emitter.emit('useSelectItem-clickParentAsinBtn')
+  }
+
+  function clickAsinBtn() {
+    emitter.emit('useSelectItem-clickAsinBtn')
+  }
+
+  onBeforeUnmount(() => {
+    emitter.all.clear()
+  })
+
+  return { asinData, skuData, selectedIndex, selectedAsinIndex, selectedSkuIndex, selectPaAsin, selectAsin, selectSku, clickParentAsinBtn, clickAsinBtn }
+}