This commit is contained in:
刘仕伟
2024-01-18 00:46:23 +08:00
parent eaea055f6c
commit 492e6b83ea
13 changed files with 1497 additions and 62 deletions

View File

@@ -1,7 +1,7 @@
<template>
<div>
<el-alert
title="采集一个商品添加进草稿箱,将消耗50金币"
title="采集一个商品添加进草稿箱,将消耗20金币"
type="success"
:closable="false" style="margin-bottom: 10px;">
</el-alert>

View File

@@ -2,7 +2,7 @@
<section class="AiPayment">
<el-tabs type="card" stretch v-model="search.module" @tab-click="getPayments">
<el-tab-pane label="激活码兑换" name="2"/>
<el-tab-pane label="基础会员" name="0"/>
<el-tab-pane label="年度会员" name="0"/>
<el-tab-pane label="金币充值" name="1"/>
</el-tabs>
<div class="content">
@@ -108,12 +108,12 @@ export default {
mallId: this.$store.state.mallId,
mallName: this.$store.state.mallName
},
vipType: ["体验会员","年会员","年会员多店通用"],
vipType: ["体验会员","单店年会员","年会员多店通用"],
search: {module: "0"},
show: true,
descriptionsModule0: ["抢仓发货", "数据下载", "复制商品", "会员服务"],
descriptionsModule1: ["商品采集", "店铺跟踪", "关键字跟踪"],
descriptionsModule1: ["商品采集", "店铺跟踪", "关键字跟踪", "单品跟踪", "新品跟踪"],
payments: [],
qrcode: "",
amount: 0,

View File

@@ -2,7 +2,7 @@
"manifest_version": 3,
"name": "TEMU助手",
"description": "TEMU助手 - 自动化提高生产效率",
"version": "3.1.5",
"version": "3.1.6",
"background": {
"service_worker": "/background.js"
},

View File

@@ -50,6 +50,11 @@ const router = new VueRouter({
name: 'waitShippingList',
component: () => import('../view/shipping/WaitShippingList.vue')
},
{
path: 'myOrder',
name: 'myOrder',
component: () => import('../view/shipping/MyOrder.vue')
},
{
path: 'returnPackage',
@@ -112,6 +117,11 @@ const router = new VueRouter({
name: 'bestSellers',
component: () => import('../view/selection/bestsellers/Index.vue')
},
{
path: 'singleTrack',
name: 'singleTrack',
component: () => import('../view/selection/singletrack/Index.vue')
},
{
path: 'message',

View File

@@ -38,6 +38,31 @@
</el-select>
</div>
</div>
<ai-dialog
title="导出SKU历史销量"
:visible.sync="downloadSkuSaleNumberDlg"
:close-on-click-modal="false"
width="790px"
append-to-body
customFooter
@close="handleClose">
<el-form class="ai-form" :model="skuDownloadForm" label-width="160px" ref="skuDownloadForm">
<el-form-item label="日期范围" style="width: 100%;" prop="date" :rules="[{ required: true, message: '请选择时间范围', trigger: 'blur' }]">
<el-date-picker
v-model="skuDownloadForm.date"
type="daterange"
range-separator=""
start-placeholder="开始日期"
end-placeholder="结束日期">
</el-date-picker>
</el-form-item>
</el-form>
<div class="dialog-footer" slot="footer">
<el-button @click="downloadSkuSaleNumberDlg = false"> </el-button>
<el-button type="primary" @click="toDownloadSkuSaleNumber">确定</el-button>
</div>
</ai-dialog>
</template>
</ai-title>
<template slot="content" v-if="type === '0'">
@@ -87,6 +112,7 @@
worksheet="SKU历史销量">
<el-button type="primary" id="downloadSkuSaleNumber"></el-button>
</json-excel>
<el-button type="primary" :disabled="!mallId" @click="toDownload">导出SKU历史销量</el-button>
</template>
<ai-table
ref="table0"
@@ -151,29 +177,7 @@
</ai-card>
</template>
<ai-dialog
title="导出SKU历史销量"
:visible.sync="downloadSkuSaleNumberDlg"
:close-on-click-modal="false"
width="790px"
customFooter
@close="handleClose">
<!--<el-form class="ai-form" :model="skuDownloadForm" label-width="160px" ref="skuDownloadForm">
<el-form-item label="日期范围" style="width: 100%;" prop="date" :rules="[{ required: true, message: '请选择时间范围', trigger: 'blur' }]">
<el-date-picker
v-model="skuDownloadForm.date"
type="daterange"
range-separator=""
start-placeholder="开始日期"
end-placeholder="结束日期">
</el-date-picker>
</el-form-item>
</el-form>-->
<div class="dialog-footer" slot="footer">
<el-button @click="downloadSkuSaleNumberDlg = false"> </el-button>
<el-button type="primary" @click="toDownloadSkuSaleNumber">确定</el-button>
</div>
</ai-dialog>
</ai-list>
</template>
@@ -262,11 +266,12 @@ import { Message } from 'element-ui'
"生产建议信息 - 剩余件数": 'availableProduceNum'
},
skuSaleNumberFields: {},
skuSaleNumberList: [],
downloadSkuSaleNumberDlg: false,
skuDownloadForm: {
date: ''
}
},
}
},
@@ -307,16 +312,19 @@ import { Message } from 'element-ui'
{
prop: 'productId',
label: 'SPU',
width: '120px',
align: 'center'
},
{
prop: 'productSkcId',
label: 'SKC',
width: '120px',
align: 'center'
},
{
prop: 'productSkuId',
label: 'SKU ID',
width: '120px',
align: 'center'
},
{
@@ -327,22 +335,26 @@ import { Message } from 'element-ui'
{
prop: 'skuExtCode',
label: 'SKU货号',
width: '120px',
align: 'center'
},
{
prop: 'onSalesDurationOffline',
label: '加入站点时长',
width: '160px',
align: 'center'
},
{
prop: 'isVerifyPrice',
label: '开款核价状态',
width: '160px',
align: 'center',
format: v => v ? '核价通过': '核价未通过 / 无法备货'
},
{
prop: 'supplierPrice',
label: '申报价格(CNY)',
width: '160px',
align: 'center',
format: v => v / 100,
fixed: "right"
@@ -350,6 +362,7 @@ import { Message } from 'element-ui'
{
prop: 'warehouseInventoryNum',
label: '仓内可用库存',
width: '160px',
align: 'center',
fixed: "right",
sortable: true,
@@ -360,6 +373,7 @@ import { Message } from 'element-ui'
{
prop: 'productTotalPrice',
label: '库存货值(CNY)',
width: '160px',
align: 'center',
fixed: "right",
sortable: true,
@@ -371,6 +385,7 @@ import { Message } from 'element-ui'
prop: 'purchaseConfig',
label: '备货逻辑',
align: 'center',
width: '120px',
fixed: "right",
sortable: true,
'sort-method': (a, b) => {
@@ -571,21 +586,6 @@ import { Message } from 'element-ui'
jsonFields[dateStr] = dateStr
}
return jsonFields
},
skuSaleNumberFields () {
let jsonFields = {
"日期": "date"
}
let date = new Date()
date.setDate(date.getDate() )
for (let i = 0; i < 30; i++) {
date.setDate(date.getDate() - 1)
let dateStr = formatDate(date)
jsonFields[dateStr] = dateStr
}
return jsonFields
}
},
@@ -835,7 +835,6 @@ import { Message } from 'element-ui'
})
},
toDownload() {
console.log(111)
this.downloadSkuSaleNumberDlg = true
},
startSkuSaleNumberDownload() {
@@ -845,6 +844,7 @@ import { Message } from 'element-ui'
this.downloadSkuSaleNumberDlg = false
},
async toDownloadSkuSaleNumber() {
this.downloadSkuSaleNumberDlg = false
this.isLoading = true
if (!this.skuDownloadForm.date) {
Message.error("请选择时间")
@@ -853,40 +853,78 @@ import { Message } from 'element-ui'
let beginDateStr = formatDate(this.skuDownloadForm.date[0])
let endDateStyr = formatDate(this.skuDownloadForm.date[1])
let beginDate = this.skuDownloadForm.date[0]
let endDate = this.skuDownloadForm.date[1]
this.skuSaleNumberFields = {
"日期": "date"
let temp = {}
temp = {
'SKC': 'skc',
'SKU': 'sku',
'SKU货号': 'skuExtCode'
}
let beginTime = new Date(this.skuDownloadForm.date[0])
let endTime = new Date(this.skuDownloadForm.date[1])
for (; beginTime.getTime() <= endTime.getTime(); ) {
let dateStr = formatDate(endTime)
temp[dateStr] = dateStr
for (; beginDate.getTime() < endDate.getTime(); ) {
let dateStr = formatDate(endDate)
this.skuSaleNumberFields[dateStr] = dateStr
endDate.setDate(endDate.getDate() - 1)
endTime.setDate(endTime.getDate() - 1)
}
this.skuSaleNumberFields = temp
let tempSkuList = this.list.filter(item => {
return item.onSalesDurationOffline != '-天'
})
let tempIds = []
tempSkuId.map(i => {
tempIds.push(i.productSkuId)
this.tempSkuIds = []
tempSkuList.map(i => {
this.tempSkuIds.push(i.productSkuId)
})
this.skuSaleNumberList = []
this.list.map(item => {
if (item.onSalesDurationOffline != '-天') {
let temp = {
sku: item.productSkuId,
skc: item.productSkcId,
skuExtCode: item.skuExtCode
}
beginTime = new Date(this.skuDownloadForm.date[0])
endTime = new Date(this.skuDownloadForm.date[1])
for (; beginTime.getTime() <= endTime.getTime(); ) {
let dateStr = formatDate(endTime)
temp[dateStr] = 0
endTime.setDate(endTime.getDate() - 1)
}
this.skuSaleNumberList.push(temp)
}
})
let res = await sendChromeAPIMessage({
url: 'oms/bg/venom/api/supplier/sales/management/querySkuSalesNumber',
needMallId: true,
mallId: this.mallId,
data: {
"productSkuIds": tempIds,
"productSkuIds": this.tempSkuIds,
"startDate": beginDateStr,
"endDate": endDateStyr
}})
console.log(res)
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历史销量数据失败")
}
this.isLoading = false
}
}

View File

@@ -58,6 +58,7 @@
<el-menu-item index="/waitPackageList">待装箱发货单</el-menu-item>
<el-menu-item index="/waitShippingList">待收货发货单</el-menu-item>
<el-menu-item index="/shippingList">已收货发货单</el-menu-item>
<el-menu-item index="/myOrder">我的备货单</el-menu-item>
</el-submenu>
<el-submenu index="/copyProduct">
@@ -97,6 +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="/bestSellers">7天畅销品</el-menu-item>
<el-menu-item index="/indexTrack">首页商品跟踪</el-menu-item>
</el-submenu>

View File

@@ -0,0 +1,64 @@
<template>
<div style="height: 100%;">
<transition name="fade-transform" mode="out-in">
<keep-alive :include="['List']">
<component ref="component" :is="component" @change="onChange" :params="params"></component>
</keep-alive>
</transition>
</div>
</template>
<script>
import List from './components/List.vue'
import Detail from './components/Detail.vue'
import SheinDetail from './components/SheinDetail.vue'
export default {
name: 'SingleTrack',
label: '单品跟踪',
components: {
List,
Detail,
SheinDetail
},
data () {
return {
component: 'List',
params: {}
}
},
methods: {
onChange (data) {
if (data.type === 'Detail') {
this.component = 'Detail'
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
this.$nextTick(() => {
if (data.isRefresh) {
setTimeout(() => {
this.$refs.component.getList()
}, 600)
}
})
}
}
}
}
</script>
<style lang="scss" scoped>
</style>

View File

@@ -0,0 +1,298 @@
<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" :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 => {
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>

View File

@@ -0,0 +1,406 @@
<template>
<div>
<ai-list class="list" v-loading="isLoading" element-loading-text="正在采集中……" element-loading-spinner="el-icon-loading">
<ai-title
slot="title"
title="单品跟踪"
isShowBottomBorder>
</ai-title>
<template slot="content">
<div class="content">
<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>
<el-button size="small" circle icon="el-icon-refresh-right" @click="getList()"></el-button>
</template>
</ai-search-bar>
<ai-table
:tableData="tableData"
:col-configs="colConfigs"
:total="total"
style="margin-top: 8px;"
@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">
<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="toBegin(row)">采集数据</el-button>
</div>
</template>
</el-table-column>
</ai-table>
</div>
</template>
</ai-list>
<ai-dialog
title="添加分组"
:visible.sync="isDlgShow"
:close-on-click-modal="false"
width="790px"
customFooter
@close="isDlgShow = false">
<el-form class="ai-form" style="margin-top: 20px" :model="form" label-width="120px" ref="form">
<el-form-item
prop="name"
label="分组名称"
:rules="[{ required: true, message: '请输入分组名称', trigger: 'blur' }]">
<el-input placeholder="请输入分组名称" v-model="form.name"></el-input>
</el-form-item>
</el-form>
<div class="dialog-footer" slot="footer">
<el-button @click="isDlgShow = false"> </el-button>
<el-button type="primary" @click="saveGroup">确定</el-button>
</div>
</ai-dialog>
<ai-dialog
title="修改分组"
:visible.sync="isUpdateDlgShow"
:close-on-click-modal="false"
width="790px"
customFooter
@close="isDlgShow = false">
<el-form class="ai-form" :model="updateForm" label-width="120px" ref="updateForm">
<el-form-item
prop="name"
label="分组名称"
:rules="[{ required: true, message: '请输入分组名称', trigger: 'blur' }]">
<el-input placeholder="请输入分组名称" v-model="updateForm.name"></el-input>
</el-form-item>
</el-form>
<div class="dialog-footer" slot="footer">
<el-button @click="isUpdateDlgShow = false"> </el-button>
<el-button type="primary" @click="updateGroup">确定</el-button>
</div>
</ai-dialog>
</div>
</template>
<script>
import {sendTemuAPIMessage, sendSheinAPIMessage} from '@/api/chromeApi'
export default {
name: 'List',
data () {
return {
search: {
current: 1,
type: '1',
size: 10
},
colConfigs: [
{ type: "selection", width: '70px', align: 'left' },
{ prop: 'name', label: '分组名称', align: 'left' },
{ prop: 'lastUpdateTime', label: '上一次更新时间', align: 'left' },
{ prop: 'createTime', label: '添加时间', width: '180px', fixed: 'right'}
],
tableData: [],
total: 0,
form: {
name: ''
},
updateObj: {},
isUpdateDlgShow: false,
updateForm: {
id: '',
name: ''
},
isDlgShow: false,
detailsVo: {},
pageNo: 1,
pageSize: 120,
isLoading: false,
selectRows: [],
isBatchCollect: false
}
},
created () {
this.getList()
},
methods: {
getList () {
this.$http.post('/api/singleGroup/myPage',null,{
params: {
...this.search
}
}).then(res => {
this.tableData = res.data.records
this.total = res.data.total
})
},
onChooseChange (val) {
this.selectRows = val;
},
saveGroup () {
this.$refs.form.validate((valid) => {
if (valid) {
this.$http.post(`/api/singleGroup/add`, this.form).then(res => {
if (res.code == 0) {
this.$message.success('添加成功!')
this.getList()
this.isDlgShow = false
}
})
}
})
},
toUpdateGroup (obj) {
this.updateObj = obj
this.updateForm.name = obj.name
this.isUpdateDlgShow = true
},
updateGroup () {
this.$refs.updateForm.validate((valid) => {
if (valid) {
this.$http.post(`/api/singleGroup/update`, {id: this.updateObj.id, name: this.updateForm.name}).then(res => {
if (res.code == 0) {
this.$message.success('修改成功!')
this.getList()
this.isUpdateDlgShow = false
}
})
}
})
},
batchRemove() {
if (this.selectRows.length <= 0) {
this.$message.error('请选择要删除的分组');
return;
}
let ids = this.selectRows.map(item => {
return item.id
})
this.$confirm('确定要删除?', '温馨提示', {
type: 'warning'
}).then(() => {
this.$http.post('/api/singleGroup/delByIds', ids
).then(res => {
if (res.code == 0) {
this.$message.success('删除成功!')
this.getList()
}
})
})
},
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'
}).then(() => {
this.$http.post('/api/singleGroup/del',null, {
params: {
id: id
}
}
).then(res => {
if (res.code == 0) {
this.$message.success('删除成功!')
this.getList()
}
})
})
},
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
}
})
}
},
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)
}
},
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
})
})
if (res.result.data.goods_list.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 => {
if (res.code == 0) {
this.$message.success('店铺ID【' + row.content + '】数据采集成功!')
this.getList()
}
})
}
} 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 => {
if (res.code == 0) {
this.$message.success('店铺ID【' + row.content + '】数据采集成功!')
this.getList()
}
})
}
}
}
}
}
</script>
<style scoped lang="scss">
</style>

View File

@@ -0,0 +1,302 @@
<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>

View File

@@ -0,0 +1,249 @@
<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="form.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-card title="数据明细" style="padding-bottom: 40px;">
<template #right>
<label style="width:80px">状态</label>
<el-select v-model="form.status" multiple placeholder="请选择">
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
<label style="width:120px">备货单创建时间</label>
<el-date-picker
v-model="form.date"
type="daterange"
range-separator=""
start-placeholder="开始日期"
end-placeholder="结束日期">
</el-date-picker>
<el-button type="primary" @click="toLoad">加载</el-button>&nbsp;
<json-excel
:data="tableData"
:fields="jsonFields"
name="备货单列表.xls"
worksheet="备货单列表">
<el-button type="primary" :disabled="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 { Message } from 'element-ui'
import {sendChromeAPIMessage} from '@/api/chromeApi'
import {timestampToTime} from '@/utils/date'
import JsonExcel from 'vue-json-excel'
export default {
name: 'MyOrder',
data () {
return {
form: {
date: '',
beginDate: '',
endDate: '',
status: [],
mallId: ''
},
reqData: {
purchaseTimeFrom: '',
purchaseTimeTo: '',
pageNo: 1,
pageSize: 100,
urgencyType: 0,
statusList: [],
isCustomGoods: false,
oneDimensionSort: {
firstOrderByParam: "createdAt",
firstOrderByDesc: 1
}
},
options: [
{label: '待创建', value: 0},
{label: '待发货', value: 1},
{label: '已送货', value: 2},
{label: '已收货', value: 3},
{label: '质检全部退回', value: 5},
{label: '已验收', value: 6},
{label: '已入库', value: 7},
{label: '已作废', value: 8},
{label: '已取消', value: 10},
],
colConfigs: [
{ prop: 'purchaseTime', label: '备货单创建时间', width: '180px', align: 'left', fixed: 'left' },
{ prop: 'subPurchaseOrderSn', label: '备货单号', width: '160px', align: 'left', fixed: 'left' },
{ prop: 'productName', label: '商品名称', width: '240px', align: 'left', fixed: 'left' },
{ prop: 'status', label: '状态', width: '80px', align: 'left' },
{ prop: 'productSkcId', label: 'SKC ID', width: '120px', align: 'left' },
{ prop: 'skcExtCode', label: 'SKC货号', width: '100px', align: 'left' },
{ prop: 'productSkuId', label: 'SKU ID', width: '120px', align: 'left' },
{ prop: 'extCode', label: 'SKU货号', width: '160px', align: 'left' },
{ prop: 'specName', label: 'SKU属性', width: '100px', align: 'left' },
{ prop: 'supplierPrice', label: '申报价格(CNY)', width: '180px', align: 'left' },
{ prop: 'xiadan', label: '送货数量', width: '100px', align: 'left' },
{ prop: 'skuNum', label: '入库数量', width: '100px', align: 'left' },
{ prop: 'deliveryOrderSn', label: '发货单号', width: '140px', align: 'left' },
{ prop: 'deliverTime', label: '发货时间', width: '160px', align: 'left' },
{ prop: 'receiveTime', label: '收货时间', width: '160px', align: 'left' }
],
isLoading: false,
tableData: [],
jsonFields: {
"备货单创建时间": "purchaseTime",
"备货单号": "subPurchaseOrderSn",
"商品名称": "productName",
"商品图片": "productSkcPicture",
"状态": "status",
"SKC ID": "productSkcId",
"SKC货号": "skcExtCode",
"SKU ID": "productSkuId",
"SKU货号": "extCode",
"SKU属性": "specName",
"申报价格(CNY)": "supplierPrice",
"下单数量": "xiadan",
"实际入库数量": "skuNum",
"发货单号": "deliveryOrderSn",
"发货时间": "deliverTime",
"收货时间": "receiveTime"
},
snList: [],
currentIndex: 0
}
},
components: {
JsonExcel
},
methods: {
beforeGetList() {
this.$userCheck(this.form.mallId).then(() => {
}).catch((err) => {
this.form.mallId = ''
})
},
toLoad() {
if (!this.form.mallId) {
Message.error("请选择店铺")
return
}
if (!this.form.date) {
Message.error("请选择时间")
return
}
this.reqData.purchaseTimeFrom = this.form.date[0].getTime()
this.reqData.purchaseTimeTo = this.form.date[1].getTime() + 86400 * 1000
this.reqData.pageNo = 1
this.reqData.statusList = this.form.status
this.tableData = []
this.packageNumber = 0
this.snList = []
this.currentIndex = 0
this.isLoading = true
this.load()
},
load() {
sendChromeAPIMessage({
url: 'oms/bg/venom/api/supplier/purchase/manager/querySubOrderList',
needMallId: true,
mallId: this.form.mallId,
anti: true,
data: this.reqData}).then((res) => {
if (res.errorCode == 1000000) {
for(let i = 0;i < res.result.subOrderForSupplierList.length; i++) {
let item = res.result.subOrderForSupplierList[i];
let data = {};
data.purchaseTime = timestampToTime(item.purchaseTime)
data.subPurchaseOrderSn = item.subPurchaseOrderSn
data.productName = item.productName
data.productSkcPicture = item.productSkcPicture
data.productSkcId = item.productSkcId
data.skcExtCode = item.productSn
data.status = this.options.filter(i => {return i.value == item.status})[0].label
data.deliveryOrderSn = item.deliverInfo.deliveryOrderSn
data.deliverTime = timestampToTime(item.deliverInfo.deliverTime)
data.receiveTime = timestampToTime(item.deliverInfo.receiveTime)
for(let k = 0; k < item.skuQuantityDetailList.length; k++) {
data = {...data,
productSkuId: item.skuQuantityDetailList[k].productSkuId,
specName: item.skuQuantityDetailList[k].className,
extCode: item.skuQuantityDetailList[k].extCode,
supplierPrice: item.skuQuantityDetailList[k].supplierPrice / 100,
xiadan: item.skuQuantityDetailList[k].deliverQuantity,
skuNum: item.skuQuantityDetailList[k].realReceiveAuthenticQuantity}
this.tableData.push(data)
}
}
if (this.reqData.pageNo == 1 && res.result.subOrderForSupplierList.length == 0) {
this.isLoading = false
}
else if (res.result.subOrderForSupplierList.length == 100) {
this.reqData.pageNo ++
this.load()
} else {
this.isLoading = false
}
}
})
}
}
}
</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>

View File

@@ -599,7 +599,7 @@
data: {
"subPurchaseOrderSn": sn
}}).then((res) => {
if (res.errorCode == 1000000) {
if (res.errorCode == 1000000 && res.result.isSuccess) {
for (let j = 0; j < this.choosedList.length; j++) {
if (this.choosedList[j].subPurchaseOrderSn == sn) {
this.successList.push(this.choosedList[j])

View File

@@ -91,8 +91,10 @@ import { Message } from 'element-ui'
{ prop: 'productSpuId', label: 'SPU', width: '120px', align: 'left', fixed: 'left' },
{ prop: 'productSkcId', label: 'SKC', width: '120px', align: 'left', fixed: 'left' },
{ prop: 'productSkuId', label: 'SKU', width: '120px', align: 'left', fixed: 'left' },
{ prop: 'skuExtCode', label: 'SKU属性', width: '120px', align: 'left', fixed: 'left' },
{ slot: 'productName', label: '商品信息' },
{ prop: 'purchaseSubOrderSn', label: '备货单号',width: '180px', align: 'left' },
{ prop: 'expressDeLiverySn', label: '运单号',width: '180px', align: 'left' },
{ prop: 'orderTypeDesc', label: '退货原因',width: '220px', align: 'left' },
{ prop: 'packageSn', label: '退货包裹号', width: '200px',align: 'left' },
{ prop: 'quantity', label: 'SKU件数',width: '100px', },
@@ -102,9 +104,11 @@ import { Message } from 'element-ui'
"SPU": "productSpuId",
"SKC": "productSkcId",
"SKU": "productSkuId",
"SKU属性": "skuExtCode",
"图片地址": "thumbUrl",
"属性集": "secondarySaleSpec",
"备货单号": "purchaseSubOrderSn",
"运单号": "expressDeLiverySn",
"退货原因": "orderTypeDesc",
"退货包裹号": "packageSn",
"SKU件数": "quantity",
@@ -210,6 +214,8 @@ import { Message } from 'element-ui'
this.currentPage = 1
this.getList(startTimeTemp, endTimeTemp)
} else {
this.getDeliverySn(1)
this.getSkuExtCode(1)
this.isLoading = false
}
}
@@ -222,6 +228,66 @@ import { Message } from 'element-ui'
this.isLoading = false
})
},
async getDeliverySn(pageNo) {
let arr = []
this.tableData.map(item => {
if (arr.indexOf(item.packageSn) == -1) {
arr.push(item.packageSn)
}
})
let res1 = await sendChromeAPIMessage({
url: 'dunland/api/gmp/returnSupplier/package/pageQueryReturnSupplierPackage',
needMallId: true,
mallId: this.form.mallId,
data: {
pageNo: pageNo,
pageSize: 100,
returnSupplierPackageNos: arr
}})
if (res1.success) {
res1.result.items.map(item => {
for (let i = 0; i < this.tableData.length; i++) {
if (this.tableData[i].packageSn == item.returnSupplierPackageNo) {
this.tableData[i].expressDeLiverySn = item.expressDeLiverySn
}
}
})
}
this.tableData = JSON.parse(JSON.stringify(this.tableData))
if (res1.result.items.length == 100) {
await getDeliverySn(pageNo + 1)
}
},
async getSkuExtCode(pageNo) {
let arr = []
this.tableData.map(item => {
if (arr.indexOf(item.productSkuId) == -1) {
arr.push(item.productSkuId)
}
})
let res1 = await sendChromeAPIMessage({
url: 'bg-visage-mms/labelcode/pageQuery',
needMallId: true,
mallId: this.form.mallId,
data: {
page: pageNo,
pageSize: 100,
productSkuIdList: arr
}})
if (res1.success) {
res1.result.pageItems.map(item => {
for (let i = 0; i < this.tableData.length; i++) {
if (this.tableData[i].productSkuId == item.labelCodeVO.productSkuId) {
this.tableData[i].skuExtCode = item.labelCodeVO.skuExtCode
}
}
})
}
this.tableData = JSON.parse(JSON.stringify(this.tableData))
if (res1.result.pageItems.length == 100) {
await getSkuExtCode(pageNo + 1)
}
},
startDownload() {
this.$http.post('/api/malluser/info').then(res => {
if (res.code == 0) {