Ver código fonte

✨ feat: 切换商品弹出窗口选择功能

WanGxC 1 ano atrás
pai
commit
44cdbd9d94

+ 8 - 42
src/views/demo/index.vue

@@ -1,48 +1,14 @@
 <template>
+  <div style="width: 400px;">
+    <InfiniteScroll style="width: auto;"></InfiniteScroll>
+  </div>
 
 </template>
 
-<script lang="ts" setup>
-import { ref, onMounted, reactive } from 'vue'
-import { VXETable } from 'vxe-table'
-
-const gridOptions = reactive({
-  border: true,
-  showFooter: true,
-  columns: [
-    { type: 'seq', width: 60 },
-    { field: 'name', title: 'Name' },
-    { field: 'sex', title: 'Sex' },
-    { field: 'num', title: 'Number', slots: { footer: 'num_footer' } },
-    { field: 'age', title: 'Age' },
-    { field: 'address', title: 'Address' },
-  ],
-  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' },
-  ],
-  footerMethod({ columns, data }) {
-    return [
-      columns.map(column => {
-        if (column.type === 'seq') {
-          return '合计'
-        } else if (['num'].includes(column.field)) {
-          return sumNum(data, column.field)
-        }
-        return '-'
-      })
-    ]
-  },
-})
-
-const sumNum = (list, field) => {
-  let count = 0
-  list.forEach(item => {
-    count += Number(item[field])
-  })
-  return count
-}
+<script setup lang="ts">
+import InfiniteScroll from '/@/views/productCenter/productAnalysis/components/InfiniteScroll/index.vue'
 </script>
 
-<style scoped></style>
+<style scoped>
+
+</style>

+ 138 - 24
src/views/productCenter/productAnalysis/components/TopParentAsin/ExchangeProduct.vue

@@ -28,17 +28,17 @@
       <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 in allData" class="infinite-list-item" @click="selectPaAsin">
+          <li v-for="(item, index) in allData" :key="index" class="infinite-list-item" @click="selectPaAsin(index)" :class="{ selected: index === selectedIndex }">
             <div class="list-content">
-              <img :src="item.Image" class="image-item" />
+              <img :src="item.Image" class="list-item-image" />
               <div>
                 <el-tooltip effect="dark" :content="item.Title" placement="top-start">
                   <span class="list-item-title">{{ item.Title }}</span>
                 </el-tooltip>
                 <div>
-                  <span class="item-font">${{ item.priceMin ? item.priceMin : '--' }}</span>
+                  <span class="list-item-font">${{ item.priceMin ? item.priceMin : '--' }}</span>
                   ~
-                  <span class="item-font">${{ item.priceMax ? item.priceMax : '--' }}</span>
+                  <span class="list-item-font">${{ item.priceMax ? item.priceMax : '--' }}</span>
                 </div>
                 <div>
                   <span class="li-label">父ASIN:</span>
@@ -51,14 +51,51 @@
                   {{ item.skuNumbers ? item.skuNumbers : '--' }}
                 </div>
               </div>
+              <div style="position: relative">
+                <el-icon><ArrowRight /></el-icon>
+              </div>
             </div>
           </li>
         </ul>
       </div>
       <div class="asin-selector__part">
         <div class="part-title">ASIN</div>
+        <el-scrollbar height="450px">
+          <li v-for="(item, index) in asinData" :key="index" class="infinite-list-item" @click="selectAsin(index)" :class="{ selected: index === selectedAsinIndex }">
+            <div class="list-content">
+              <img :src="item.Image" class="asin-list-item-image" />
+              <div>
+                <el-tooltip effect="dark" :content="item.Title" placement="top-start">
+                  <span class="list-item-title">{{ item.Title }}</span>
+                </el-tooltip>
+                <div>
+                  <span class="list-item-font">${{ item.price ? item.price : '--' }}</span>
+                  |
+                  <span>FBA库存:</span>
+                  <span class="list-item-font">{{ item.FBAQuantity ? item.FBAQuantity : '--' }}</span>
+                </div>
+                <div>
+                  <span class="li-label">ASIN:</span>
+                  {{ item.Asin ? item.Asin : '--' }}
+                  <span class="li-label">SKU:</span>
+                  {{ item.skuNumbers ? item.skuNumbers : '--' }}
+                </div>
+              </div>
+              <div style="position: relative">
+                <el-icon><ArrowRight /></el-icon>
+              </div>
+            </div>
+          </li>
+        </el-scrollbar>
+      </div>
+      <div class="asin-selector__part sku">
+        <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>
+          </li>
+        </el-scrollbar>
       </div>
-      <div class="asin-selector__part sku"></div>
     </div>
   </el-popover>
 </template>
@@ -69,7 +106,6 @@ import { inject, onMounted, ref } from 'vue'
 import { getProductLineSelect, getProduct } from '../../api'
 
 const profile = <any>inject('profile')
-
 const visible = ref(false)
 const parentloading = ref(false)
 
@@ -82,14 +118,24 @@ const options = ref([])
 const allData = ref([])
 let currentPage = 1
 let total = 0
-let limit = 40  // 不要修改
+let limit = 10
+
+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 load() {
   if (currentPage * limit < total) {
     currentPage++
     fetchProduct()
   }
-  console.log(12)
 }
 
 async function fetchProductLine() {
@@ -107,7 +153,7 @@ async function fetchProduct() {
   const query = {
     profileId: profile.value.profile_id,
     productlineId: 'ALL',
-    page: 1,
+    page: currentPage,
     limit: limit,
   }
   try {
@@ -127,13 +173,61 @@ async function fetchProduct() {
     parentloading.value = false
   }
 }
-function selectPaAsin() {
-console.log(1233)
+
+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
+  } 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)
+  }
+}
+
+function selectSku(index) {
+  selectedSkuIndex.value = index
+  const selectedItem = skuData.value[index]
+  selectedSku.value = selectedItem.sku
+  console.log('🚀 ~ selectedSku.value', selectedSku.value)
+  // fetchSku()
 }
 
 onMounted(() => {
-  fetchProductLine()
   fetchProduct()
+  fetchProductLine()
 })
 </script>
 
@@ -166,42 +260,51 @@ onMounted(() => {
   width: 40%;
   border: 1px solid #e5e6eb;
 }
-.asin-selector__part .sku {
+.asin-selector__part.sku {
   width: 20%;
 }
 .part-title {
   padding: 8px 4px;
   color: #6b7785;
 }
-.infinite-list-item {
-  display: flex;
-}
 .infinite-list {
-  height: 420px;
+  height: 450px;
   padding: 0;
   margin: 0;
   list-style: none;
 }
-.infinite-list .infinite-list-item + .list-item {
-  margin-top: 10px;
+.infinite-list-item {
+  display: flex;
+  height: 80px;
+  border: 1px solid transparent;
+  cursor: pointer;
+}
+.infinite-list-item:hover {
+  background-color: #ecf5ff;
 }
-.image-item {
+.list-item-image {
   min-width: 70px;
   height: 70px;
   margin: 0 5px;
   border: 1px solid #e5e6eb;
   border-radius: 4px;
 }
+.asin-list-item-image {
+  min-width: 55px;
+  height: 55px;
+  margin: 0 5px;
+  border: 1px solid #e5e6eb;
+  border-radius: 4px;
+}
 .list-item-title {
   color: #6b7785;
   overflow: hidden;
   display: -webkit-box;
   -webkit-box-orient: vertical;
-  -webkit-line-clamp: var(--line-clamp);
+  -webkit-line-clamp: 1;
   white-space: pre-wrap;
-  --line-clamp: 1;
 }
-.item-font {
+.list-item-font {
   font-weight: 700;
   color: #1d2129;
 }
@@ -214,9 +317,20 @@ onMounted(() => {
 .list-content {
   display: flex;
   align-items: center;
-  padding-bottom: 5px;
+  border-bottom: 8px;
 }
 .li-label {
   color: #6b7785;
 }
+.selected {
+  border: 1px solid #409eff;
+  background-color: #ecf5ff;
+}
+.sku-list-item {
+  list-style-type: none;
+  text-align: center;
+  margin-bottom: 8px;
+  border: 1px solid transparent;
+  cursor: pointer;
+}
 </style>