diff --git a/public/js/temuSeller.js b/public/js/temuSeller.js index 1ccfa80..0d5ea95 100644 --- a/public/js/temuSeller.js +++ b/public/js/temuSeller.js @@ -42,8 +42,49 @@ function init() { flag = true } } + + const regex = /price-adjust-confirm[^\n]+content/ + let modelsAll = document.querySelectorAll('div[class*="price-adjust-confirm"]') + const results = Array.from(modelsAll).filter(item => regex.test(item.getAttribute('class'))) + + for (let i = 0; i < results.length; i++) { + let tipsObj = results[i].querySelector('div[class*="_tips"]') + let spanObj = tipsObj.querySelector('div span:last-child') + if (spanObj) { + const popup = document.createElement("div") + popup.innerText = "拒绝调价" + const styles = { + padding: "8px", + background: "#fb7701", + color: "#fff", + display: 'inline', + borderRadius: "8px", + cursor: "pointer" + } + for (const e in styles) { + popup.style[e] = styles[e] + } + spanObj.appendChild(popup) + + popup.addEventListener('click', async () => { + let tbodyObj = results[i].querySelector('tbody') + let trList = tbodyObj.querySelectorAll('tr') + for (let i = 0; i < trList.length; i++) { + let tdObj = trList[i].querySelector('td:last-child') + let firstLabelObj = tdObj.querySelector('div label:first-child') + if (firstLabelObj.getAttribute("data-checked")) { + let labelObj = tdObj.querySelector('div label:nth-child(2)') + let radioObj = labelObj.querySelector('div[class^="RD_radioWrapper"]') + // await sleepSync(50) + radioObj.click() + } + } + }) + flag = true + } + } - let models2 = document.querySelectorAll('div[class^="price-adjust-confirm-system_contentWrp"]') + /*let models2 = document.querySelectorAll('div[class^="price-adjust-confirm-system_contentWrp"]') for (let i = 0; i < models2.length; i++) { let tipsObj = models2[i].querySelector('div[class^="price-adjust-confirm-system_tips"]') let spanObj = tipsObj.querySelector('div span:last-child') @@ -194,6 +235,43 @@ function init() { flag = true } } + let models6 = document.querySelectorAll('div[class^="grape-price-adjust-confirm_content"]') + for (let i = 0; i < models6.length; i++) { + let tipsObj = models6[i].querySelector('div[class^="grape-price-adjust-confirm_tips"]') + let spanObj = tipsObj.querySelector('div span:last-child') + if (spanObj) { + const popup = document.createElement("div") + popup.innerText = "拒绝调价" + const styles = { + padding: "8px", + background: "#fb7701", + color: "#fff", + display: 'inline', + borderRadius: "8px", + cursor: "pointer" + } + for (const e in styles) { + popup.style[e] = styles[e] + } + spanObj.appendChild(popup) + + popup.addEventListener('click', async () => { + let tbodyObj = models6[i].querySelector('tbody') + let trList = tbodyObj.querySelectorAll('tr') + for (let i = 0; i < trList.length; i++) { + let tdObj = trList[i].querySelector('td:last-child') + let firstLabelObj = tdObj.querySelector('div label:first-child') + if (firstLabelObj.getAttribute("data-checked")) { + let labelObj = tdObj.querySelector('div label:nth-child(2)') + let radioObj = labelObj.querySelector('div[class^="RD_radioWrapper"]') + // await sleepSync(50) + radioObj.click() + } + } + }) + flag = true + } + }*/ if (flag) { clearInterval(timer) } else { diff --git a/src/manifest.production.json b/src/manifest.production.json index 58bd0bc..7a9efd4 100644 --- a/src/manifest.production.json +++ b/src/manifest.production.json @@ -2,7 +2,7 @@ "manifest_version": 3, "name": "TEMU助手", "description": "TEMU助手 - 自动化提高生产效率", - "version": "3.2.8", + "version": "3.2.11", "background": { "service_worker": "/background.js" }, diff --git a/src/router/index.js b/src/router/index.js index ec7ce2e..26ab376 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -212,6 +212,11 @@ const router = new VueRouter({ name: 'saleStatTemu', component: () => import('../view/sale/ExportSaleStatTemu.vue') }, + { + path: 'priceAdjustment', + name: 'priceAdjustment', + component: () => import('../view/sale/PriceAdjustment.vue') + }, { path: 'costManageShein', name: 'costManageShein', @@ -237,6 +242,16 @@ const router = new VueRouter({ name: 'copyProductShein', component: () => import('../view/shein/CopyProductShein.vue') }, + { + path: 'orderListShein', + name: 'orderListShein', + component: () => import('../view/shein/OrderListShein.vue') + }, + { + path: 'returnRecordShein', + name: 'returnRecordShein', + component: () => import('../view/shein/ReturnRecordShein.vue') + }, // { // path: 'statistics', diff --git a/src/utils/index.js b/src/utils/index.js index 156cf67..9a4a0c0 100644 --- a/src/utils/index.js +++ b/src/utils/index.js @@ -114,9 +114,14 @@ const userCheck = (mallId) => { }) } +const sleepSync = (milliseconds) => { + return new Promise(resolve => setTimeout(resolve, milliseconds)); +} + export default { dict, dateUtil, + sleepSync, userCheck } diff --git a/src/view/Home.vue b/src/view/Home.vue index 8defa4e..e18c3f4 100644 --- a/src/view/Home.vue +++ b/src/view/Home.vue @@ -136,6 +136,7 @@ 售罄看板 售后统计 售后赔付统计 + 调价管理 { @@ -218,57 +221,79 @@ import { Message } from 'element-ui' }, getList () { sendGeiwohuoAPIMessage({ - url: 'gmpj/goods/goods/list', + url: 'idms/goods-skc/list', method: 'POST', data: { - "mallStatusList": [ - 1 - ], - "page": this.currentPage, - "perPage": this.pageSize + "pageNumber": this.currentPage, + "pageSize": this.pageSize, + "supplierCodes": "", + "skcs": "", + "spu": "", + "c7dSaleCntBegin": "", + "c7dSaleCntEnd": "", + "goodsLevelIdList": [], + "supplyStatus": "", + "shelfStatus": "", + "categoryIdList": [], + "skcStockBegin": "", + "skcStockEnd": "", + "skuStockBegin": "", + "skuStockEnd": "", + "skcSaleDaysBegin": "", + "skcSaleDaysEnd": "", + "skuSaleDaysBegin": "", + "skuSaleDaysEnd": "", + "planUrgentCountBegin": "", + "planUrgentCountEnd": "", + "shelfDateBegin": "", + "shelfDateEnd": "", + "stockWarnStatusList": [], + "labelFakeIdList": [], + "tspIdList": [], + "sortBy7dSaleCnt": 2 }}).then((res) => { if (res.code == '0' && res.msg == "OK") { for(let i = 0;i < res.info.list.length; i++) { let item = res.info.list[i]; let data = {}; data.categoryName = item.categoryName - data.goodsThumb = item.goodsThumb - data.mallStatusName = item.mallStatusName + data.goodsThumb = item.picUrl + data.mallStatusName = item.shelfStatus.name data.supplierCode = item.supplierCode data.skc = item.skc - for(let j = 0;j < item.sizes.length; j++) { - let sku = item.sizes[j] - data = {...data, - ableSaleDays: sku.ableSaleDays, - cost: sku.cost, + for(let j = 0;j < item.skuList.length; j++) { + let sku = item.skuList[j] + if (sku.attr == '合计') continue + let temp = {...data, + ableSaleDays: sku.saleDays, + cost: sku.price, skuCode: sku.skuCode, - purchaseConfig: (sku.operateTime?sku.operateTime:'/') + '+' + (sku.prepareDay?sku.prepareDay:'/'), - saleInfoMonth: sku.saleInfoMonth, - saleInfoPreMonth: sku.saleInfoPreMonth, - saleInfoWeek: sku.saleInfoWeek, - suffixZh: sku.suffixZh, - todaySale: sku.todaySale, - onWayNum: sku.onWayNum, - ivtNum: sku.ivtNum, + purchaseConfig: (sku.goodsDate?sku.goodsDate:'/') + '+' + (sku.stockDays?sku.stockDays:'/'), + saleInfoMonth: sku.c30dSaleCnt, + saleInfoWeek: sku.c7dSaleCnt, + suffixZh: sku.attr, + todaySale: sku.totalSaleVolume, + onWayNum: sku.transit, + ivtNum: sku.stock, costPrice: null, todayProfit: null, - productTotalPrice: Math.round((sku.cost * sku.ivtNum)*100)/100, - inroadTotalPrice: Math.round((sku.cost * sku.onWayNum)*100)/100} + productTotalPrice: Math.round((sku.price * sku.stock)*100)/100, + inroadTotalPrice: Math.round((sku.price * sku.transit)*100)/100} - this.todayTotal += sku.todaySale - this.todayMoney += Math.round((sku.cost * sku.todaySale)*100)/100 + this.todayTotal += temp.todaySale + this.todayMoney += Math.round((temp.cost * temp.todaySale)*100)/100 this.todayMoney = Math.round(this.todayMoney * 100) / 100 - this.inventoryTotal += sku.ivtNum - this.inventoryMoney += Math.round((sku.cost * sku.ivtNum)*100)/100 + this.inventoryTotal += temp.ivtNum + this.inventoryMoney += Math.round((temp.cost * temp.ivtNum)*100)/100 this.inventoryMoney = Math.round(this.inventoryMoney*100)/100 - this.inroadTotal += sku.onWayNum - this.inroadTotalMoney += Math.round((sku.cost * sku.onWayNum)*100)/100 + this.inroadTotal += temp.onWayNum + this.inroadTotalMoney += Math.round((temp.cost * temp.onWayNum)*100)/100 this.inroadTotalMoney = Math.round(this.inroadTotalMoney*100)/100 - this.list.push(data); + this.list.push(temp); + } } - if (this.pageSize == res.info.list.length) { this.currentPage ++ setTimeout(() => { @@ -312,6 +337,36 @@ import { Message } from 'element-ui' this.costList = res.data } }, + exportToExcel() { + // 假设你有一个表格数据的数组 + const data = [ + ["图片地址", "货号", "规格", "分类", "状态", "SKC", "可售天数", "价格", "成本", "今日销量", "利润", "近7天销量", "本月销量", "在途数量", "库存数量", "库存货值", "在途货值", "备货逻辑"] + ] + + this.filteredData.map(item => { + data.push([item.goodsThumb, item.supplierCode, item.suffixZh, item.categoryName, item.mallStatusName, item.skc, item.ableSaleDays, item.cost, item.costPrice, item.todaySale, item.todayProfit, item.saleInfoWeek, item.saleInfoMonth, item.onWayNum, item.ivtNum, item.productTotalPrice, item.inroadTotalPrice, item.purchaseConfig]) + }) + + // 将数据转换为工作表 + const worksheet = XLSX.utils.aoa_to_sheet(data); + + // 创建工作簿并添加工作表 + const workbook = XLSX.utils.book_new(); + XLSX.utils.book_append_sheet(workbook, worksheet, 'Sheet1'); + + // 生成Excel文件 + const excelBuffer = XLSX.write(workbook, { bookType: 'xlsx', type: 'array' }); + + // 使用blob和FileReader创建一个Blob URL + const dataBlob = new Blob([excelBuffer], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8' }); + const blobUrl = window.URL.createObjectURL(dataBlob); + + // 使用saveAs下载文件 + saveAs(dataBlob, '销售数据.xlsx'); + + // 清理 + window.URL.revokeObjectURL(blobUrl); + } } } diff --git a/src/view/shein/ExportSaleStatShein.vue b/src/view/shein/ExportSaleStatShein.vue index c67fd5c..ae21801 100644 --- a/src/view/shein/ExportSaleStatShein.vue +++ b/src/view/shein/ExportSaleStatShein.vue @@ -42,18 +42,25 @@
- +
-
- + +
+ + +
+
+
- +
- +
+ + + + + + + + + + + diff --git a/src/view/shein/ReturnRecordShein.vue b/src/view/shein/ReturnRecordShein.vue new file mode 100644 index 0000000..8033043 --- /dev/null +++ b/src/view/shein/ReturnRecordShein.vue @@ -0,0 +1,265 @@ + + + + +