From 25ba3eb387ebfb365782d5355aa76f5500c4c621 Mon Sep 17 00:00:00 2001 From: liushiwei <499672082@qq.com> Date: Wed, 7 Aug 2024 14:46:26 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/js/temuSeller.js | 80 +++++- src/manifest.production.json | 2 +- src/router/index.js | 15 ++ src/utils/index.js | 5 + src/view/Home.vue | 5 +- src/view/Welcome.vue | 12 +- src/view/sale/AfterSaleDeductStat.vue | 2 +- src/view/sale/ExportSaleData.vue | 3 +- src/view/sale/ExportSaleStatTemu.vue | 2 +- src/view/sale/PriceAdjustment.vue | 256 ++++++++++++++++++++ src/view/shein/ExportSaleDataShein.vue | 121 ++++++--- src/view/shein/ExportSaleStatShein.vue | 23 +- src/view/shein/OrderListShein.vue | 323 +++++++++++++++++++++++++ src/view/shein/ReturnRecordShein.vue | 265 ++++++++++++++++++++ 14 files changed, 1066 insertions(+), 48 deletions(-) create mode 100644 src/view/sale/PriceAdjustment.vue create mode 100644 src/view/shein/OrderListShein.vue create mode 100644 src/view/shein/ReturnRecordShein.vue 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 @@ 售罄看板 售后统计 售后赔付统计 + 调价管理 @@ -146,6 +147,8 @@ 销售数据 证书中心 商品复制 + 发货订单 + 退货与报废单列表 商家账单统计 @@ -188,7 +191,7 @@ :close-on-click-modal="false" width="1200"> 1、检查“SHEIN商家后台”是否登录,如没登录,请先登录,之后再刷新助手 - 2、如果SHEIN商家后台已经登录,仍然弹出当前窗口,则需要SHEIN进行二次授权,二次授权可在菜单“商品管理->商品列表”,任意选择一个商品,在“价格”一栏,点击修改,在新打开的页面中可看到“正在鉴权”的字样,即可完成二次授权 + 2、如果SHEIN商家后台已经登录,仍然弹出当前窗口,则需要SHEIN进行二次授权,二次授权可在菜单“商品管理->商品列表”,任意选择一个商品,在“库存”一栏,点击修改,在新打开的页面中可看到“正在鉴权”的字样,即可完成二次授权 关 闭 diff --git a/src/view/Welcome.vue b/src/view/Welcome.vue index a277dc8..05cfe93 100644 --- a/src/view/Welcome.vue +++ b/src/view/Welcome.vue @@ -311,7 +311,7 @@ import BiVueMindmap from "bi-vue-mindmap"; { id: "01020102", parentId: "010201", - title: "销售管理:对应SHEIN商家后台“商品管理”->“备货信息”,统计当天的销售额、销量、库存等信息,计算成本和利润" + title: "销售管理:对应SHEIN商家后台“商品管理”->“备货信息(新)”,统计当天的销售额、销量、库存等信息,计算成本和利润" }, { id: "01020103", @@ -326,6 +326,16 @@ import BiVueMindmap from "bi-vue-mindmap"; { id: "01020105", parentId: "010201", + title: "发货订单:对应SHEIN商家后台“订单管理”->“发货订单”,提供急采/备货订单的导出,同时带上成本价格,方便对账与结算" + }, + { + id: "01020106", + parentId: "010201", + title: "退货与报废单列表:对应SHEIN商家后台“质量管理”->“退货与报废单列表”,提供退货订单明细的导出,同时带上成本价格,方便对账与结算" + }, + { + id: "01020107", + parentId: "010201", title: "商家账单统计:对应SHEIN商家后台“财务管理”->“商家账单”,统计一段时期内销售额、单量、成本、利润、利润率,SKC/SKU维度统计排名,支持导出" }, ], diff --git a/src/view/sale/AfterSaleDeductStat.vue b/src/view/sale/AfterSaleDeductStat.vue index 5f2a42a..5710a75 100644 --- a/src/view/sale/AfterSaleDeductStat.vue +++ b/src/view/sale/AfterSaleDeductStat.vue @@ -136,7 +136,7 @@ import JsonExcel from 'vue-json-excel' this.isLoading = true let startTime = this.searchDate[0].getTime() - let endTime = this.searchDate[1].getTime() + let endTime = this.searchDate[1].getTime() + 86400000 while(true) { if ((endTime - startTime) > 2592000000) { this.reqData.pageNum = 1 diff --git a/src/view/sale/ExportSaleData.vue b/src/view/sale/ExportSaleData.vue index cc42c37..1bcf22b 100644 --- a/src/view/sale/ExportSaleData.vue +++ b/src/view/sale/ExportSaleData.vue @@ -216,7 +216,7 @@ import { Message } from 'element-ui' mallName: '', type: '0', isLoading: false, - pageSize: 100, + pageSize: 50, currentPage: 1, todayTotal: 0, todayMoney: 0.0, @@ -727,6 +727,7 @@ import { Message } from 'element-ui' sendChromeAPIMessage({ url: 'marvel-mms/cn/api/kiana/venom/sales/management/listWarehouse', needMallId: true, + anti: true, mallId: this.mallId, data: { pageNo: this.currentPage, diff --git a/src/view/sale/ExportSaleStatTemu.vue b/src/view/sale/ExportSaleStatTemu.vue index 9651ebf..e3b7b27 100644 --- a/src/view/sale/ExportSaleStatTemu.vue +++ b/src/view/sale/ExportSaleStatTemu.vue @@ -319,7 +319,7 @@ import { DualAxes } from '@antv/g2plot' dateRange: null, currentPage: 1, - pageSize: 100, + pageSize: 50, productList: [], productCostList: [], saleAmount: 0.0, diff --git a/src/view/sale/PriceAdjustment.vue b/src/view/sale/PriceAdjustment.vue new file mode 100644 index 0000000..a1da4a9 --- /dev/null +++ b/src/view/sale/PriceAdjustment.vue @@ -0,0 +1,256 @@ + + + + + + + 店铺: + + + + + + + + + + + + + + 起始页: + + + + 结束页: + + + + + 加载 + + + + + + 下载数据 + + + {}"> + + + + + + {{ scope.row.productName }} + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/view/shein/ExportSaleDataShein.vue b/src/view/shein/ExportSaleDataShein.vue index 650f3c6..5d79718 100644 --- a/src/view/shein/ExportSaleDataShein.vue +++ b/src/view/shein/ExportSaleDataShein.vue @@ -49,6 +49,9 @@ 只显示今日有销量 + + 导出数据 + { @@ -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 @@ - + - - {{ saleAmount }}/{{ saleCount }} - - + + + + + + + - + - + + + + + + + 订单状态: + + + + + + + 下单时间: + + + + 查询 + + + + + + + + 急采 + 备货 + + + + + + + + 导出 + + {}"> + + + + + + + + + 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 @@ + + + + + + + 创建时间: + + + + 查询 + + + + + + + 导出 + + {}"> + + + + + + + + +