Files
temu-plugin/src/view/selection/bestsellers/components/Detail.vue
刘仕伟 2e957ac485 更新
2023-12-20 20:45:00 +08:00

431 lines
12 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div>
<ai-list class="list" v-loading="isLoading" :element-loading-text="loadingText">
<ai-title
slot="title"
title="7天畅销品"
isShowBottomBorder>
<template #rightBtn>
<div class="title-right">
<el-checkbox v-model="isMutiSelect">开启多选</el-checkbox>&nbsp;
<el-button type="primary" round @click="toBatchCopy" v-if="isMutiSelect">批量采集</el-button>
<div>
<el-button type="button" :class="'el-button el-button--primary'" v-if="currentData.optId" @click="beginSync">同步</el-button>
</div>
</div>
</template>
</ai-title>
<template #left>
<div class="categoryTree">
<el-tree ref="tree" :data="categoryData" node-key="optId" :props="props"
:default-expanded-keys="defaultExpanded"
:expand-on-click-node="false"
:check-on-click-node="true"
:highlight-current="true"
@node-click="handleNodeClick"/>
</div>
</template>
<template slot="content">
<ai-search-bar>
<template #left>
<label style="width:80px">排序方式</label>
<el-select v-model="search.orderBy" :clearable="true" @change="search.current =1, getList()" placeholder="请选择排序方式" size="small">
<el-option
v-for="item in orderBys"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
<label style="width:80px">价格区间</label>
<el-input :clearable="true" size="small" style="width: 80px" v-model="search.priceBegin" ></el-input>
~
<el-input :clearable="true" size="small" style="width: 80px" v-model="search.priceEnd" ></el-input>
<label style="width:80px">销量区间</label>
<el-input :clearable="true" size="small" style="width: 80px" v-model="search.saleBegin" ></el-input>
~
<el-input :clearable="true" size="small" style="width: 80px" v-model="search.saleEnd" ></el-input>
</template>
<template #right>
<el-button type="primary" @click="search.current =1, getList()">查询</el-button>
</template>
</ai-search-bar>
<div style="display: grid; grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr; gap: 16px;">
<el-card v-for="item in tableData" :key="item.id" :body-style="{ padding: '0px', margin: '5px' }">
<div :class="[{'img-background': item.isSelect}, 'img-box']" @click="onGoodsSelect(item)">
<div>
<el-image v-if="isMutiSelect" :src="item.imgUrl" :class="[{'mask': item.isSelect}, 'image']" />
<el-image v-else :src="item.imgUrl" class="image" :preview-src-list="[item.imgUrl]" />
</div>
<span class="icon-box" v-if="item.isSelect && isMutiSelect">
<img style="width: 20px; height: 20px" src="../../../../assets/right.png">
</span>
</div>
<div style="padding: 14px;">
<div class="bottom clearfix">
<div style="margin-bottom: 5px;">
<div style="display: inline; margin-left: 5px;">${{ item.price }}</div>
<div style="display: inline; margin-right: 5px; float: right;">{{ item.saleTotal }}</div>
</div>
<div style="margin-bottom: 5px;">
<div style="display: inline; margin-left: 5px;">{{ item.createTime.substring(0,10) }}</div>
<ai-product-drop-down :params="item" :isShowGroup="false" :isShowDetail="false" :isShowAddFavorite="false" :isShowDelFavorite="false"
style="float: right;"></ai-product-drop-down>
</div>
</div>
</div>
</el-card>
<el-pagination
layout="prev, pager, next"
style="position: absolute; bottom: 0px; right: 40px;"
:total="total"
:page-size.sync="search.size"
:current-page.sync="search.current"
@current-change="getList">
<div class="paginationPre-total"><label class="color-primary">{{ total }}</label>条记录
</div>
</el-pagination>
</div>
<ai-dialog
title="批量采集"
:visible.sync="copyFromDlgShow"
:close-on-click-modal="false"
width="790px"
customFooter
:append-to-body="true"
@close="copyFromDlgShow = false">
<ai-copy-from-temu v-if="copyFromDlgShow" :isMultiCopy="true" :params="temuParams" @onClose="copyFromDlgShow = false" @onSuccess="copyFromDlgShow = false"></ai-copy-from-temu>
</ai-dialog>
</template>
</ai-list>
</div>
</template>
<script>
import AiProductDropDown from '@/components/AiProductDropDown.vue'
import {sendTemuAPIMessage, sendChromeWebReqMessage} from '@/api/chromeApi'
import { Message } from 'element-ui'
export default {
name: 'DetailPage',
props: ['params'],
components: {AiProductDropDown},
data () {
return {
props: {
label: 'name',
isLeaf: data => data.parentId == 0
},
search: {
current: 1,
size: 120,
orderBy: '',
priceBegin: '',
priceEnd: '',
saleBegin: '',
saleEnd: ''
},
orderBys: [{
value: '0',
label: '按销量从多到少排序'
},{
value: '1',
label: '按销量从少到多排序'
},{
value: '2',
label: '按价格从高到底排序'
},{
value: '3',
label: '按价格从低到高排序'
}],
defaultExpanded: [],
tableData: [],
total: 0,
offset: 0,
pageSize: 120,
currentData: {},
categoryData: [],
isLoading: false,
loadingText: '拼命加载中',
isMutiSelect: false,
copyFromDlgShow: false,
temuParams: {}
}
},
created () {
this.loadCategory()
this.getList()
},
methods: {
loadCategory() {
this.$http.post('/api/category/listByParent_bestSellers',null,{
params: {
parentId: "0"
}
}).then(res => {
if (res?.data) {
let data = res.data.filter(item => {
return item.optId != -13
})
this.categoryData = data.map(item => {
return {
name: item.name + '(' + item.total + ')',
optId: item.optId,
parentId: item.parentId
}
})
}
})
},
beginSync() {
this.loadingText = '拼命加载中'
this.isLoading = true
this.offset = 0
this.getBestSellersData()
},
async getBestSellersData() {
let res = await sendTemuAPIMessage({
url: 'api/poppy/v1/title_bar_recommend?scene=home_title_bar_recommend',
anti: true,
data:
{
scene: "home_title_bar_recommend",
listId: 'best_sellers_list_vvz0h4',
pageSn: '10125',
offset: this.offset,
pageSize: this.pageSize,
filterItems: "1:1|7:7",
optId: this.currentData.optId,
optType: 1
}})
if (res.success && res.result.data.goods_list) {
let arr = []
for (let i = 0;i < res.result.data.goods_list.length; i++) {
let item = res.result.data.goods_list[i]
let total = 0
if (item.sales_tip_text[0]) {
total = item.sales_tip_text[0]
total = total.replace('+', '')
if (total.indexOf('K') != -1) {
total = total.replace('K', '')
total = total * 1000
} else if (total.indexOf('M') != -1) {
total = total.replace('M', '')
total = total * 1000000
}
}
let data = {
goodsId: item.goods_id,
price: item.price_info.price_schema,
saleTotal: item.sales_tip_text[0],
saleTotalNum: total,
url: 'https://www.temu.com/goods.html?goods_id=' + item.goods_id,
imgUrl: item.thumb_url,
category: this.currentData.optId,
mallId: item.mall_id
}
arr.push(data)
}
let res2 = await this.$http.post('/api/bestSellers/addBatch', arr)
this.offset = this.offset + this.pageSize
this.getBestSellersData()
} else {
this.loadCategory()
this.getList()
this.isLoading = false
}
},
getList() {
this.$http.post('/api/bestSellers/page',null,{
params: {
category: this.currentData?.optId || '',
...this.search
}
}).then(res => {
res.data.records.map(item => {
item.isSelect = false
})
this.tableData = res.data.records
this.total = res.data.total
})
},
handleNodeClick(data) {
this.currentData = data
this.search.current = 1
this.getList()
},
onGoodsSelect(item) {
item.isSelect = !item.isSelect
},
toBatchCopy() {
let goodsObj = this.tableData.filter(item => {
return item.isSelect
})
if (goodsObj.length > 0) {
let urlList = goodsObj.map(item => {
return 'https://www.temu.com/goods.html?goods_id=' + item.goodsId
})
this.temuParams = {
urlList: urlList
}
this.copyFromDlgShow = true
} else {
Message.error("请选择商品")
}
}
}
}
</script>
<style scoped lang="scss">
.list {
.title-right {
display: flex;
align-items: center;
& > div:first-child {
margin-right: 20px;
}
}
}
.categoryTree {
.gap {
width: 100%;
height: 17px;
}
:deep( .el-tree ) {
background: #fff;
.el-tree-node__expand-icon.is-leaf {
color: transparent !important;
}
.el-tree-node__content {
display: inline-flex;
min-width: 100%;
}
.el-tree-node__content > .el-tree-node__expand-icon {
padding: 4px;
}
.el-tree-node__content {
height: 32px;
}
.el-tree__empty-text {
color: #222;
font-size: 14px;
}
.el-tree-node__children .el-tree-node__content {
height: 32px;
}
.el-tree-node__content:hover {
background: #E8EFFF;
color: #222222;
border-radius: 2px;
}
.is-current > .el-tree-node__content {
&:hover {
background: #000;
color: #fff;
}
background: #000;
span {
color: #fff;
font-weight: bold;
}
}
}
}
.time {
font-size: 13px;
color: #999;
}
.bottom {
margin-top: 13px;
line-height: 12px;
}
.button {
padding: 0;
float: right;
}
.image {
width: 100%;
display: block;
}
.clearfix:before,
.clearfix:after {
display: table;
content: "";
}
.clearfix:after {
clear: both
}
.el-dropdown-link {
cursor: pointer;
color: #409EFF;
}
.el-icon-arrow-down {
font-size: 12px;
}
.img-box {
display: flex;
justify-content: center;
align-items: center;
//父级设置 相对定位,让 icon设置绝对定位时能够以该父级为准。
position: relative;
// icon 设置 绝对定位 让其固定在你想要的合适位置。 样式可调整,自己定位即可。
.icon-box {
position: absolute;
top: 35%;
}
}
.mask {
background-color: #000;
opacity: 0.6;
.el-image__inner {
opacity: 0.6;
}
}
::v-deep .mask > img {
opacity: 0.6;
}
::v-deep .el-loading-spinner {
top: 200px;
}
.el-icon {
display: inline-block;
}
</style>