|
@@ -1,20 +1,29 @@
|
|
<script setup lang="ts">
|
|
<script setup lang="ts">
|
|
-import { inject, reactive, Ref, ref } from 'vue'
|
|
|
|
-import { getParentAsin } from '../api'
|
|
|
|
|
|
+import { inject, onBeforeUnmount, reactive, Ref, ref } from 'vue'
|
|
|
|
+import { getParentAsin, getSearchedItem } from '../api'
|
|
import { Connection, Picture as IconPicture } from '@element-plus/icons-vue'
|
|
import { Connection, Picture as IconPicture } from '@element-plus/icons-vue'
|
|
import emitter from '/@/utils/emitter'
|
|
import emitter from '/@/utils/emitter'
|
|
|
|
|
|
|
|
|
|
emitter.on('TopFilter', (value: any) => {
|
|
emitter.on('TopFilter', (value: any) => {
|
|
- if (value) {
|
|
|
|
|
|
+ if (value.isVisible?.value) {
|
|
fetchParentAsin()
|
|
fetchParentAsin()
|
|
|
|
+ searchType = value.productFilterSelect.value
|
|
|
|
+ updateGridColumnField()
|
|
} else {
|
|
} else {
|
|
gridOptions.data = []
|
|
gridOptions.data = []
|
|
|
|
+ gridOptionsRight.data = []
|
|
}
|
|
}
|
|
})
|
|
})
|
|
|
|
+
|
|
const profile = <Ref>inject('profile')
|
|
const profile = <Ref>inject('profile')
|
|
const parentLoading = ref(false)
|
|
const parentLoading = ref(false)
|
|
|
|
+const rightLoading = ref(false)
|
|
|
|
+let page = 1
|
|
|
|
+let limit = 15
|
|
|
|
+let searchType = ''
|
|
|
|
|
|
|
|
+// 父ASIN表格配置
|
|
const gridOptions = <any>reactive({
|
|
const gridOptions = <any>reactive({
|
|
height: 500,
|
|
height: 500,
|
|
align: null,
|
|
align: null,
|
|
@@ -25,30 +34,50 @@ const gridOptions = <any>reactive({
|
|
data: [],
|
|
data: [],
|
|
})
|
|
})
|
|
|
|
|
|
|
|
+// 右侧表格配置
|
|
const gridOptionsRight = <any>reactive({
|
|
const gridOptionsRight = <any>reactive({
|
|
height: 500,
|
|
height: 500,
|
|
align: null,
|
|
align: null,
|
|
columns: [
|
|
columns: [
|
|
{ type: 'checkbox', width: 30 },
|
|
{ type: 'checkbox', width: 30 },
|
|
- { field: 'name', title: 'name', width: '300' },
|
|
|
|
- { field: 'role', title: 'role', width: '300' },
|
|
|
|
- { field: 'sex', title: 'sex', width: '300' },
|
|
|
|
- { field: 'age', title: 'age', width: '300' },
|
|
|
|
- { field: 'address', title: 'address', width: '300' },
|
|
|
|
- ],
|
|
|
|
- data: [
|
|
|
|
- { id: 10001, name: 'Test1', nickname: 'T1', role: 'Develop', sex: 'Man', age: 28, address: 'Shenzhen' },
|
|
|
|
- { id: 10002, name: 'Test2', nickname: 'T2', role: 'Test', sex: 'Women', age: 22, address: 'Guangzhou' },
|
|
|
|
- { id: 10003, name: 'Test3', nickname: 'T3', role: 'Test', sex: 'Women', age: 22, address: 'Guangzhou' },
|
|
|
|
|
|
+ { field: 'sku', title: 'SKU', width: '350' },
|
|
|
|
+ { field: 'productLineName', title: '产品线', width: '150' },
|
|
|
|
+ { field: 'ordersIn_14', title: '近14天SP广告订单数', width: '180' },
|
|
|
|
+ { field: 'acosIn_14', title: '近14天SP广告ACOS', width: '180' },
|
|
],
|
|
],
|
|
|
|
+ data: [],
|
|
})
|
|
})
|
|
|
|
|
|
|
|
+// 全选事件
|
|
|
|
+function selectAllChangeEvent(table: any) {
|
|
|
|
+ console.log(table.records)
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// 单选事件
|
|
|
|
+function selectChangeEvent(table: any) {
|
|
|
|
+ // console.log(table.records)
|
|
|
|
+ // 被选中的所有parentAsin组成的数组
|
|
|
|
+ const selectedParentAsins = table.records.map((record: any) => record.parentAsin)
|
|
|
|
+
|
|
|
|
+ // 保留被选中的parentAsin的对应的右侧表格数据
|
|
|
|
+ gridOptionsRight.data = gridOptionsRight.data.filter((item: any) => selectedParentAsins.includes(item.parentAsin))
|
|
|
|
+ // console.log(gridOptionsRight.data)
|
|
|
|
+ // 如果勾选项的parentAsin在gridOptionsRight.data中,则发送请求获取右侧表格数据
|
|
|
|
+ if (table.row && selectedParentAsins.includes(table.row.parentAsin)) {
|
|
|
|
+ fetchSearchedItem([table.row.parentAsin])
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
async function fetchParentAsin() {
|
|
async function fetchParentAsin() {
|
|
parentLoading.value = true
|
|
parentLoading.value = true
|
|
- const body = { profileId: profile.value.profile_id }
|
|
|
|
|
|
+ const body = {
|
|
|
|
+ profileId: profile.value.profile_id,
|
|
|
|
+ page,
|
|
|
|
+ limit,
|
|
|
|
+ }
|
|
try {
|
|
try {
|
|
const response = await getParentAsin(body)
|
|
const response = await getParentAsin(body)
|
|
- gridOptions.data = response.data
|
|
|
|
|
|
+ gridOptions.data.push(...response.data)
|
|
} catch (error) {
|
|
} catch (error) {
|
|
console.log('error:', error)
|
|
console.log('error:', error)
|
|
} finally {
|
|
} finally {
|
|
@@ -56,6 +85,50 @@ async function fetchParentAsin() {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// 获取右侧表格数据
|
|
|
|
+async function fetchSearchedItem(parentAsin: Array<string>) {
|
|
|
|
+ rightLoading.value = true
|
|
|
|
+ const body = {
|
|
|
|
+ profileId: profile.value.profile_id,
|
|
|
|
+ searchType: searchType,
|
|
|
|
+ parentAsin,
|
|
|
|
+ }
|
|
|
|
+ try {
|
|
|
|
+ const response = await getSearchedItem(body)
|
|
|
|
+ gridOptionsRight.data.push(...response.data)
|
|
|
|
+ } catch (error) {
|
|
|
|
+ console.log('error:', error)
|
|
|
|
+ } finally {
|
|
|
|
+ rightLoading.value = false
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+function handleScroll(event: any) {
|
|
|
|
+ const target = event.$event.target
|
|
|
|
+ // 计算是否达到底部:容器高度 + 滚动顶部距离 >= 滚动内容的总高度
|
|
|
|
+ if (target.scrollHeight - (target.scrollTop + target.clientHeight) < 1) {
|
|
|
|
+ page += 1
|
|
|
|
+ fetchParentAsin()
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// 切换搜索类型时,更新右侧表格字段
|
|
|
|
+function updateGridColumnField() {
|
|
|
|
+ // 直接映射现有的columns,只修改需要改变的部分
|
|
|
|
+ gridOptionsRight.columns = gridOptionsRight.columns.map((column: any) => {
|
|
|
|
+ if (column.field === 'sku' || column.field === 'asin') {
|
|
|
|
+ const newField = searchType === 'sku' ? 'sku' : 'asin'
|
|
|
|
+ const newTitle = searchType === 'sku' ? 'SKU' : 'ASIN'
|
|
|
|
+
|
|
|
|
+ // 返回更新后的列配置
|
|
|
|
+ return { ...column, field: newField, title: newTitle, slots: { default: `${ newField }_default` } }
|
|
|
|
+ }
|
|
|
|
+ // 对于不需要更改的列,直接返回原配置
|
|
|
|
+ return column
|
|
|
|
+ })
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// 更改表头样式
|
|
function changeHeaderCellStyle() {
|
|
function changeHeaderCellStyle() {
|
|
return {
|
|
return {
|
|
// backgroundColor: '#eef0f7',
|
|
// backgroundColor: '#eef0f7',
|
|
@@ -63,27 +136,32 @@ function changeHeaderCellStyle() {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-// onMounted(() => {
|
|
|
|
-// fetchParentAsin()
|
|
|
|
-// })
|
|
|
|
|
|
+onBeforeUnmount(() => {
|
|
|
|
+ emitter.all.clear()
|
|
|
|
+})
|
|
</script>
|
|
</script>
|
|
|
|
|
|
<template>
|
|
<template>
|
|
<div class="flex">
|
|
<div class="flex">
|
|
<vxe-grid
|
|
<vxe-grid
|
|
- v-loading="parentLoading"
|
|
|
|
- v-bind="gridOptions"
|
|
|
|
- :header-row-style="changeHeaderCellStyle"
|
|
|
|
- :header-cell-style="changeHeaderCellStyle"
|
|
|
|
- class="ml-2 mb-2 mt-0 border border-r-0 rounded-bl-md rounded-tl-md overflow-hidden"
|
|
|
|
- style="flex: 0 1 260px">
|
|
|
|
|
|
+ v-loading="parentLoading"
|
|
|
|
+ v-bind="gridOptions"
|
|
|
|
+ :header-row-style="changeHeaderCellStyle"
|
|
|
|
+ :header-cell-style="changeHeaderCellStyle"
|
|
|
|
+ @checkbox-all="selectAllChangeEvent"
|
|
|
|
+ @checkbox-change="selectChangeEvent"
|
|
|
|
+ class="ml-2 mb-2 mt-0 border border-r-0 rounded-bl-md rounded-tl-md overflow-hidden"
|
|
|
|
+ style="flex: 0 1 260px; overflow: auto"
|
|
|
|
+ @scroll.native="handleScroll">
|
|
<template #parentAsin_default="{ row }">
|
|
<template #parentAsin_default="{ row }">
|
|
<div style="display: flex">
|
|
<div style="display: flex">
|
|
- <el-image class="w-14 h-14 mr-1 border rounded" v-if="row.Image" :src="row.Image" alt="" fit="contain" />
|
|
|
|
|
|
+ <el-image class="w-14 h-14 mr-1 border rounded" v-if="row.Image" :src="row.Image" alt="" fit="contain"/>
|
|
<el-image v-else class="w-12 h-12 mr-1 border rounded">
|
|
<el-image v-else class="w-12 h-12 mr-1 border rounded">
|
|
<template #error>
|
|
<template #error>
|
|
<div class="image-slot">
|
|
<div class="image-slot">
|
|
- <el-icon><icon-picture /></el-icon>
|
|
|
|
|
|
+ <el-icon>
|
|
|
|
+ <icon-picture/>
|
|
|
|
+ </el-icon>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</template>
|
|
</el-image>
|
|
</el-image>
|
|
@@ -93,12 +171,12 @@ function changeHeaderCellStyle() {
|
|
<div>
|
|
<div>
|
|
ASIN:<span class="text-black">{{ row.asinNum }}</span>
|
|
ASIN:<span class="text-black">{{ row.asinNum }}</span>
|
|
<el-link
|
|
<el-link
|
|
- :href="row.amazonUrl"
|
|
|
|
- target="_blank"
|
|
|
|
- :disabled="!row.amazonUrl"
|
|
|
|
- :underline="false"
|
|
|
|
- :icon="Connection"
|
|
|
|
- :style="{ marginLeft: '2px', marginBottom: '2px', color: row.amazonUrl ? '#3a83f7' : '#c0c4cc' }">
|
|
|
|
|
|
+ :href="row.amazonUrl"
|
|
|
|
+ target="_blank"
|
|
|
|
+ :disabled="!row.amazonUrl"
|
|
|
|
+ :underline="false"
|
|
|
|
+ :icon="Connection"
|
|
|
|
+ :style="{ marginLeft: '2px', marginBottom: '2px', color: row.amazonUrl ? '#3a83f7' : '#c0c4cc' }">
|
|
</el-link>
|
|
</el-link>
|
|
<span class="text-gray-300 mx-1">|</span>
|
|
<span class="text-gray-300 mx-1">|</span>
|
|
SKU:<span class="text-black">{{ row.skuNum }}</span>
|
|
SKU:<span class="text-black">{{ row.skuNum }}</span>
|
|
@@ -107,11 +185,102 @@ function changeHeaderCellStyle() {
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</template>
|
|
</vxe-grid>
|
|
</vxe-grid>
|
|
|
|
+
|
|
<vxe-grid
|
|
<vxe-grid
|
|
- v-bind="gridOptionsRight"
|
|
|
|
- :header-cell-style="changeHeaderCellStyle"
|
|
|
|
- class="mr-2 mb-2 mt-0 border rounded-br-md rounded-tr-md overflow-hidden w-0"
|
|
|
|
- style="flex: 2 1 0">
|
|
|
|
|
|
+ v-loading="rightLoading"
|
|
|
|
+ v-bind="gridOptionsRight"
|
|
|
|
+ :header-cell-style="changeHeaderCellStyle"
|
|
|
|
+ class="mr-2 mb-2 mt-0 border rounded-br-md rounded-tr-md overflow-hidden w-0"
|
|
|
|
+ style="flex: 2 1 0">
|
|
|
|
+ <template v-if="searchType === 'sku'" #sku_default="{ row }">
|
|
|
|
+ <div style="display: flex; align-items: center">
|
|
|
|
+ <el-image class="w-14 h-14 mr-1 border rounded" style="min-width: 56px; min-height: 56px" v-if="row.Image" :src="row.Image" alt=""
|
|
|
|
+ fit="contain"/>
|
|
|
|
+ <el-image v-else class="w-12 h-12 mr-1 border rounded">
|
|
|
|
+ <template #error>
|
|
|
|
+ <div class="image-slot">
|
|
|
|
+ <el-icon>
|
|
|
|
+ <icon-picture/>
|
|
|
|
+ </el-icon>
|
|
|
|
+ </div>
|
|
|
|
+ </template>
|
|
|
|
+ </el-image>
|
|
|
|
+ <!--<div class="flex flex-col justify-center">-->
|
|
|
|
+ <div>
|
|
|
|
+ <el-tooltip
|
|
|
|
+ class="box-item"
|
|
|
|
+ effect="dark"
|
|
|
|
+ :content="row.Title"
|
|
|
|
+ placement="top-start">
|
|
|
|
+ <div class="font-medium text-black display-line">{{ row.Title }}</div>
|
|
|
|
+ </el-tooltip>
|
|
|
|
+
|
|
|
|
+ <div>
|
|
|
|
+ <span class="text-black font-semibold">{{ row.price }}</span>
|
|
|
|
+ <span class="text-gray-300 mx-1">|</span>
|
|
|
|
+ <span>{{ row.quantity }}</span>
|
|
|
|
+ </div>
|
|
|
|
+ <el-tooltip
|
|
|
|
+ offset="0"
|
|
|
|
+ :show-arrow="false"
|
|
|
|
+ effect="dark"
|
|
|
|
+ :content="row.sku"
|
|
|
|
+ placement="top-end">
|
|
|
|
+ <div class="display-line">
|
|
|
|
+
|
|
|
|
+ ASIN:<span class="text-black">{{ row.asin }}</span>
|
|
|
|
+ <el-link
|
|
|
|
+ :href="row.amazonUrl"
|
|
|
|
+ target="_blank"
|
|
|
|
+ :disabled="!row.amazonUrl"
|
|
|
|
+ :underline="false"
|
|
|
|
+ :icon="Connection"
|
|
|
|
+ :style="{ marginLeft: '2px', marginBottom: '2px', color: row.amazonUrl ? '#3a83f7' : '#c0c4cc' }">
|
|
|
|
+ </el-link>
|
|
|
|
+ <span class="text-gray-300 mx-1">|</span>
|
|
|
|
+
|
|
|
|
+ SKU:<span class="text-black">{{ row.sku }}</span>
|
|
|
|
+ </div>
|
|
|
|
+ </el-tooltip>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </template>
|
|
|
|
+
|
|
|
|
+ <template v-if="searchType === 'asin'" #asin_default="{ row }">
|
|
|
|
+ <div style="display: flex">
|
|
|
|
+ <el-image class="w-14 h-14 mr-1 border rounded" v-if="row.Image" :src="row.Image" alt="" fit="contain"/>
|
|
|
|
+ <el-image v-else class="w-12 h-12 mr-1 border rounded">
|
|
|
|
+ <template #error>
|
|
|
|
+ <div class="image-slot">
|
|
|
|
+ <el-icon>
|
|
|
|
+ <icon-picture/>
|
|
|
|
+ </el-icon>
|
|
|
|
+ </div>
|
|
|
|
+ </template>
|
|
|
|
+ </el-image>
|
|
|
|
+ <div class="flex flex-col justify-center">
|
|
|
|
+ <div class="font-medium text-black">{{ row.Title }}</div>
|
|
|
|
+ <div>
|
|
|
|
+ <span>{{ row.price }}</span>
|
|
|
|
+ <span>|</span>
|
|
|
|
+ <span>{{ row.quantity }}</span>
|
|
|
|
+ </div>
|
|
|
|
+ <div>
|
|
|
|
+ ASIN:<span class="text-black">{{ row.asin }}</span>
|
|
|
|
+ <el-link
|
|
|
|
+ :href="row.amazonUrl"
|
|
|
|
+ target="_blank"
|
|
|
|
+ :disabled="!row.amazonUrl"
|
|
|
|
+ :underline="false"
|
|
|
|
+ :icon="Connection"
|
|
|
|
+ :style="{ marginLeft: '2px', marginBottom: '2px', color: row.amazonUrl ? '#3a83f7' : '#c0c4cc' }">
|
|
|
|
+ </el-link>
|
|
|
|
+ <span class="text-gray-300 mx-1">|</span>
|
|
|
|
+ SKU:<span class="text-black">{{ row.sku }}</span>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </template>
|
|
</vxe-grid>
|
|
</vxe-grid>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</template>
|
|
@@ -121,6 +290,7 @@ function changeHeaderCellStyle() {
|
|
:deep(.vxe-table--render-default .vxe-table--border-line) {
|
|
:deep(.vxe-table--render-default .vxe-table--border-line) {
|
|
border: none;
|
|
border: none;
|
|
}
|
|
}
|
|
|
|
+
|
|
.image-slot {
|
|
.image-slot {
|
|
display: flex;
|
|
display: flex;
|
|
justify-content: center;
|
|
justify-content: center;
|
|
@@ -131,11 +301,22 @@ function changeHeaderCellStyle() {
|
|
color: var(--el-text-color-secondary);
|
|
color: var(--el-text-color-secondary);
|
|
font-size: 30px;
|
|
font-size: 30px;
|
|
}
|
|
}
|
|
-.image-slot .el-icon {
|
|
|
|
|
|
+
|
|
|
|
+.image-slot el-icon {
|
|
font-size: 30px;
|
|
font-size: 30px;
|
|
}
|
|
}
|
|
|
|
+
|
|
/* 修改表头填充颜色 默认会有空隙 */
|
|
/* 修改表头填充颜色 默认会有空隙 */
|
|
:deep(.vxe-table--header-wrapper.body--wrapper) {
|
|
:deep(.vxe-table--header-wrapper.body--wrapper) {
|
|
background-color: #eef0f7;
|
|
background-color: #eef0f7;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+.display-line {
|
|
|
|
+ overflow: hidden;
|
|
|
|
+ display: -webkit-box;
|
|
|
|
+ -webkit-box-orient: vertical;
|
|
|
|
+ -webkit-line-clamp: var(--line-clamp);
|
|
|
|
+ /* white-space: pre-wrap; */
|
|
|
|
+ --line-clamp: 1;
|
|
|
|
+}
|
|
</style>
|
|
</style>
|