|  | @@ -0,0 +1,222 @@
 | 
	
		
			
				|  |  | +<template>
 | 
	
		
			
				|  |  | +  <el-popover placement="bottom-start" :width="1000" :visible="visible">
 | 
	
		
			
				|  |  | +    <template #reference>
 | 
	
		
			
				|  |  | +      <span class="exchange-btn" @click="visible = true">
 | 
	
		
			
				|  |  | +        <el-icon><Switch /></el-icon>
 | 
	
		
			
				|  |  | +        切换商品
 | 
	
		
			
				|  |  | +      </span>
 | 
	
		
			
				|  |  | +    </template>
 | 
	
		
			
				|  |  | +    <div class="exchange-popover__title">切换商品</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-option label="模糊" value="vague" />
 | 
	
		
			
				|  |  | +            <el-option label="精确" value="accurate" />
 | 
	
		
			
				|  |  | +          </el-select>
 | 
	
		
			
				|  |  | +        </template>
 | 
	
		
			
				|  |  | +        <template #append>
 | 
	
		
			
				|  |  | +          <el-button :icon="Search" />
 | 
	
		
			
				|  |  | +        </template>
 | 
	
		
			
				|  |  | +      </el-input>
 | 
	
		
			
				|  |  | +      <el-select v-if="select == 'vague'" v-model="selectValue" 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 in allData" class="infinite-list-item" @click="selectPaAsin">
 | 
	
		
			
				|  |  | +            <div class="list-content">
 | 
	
		
			
				|  |  | +              <img :src="item.Image" class="image-item" />
 | 
	
		
			
				|  |  | +              <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="item-font">${{ item.priceMax ? item.priceMax : '--' }}</span>
 | 
	
		
			
				|  |  | +                </div>
 | 
	
		
			
				|  |  | +                <div>
 | 
	
		
			
				|  |  | +                  <span class="li-label">父ASIN:</span>
 | 
	
		
			
				|  |  | +                  {{ item.parentAsin ? item.parentAsin : '--' }}
 | 
	
		
			
				|  |  | +                </div>
 | 
	
		
			
				|  |  | +                <div>
 | 
	
		
			
				|  |  | +                  <span class="li-label">ASIN:</span>
 | 
	
		
			
				|  |  | +                  {{ item.asinNumbers ? item.asinNumbers : '--' }}
 | 
	
		
			
				|  |  | +                  <span class="li-label">SKU:</span>
 | 
	
		
			
				|  |  | +                  {{ item.skuNumbers ? item.skuNumbers : '--' }}
 | 
	
		
			
				|  |  | +                </div>
 | 
	
		
			
				|  |  | +              </div>
 | 
	
		
			
				|  |  | +            </div>
 | 
	
		
			
				|  |  | +          </li>
 | 
	
		
			
				|  |  | +        </ul>
 | 
	
		
			
				|  |  | +      </div>
 | 
	
		
			
				|  |  | +      <div class="asin-selector__part">
 | 
	
		
			
				|  |  | +        <div class="part-title">ASIN</div>
 | 
	
		
			
				|  |  | +      </div>
 | 
	
		
			
				|  |  | +      <div class="asin-selector__part sku"></div>
 | 
	
		
			
				|  |  | +    </div>
 | 
	
		
			
				|  |  | +  </el-popover>
 | 
	
		
			
				|  |  | +</template>
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +<script setup lang="ts">
 | 
	
		
			
				|  |  | +import { Search } from '@element-plus/icons-vue'
 | 
	
		
			
				|  |  | +import { inject, onMounted, ref } from 'vue'
 | 
	
		
			
				|  |  | +import { getProductLineSelect, getProduct } from '../../api'
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +const profile = <any>inject('profile')
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +const visible = ref(false)
 | 
	
		
			
				|  |  | +const parentloading = ref(false)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +const searchInp = ref('')
 | 
	
		
			
				|  |  | +const select = ref('vague')
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +const selectValue = ref('')
 | 
	
		
			
				|  |  | +const options = ref([])
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +const allData = ref([])
 | 
	
		
			
				|  |  | +let currentPage = 1
 | 
	
		
			
				|  |  | +let total = 0
 | 
	
		
			
				|  |  | +let limit = 40  // 不要修改
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +function load() {
 | 
	
		
			
				|  |  | +  if (currentPage * limit < total) {
 | 
	
		
			
				|  |  | +    currentPage++
 | 
	
		
			
				|  |  | +    fetchProduct()
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  console.log(12)
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +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: 1,
 | 
	
		
			
				|  |  | +    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() {
 | 
	
		
			
				|  |  | +console.log(1233)
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +onMounted(() => {
 | 
	
		
			
				|  |  | +  fetchProductLine()
 | 
	
		
			
				|  |  | +  fetchProduct()
 | 
	
		
			
				|  |  | +})
 | 
	
		
			
				|  |  | +</script>
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +<style scoped>
 | 
	
		
			
				|  |  | +.exchange-btn {
 | 
	
		
			
				|  |  | +  color: #3359b5;
 | 
	
		
			
				|  |  | +  font-weight: 700;
 | 
	
		
			
				|  |  | +  cursor: pointer;
 | 
	
		
			
				|  |  | +  width: fit-content;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +.exchange-popover__title {
 | 
	
		
			
				|  |  | +  padding-bottom: 12px;
 | 
	
		
			
				|  |  | +  color: #1d2129;
 | 
	
		
			
				|  |  | +  font-size: 16px;
 | 
	
		
			
				|  |  | +  font-weight: 700;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +.filter-bar {
 | 
	
		
			
				|  |  | +  display: flex;
 | 
	
		
			
				|  |  | +  gap: 8px;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +.asin-selector {
 | 
	
		
			
				|  |  | +  display: flex;
 | 
	
		
			
				|  |  | +  align-items: stretch;
 | 
	
		
			
				|  |  | +  padding-top: 12px;
 | 
	
		
			
				|  |  | +  color: #1d2129;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +.asin-selector__part {
 | 
	
		
			
				|  |  | +  position: relative;
 | 
	
		
			
				|  |  | +  flex-grow: 1;
 | 
	
		
			
				|  |  | +  width: 40%;
 | 
	
		
			
				|  |  | +  border: 1px solid #e5e6eb;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +.asin-selector__part .sku {
 | 
	
		
			
				|  |  | +  width: 20%;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +.part-title {
 | 
	
		
			
				|  |  | +  padding: 8px 4px;
 | 
	
		
			
				|  |  | +  color: #6b7785;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +.infinite-list-item {
 | 
	
		
			
				|  |  | +  display: flex;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +.infinite-list {
 | 
	
		
			
				|  |  | +  height: 420px;
 | 
	
		
			
				|  |  | +  padding: 0;
 | 
	
		
			
				|  |  | +  margin: 0;
 | 
	
		
			
				|  |  | +  list-style: none;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +.infinite-list .infinite-list-item + .list-item {
 | 
	
		
			
				|  |  | +  margin-top: 10px;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +.image-item {
 | 
	
		
			
				|  |  | +  min-width: 70px;
 | 
	
		
			
				|  |  | +  height: 70px;
 | 
	
		
			
				|  |  | +  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);
 | 
	
		
			
				|  |  | +  white-space: pre-wrap;
 | 
	
		
			
				|  |  | +  --line-clamp: 1;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +.item-font {
 | 
	
		
			
				|  |  | +  font-weight: 700;
 | 
	
		
			
				|  |  | +  color: #1d2129;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +.item-asin {
 | 
	
		
			
				|  |  | +  color: #6b7785;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +.filter-select {
 | 
	
		
			
				|  |  | +  width: 300px;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +.list-content {
 | 
	
		
			
				|  |  | +  display: flex;
 | 
	
		
			
				|  |  | +  align-items: center;
 | 
	
		
			
				|  |  | +  padding-bottom: 5px;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +.li-label {
 | 
	
		
			
				|  |  | +  color: #6b7785;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +</style>
 |