调整
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-alert
|
||||
title="采集一个商品添加进草稿箱,将消耗50金币"
|
||||
title="采集一个商品添加进草稿箱,将消耗20金币"
|
||||
type="success"
|
||||
:closable="false" style="margin-bottom: 10px;">
|
||||
</el-alert>
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"manifest_version": 3,
|
||||
"name": "TEMU助手",
|
||||
"description": "TEMU助手 - 自动化提高生产效率",
|
||||
"version": "3.1.5",
|
||||
"version": "3.1.6",
|
||||
"background": {
|
||||
"service_worker": "/background.js"
|
||||
},
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
64
src/view/selection/singletrack/Index.vue
Normal file
64
src/view/selection/singletrack/Index.vue
Normal 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>
|
||||
|
||||
298
src/view/selection/singletrack/components/Detail.vue
Normal file
298
src/view/selection/singletrack/components/Detail.vue
Normal 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>
|
||||
406
src/view/selection/singletrack/components/List.vue
Normal file
406
src/view/selection/singletrack/components/List.vue
Normal 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>
|
||||
302
src/view/selection/singletrack/components/SheinDetail.vue
Normal file
302
src/view/selection/singletrack/components/SheinDetail.vue
Normal 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>
|
||||
249
src/view/shipping/MyOrder.vue
Normal file
249
src/view/shipping/MyOrder.vue
Normal 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>
|
||||
<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>
|
||||
@@ -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])
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user