调整
This commit is contained in:
81
src/components/AiSingleProductDetail.vue
Normal file
81
src/components/AiSingleProductDetail.vue
Normal file
@@ -0,0 +1,81 @@
|
||||
<template>
|
||||
<ai-detail class="audit">
|
||||
<template slot="content">
|
||||
<ai-card title="基本信息">
|
||||
<ai-product-drop-down v-if="info" :params="info" slot="right"></ai-product-drop-down>
|
||||
<template #content>
|
||||
<div class="flex">
|
||||
<ai-avatar v-model="info.imgUrl" :editable="false" :preview="true"/>
|
||||
<ai-wrapper
|
||||
label-width="120px" class="fill">
|
||||
<ai-info-item label="价格:" :value="'$' + info.price"></ai-info-item>
|
||||
<ai-info-item label="销量:" :value="info.saleTotal"></ai-info-item>
|
||||
</ai-wrapper>
|
||||
</div>
|
||||
</template>
|
||||
</ai-card>
|
||||
<ai-card title="趋势信息">
|
||||
<template #content>
|
||||
<div id="dataChart"></div>
|
||||
</template>
|
||||
</ai-card>
|
||||
</template>
|
||||
</ai-detail>
|
||||
</template>
|
||||
<script>
|
||||
import AiProductDropDown from './AiProductDropDown.vue'
|
||||
import { DualAxes } from '@antv/g2plot'
|
||||
|
||||
export default {
|
||||
name: "AiSingleProductDetail",
|
||||
props: ['params', 'url'],
|
||||
components: {
|
||||
AiProductDropDown
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
info: {}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
},
|
||||
mounted() {
|
||||
// this.info = this.params
|
||||
this.$nextTick(() => {
|
||||
this.init()
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
init() {
|
||||
this.$http.post(this.url ? this.url: '/api/singleGoodsDetail/queryDetail',null,{
|
||||
params: {
|
||||
goodsId: this.params.goodsId,
|
||||
groupId: this.params.groupId
|
||||
}
|
||||
}).then(res => {
|
||||
this.info = res.data
|
||||
|
||||
const dualAxes = new DualAxes('dataChart', {
|
||||
data: [this.info.priceAndSale, this.info.priceAndSale],
|
||||
xField: '日期',
|
||||
yField: ['价格', '销量'],
|
||||
geometryOptions: [
|
||||
{
|
||||
geometry: 'line',
|
||||
color: '#5B8FF9',
|
||||
},
|
||||
{
|
||||
geometry: 'line',
|
||||
color: '#5AD8A6',
|
||||
}
|
||||
],
|
||||
});
|
||||
|
||||
dualAxes.render();
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
@@ -2,7 +2,7 @@
|
||||
"manifest_version": 3,
|
||||
"name": "TEMU助手",
|
||||
"description": "TEMU助手 - 自动化提高生产效率",
|
||||
"version": "3.1.6",
|
||||
"version": "3.1.7",
|
||||
"background": {
|
||||
"service_worker": "/background.js"
|
||||
},
|
||||
|
||||
@@ -138,7 +138,12 @@ const router = new VueRouter({
|
||||
{
|
||||
path: 'saleData',
|
||||
name: 'saleData',
|
||||
component: () => import('../view/ExportSaleData.vue')
|
||||
component: () => import('../view/sale/ExportSaleData.vue')
|
||||
},
|
||||
{
|
||||
path: 'saleOut',
|
||||
name: 'saleOut',
|
||||
component: () => import('../view/sale/ExportSaleOutData.vue')
|
||||
},
|
||||
|
||||
// {
|
||||
|
||||
@@ -98,7 +98,7 @@
|
||||
<el-menu-item index="/newProduct">上架新品</el-menu-item>
|
||||
<el-menu-item index="/newProductGroup">我的分组</el-menu-item>
|
||||
</el-submenu>
|
||||
<!-- <el-menu-item index="/singleTrack">单品跟踪</el-menu-item> -->
|
||||
<el-menu-item index="/singleTrack">单品跟踪</el-menu-item>
|
||||
<el-menu-item index="/bestSellers">7天畅销品</el-menu-item>
|
||||
<el-menu-item index="/indexTrack">首页商品跟踪</el-menu-item>
|
||||
</el-submenu>
|
||||
@@ -115,10 +115,14 @@
|
||||
</template>
|
||||
</el-menu-item>
|
||||
</el-submenu>
|
||||
<el-menu-item index="/saleData">
|
||||
<i class="el-icon-s-data"></i>
|
||||
<span slot="title">销售数据</span>
|
||||
</el-menu-item>
|
||||
<el-submenu index="/saleManager">
|
||||
<template slot="title">
|
||||
<i class="el-icon-s-data"></i>
|
||||
<span slot="title">销售管理</span>
|
||||
</template>
|
||||
<el-menu-item index="/saleData">销售管理</el-menu-item>
|
||||
<el-menu-item index="/saleOut">售罄看板</el-menu-item>
|
||||
</el-submenu>
|
||||
<el-menu-item index="/learning">
|
||||
<i class="el-icon-eleme"></i>
|
||||
<span slot="title">新手园地</span>
|
||||
|
||||
@@ -851,7 +851,7 @@ import { Message } from 'element-ui'
|
||||
return
|
||||
}
|
||||
let beginDateStr = formatDate(this.skuDownloadForm.date[0])
|
||||
let endDateStyr = formatDate(this.skuDownloadForm.date[1])
|
||||
let endDateStr = formatDate(this.skuDownloadForm.date[1])
|
||||
|
||||
let temp = {}
|
||||
temp = {
|
||||
@@ -872,9 +872,9 @@ import { Message } from 'element-ui'
|
||||
let tempSkuList = this.list.filter(item => {
|
||||
return item.onSalesDurationOffline != '-天'
|
||||
})
|
||||
this.tempSkuIds = []
|
||||
let tempSkuIds = []
|
||||
tempSkuList.map(i => {
|
||||
this.tempSkuIds.push(i.productSkuId)
|
||||
tempSkuIds.push(i.productSkuId)
|
||||
})
|
||||
|
||||
this.skuSaleNumberList = []
|
||||
@@ -898,34 +898,43 @@ import { Message } from 'element-ui'
|
||||
this.skuSaleNumberList.push(temp)
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
let res = await sendChromeAPIMessage({
|
||||
url: 'oms/bg/venom/api/supplier/sales/management/querySkuSalesNumber',
|
||||
needMallId: true,
|
||||
mallId: this.mallId,
|
||||
data: {
|
||||
"productSkuIds": this.tempSkuIds,
|
||||
"startDate": beginDateStr,
|
||||
"endDate": endDateStyr
|
||||
}})
|
||||
let reqSkusIds = [], pageSize = 200
|
||||
for (let i = 0; i < tempSkuIds.length; i++) {
|
||||
reqSkusIds.push(tempSkuIds[i])
|
||||
if (reqSkusIds.length % pageSize == 0 || ((i+1) == tempSkuIds.length)) {
|
||||
let res = await sendChromeAPIMessage({
|
||||
url: 'oms/bg/venom/api/supplier/sales/management/querySkuSalesNumber',
|
||||
needMallId: true,
|
||||
mallId: this.mallId,
|
||||
data: {
|
||||
"productSkuIds": reqSkusIds,
|
||||
"startDate": beginDateStr,
|
||||
"endDate": endDateStr
|
||||
}})
|
||||
|
||||
if (res.success) {
|
||||
res.result.map(item => {
|
||||
for (let i = 0; i < this.skuSaleNumberList.length; i++) {
|
||||
if (this.skuSaleNumberList[i].sku == item.prodSkuId) {
|
||||
this.skuSaleNumberList[i][item.date] = item.salesNumber
|
||||
break
|
||||
if (res.success) {
|
||||
res.result.map(item => {
|
||||
for (let i = 0; i < this.skuSaleNumberList.length; i++) {
|
||||
if (this.skuSaleNumberList[i].sku == item.prodSkuId) {
|
||||
this.skuSaleNumberList[i][item.date] = item.salesNumber
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
document.getElementById('downloadSkuSaleNumber').click()
|
||||
} else {
|
||||
Message.error("获取SKU历史销量数据失败")
|
||||
})
|
||||
} else {
|
||||
this.isLoading = false
|
||||
Message.error("获取SKU历史销量数据失败")
|
||||
break
|
||||
}
|
||||
|
||||
if ((i+1) == tempSkuIds.length) {
|
||||
document.getElementById('downloadSkuSaleNumber').click()
|
||||
this.isLoading = false
|
||||
}
|
||||
reqSkusIds = []
|
||||
}
|
||||
|
||||
this.isLoading = false
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
223
src/view/sale/ExportSaleOutData.vue
Normal file
223
src/view/sale/ExportSaleOutData.vue
Normal file
@@ -0,0 +1,223 @@
|
||||
<template>
|
||||
<ai-list class="list" v-loading="isLoading" element-loading-text="拼命加载中" element-loading-spinner="el-icon-loading">
|
||||
<ai-title
|
||||
slot="title"
|
||||
title="售罄看板"
|
||||
isShowBottomBorder>
|
||||
<template #rightBtn>
|
||||
<div class="title-right">
|
||||
<div>
|
||||
<label style="width:90px">店铺:</label>
|
||||
<el-select v-model="mallId" @change="beforeGetList" placeholder="请选择" size="small">
|
||||
<el-option
|
||||
v-for="item in $store.state.mallList"
|
||||
:key="item.mallId"
|
||||
:label="item.mallName"
|
||||
:value="item.mallId">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</ai-title>
|
||||
<template slot="content">
|
||||
<ai-search-bar>
|
||||
<template #left>
|
||||
<el-radio-group v-model="type" @change="onChange">
|
||||
<el-radio-button label="0">即将售罄</el-radio-button>
|
||||
<el-radio-button label="1">已售罄</el-radio-button>
|
||||
</el-radio-group>
|
||||
</template>
|
||||
<template #right>
|
||||
</template>
|
||||
</ai-search-bar>
|
||||
<ai-card title="数据明细" style="padding-bottom: 40px;">
|
||||
<template #right>
|
||||
<json-excel
|
||||
:data="tableData"
|
||||
:fields="jsonFields"
|
||||
:before-generate = "startDownload"
|
||||
name="即将售罄明细.xls"
|
||||
worksheet="即将售罄明细">
|
||||
<el-button type="primary" :disabled="!mallId || (tableData.length == 0)">导出数据</el-button>
|
||||
</json-excel>
|
||||
</template>
|
||||
<ai-table
|
||||
:isShowPagination="false"
|
||||
:tableData="tableData"
|
||||
:col-configs="colConfigs"
|
||||
:total="tableData.length"
|
||||
height="500"
|
||||
style="margin-top: 8px;"
|
||||
@getList="() => {}">
|
||||
</ai-table>
|
||||
</ai-card>
|
||||
</template>
|
||||
</ai-list>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {sendChromeAPIMessage} from '@/api/chromeApi'
|
||||
import JsonExcel from 'vue-json-excel'
|
||||
import { Message } from 'element-ui'
|
||||
|
||||
export default {
|
||||
name: 'ExportSaleOutData',
|
||||
|
||||
data () {
|
||||
return {
|
||||
type: '0',
|
||||
isLoading: false,
|
||||
tableData: [],
|
||||
mallId: '',
|
||||
colConfigs: [
|
||||
{ prop: 'productName', label: '商品名称', align: 'left' },
|
||||
{ prop: 'catName', label: '类目', align: 'left' },
|
||||
{ prop: 'productSkcId', label: 'SKC ID', align: 'left' },
|
||||
{ prop: 'skcExtCode', label: 'SKC货号', align: 'left' },
|
||||
{ prop: 'productSkuId', label: 'SKU ID', align: 'left' },
|
||||
{ prop: 'skuExtCode', label: 'SKU货号', align: 'left' },
|
||||
{ prop: 'className', label: 'SKU属性', align: 'left' },
|
||||
{ prop: 'prodSkuPayQtyTotal7d', label: '近7天SKU销量', align: 'left' },
|
||||
{ prop: 'prodSkcPayQtyTotal7d', label: '近7天SKC销量', align: 'left' },
|
||||
{ prop: 'totalStock', label: '仓内可用库存', align: 'left' },
|
||||
{ prop: 'stockNotAvailable', label: '仓内暂不可用库存', align: 'left' },
|
||||
{ prop: 'totalWaitReceiveNum', label: '已发货库存', align: 'left' },
|
||||
{ prop: 'stockAvailable', label: '合计库存', align: 'left' },
|
||||
{ prop: 'stockAvlbDays', label: '库存可售天数', align: 'left' },
|
||||
{ prop: 'p7dSellOutSimuAmount', label: '近7天销售损失(CNY)', align: 'left' },
|
||||
{ prop: 'p7dSellOutSimuAmountRatio', label: '近7天销售损失占比', align: 'left' },
|
||||
{ prop: 'prodSkuPayQtyTotal7d2', label: '近7天sku已支付销量', align: 'left' },
|
||||
{ prop: 'waitDeliverOrderSnList', label: '待发货备货单ID', align: 'left' }
|
||||
],
|
||||
jsonFields: {
|
||||
"商品名称": "productName",
|
||||
"类目": "catName",
|
||||
"SKC ID": "productSkcId",
|
||||
"SKC货号": "skcExtCode",
|
||||
"SKU ID": "productSkuId",
|
||||
"SKU货号": "skuExtCode",
|
||||
"SKU属性": "className",
|
||||
"近7天SKU销量": "prodSkuPayQtyTotal7d",
|
||||
"近7天SKC销量": "prodSkcPayQtyTotal7d",
|
||||
"仓内可用库存": "totalStock",
|
||||
"仓内暂不可用库存": "stockNotAvailable",
|
||||
"已发货库存": "totalWaitReceiveNum",
|
||||
"合计库存": "stockAvailable",
|
||||
"库存可售天数": "stockAvlbDays",
|
||||
"近7天销售损失(CNY)": "p7dSellOutSimuAmount",
|
||||
"近7天销售损失占比": "p7dSellOutSimuAmountRatio",
|
||||
"近7天sku已支付销量": "prodSkuPayQtyTotal7d2",
|
||||
"待发货备货单ID": "waitDeliverOrderSnList"
|
||||
},
|
||||
|
||||
currentPage: 1
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
},
|
||||
|
||||
components: {
|
||||
JsonExcel
|
||||
},
|
||||
|
||||
created () {
|
||||
},
|
||||
|
||||
methods: {
|
||||
onChange (e) {
|
||||
this.tableData = []
|
||||
this.currentPage = 1
|
||||
if (e === '0') {
|
||||
this.getList(1)
|
||||
} else {
|
||||
this.getList(2)
|
||||
}
|
||||
},
|
||||
beforeGetList() {
|
||||
if (!this.mallId) {
|
||||
Message.error("请先选择店铺")
|
||||
return
|
||||
}
|
||||
this.currentPage = 1
|
||||
this.tableData = []
|
||||
this.$userCheck(this.mallId).then(() => {
|
||||
this.isLoading = true
|
||||
if (this.type == '0') {
|
||||
this.getList(1)
|
||||
} else {
|
||||
this.getList(2)
|
||||
}
|
||||
}).catch((err) => {
|
||||
this.isLoading = false
|
||||
})
|
||||
},
|
||||
getList (detailType) {
|
||||
sendChromeAPIMessage({
|
||||
url: 'marvel-mms/cn/api/kiana/venom/sold/out/querySoldOutDetail',
|
||||
needMallId: true,
|
||||
mallId: this.mallId,
|
||||
anti: true,
|
||||
data: {
|
||||
"pageNo": this.currentPage,
|
||||
"pageSize": 200,
|
||||
"detailType": detailType
|
||||
}}).then((res) => {
|
||||
if (res.errorCode == 1000000) {
|
||||
res.result.soldOutDetailList.map(item => {
|
||||
this.tableData.push({...item,
|
||||
p7dSellOutSimuAmount: item.p7dSellOutSimuAmount/100,
|
||||
p7dSellOutSimuAmountRatio: (item.p7dSellOutSimuAmountRatio * 100).toFixed(2) + '%',
|
||||
waitDeliverOrderSnList: item.waitDeliverOrderSnList.join(',')})
|
||||
})
|
||||
if (200 == res.result.soldOutDetailList.length) {
|
||||
this.currentPage ++
|
||||
setTimeout(() => {
|
||||
this.getList(detailType)
|
||||
}, 1000)
|
||||
} else {
|
||||
this.isLoading = false
|
||||
}
|
||||
} else {
|
||||
setTimeout(() => {
|
||||
this.getList(detailType)
|
||||
}, 1000)
|
||||
}
|
||||
})
|
||||
},
|
||||
startDownload() {
|
||||
this.$http.post('/api/malluser/info').then(res => {
|
||||
if (res.code == 0) {
|
||||
this.$store.commit('setUserInfo', res.data)
|
||||
if (res.data.flag != 1) {
|
||||
Message.error('您的账号未激活或已失效,请激活后使用')
|
||||
this.$store.commit('setActiveDlgShow', true)
|
||||
return;
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.list {
|
||||
.title-right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
& > div:first-child {
|
||||
margin-right: 20px;
|
||||
}
|
||||
}
|
||||
::v-deep.ai-list {
|
||||
.ai-list__content--right-wrapper {
|
||||
background: transparent;
|
||||
box-shadow: none;
|
||||
padding: 0!important;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -11,7 +11,6 @@
|
||||
<script>
|
||||
import List from './components/List.vue'
|
||||
import Detail from './components/Detail.vue'
|
||||
import SheinDetail from './components/SheinDetail.vue'
|
||||
|
||||
export default {
|
||||
name: 'SingleTrack',
|
||||
@@ -19,8 +18,7 @@
|
||||
|
||||
components: {
|
||||
List,
|
||||
Detail,
|
||||
SheinDetail
|
||||
Detail
|
||||
},
|
||||
|
||||
data () {
|
||||
@@ -37,11 +35,6 @@
|
||||
this.params = data.params
|
||||
}
|
||||
|
||||
if (data.type === 'SheinDetail') {
|
||||
this.component = 'SheinDetail'
|
||||
this.params = data.params
|
||||
}
|
||||
|
||||
if (data.type === 'List') {
|
||||
this.component = 'List'
|
||||
this.params = data.params
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<ai-list class="list">
|
||||
<ai-title
|
||||
slot="title"
|
||||
:title="'店铺ID(' + `${content}` + ')商品列表'"
|
||||
:title="'分组(' + `${content}` + ')商品列表'"
|
||||
isShowBottomBorder isShowBack @onBackClick="cancel(false)">
|
||||
</ai-title>
|
||||
<template slot="content">
|
||||
@@ -26,10 +26,6 @@
|
||||
<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>
|
||||
<label style="width:100px">仅显示最新:</label>
|
||||
<ai-select :selectList="$dict.getDict('mall_yesno')" v-model="search.isNew"></ai-select>
|
||||
<label style="width:100px">仅显示下架:</label>
|
||||
<ai-select :selectList="$dict.getDict('mall_yesno')" v-model="search.isOff"></ai-select>
|
||||
</template>
|
||||
<template #right>
|
||||
<el-button type="primary" @click="search.current =1, getList()">查询</el-button>
|
||||
@@ -37,16 +33,7 @@
|
||||
</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']" v-if="item.isOff == '1'">
|
||||
<div>
|
||||
<el-image :src="item.imgUrl" class="mask image" :preview-src-list="[item.imgUrl]" />
|
||||
</div>
|
||||
<span class="icon-box">
|
||||
<img style="width: 50px; height: 50px" src="../../../../assets/off.png">
|
||||
</span>
|
||||
</div>
|
||||
<span class="nav-label labelBadge" v-else>
|
||||
<span class="ii" v-if="item.isNew == 1">新</span>
|
||||
<span class="nav-label labelBadge">
|
||||
<el-image :src="item.imgUrl" class="image" :preview-src-list="[item.imgUrl]" />
|
||||
</span>
|
||||
<div style="padding: 14px;">
|
||||
@@ -56,11 +43,8 @@
|
||||
<div style="display: inline; margin-right: 5px; float: right;">{{ item.saleTotal }}<sub style="margin-left: 2px;" v-html="getSalePercent(item.saleChange)"></sub></div>
|
||||
</div>
|
||||
<div>
|
||||
<div v-if="search.orderBy == '5'" style="display: inline">近3次日均销量: <span style="color: red; font-weight: bold">{{ item.days3AverageSale }}</span></div>
|
||||
<div v-else-if="search.orderBy == '6'" style="display: inline">近7次日均销量: <span style="color: red; font-weight: bold">{{ item.days7AverageSale }}</span></div>
|
||||
<div v-else-if="search.orderBy == '7'" style="display: inline">近15次日均销量: <span style="color: red; font-weight: bold">{{ item.days15AverageSale }}</span></div>
|
||||
<div v-else style="display: inline">日均销量: <span style="color: red; font-weight: bold">{{ item.averageSale }}</span></div>
|
||||
<ai-product-drop-down :params="item" :isShowDetail="true" :isShowAddFavorite="true" :isShowDelFavorite="false" @onGoDetail="goDetail(item.goodsId, item.monitorId)" style="float: right;"></ai-product-drop-down>
|
||||
<div style="display: inline">日均销量: <span style="color: red; font-weight: bold">{{ item.averageSale }}</span></div>
|
||||
<ai-product-drop-down :params="item" :isShowDetail="true" :isShowAddFavorite="true" :isShowDelFavorite="false" @onGoDetail="goDetail(item.goodsId, item.groupId)" style="float: right;"></ai-product-drop-down>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -84,23 +68,23 @@
|
||||
:close-on-click-modal="false"
|
||||
width="80%"
|
||||
:before-close="handleClose">
|
||||
<ai-product-detail v-if="isShowDetailDlg" :params="detailParams"/>
|
||||
<ai-single-product-detail v-if="isShowDetailDlg" :params="detailParams"/>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import AiProductDetail from "@/components/AiProductDetail.vue";
|
||||
import AiSingleProductDetail from "@/components/AiSingleProductDetail.vue";
|
||||
import AiProductDropDown from '@/components/AiProductDropDown.vue';
|
||||
|
||||
export default {
|
||||
name: 'DetailPage',
|
||||
props: ['params'],
|
||||
components: {AiProductDetail, AiProductDropDown},
|
||||
components: {AiSingleProductDetail, AiProductDropDown},
|
||||
data () {
|
||||
return {
|
||||
monitorId: '',
|
||||
groupId: '',
|
||||
content: '',
|
||||
search: {
|
||||
current: 1,
|
||||
@@ -110,9 +94,7 @@ import AiProductDropDown from '@/components/AiProductDropDown.vue';
|
||||
priceBegin: '',
|
||||
priceEnd: '',
|
||||
saleBegin: '',
|
||||
saleEnd: '',
|
||||
isNew: '',
|
||||
isOff: ''
|
||||
saleEnd: ''
|
||||
},
|
||||
orderBys: [{
|
||||
value: '0',
|
||||
@@ -129,15 +111,6 @@ import AiProductDropDown from '@/components/AiProductDropDown.vue';
|
||||
},{
|
||||
value: '4',
|
||||
label: '按日均销量排序'
|
||||
},{
|
||||
value: '5',
|
||||
label: '按近3次采集平均销售量排序'
|
||||
},{
|
||||
value: '6',
|
||||
label: '按近7次采集平均销售量排序'
|
||||
},{
|
||||
value: '7',
|
||||
label: '按近15次采集平均销售量排序'
|
||||
}],
|
||||
tableData: [],
|
||||
total: 0,
|
||||
@@ -147,17 +120,16 @@ import AiProductDropDown from '@/components/AiProductDropDown.vue';
|
||||
},
|
||||
|
||||
created () {
|
||||
this.$dict.load('mall_yesno');
|
||||
this.monitorId = this.params.id
|
||||
this.groupId = this.params.id
|
||||
this.content = this.params.content
|
||||
this.getList()
|
||||
},
|
||||
|
||||
methods: {
|
||||
getList () {
|
||||
this.$http.post('/api/monitorDetail/myPageNew',null,{
|
||||
this.$http.post('/api/singleGoodsDetail/myPageNew',null,{
|
||||
params: {
|
||||
monitorId: this.monitorId,
|
||||
groupId: this.groupId,
|
||||
...this.search
|
||||
}
|
||||
}).then(res => {
|
||||
@@ -190,8 +162,8 @@ import AiProductDropDown from '@/components/AiProductDropDown.vue';
|
||||
handleClose() {
|
||||
this.isShowDetailDlg = false
|
||||
},
|
||||
goDetail (goodsId, monitorId) {
|
||||
this.detailParams = {goodsId: goodsId, monitorId: monitorId}
|
||||
goDetail (goodsId, groupId) {
|
||||
this.detailParams = {goodsId: goodsId, groupId: groupId}
|
||||
this.isShowDetailDlg = true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div>
|
||||
<ai-list class="list" v-loading="isLoading" element-loading-text="正在采集中……" element-loading-spinner="el-icon-loading">
|
||||
<ai-list class="list" v-loading="isLoading" :element-loading-text="loadingText" element-loading-spinner="el-icon-loading">
|
||||
<ai-title
|
||||
slot="title"
|
||||
title="单品跟踪"
|
||||
@@ -11,7 +11,6 @@
|
||||
<ai-search-bar>
|
||||
<template #left>
|
||||
<el-button type="button" :icon="'el-icon-delete'" :class="'el-button el-button--primary'" @click="batchRemove()">删除</el-button>
|
||||
<el-button type="button" :class="'el-button el-button--primary'" @click="batchCollect()">批量采集</el-button>
|
||||
<el-button type="button" :class="'el-button el-button--primary'" @click="addGroup()">添加分组</el-button>
|
||||
</template>
|
||||
<template #right>
|
||||
@@ -26,12 +25,13 @@
|
||||
@selection-change="onChooseChange"
|
||||
:current.sync="search.current" :size.sync="search.size"
|
||||
@getList="getList">
|
||||
<el-table-column slot="options" label="操作" width="240px" show-overflow-tooltip align="center" fixed="right">
|
||||
<el-table-column slot="options" label="操作" width="280px" show-overflow-tooltip align="center" fixed="right">
|
||||
<template slot-scope="{ row }">
|
||||
<div class="table-options">
|
||||
<el-button type="text" @click="deleteGroup(row.id)">删除</el-button>
|
||||
<el-button type="text" @click="toUpdateGroup(row)">修改</el-button>
|
||||
<el-button type="text" @click="toDetail(row.id, row.content, row.source)">详情</el-button>
|
||||
<el-button type="text" @click="toAddUrl(row)">添加商品</el-button>
|
||||
<el-button type="text" @click="toDetail(row.id, row.name)">详情</el-button>
|
||||
<el-button type="text" @click="toBegin(row)">采集数据</el-button>
|
||||
</div>
|
||||
</template>
|
||||
@@ -82,11 +82,53 @@
|
||||
<el-button type="primary" @click="updateGroup">确定</el-button>
|
||||
</div>
|
||||
</ai-dialog>
|
||||
|
||||
<ai-dialog
|
||||
title="添加商品"
|
||||
:visible.sync="isAddUrlDlgShow"
|
||||
:close-on-click-modal="false"
|
||||
width="80%"
|
||||
customFooter
|
||||
@close="isDlgShow = false">
|
||||
<el-alert
|
||||
title="每成功添加一个商品,将消耗10金币"
|
||||
type="success"
|
||||
:closable="false" style="margin-bottom: 10px;">
|
||||
</el-alert>
|
||||
<el-form class="ai-form" style="margin-top: 20px" :model="addUrlForm" label-width="120px" ref="addUrlForm">
|
||||
<el-form-item
|
||||
prop="urls"
|
||||
label="商品地址"
|
||||
:rules="[{ required: true, message: '请输入TEMU商品地址,多个用英文,号或换行隔开', trigger: 'blur' }]">
|
||||
<el-input type="textarea" placeholder="请输入TEMU商品地址,多个用英文,号或换行隔开" :rows="20" v-model="addUrlForm.urls"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div class="dialog-footer" slot="footer">
|
||||
<el-button @click="isAddUrlDlgShow = false">取 消</el-button>
|
||||
<el-button type="primary" @click="addUrl">确定</el-button>
|
||||
</div>
|
||||
</ai-dialog>
|
||||
|
||||
<ai-dialog
|
||||
title="提示"
|
||||
:visible.sync="isTipDlgShow"
|
||||
:close-on-click-modal="false"
|
||||
width="790px"
|
||||
customFooter
|
||||
@close="isDlgShow = false">
|
||||
<div style="display: block;height: 30px;">商品链接可能出现图形验证码,导致采集失败,是否前往验证?</div>
|
||||
<div class="dialog-footer" slot="footer">
|
||||
<el-button @click="isTipDlgShow = false">取消</el-button>
|
||||
<el-button style="width: 180px;" @click="isTipDlgShow = false, isLoading = true, beginCollect()">已验证,继续采集</el-button>
|
||||
<el-button style="width: 180px;" @click="isTipDlgShow = false, isLoading = true, currentIndex ++, beginCollect()">跳过</el-button>
|
||||
<el-button type="primary" @click="gotoValid">前往验证</el-button>
|
||||
</div>
|
||||
</ai-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {sendTemuAPIMessage, sendSheinAPIMessage} from '@/api/chromeApi'
|
||||
import {sendTemuAPIMessage, sendSheinAPIMessage, sendChromeWebReqMessage} from '@/api/chromeApi'
|
||||
|
||||
export default {
|
||||
name: 'List',
|
||||
@@ -101,6 +143,7 @@ import {sendTemuAPIMessage, sendSheinAPIMessage} from '@/api/chromeApi'
|
||||
colConfigs: [
|
||||
{ type: "selection", width: '70px', align: 'left' },
|
||||
{ prop: 'name', label: '分组名称', align: 'left' },
|
||||
{ prop: 'total', label: '商品个数', align: 'left' },
|
||||
{ prop: 'lastUpdateTime', label: '上一次更新时间', align: 'left' },
|
||||
{ prop: 'createTime', label: '添加时间', width: '180px', fixed: 'right'}
|
||||
],
|
||||
@@ -126,7 +169,22 @@ import {sendTemuAPIMessage, sendSheinAPIMessage} from '@/api/chromeApi'
|
||||
isLoading: false,
|
||||
|
||||
selectRows: [],
|
||||
isBatchCollect: false
|
||||
isBatchCollect: false,
|
||||
|
||||
isAddUrlDlgShow: false,
|
||||
addUrlForm: {
|
||||
groupId: '',
|
||||
urls: ''
|
||||
},
|
||||
|
||||
loadingText: '正在采集中……',
|
||||
isTipDlgShow: false,
|
||||
errorUrl: '',
|
||||
collectList: [],
|
||||
currentIndex: 0,
|
||||
collectData: {
|
||||
groupId: ''
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -200,26 +258,6 @@ import {sendTemuAPIMessage, sendSheinAPIMessage} from '@/api/chromeApi'
|
||||
})
|
||||
})
|
||||
},
|
||||
batchCollect () {
|
||||
if (this.selectRows.length <= 0) {
|
||||
this.$message.error('请选择要采集的分组');
|
||||
return;
|
||||
}
|
||||
this.isBatchCollect = true
|
||||
this.isLoading = true
|
||||
this.selectRows.map((item, index) => {
|
||||
setTimeout(() => {
|
||||
this.pageNo = 1
|
||||
|
||||
let data = {}
|
||||
data.monitorId = item.id
|
||||
data.source = item.source
|
||||
data.details = []
|
||||
|
||||
this.beginCollect(item, data, index)
|
||||
}, 1000*(index+1))
|
||||
})
|
||||
},
|
||||
deleteGroup(id) {
|
||||
this.$confirm('确定要删除?', '温馨提示', {
|
||||
type: 'warning'
|
||||
@@ -237,166 +275,182 @@ import {sendTemuAPIMessage, sendSheinAPIMessage} from '@/api/chromeApi'
|
||||
})
|
||||
})
|
||||
},
|
||||
toDetail (id, content, source) {
|
||||
if (source == '0') {
|
||||
this.$emit('change', {
|
||||
type: 'Detail',
|
||||
params: {
|
||||
id: id || '',
|
||||
content: content
|
||||
}
|
||||
})
|
||||
} else {
|
||||
this.$emit('change', {
|
||||
type: 'SheinDetail',
|
||||
params: {
|
||||
id: id || '',
|
||||
content: content
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
toDetail (id, content) {
|
||||
this.$emit('change', {
|
||||
type: 'Detail',
|
||||
params: {
|
||||
id: id || '',
|
||||
content: content
|
||||
}
|
||||
})
|
||||
},
|
||||
addGroup() {
|
||||
this.form.mallId = ''
|
||||
this.isDlgShow = true
|
||||
},
|
||||
toBegin(row) {
|
||||
this.isBatchCollect = false
|
||||
this.pageNo = 1
|
||||
this.isLoading = true
|
||||
|
||||
let data = {}
|
||||
data.monitorId = row.id
|
||||
data.details = []
|
||||
|
||||
this.beginCollect(row, data, 0)
|
||||
},
|
||||
|
||||
beginCollect(row, reqData, index) {
|
||||
if (row.source == '0') {
|
||||
this.beginTemuCollect(row, reqData, index)
|
||||
} else if (row.source == '1') {
|
||||
this.beginSheinCollect(row, reqData, index)
|
||||
}
|
||||
toAddUrl(row) {
|
||||
this.isAddUrlDlgShow = true
|
||||
this.addUrlForm.groupId = row.id
|
||||
this.addUrlForm.urls = ''
|
||||
},
|
||||
beginTemuCollect(row, reqData, index) {
|
||||
sendTemuAPIMessage({
|
||||
url: 'api/bg/circle/c/mall/newGoodsList',
|
||||
anti: true,
|
||||
data: {
|
||||
"mall_id": row.content,
|
||||
"filter_items": "0:1",
|
||||
"page_number": this.pageNo,
|
||||
"page_size": this.pageSize
|
||||
}}).then((res) => {
|
||||
if (this.isBatchCollect && (index+1) == this.selectRows.length) {
|
||||
this.isLoading = false
|
||||
this.isBatchCollect = false
|
||||
} else {
|
||||
this.isLoading = false
|
||||
}
|
||||
if (res.errorCode == 1000000) {
|
||||
res.result.data.goods_list.map(item => {
|
||||
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
|
||||
}
|
||||
}
|
||||
reqData.details.push({
|
||||
url: 'https://www.temu.com/goods.html?goods_id=' + item.goods_id,
|
||||
price: item.price_info.price_schema,
|
||||
saleTotal: total,
|
||||
goodsId: item.goods_id,
|
||||
imgUrl: item.thumb_url,
|
||||
mallId: item.mall_id
|
||||
})
|
||||
})
|
||||
addUrl() {
|
||||
this.$refs.addUrlForm.validate((valid) => {
|
||||
if (valid) {
|
||||
let params = []
|
||||
let arr = this.addUrlForm.urls.split(/[\n,]/).map((value) => value.trim());
|
||||
arr.map(url => {
|
||||
let urlParams = this.parseURL(url)
|
||||
let tmpUrl = url.substring(0,url.indexOf(".html"))
|
||||
|
||||
if (res.result.data.goods_list.length == this.pageSize) {
|
||||
this.pageNo = this.pageNo + 1
|
||||
this.beginCollect(row, reqData, index)
|
||||
if (tmpUrl.lastIndexOf("-g-") > 0) {
|
||||
tmpUrl = tmpUrl.substring(tmpUrl.lastIndexOf("-g-"), tmpUrl.length);
|
||||
tmpUrl = tmpUrl.substring(3, tmpUrl.length);
|
||||
params.push({
|
||||
groupId: this.addUrlForm.groupId,
|
||||
goodsUrl: url,
|
||||
goodsId: tmpUrl
|
||||
})
|
||||
} else {
|
||||
this.isLoading = false
|
||||
this.$http.post('/api/monitorDetail/addDetails', reqData
|
||||
).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.$message.success('店铺ID【' + row.content + '】数据采集成功!')
|
||||
this.getList()
|
||||
let urlParams = this.parseURL(url)
|
||||
if (urlParams.params) {
|
||||
let goodsId = urlParams.params.goods_id
|
||||
if (goodsId) {
|
||||
params.push({
|
||||
groupId: this.addUrlForm.groupId,
|
||||
goodsUrl: url,
|
||||
goodsId: goodsId
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
} else {
|
||||
this.isLoading = false
|
||||
this.$message.error("采集失败,请检查https://www.temu.com是否能正常访问")
|
||||
}
|
||||
})
|
||||
},
|
||||
async beginSheinCollect(row, reqData, index) {
|
||||
let res = await sendSheinAPIMessage({
|
||||
url: 'api/store/items/get',
|
||||
method: 'GET',
|
||||
params: {
|
||||
_ver: '1.1.8',
|
||||
_lang: 'en',
|
||||
scene_id: '10188',
|
||||
rule_poskey: "shoprecommend",
|
||||
requestType: "pageChange",
|
||||
search_type: "store",
|
||||
store_code: row.content,
|
||||
viewed_goods: '',
|
||||
limit: 120,
|
||||
page: this.pageNo
|
||||
}})
|
||||
if (this.isBatchCollect && (index+1) == this.selectRows.length) {
|
||||
this.isLoading = false
|
||||
this.isBatchCollect = false
|
||||
} else {
|
||||
this.isLoading = false
|
||||
}
|
||||
if (res.goods && res.goods.length > 0) {
|
||||
res.goods.map(item => {
|
||||
let total = 0
|
||||
if (item.pretreatInfo?.sellingPointUniversalLabels) {
|
||||
for (let i = 0; i < item.pretreatInfo.sellingPointUniversalLabels.length; i++) {
|
||||
if (item.pretreatInfo.sellingPointUniversalLabels[i].starComment) {
|
||||
total = item.pretreatInfo.sellingPointUniversalLabels[i].starComment?.comment_num || 0
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
reqData.details.push({
|
||||
url: 'https://www.shein.com/'+item.goods_url_name.replace(/ /g, '-')+'-p-'+item.goods_id+'-cat-'+item.cat_id+'.html',
|
||||
price: item.salePrice.amount,
|
||||
saleTotal: total,
|
||||
goodsId: item.goods_id,
|
||||
imgUrl: 'https:'+item.goods_img,
|
||||
mallId: item.store_code
|
||||
})
|
||||
})
|
||||
|
||||
if (res.goods.length == this.pageSize) {
|
||||
this.pageNo = this.pageNo + 1
|
||||
this.beginCollect(row, reqData, index)
|
||||
} else {
|
||||
this.isLoading = false
|
||||
this.$http.post('/api/monitorDetail/addDetails', reqData
|
||||
).then(res => {
|
||||
this.$http.post(`/api/singleGroup/saveGoods`, params).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.$message.success('店铺ID【' + row.content + '】数据采集成功!')
|
||||
this.$message.success(res.msg)
|
||||
this.getList()
|
||||
this.isAddUrlDlgShow = false
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
toBegin(row) {
|
||||
this.isLoading = true
|
||||
|
||||
this.collectData.groupId = row.id
|
||||
this.collectData.details = []
|
||||
|
||||
this.$http.post(`/api/singleGroup/getGoodsList`, null, {params: {
|
||||
id: row.id
|
||||
}}).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.collectList = res.data
|
||||
this.currentIndex = 0
|
||||
|
||||
this.beginCollect()
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
},
|
||||
async beginCollect() {
|
||||
this.loadingText = `正在采集第(${this.currentIndex}/${this.collectList.length})个商品的商品信息`
|
||||
if (this.currentIndex == this.collectList.length) {
|
||||
let res = await this.$http.post(`/api/singleGoodsDetail/addDetails`, this.collectData)
|
||||
if (res.code == 0) {
|
||||
this.getList()
|
||||
}
|
||||
this.isLoading = false
|
||||
this.$message.success('采集成功')
|
||||
return
|
||||
}
|
||||
let res = await sendTemuAPIMessage({
|
||||
url: 'api/oak/integration/render',
|
||||
anti: true,
|
||||
data: {
|
||||
goods_id: this.collectList[this.currentIndex].goodsId
|
||||
}})
|
||||
|
||||
if (!res.goods || !res.goods.productName) {
|
||||
res = await sendChromeWebReqMessage({
|
||||
type: 'temu',
|
||||
url: this.collectList[this.currentIndex].goodsUrl,
|
||||
})
|
||||
|
||||
if (res.indexOf("window.rawData") == -1) {
|
||||
this.$message.error("请检查地址是否正确,或者“TEMU”网站是否出现图形验证码")
|
||||
|
||||
this.isLoading = false
|
||||
this.errorUrl = this.collectList[this.currentIndex].goodsUrl
|
||||
this.isTipDlgShow = true
|
||||
return
|
||||
} else {
|
||||
let str = res.substring(res.indexOf("window.rawData"))
|
||||
str = str.substring(0, str.indexOf("<\/script>"))
|
||||
str = str.substring(str.indexOf("{"))
|
||||
str = str.substring(0, str.lastIndexOf("}"))
|
||||
str = str + "}"
|
||||
let goodsObj = JSON.parse(str)
|
||||
let goods = goodsObj.store.goods
|
||||
|
||||
this.collectData.details.push({
|
||||
groupId: this.collectData.groupId,
|
||||
price: goods.minOnSalePrice / 100,
|
||||
saleTotal: goods.soldQuantity,
|
||||
goodsId: goods.goodsId,
|
||||
url: 'https://www.temu.com/goods.html?goods_id=' +goods.goodsId,
|
||||
imgUrl: goods.hdThumbUrl,
|
||||
mallId: goods.mallId
|
||||
})
|
||||
|
||||
this.currentIndex ++
|
||||
this.beginCollect()
|
||||
}
|
||||
} else {
|
||||
this.collectData.details.push({
|
||||
groupId: this.collectData.groupId,
|
||||
price: res.goods.min_on_sale_price / 100,
|
||||
saleTotal: res.goods.sold_quantity,
|
||||
goodsId: res.goods.goods_id,
|
||||
url: 'https://www.temu.com/goods.html?goods_id=' + res.goods.goods_id,
|
||||
imgUrl: res.goods.hd_thumb_url,
|
||||
mallId: res.goods.mall_id
|
||||
})
|
||||
|
||||
this.currentIndex ++
|
||||
this.beginCollect()
|
||||
}
|
||||
|
||||
},
|
||||
gotoValid() {
|
||||
window.open(this.errorUrl, '_blank');
|
||||
},
|
||||
parseURL(url) {
|
||||
let a = document.createElement('a');
|
||||
a.href = url;
|
||||
return {
|
||||
source: url,
|
||||
protocol: a.protocol.replace(':',''),
|
||||
host: a.hostname,
|
||||
port: a.port,
|
||||
query: a.search,
|
||||
params: (function(){
|
||||
var ret = {},
|
||||
seg = a.search.replace(/^\?/,'').split('&'),
|
||||
len = seg.length, i = 0, s;
|
||||
for (;i<len;i++) {
|
||||
if (!seg[i]) { continue; }
|
||||
s = seg[i].split('=');
|
||||
ret[s[0]] = s[1];
|
||||
}
|
||||
return ret;
|
||||
})(),
|
||||
file: (a.pathname.match(/\/([^\/?#]+)$/i) || [,''])[1],
|
||||
hash: a.hash.replace('#',''),
|
||||
path: a.pathname.replace(/^([^\/])/,'/$1'),
|
||||
relative: (a.href.match(/tps?:\/\/[^\/]+(.+)/) || [,''])[1],
|
||||
segments: a.pathname.replace(/^\//,'').split('/')
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,302 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<ai-list class="list">
|
||||
<ai-title
|
||||
slot="title"
|
||||
:title="'店铺ID(' + `${content}` + ')商品列表'"
|
||||
isShowBottomBorder isShowBack @onBackClick="cancel(false)">
|
||||
</ai-title>
|
||||
<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>
|
||||
<label style="width:100px">仅显示最新:</label>
|
||||
<ai-select :selectList="$dict.getDict('mall_yesno')" v-model="search.isNew"></ai-select>
|
||||
<label style="width:100px">仅显示下架:</label>
|
||||
<ai-select :selectList="$dict.getDict('mall_yesno')" v-model="search.isOff"></ai-select>
|
||||
</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']" v-if="item.isOff == '1'">
|
||||
<div>
|
||||
<el-image :src="item.imgUrl" class="mask image" :preview-src-list="[item.imgUrl]" />
|
||||
</div>
|
||||
<span class="icon-box">
|
||||
<img style="width: 50px; height: 50px" src="../../../../assets/off.png">
|
||||
</span>
|
||||
</div>
|
||||
<span class="nav-label labelBadge" v-else>
|
||||
<span class="ii" v-if="item.isNew == 1">新</span>
|
||||
<el-image :src="item.imgUrl" class="image" :preview-src-list="[item.imgUrl]" />
|
||||
</span>
|
||||
<div style="padding: 14px;">
|
||||
<div class="bottom clearfix">
|
||||
<div style="margin-bottom: 5px;">
|
||||
<div style="display: inline; margin-left: 5px;">${{ item.price }}<sub style="margin-left: 2px;" v-html="getPricePercent(item.priceChange)"></sub></div>
|
||||
<div style="display: inline; margin-right: 5px; float: right;">{{ item.saleTotal }}<sub style="margin-left: 2px;" v-html="getSalePercent(item.saleChange)"></sub></div>
|
||||
</div>
|
||||
<div>
|
||||
<div v-if="search.orderBy == '5'" style="display: inline">近3次日均评论数: <span style="color: red; font-weight: bold">{{ item.days3AverageSale }}</span></div>
|
||||
<div v-else-if="search.orderBy == '6'" style="display: inline">近7次日均评论数: <span style="color: red; font-weight: bold">{{ item.days7AverageSale }}</span></div>
|
||||
<div v-else-if="search.orderBy == '7'" style="display: inline">近15次日均评论数: <span style="color: red; font-weight: bold">{{ item.days15AverageSale }}</span></div>
|
||||
<div v-else style="display: inline">日均评论数: <span style="color: red; font-weight: bold">{{ item.averageSale }}</span></div>
|
||||
<ai-product-drop-down :params="item" :isHideCopy="true" :isShowDetail="true" :isShowAddFavorite="true" :isShowDelFavorite="false" @onGoDetail="goDetail(item.goodsId, item.monitorId)" 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">
|
||||
</el-pagination>
|
||||
</div>
|
||||
</template>
|
||||
</ai-list>
|
||||
|
||||
<div class="productDetail">
|
||||
<el-dialog
|
||||
title="商品详情"
|
||||
:visible="isShowDetailDlg"
|
||||
:close-on-click-modal="false"
|
||||
width="80%"
|
||||
:before-close="handleClose">
|
||||
<ai-product-detail v-if="isShowDetailDlg" :params="detailParams"/>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import AiProductDetail from "@/components/AiProductDetail.vue";
|
||||
import AiProductDropDown from '@/components/AiProductDropDown.vue';
|
||||
|
||||
export default {
|
||||
name: 'DetailPage',
|
||||
props: ['params'],
|
||||
components: {AiProductDetail, AiProductDropDown},
|
||||
data () {
|
||||
return {
|
||||
monitorId: '',
|
||||
content: '',
|
||||
search: {
|
||||
current: 1,
|
||||
type: '1',
|
||||
size: 120,
|
||||
orderBy: '',
|
||||
priceBegin: '',
|
||||
priceEnd: '',
|
||||
saleBegin: '',
|
||||
saleEnd: '',
|
||||
isNew: '',
|
||||
isOff: ''
|
||||
},
|
||||
orderBys: [{
|
||||
value: '0',
|
||||
label: '按评论数涨辐排序'
|
||||
},{
|
||||
value: '1',
|
||||
label: '按价格涨辐排序'
|
||||
},{
|
||||
value: '2',
|
||||
label: '按评论数排序'
|
||||
},{
|
||||
value: '3',
|
||||
label: '按价格排序'
|
||||
},{
|
||||
value: '4',
|
||||
label: '按日均评论数排序'
|
||||
},{
|
||||
value: '5',
|
||||
label: '按近3次采集平均评论数排序'
|
||||
},{
|
||||
value: '6',
|
||||
label: '按近7次采集平均评论数排序'
|
||||
},{
|
||||
value: '7',
|
||||
label: '按近15次采集平均评论数排序'
|
||||
}],
|
||||
tableData: [],
|
||||
total: 0,
|
||||
isShowDetailDlg: false,
|
||||
detailParams: {}
|
||||
}
|
||||
},
|
||||
|
||||
created () {
|
||||
this.$dict.load('mall_yesno');
|
||||
this.monitorId = this.params.id
|
||||
this.content = this.params.content
|
||||
this.getList()
|
||||
},
|
||||
|
||||
methods: {
|
||||
getList () {
|
||||
this.$http.post('/api/monitorDetail/myPageNew',null,{
|
||||
params: {
|
||||
monitorId: this.monitorId,
|
||||
...this.search
|
||||
}
|
||||
}).then(res => {
|
||||
res.data.records = res.data.records.map(item => {
|
||||
item.mallId = 'https://www.shein.com/store/home?store_code=' + item.mallId
|
||||
return item
|
||||
})
|
||||
this.tableData = res.data.records
|
||||
this.total = res.data.total
|
||||
})
|
||||
},
|
||||
cancel (isRefresh) {
|
||||
this.$emit('change', {
|
||||
type: 'List',
|
||||
isRefresh: !!isRefresh
|
||||
})
|
||||
},
|
||||
getPricePercent(data) {
|
||||
if (data < 0) {
|
||||
return '<div style="display: inline; color: green">↓' + data + '%</div>'
|
||||
} else if (data > 0) {
|
||||
return '<div style="display: inline; color: red">↑' + data + '%</div>'
|
||||
}
|
||||
return ''
|
||||
},
|
||||
getSalePercent(data) {
|
||||
if (data < 0) {
|
||||
return '<div style="display: inline; color: green">↓' + data + '%</div>'
|
||||
} else if (data > 0) {
|
||||
return '<div style="display: inline; color: red">↑' + data + '%</div>'
|
||||
}
|
||||
return ''
|
||||
},
|
||||
handleClose() {
|
||||
this.isShowDetailDlg = false
|
||||
},
|
||||
goDetail (goodsId, monitorId) {
|
||||
this.detailParams = {goodsId: goodsId, monitorId: monitorId}
|
||||
this.isShowDetailDlg = true
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.productDetail {
|
||||
:deep(.el-dialog) {
|
||||
height: 78vh;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
}
|
||||
.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;
|
||||
}
|
||||
|
||||
/*徽标*/
|
||||
.labelBadge {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.ii {
|
||||
background: #f00;
|
||||
border-radius: 50%;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
top: -3px;
|
||||
right: -5px;
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
color: #FFF;
|
||||
z-index: 999;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.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;
|
||||
}
|
||||
|
||||
|
||||
.el-icon {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
</style>
|
||||
Reference in New Issue
Block a user