This commit is contained in:
liushiwei
2023-12-16 22:56:15 +08:00
parent fa57f0fa99
commit 0a7f8eb036
14 changed files with 281 additions and 111 deletions

BIN
src/assets/off.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
src/assets/right.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

View File

@@ -143,6 +143,7 @@ export default {
},
handleClose() {
this.copyFromDlgShow = false
this.addGroupDlgShow = false
},
handleSuccess() {
this.copyFromDlgShow = false

View File

@@ -49,12 +49,12 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
new Promise((resolve) => {
let headers = {};
headers['Content-Type'] = 'text/html';
headers.cookie = getTemuCookie();
//headers.cookie = getTemuCookie();
Promise.resolve().then(() => fetch(request.url, {
'headers': headers,
'method': 'GET',
'referrerPolicy': 'no-referrer',
'credentials': 'include',
//'credentials': 'include',
'mode': 'cors'
})).then((res) => {
// 创建了一个数据读取器

View File

@@ -35,10 +35,6 @@
"id": "1",
"enabled": true,
"path": "rules_1.json"
},{
"id": "2",
"enabled": true,
"path": "rules_2.json"
}]
},
"content_scripts": [

View File

@@ -2,7 +2,7 @@
"manifest_version": 3,
"name": "TEMU助手",
"description": "TEMU助手 - 自动化提高生产效率",
"version": "3.1.1",
"version": "3.1.3",
"background": {
"service_worker": "/background.js"
},
@@ -35,10 +35,6 @@
"id": "1",
"enabled": true,
"path": "rules_1.json"
},{
"id": "2",
"enabled": true,
"path": "rules_2.json"
}]
},
"content_scripts": [

View File

@@ -3,7 +3,7 @@
<ai-list class="list">
<ai-title
slot="title"
title="商品列表"
:title="'关键字('+`${content}` + ')商品列表'"
isShowBottomBorder isShowBack @onBackClick="cancel(false)">
</ai-title>
<template slot="content">
@@ -42,7 +42,10 @@
<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 style="display: inline">日均销量: <span style="color: red; font-weight: bold">{{ item.averageSale }}</span></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>
@@ -86,6 +89,7 @@ import AiProductDropDown from '@/components/AiProductDropDown.vue';
data () {
return {
monitorId: '',
content: '',
search: {
current: 1,
type: '1',
@@ -111,6 +115,15 @@ import AiProductDropDown from '@/components/AiProductDropDown.vue';
},{
value: '4',
label: '按日均销量排序'
},{
value: '5',
label: '按近3次采集平均销售量排序'
},{
value: '6',
label: '按近7次采集平均销售量排序'
},{
value: '7',
label: '按近15次采集平均销售量排序'
}],
tableData: [],
total: 0,
@@ -121,6 +134,7 @@ import AiProductDropDown from '@/components/AiProductDropDown.vue';
created () {
this.monitorId = this.params.id
this.content = this.params.content
this.getList()
},

View File

@@ -32,7 +32,7 @@
<el-button type="text" @click="deleteMonitor(row.id)">删除</el-button>
<el-button type="text" @click="toUpdateMonitor(row)">修改</el-button>
<el-button type="text" @click="renew(row.id)">续费</el-button>
<el-button type="text" @click="toDetail(row.id)">详情</el-button>
<el-button type="text" @click="toDetail(row.id, row.content)">详情</el-button>
<el-button type="text" @click="toBegin(row)">采集数据</el-button>
</div>
</template>
@@ -298,11 +298,12 @@ import { Message } from 'element-ui'
})
})
},
toDetail (id) {
toDetail (id, content) {
this.$emit('change', {
type: 'Detail',
params: {
id: id || ''
id: id || '',
content: content
}
})
},

View File

@@ -1,12 +1,14 @@
<template>
<div>
<ai-list class="list" v-loading="isLoading" element-loading-text="拼命加载中">
<ai-list class="list" v-loading="isLoading" :element-loading-text="loadingText">
<ai-title
slot="title"
title="上架新品"
isShowBottomBorder>
<template #rightBtn>
<div class="title-right">
<el-checkbox v-model="isMutiSelect">开启多选</el-checkbox>&nbsp;
<el-button type="primary" round @click="toAddToGroup" v-if="isMutiSelect">加入分组</el-button>
上次更新时间{{ lastUpdateTime }}
<div>
<el-button type="button" :class="'el-button el-button--primary'" @click="beginSync">同步</el-button>
@@ -27,7 +29,16 @@
<template slot="content">
<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' }">
<el-image :src="item.imgUrl" class="image" :preview-src-list="[item.imgUrl]" />
<div :class="[{'img-background': item.isSelect}, 'img-box']" @click="onGoodsSelect(item)">
<div>
<el-image v-if="isMutiSelect" :src="item.imgUrl" :class="[{'mask': item.isSelect}, 'image']" />
<el-image v-else :src="item.imgUrl" class="image" :preview-src-list="[item.imgUrl]" />
</div>
<span class="icon-box" v-if="item.isSelect && isMutiSelect">
<img style="width: 20px; height: 20px" src="../../../../../assets/right.png">
</span>
</div>
<div style="padding: 14px;">
<div class="bottom clearfix">
<div style="margin-bottom: 5px;">
@@ -65,6 +76,31 @@
<el-button type="primary" @click="gotoValid">前往验证</el-button>
</div>
</ai-dialog>
<ai-dialog
title="添加到分组"
:visible.sync="addGroupDlgShow"
:close-on-click-modal="false"
width="790px"
customFooter
:append-to-body="true"
@close="addGroupDlgShow = false">
<el-form class="ai-form" :model="addGroupForm" label-width="120px" ref="addGroupForm">
<el-form-item label="分组" style="width: 100%;" prop="groupId" :rules="[{ required: true, message: '请选择分组', trigger: 'blur' }]">
<el-select style="width: 380px" v-model="addGroupForm.groupId" placeholder="请选择分组">
<el-option
v-for="item in groupList"
:key="item.id"
:label="item.name"
:value="item.id">
</el-option>
</el-select>
</el-form-item>
</el-form>
<div class="dialog-footer" slot="footer">
<el-button @click="addGroupDlgShow = false">取消</el-button>
<el-button type="primary" @click="addToGroup">确定</el-button>
</div>
</ai-dialog>
</div>
</template>
@@ -110,7 +146,16 @@ import { Message } from 'element-ui'
lastUpdateTime: '',
treeNode: null,
treeResolve: null
treeResolve: null,
loadingText: '拼命加载中',
isMutiSelect: false,
addGroupDlgShow: false,
addGroupForm: {
groupId: '',
goodsId: ''
},
groupList: []
}
},
@@ -155,6 +200,7 @@ import { Message } from 'element-ui'
})
},
beginSync() {
this.loadingText = '拼命加载中'
this.isLoading = true
this.offset = 0
this.getNewProductData()
@@ -223,6 +269,7 @@ import { Message } from 'element-ui'
this.getLastUpdateTime()
return
}
this.loadingText = `正在采集第(${this.currentIndex}/${this.goodsList.length})个商品的分类信息`
let res1 = null
let opts = null
if (this.isOptApi) {
@@ -289,6 +336,9 @@ import { Message } from 'element-ui'
size: this.form.size
}
}).then(res => {
res.data.records.map(item => {
item.isSelect = false
})
this.tableData = res.data.records
this.total = res.data.total
})
@@ -300,7 +350,41 @@ import { Message } from 'element-ui'
},
gotoValid() {
window.open(this.errorUrl, '_blank');
}
},
onGoodsSelect(item) {
item.isSelect = !item.isSelect
},
toAddToGroup() {
let goodsObj = this.tableData.filter(item => {
return item.isSelect
})
if (goodsObj.length > 0) {
let goodsIds = goodsObj.map(i => {
return i.goodsId
})
this.$http.post('/api/newProductGroup/myPage?size=1000').then(res => {
if (res.code == 0) {
this.addGroupDlgShow = true
this.addGroupForm.goodsId = goodsIds.join(',')
this.groupList = res.data.records
}
})
} else {
Message.error("请选择商品")
}
},
addToGroup() {
this.$refs.addGroupForm.validate((valid) => {
if (valid) {
this.$http.post('/api/newProductGroupDetail/add', {...this.addGroupForm}).then(res => {
if (res.code == 0) {
this.addGroupDlgShow = false
Message.success("商品成功添加到分组")
}
})
}
})
}
}
}
</script>
@@ -409,4 +493,36 @@ import { Message } from 'element-ui'
.el-icon-arrow-down {
font-size: 12px;
}
.img-box {
display: flex;
justify-content: center;
align-items: center;
//父级设置 相对定位,让 icon设置绝对定位时能够以该父级为准。
position: relative;
// icon 设置 绝对定位 让其固定在你想要的合适位置。 样式可调整,自己定位即可。
.icon-box {
position: absolute;
top: 35%;
}
}
.mask {
background-color: #000;
opacity: 0.6;
.el-image__inner {
opacity: 0.6;
}
}
::v-deep .mask > img {
opacity: 0.6;
}
.el-icon {
display: inline-block;
}
</style>

View File

@@ -3,7 +3,7 @@
<ai-list class="list">
<ai-title
slot="title"
title="商品列表"
:title="'店铺ID(' + `${content}` + ')商品列表'"
isShowBottomBorder isShowBack @onBackClick="cancel(false)">
</ai-title>
<template slot="content">
@@ -28,6 +28,8 @@
<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>
@@ -35,7 +37,15 @@
</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' }">
<span class="nav-label labelBadge">
<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>
@@ -46,7 +56,10 @@
<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 style="display: inline">日均销量: <span style="color: red; font-weight: bold">{{ item.averageSale }}</span></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>
@@ -88,6 +101,7 @@ import AiProductDropDown from '@/components/AiProductDropDown.vue';
data () {
return {
monitorId: '',
content: '',
search: {
current: 1,
type: '1',
@@ -97,7 +111,8 @@ import AiProductDropDown from '@/components/AiProductDropDown.vue';
priceEnd: '',
saleBegin: '',
saleEnd: '',
isNew: ''
isNew: '',
isOff: ''
},
orderBys: [{
value: '0',
@@ -114,6 +129,15 @@ import AiProductDropDown from '@/components/AiProductDropDown.vue';
},{
value: '4',
label: '按日均销量排序'
},{
value: '5',
label: '按近3次采集平均销售量排序'
},{
value: '6',
label: '按近7次采集平均销售量排序'
},{
value: '7',
label: '按近15次采集平均销售量排序'
}],
tableData: [],
total: 0,
@@ -125,6 +149,7 @@ import AiProductDropDown from '@/components/AiProductDropDown.vue';
created () {
this.$dict.load('mall_yesno');
this.monitorId = this.params.id
this.content = this.params.content
this.getList()
},
@@ -237,4 +262,37 @@ import AiProductDropDown from '@/components/AiProductDropDown.vue';
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

@@ -32,7 +32,7 @@
<el-button type="text" @click="deleteMonitor(row.id)">删除</el-button>
<el-button type="text" @click="toUpdateMonitor(row)">修改</el-button>
<el-button type="text" @click="renew(row.id)">续费</el-button>
<el-button type="text" @click="toDetail(row.id)">详情</el-button>
<el-button type="text" @click="toDetail(row.id, row.content)">详情</el-button>
<el-button type="text" @click="toBegin(row)">采集数据</el-button>
</div>
</template>
@@ -289,11 +289,12 @@ import {sendTemuAPIMessage} from '@/api/chromeApi'
})
})
},
toDetail (id) {
toDetail (id, content) {
this.$emit('change', {
type: 'Detail',
params: {
id: id || ''
id: id || '',
content: content
}
})
},

View File

@@ -92,7 +92,9 @@ import { Message } from 'element-ui'
packageNumber: 0,
lastSyncDate: '',
totalDelivery: 0,
lastDeliveryTimestamp: 0
lastDeliveryTimestamp: 0,
deliveryOrderList: []
}
},
@@ -160,7 +162,7 @@ import { Message } from 'element-ui'
}).then(res => {
if (res.code === 0) {
this.lastDeliveryTimestamp = res.data?.lastDeliveryTime
this.getList()
this.toGetList()
} else {
this.isLoading = false
Message.error("同步发货单失败")
@@ -181,103 +183,88 @@ import { Message } from 'element-ui'
}
})
},
getList () {
toGetList() {
let data = {
"pageNo": this.currentPage,
"pageSize": this.pageSize,
"status": 2
pageNo: 1,
pageSize: 100,
status: 2
}
if (this.lastDeliveryTimestamp) {
data.deliverTimeFrom = this.lastDeliveryTimestamp * 1000
data.deliverTimeTo = Date.now()
data.deliverTimeTo = data.deliverTimeFrom + 30 * 86400 * 1000
}
sendChromeAPIMessage({
this.getList(data)
},
async getList (data) {
let res = await sendChromeAPIMessage({
url: 'bgSongbird-api/supplier/deliverGoods/management/pageQueryDeliveryOrders',
needMallId: true,
mallId: this.search.mallId,
anti: true,
data: data}).then((res) => {
if (res.errorCode == 1000000) {
let list = []
for(let i = 0;i < res.result.list.length; i++) {
let item = res.result.list[i];
let data = {};
data.id = item.deliveryOrderSn
data.productName = item.subPurchaseOrderBasicVO.productName;
data.mallId = this.search.mallId
data.skcId = item.subPurchaseOrderBasicVO.productSkcId;
data.skcExtCode = item.subPurchaseOrderBasicVO.skcExtCode;
data.logisticName = item.expressCompany
data.logisticNumber = item.expressDeliverySn
data.totalNumber = item.deliverSkcNum
data.deliveryTime = timestampToTime(item.deliverTime)
data: data})
list.push(data)
if (res.errorCode == 1000000) {
let list = []
for(let i = 0;i < res.result.list.length; i++) {
let item = res.result.list[i];
let data = {};
data.id = item.deliveryOrderSn
data.productName = item.subPurchaseOrderBasicVO.productName;
data.mallId = this.search.mallId
data.skcId = item.subPurchaseOrderBasicVO.productSkcId;
data.skcExtCode = item.subPurchaseOrderBasicVO.skcExtCode;
data.logisticName = item.expressCompany
data.logisticNumber = item.expressDeliverySn
data.totalNumber = item.deliverSkcNum
data.deliveryTime = timestampToTime(item.deliverTime)
this.packageNumber = this.packageNumber + item.receivePackageNum
setTimeout(() => {
this.getSkuDetailList(data.id)
}, 200 * i)
}
list.push(data)
this.$http.post('/api/deliveryOrder/add',list).then(res => {
console.log(res)
})
let res1 = await sendChromeAPIMessage({
url: 'bgSongbird-api/supplier/deliverGoods/management/queryDeliveryOrderPackageDetailInfo',
needMallId: true,
mallId: this.search.mallId,
anti: true,
data: {deliveryOrderSn: data.id}})
if (res1.errorCode == 1000000) {
let tempList = []
for(let i = 0;i < res1.result.deliveryOrderDetails.length; i++) {
let item1 = res1.result.deliveryOrderDetails[i]
if (this.pageSize == res.result.list.length) {
this.currentPage ++
setTimeout(() => {
this.getList()
}, 1500)
} else {
if (this.currentPage == 1 && res.result.list.length == 0) {
this.isLoading = false
let data1 = {}
data1.deliveryOrderId = data.id
data1.productSkuId = item1.productSkuId
data1.productSkuNumber = item1.deliverSkuNum
tempList.push(data1)
}
this.end()
await this.$http.post('/api/deliveryOrderDetail/add',tempList)
}
} else {
setTimeout(() => {
this.getList()
}, 1500)
}
}).catch(() => {
Message.error("同步发货单失败")
if (list.length > 0) {
await this.$http.post('/api/deliveryOrder/add',list)
}
if (data.pageSize == res.result.list.length) {
data.pageNo ++
this.getList(data)
return
} else if (data.deliverTimeFrom && (Date.now() > (data.deliverTimeFrom + 30 * 86400 * 1000))) {
data.deliverTimeFrom = data.deliverTimeFrom + 30 * 86400 * 1000
data.deliverTimeTo = data.deliverTimeFrom + 30 * 86400 * 1000
data.pageNo = 1
this.getList(data)
return
}
this.isLoading = false
})
},
getSkuDetailList(sn) {
sendChromeAPIMessage({
url: 'bgSongbird-api/supplier/deliverGoods/management/queryDeliveryOrderPackageDetailInfo',
needMallId: true,
mallId: this.search.mallId,
anti: true,
data: {deliveryOrderSn: sn}}).then((res) => {
if (res.errorCode == 1000000) {
let list = []
for(let i = 0;i < res.result.deliveryOrderDetails.length; i++) {
let item = res.result.deliveryOrderDetails[i]
let data = {}
data.deliveryOrderId = sn
data.productSkuId = item.productSkuId
data.productSkuNumber = item.deliverSkuNum
list.push(data)
}
this.packageNumber = this.packageNumber - res.result.deliveryOrderDetails.length
console.log(this.packageNumber)
if (this.packageNumber < 10) {
this.isLoading = false
this.getInfo()
}
this.$http.post('/api/deliveryOrderDetail/add',list)
} else {
setTimeout(() => {
this.getSkuDetailList(sn)
}, 200)
}
})
this.end()
} else {
setTimeout(() => {
this.getList()
}, 1500)
}
}
}
}

View File

@@ -164,7 +164,7 @@ import { Message } from 'element-ui'
if (startTime < this.form.date[0].getTime()) {
startTime = this.form.date[0].getTime()
}
this.getList(startTime, this.form.date[1].getTime() - 1)
this.getList(startTime, this.form.date[1].getTime() + 86400*1000 - 1)
},
getList (startTime, endTime) {
sendChromeAPIMessage({

View File

@@ -172,7 +172,7 @@ import { Message } from 'element-ui'
data: {
pageNo: this.currentPage,
pageSize: 100,
packageTimeEnd: this.form.date[1].getTime() - 1,
packageTimeEnd: this.form.date[1].getTime() + 86400*1000 - 1,
packageTimeStart: this.form.date[0].getTime()
}}).then((res) => {
if (res.errorCode == 1000000) {