调整
This commit is contained in:
		| @@ -9,6 +9,7 @@ | ||||
|   "dependencies": { | ||||
|     "@antv/g2plot": "^2.4.25", | ||||
|     "axios": "^1.4.0", | ||||
|     "bi-vue-mindmap": "^0.6.12", | ||||
|     "core-js": "^3.8.3", | ||||
|     "crypto-js": "^4.0.0", | ||||
|     "dayjs": "^1.11.9", | ||||
|   | ||||
							
								
								
									
										274
									
								
								public/js/temuSeller.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										274
									
								
								public/js/temuSeller.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,274 @@ | ||||
| function matchTemuDomain(url) { | ||||
|     const urlPattern = /https:\/\/([\da-z\.-]+)\.kuajingmaihuo\.com\// | ||||
|     return urlPattern.test(url); | ||||
| } | ||||
|  | ||||
| function init() { | ||||
|     if (matchTemuDomain(window.location.href)) { | ||||
|         let j = 0 | ||||
|         let timer = setInterval(() => { | ||||
|             let models = document.querySelectorAll('div[class^="MDL_header"]') | ||||
|             let flag = false | ||||
|             for (let i = 0; i < models.length; i++) { | ||||
|                 if (models[i].textContent.includes("商品降价提醒") || models[i].textContent.includes("降价,提升竞争力,避免限制备货")) { | ||||
|                     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] | ||||
|                     } | ||||
|                     models[i].appendChild(popup) | ||||
|                     popup.addEventListener('click', async () => { | ||||
|                         let tbodyObj = models[i].parentElement.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"]') | ||||
|             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') | ||||
|                 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 = models2[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 models3 = document.querySelectorAll('div[class^="price-adjust-confirm-new_content"]') | ||||
|             for (let i = 0; i < models3.length; i++) { | ||||
|                 let tipsObj = models3[i].querySelector('div[class^="price-adjust-confirm-new_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 = models3[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 models4 = document.querySelectorAll('div[class^="price-adjust-confirm-system-old_contentWrp"]') | ||||
|             for (let i = 0; i < models4.length; i++) { | ||||
|                 let tipsObj = models4[i].querySelector('div[class^="price-adjust-confirm-system-old_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 = models4[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 models5 = document.querySelectorAll('div[class^="new-price-adjust-confirm_content"]') | ||||
|             for (let i = 0; i < models5.length; i++) { | ||||
|                 let tipsObj = models5[i].querySelector('div[class^="new-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 = models5[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 { | ||||
|                 j++ | ||||
|                 if (j == 10) { | ||||
|                     clearInterval(timer) | ||||
|                 } | ||||
|             } | ||||
|         }, 3000) | ||||
|          | ||||
|         // document.body.appendChild(popup) | ||||
|     } | ||||
| } | ||||
| /* | ||||
| function createElement() { | ||||
|     const popup = document.createElement("div") | ||||
|     popup.innerText = "拒绝调价" | ||||
|     const styles = { | ||||
|         position: "fixed", | ||||
|         right: '10px', | ||||
|         top: '60px', | ||||
|         zIndex: 999999, | ||||
|         padding: "8px", | ||||
|         background: "#409EFF", | ||||
|         color: "#fff", | ||||
|         borderRadius: "8px", | ||||
|         cursor: "pointer" | ||||
|     } | ||||
|     for (const e in styles) { | ||||
|         popup.style[e] = styles[e] | ||||
|     } | ||||
|     popup.addEventListener('click', async () => { | ||||
|         let divObj1 = document.querySelector('div[class^="price-adjust-confirm-system_contentWrp"]') | ||||
|         if (divObj1) { | ||||
|             let tbodyObj = divObj1.querySelector('tbody') | ||||
|             let trList = tbodyObj.querySelectorAll('tr') | ||||
|             for (let i = 0; i < trList.length; i++) { | ||||
|                 let tdObj = trList[i].querySelector('td:last-child') | ||||
|                 let labelObj = tdObj.querySelector('div label:last-child') | ||||
|                 let radioObj = labelObj.querySelector('div[class^="RD_radioWrapper"]') | ||||
|                 // await sleepSync(50) | ||||
|                 radioObj.click() | ||||
|             } | ||||
|         } | ||||
|         let divObj2 = document.querySelector('div[class^="price-adjust-confirm_header"]') | ||||
|         if (divObj2) { | ||||
|             let divObj = divObj2.nextElementSibling | ||||
|             let tbodyObj = divObj.querySelector('tbody') | ||||
|             let trList = tbodyObj.querySelectorAll('tr') | ||||
|             for (let i = 0; i < trList.length; i++) { | ||||
|                 let tdObj = trList[i].querySelector('td:last-child') | ||||
|                 let labelObj = tdObj.querySelector('div label:last-child') | ||||
|                 //let radioObj = labelObj.querySelector("[type='radio']") | ||||
|                 // await sleepSync(50) | ||||
|                 let radioObj = labelObj.querySelector('div[class^="RD_radioWrapper"]') | ||||
|                 radioObj.click() | ||||
|             } | ||||
|         } | ||||
|         let divObj3 = document.querySelector('div[class^="price-adjust-confirm-new_banner"]') | ||||
|         if (divObj3) { | ||||
|             let divObj = divObj3.nextElementSibling | ||||
|             let tbodyObj = divObj.querySelector('tbody') | ||||
|             let trList = tbodyObj.querySelectorAll('tr') | ||||
|             for (let i = 0; i < trList.length; i++) { | ||||
|                 let tdObj = trList[i].querySelector('td:last-child') | ||||
|                 let labelObj = tdObj.querySelector('div label:last-child') | ||||
|                 //let radioObj = labelObj.querySelector("[type='radio']") | ||||
|                 // await sleepSync(50) | ||||
|                 let radioObj = labelObj.querySelector('div[class^="RD_radioWrapper"]') | ||||
|                 radioObj.click() | ||||
|             } | ||||
|         } | ||||
|     }) | ||||
|  | ||||
|     return popup | ||||
| } | ||||
| */ | ||||
| init() | ||||
							
								
								
									
										8
									
								
								public/js/temuSellerContent.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								public/js/temuSellerContent.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | ||||
| function injectScript(file, node) { | ||||
|   var th = document.getElementsByTagName(node)[0]; | ||||
|   var s = document.createElement('script'); | ||||
|   s.setAttribute('type', 'text/javascript'); | ||||
|   s.setAttribute('src', file); | ||||
|   th.appendChild(s); | ||||
| } | ||||
| injectScript( chrome.runtime.getURL('/js/temuSeller.js'), 'body'); | ||||
| @@ -426,13 +426,14 @@ export default { | ||||
|               content['cat' + (i+1) + 'Id'] = this.form.targetCatId[i] | ||||
|             } | ||||
|           } | ||||
|           if (content['cat'+(i+1)+'Id'] != reqData.catId) { | ||||
|           if (content['cat'+(i)+'Id'] != reqData.catId) { | ||||
|             content['cat'+(++i)+'Id'] = reqData.catId | ||||
|           } | ||||
|           for (; i < 10; i++) { | ||||
|             content['cat' + (i+1) + 'Id'] = '' | ||||
|           } | ||||
|  | ||||
|           content.personalizationSwitch = 0 | ||||
|           content.productDraftId = draftId | ||||
|  | ||||
|           this.createProduct(content) | ||||
|   | ||||
| @@ -8,3 +8,4 @@ function injectScript(file, node) { | ||||
| injectScript( chrome.runtime.getURL('/js/jszip.min.js'), 'body'); | ||||
| injectScript( chrome.runtime.getURL('/js/FileSaver.js'), 'body'); | ||||
| injectScript( chrome.runtime.getURL('/js/download.js'), 'body'); | ||||
| injectScript( chrome.runtime.getURL('/js/temuSeller.js'), 'body'); | ||||
|   | ||||
| @@ -76,12 +76,24 @@ | ||||
|       "js": [ | ||||
|         "/content.js" | ||||
|       ] | ||||
|     }, | ||||
|     { | ||||
|       "matches": [ | ||||
|         "*://*.kuajingmaihuo.com/*" | ||||
|       ], | ||||
|       "js": [ | ||||
|         "/js/temuSellerContent.js" | ||||
|       ] | ||||
|     } | ||||
|   ], | ||||
|   "web_accessible_resources": [ | ||||
|     { | ||||
|       "resources": [ "js/download.js","js/jszip.min.js","js/FileSaver.js" ], | ||||
|       "matches": [ "*://*.aliexpress.com/*", "*://*.amazon.com/*", "*://*.shein.com/*" ] | ||||
|     }, | ||||
|     { | ||||
|       "resources": [ "js/temuSeller.js" ], | ||||
|       "matches": [ "*://*.kuajingmaihuo.com/*" ] | ||||
|     } | ||||
|   ] | ||||
| } | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
|   "manifest_version": 3, | ||||
|   "name": "TEMU助手", | ||||
|   "description": "TEMU助手 - 自动化提高生产效率", | ||||
|   "version": "3.2.3", | ||||
|   "version": "3.2.8", | ||||
|   "background": { | ||||
|     "service_worker": "/background.js" | ||||
|   }, | ||||
| @@ -80,12 +80,24 @@ | ||||
|       "js": [ | ||||
|         "/content.js" | ||||
|       ] | ||||
|     }, | ||||
|     { | ||||
|       "matches": [ | ||||
|         "*://*.kuajingmaihuo.com/*" | ||||
|       ], | ||||
|       "js": [ | ||||
|         "/js/temuSellerContent.js" | ||||
|       ] | ||||
|     } | ||||
|   ], | ||||
|   "web_accessible_resources": [ | ||||
|     { | ||||
|       "resources": [ "js/download.js","js/jszip.min.js","js/FileSaver.js" ], | ||||
|       "matches": [ "*://*.aliexpress.com/*", "*://*.amazon.com/*", "*://*.shein.com/*" ] | ||||
|     }, | ||||
|     { | ||||
|       "resources": [ "js/temuSeller.js" ], | ||||
|       "matches": [ "*://*.kuajingmaihuo.com/*" ] | ||||
|     } | ||||
|   ] | ||||
| } | ||||
|   | ||||
| @@ -65,6 +65,11 @@ const router = new VueRouter({ | ||||
|           name: 'myUrgencyOrder', | ||||
|           component: () => import('../view/shipping/MyUrgencyOrder.vue') | ||||
|         }, | ||||
|         { | ||||
|           path: 'productLabel', | ||||
|           name: 'productLabel', | ||||
|           component: () => import('../view/shipping/ProductLabel.vue') | ||||
|         }, | ||||
|         { | ||||
|           path: 'returnPackage', | ||||
|           name: 'returnPackage', | ||||
| @@ -202,6 +207,11 @@ const router = new VueRouter({ | ||||
|           name: 'afterSaleDeductStat', | ||||
|           component: () => import('../view/sale/AfterSaleDeductStat.vue') | ||||
|         }, | ||||
|         { | ||||
|           path: 'saleStatTemu', | ||||
|           name: 'saleStatTemu', | ||||
|           component: () => import('../view/sale/ExportSaleStatTemu.vue') | ||||
|         }, | ||||
|         { | ||||
|           path: 'costManageShein', | ||||
|           name: 'costManageShein', | ||||
|   | ||||
| @@ -135,6 +135,7 @@ export function transform(leftData) { | ||||
|       countryShortName: leftData.productWhExtAttr.productOrigin ? leftData.productWhExtAttr.productOrigin.countryShortName: 'CN' | ||||
|     } | ||||
|   }; | ||||
|   rightData.personalizationSwitch = leftData.productWhExtAttr.personalizationSwitch || "0" | ||||
|   rightData.productCarouseVideoReqList = leftData.carouseVideoVOList; | ||||
|   rightData.goodsAdvantageLabelTypes = leftData.goodsAdvantageLabelVOList; | ||||
|   rightData.productDetailVideoReqList = leftData.detailVideoVOList; | ||||
| @@ -297,6 +298,7 @@ export function transformSubmitForHalf(leftData, config, draftId) { | ||||
|       countryShortName: leftData.productWhExtAttr.productOrigin ? leftData.productWhExtAttr.productOrigin.countryShortName: 'CN' | ||||
|     } | ||||
|   }; | ||||
|   rightData.personalizationSwitch = leftData.productWhExtAttr.personalizationSwitch || 0 | ||||
|   rightData.productCarouseVideoReqList = leftData.carouseVideoVOList; | ||||
|   rightData.goodsAdvantageLabelTypes = leftData.goodsAdvantageLabelVOList; | ||||
|   rightData.productDetailVideoReqList = leftData.detailVideoVOList; | ||||
| @@ -323,14 +325,20 @@ export function transformSubmitForHalf(leftData, config, draftId) { | ||||
|     freightTemplateId: config.freightTemplateId, | ||||
|     shipmentLimitSecond: config.sendGoodsSecond | ||||
|   } | ||||
|   let bindSiteIds = [] | ||||
|   if (leftData.productSaleExtAttr?.productSemiManaged?.bindSites) { | ||||
|     leftData.productSaleExtAttr?.productSemiManaged?.bindSites.map(ii => { | ||||
|       bindSiteIds.push(ii.siteId) | ||||
|     }) | ||||
|   } | ||||
|   rightData.productSemiManagedReq = { | ||||
|     bindSiteIds: config.siteList | ||||
|     bindSiteIds: bindSiteIds | ||||
|   } | ||||
|   let targetRouteList = [] | ||||
|   for (let m = 0; m < config.wareHouseList.length; m++) { | ||||
|     targetRouteList.push({ | ||||
|       warehouseId: config.wareHouseList[m], | ||||
|       siteIdList: config.siteList | ||||
|       siteIdList: bindSiteIds | ||||
|     }) | ||||
|   } | ||||
|   rightData.productWarehouseRouteReq = { | ||||
|   | ||||
| @@ -61,6 +61,7 @@ | ||||
|             <el-menu-item index="/shippingList">已收货发货单</el-menu-item> | ||||
|             <el-menu-item index="/myNormalOrder">普通备货单</el-menu-item> | ||||
|             <el-menu-item index="/myUrgencyOrder">紧急备货单</el-menu-item> | ||||
|             <el-menu-item index="/productLabel">商品条码管理</el-menu-item> | ||||
|           </el-submenu> | ||||
|  | ||||
|           <el-submenu index="/copyProduct"> | ||||
| @@ -131,6 +132,7 @@ | ||||
|             </template> | ||||
|             <el-menu-item index="/costManageTemu">成本管理</el-menu-item> | ||||
|             <el-menu-item index="/saleData">销售管理</el-menu-item> | ||||
|             <el-menu-item index="/saleStatTemu">销售统计</el-menu-item> | ||||
|             <el-menu-item index="/saleOut">售罄看板</el-menu-item> | ||||
|             <el-menu-item index="/afterSaleStat">售后统计</el-menu-item> | ||||
|             <el-menu-item index="/afterSaleDeductStat">售后赔付统计</el-menu-item> | ||||
|   | ||||
| @@ -106,6 +106,7 @@ | ||||
|                       productName: item.productName, | ||||
|                       skcId: item.skcId, | ||||
|                       popUpType: 1, | ||||
|                       createTime: res.result.createTime, | ||||
|                       versionId: res.result.popUpAutoPass12.versionId, | ||||
|                       newSupplyPrice: item.newSupplyPrice / 100, | ||||
|                     } | ||||
| @@ -119,6 +120,7 @@ | ||||
|                       productName: item.productName, | ||||
|                       skcId: item.skcId, | ||||
|                       popUpType: 2, | ||||
|                       createTime: res.result.createTime, | ||||
|                       versionId: res.result.popUpAutoPass24.versionId, | ||||
|                       newSupplyPrice: item.newSupplyPrice / 100, | ||||
|                     } | ||||
| @@ -132,6 +134,7 @@ | ||||
|                       productName: item.productName, | ||||
|                       skcId: item.skcId, | ||||
|                       popUpType: 3, | ||||
|                       createTime: res.result.createTime, | ||||
|                       versionId: res.result.popUpOthers.versionId, | ||||
|                       newSupplyPrice: item.newSupplyPrice / 100, | ||||
|                     } | ||||
| @@ -166,10 +169,12 @@ | ||||
|             let popUpType1VersionId = '' | ||||
|             let popUpType2VersionId = '' | ||||
|             let popUpType3VersionId = '' | ||||
|             let createTime = null | ||||
|             let ids = [] | ||||
|             this.priceList.map(item => { | ||||
|               if (item.popUpType == 1) { | ||||
|                 popUpType1VersionId = item.versionId | ||||
|                 createTime = item.createTime | ||||
|                 ids.push(item.id) | ||||
|               } | ||||
|             }) | ||||
| @@ -183,12 +188,13 @@ | ||||
|                   "rejectOrderIdList": ids, | ||||
|                   "maxOrderId": popUpType1VersionId, | ||||
|                   "popUpType": 1, | ||||
|                   "createTime": new Date().getTime() | ||||
|                   "createTime": createTime | ||||
|                 }}) | ||||
|             } | ||||
|             ids = [] | ||||
|             this.priceList.map(item => { | ||||
|               if (item.popUpType == 2) { | ||||
|                 createTime = item.createTime | ||||
|                 popUpType2VersionId = item.versionId | ||||
|                 ids.push(item.id) | ||||
|               } | ||||
| @@ -202,12 +208,13 @@ | ||||
|                   "rejectOrderIdList": ids, | ||||
|                   "maxOrderId": popUpType2VersionId, | ||||
|                   "popUpType": 2, | ||||
|                   "createTime": new Date().getTime() | ||||
|                   "createTime": createTime | ||||
|                 }}) | ||||
|             } | ||||
|             ids = [] | ||||
|             this.priceList.map(item => { | ||||
|               if (item.popUpType == 3) { | ||||
|                 createTime = item.createTime | ||||
|                 popUpType3VersionId = item.versionId | ||||
|                 ids.push(item.id) | ||||
|               } | ||||
| @@ -221,7 +228,7 @@ | ||||
|                   "rejectOrderIdList": ids, | ||||
|                   "maxOrderId": popUpType3VersionId, | ||||
|                   "popUpType": 3, | ||||
|                   "createTime": new Date().getTime() | ||||
|                   "createTime": createTime | ||||
|                 }}) | ||||
|             } | ||||
|             if (res.success && res.errorCode == 1000000) { | ||||
|   | ||||
| @@ -32,9 +32,12 @@ | ||||
|         </div> | ||||
|       </ai-card> | ||||
|     </div> | ||||
|     <ai-card title="常用工具" v-if="false"> | ||||
|       <div class=""> | ||||
|         dsad | ||||
|     <ai-card title="TEMU助手功能概览"> | ||||
|       <template #right> | ||||
|         <a href="https://www.yuque.com/liushiwei-f582m/kb/bmqqls0o5ybd6c8p?singleDoc" style="color: blue; font-size: 18px; text-decoration: underline;" target="_blank">在线帮助手册</a> | ||||
|       </template> | ||||
|       <div style="height: 1000px"> | ||||
|         <BiVueMindmap ref="bi-vue-mindmap" :isReadonly="true" :flatNodes="mindmapNodes" /> | ||||
|       </div> | ||||
|     </ai-card> | ||||
|     <AiDialog | ||||
| @@ -58,9 +61,13 @@ | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import BiVueMindmap from "bi-vue-mindmap"; | ||||
|  | ||||
|   export default { | ||||
|     name: 'AdminHome', | ||||
|     components: { | ||||
|       BiVueMindmap, | ||||
|     }, | ||||
|     data () { | ||||
|       return { | ||||
|         noticeList: [], | ||||
| @@ -70,7 +77,258 @@ | ||||
|         changeLogList: [], | ||||
|         isImportant: false, | ||||
|         version: '', | ||||
|         isShowDownload: false | ||||
|         isShowDownload: false, | ||||
|         mindmapNodes: [ | ||||
|           { | ||||
|             id: "01", | ||||
|             parentId: null, | ||||
|             title: "TEMU助手" | ||||
|           }, | ||||
|           { | ||||
|             id: "0101", | ||||
|             parentId: "01", | ||||
|             title: "TEMU" | ||||
|           }, | ||||
|           { | ||||
|             id: "010101", | ||||
|             parentId: "0101", | ||||
|             title: "辅助运营" | ||||
|           }, | ||||
|           { | ||||
|             id: "01010101", | ||||
|             parentId: "010101", | ||||
|             title: "备货单管理", | ||||
|             isFolded: true | ||||
|           }, | ||||
|           { | ||||
|             id: "0101010101", | ||||
|             parentId: "01010101", | ||||
|             title: "创建备货单:批量领取系统下的备货单" | ||||
|           }, | ||||
|           { | ||||
|             id: "0101010102", | ||||
|             parentId: "01010101", | ||||
|             title: "抢仓发货:同时操作多个店铺自动抢仓并创建发货单", | ||||
|             resources: [{ | ||||
|               type: "VIDEO", | ||||
|               url: "http://temu.jjcp52.com/dist/qiangcang.mp4" | ||||
|             }] | ||||
|           }, | ||||
|           { | ||||
|             id: "0101010103", | ||||
|             parentId: "01010101", | ||||
|             title: "发货台管理:批量从“发货台”创建发货单" | ||||
|           }, | ||||
|           { | ||||
|             id: "0101010104", | ||||
|             parentId: "01010101", | ||||
|             title: "待装箱发货单:对应“备货单管理”->“发货单列表”,“待装箱发货”列表,支持导出" | ||||
|           }, | ||||
|           { | ||||
|             id: "0101010105", | ||||
|             parentId: "01010101", | ||||
|             title: "待收货发货单:对应“备货单管理”->“发货单列表”,“待仓库收货”列表,支持导出" | ||||
|           }, | ||||
|           { | ||||
|             id: "0101010106", | ||||
|             parentId: "01010101", | ||||
|             title: "已收货发货单:对应“备货单管理”->“发货单列表”,“已收货”列表,支持导出" | ||||
|           }, | ||||
|           { | ||||
|             id: "0101010107", | ||||
|             parentId: "01010101", | ||||
|             title: "普通备货单:对应“备货单管理”->“我的备货单”,“普通备货单”列表,支持导出、成本统计" | ||||
|           }, | ||||
|           { | ||||
|             id: "0101010108", | ||||
|             parentId: "01010101", | ||||
|             title: "紧急备货单:对应“备货单管理”->“我的备货单”,“紧急备货单”列表,支持导出、成本统计" | ||||
|           }, | ||||
|           { | ||||
|             id: "0101010109", | ||||
|             parentId: "01010101", | ||||
|             title: "商品条码管理:对应“备货单管理”->“商品条码管理”,支持导出,可用于自定义生成标签,提高贴标效率" | ||||
|           }, | ||||
|           { | ||||
|             id: "01010102", | ||||
|             parentId: "010101", | ||||
|             title: "商品管理", | ||||
|             isFolded: true | ||||
|           }, | ||||
|           { | ||||
|             id: "0101010201", | ||||
|             parentId: "01010102", | ||||
|             title: "商品管理:对应“商品管理”->“商品列表”,支持导出,支持半托管" | ||||
|           }, | ||||
|           { | ||||
|             id: "0101010202", | ||||
|             parentId: "01010102", | ||||
|             title: "商品复制:店铺之间快速商品拷贝" | ||||
|           }, | ||||
|           { | ||||
|             id: "0101010203", | ||||
|             parentId: "01010102", | ||||
|             title: "查找买手:根据SKC查询买手名字" | ||||
|           }, | ||||
|           { | ||||
|             id: "0101010204", | ||||
|             parentId: "01010102", | ||||
|             title: "上新生命周期:对应“商品管理”->“上新生命周期管理”,支持导出未发布到站点、已下架的数据" | ||||
|           }, | ||||
|           { | ||||
|             id: "01010103", | ||||
|             parentId: "010101", | ||||
|             title: "库存管理", | ||||
|             isFolded: true | ||||
|           }, | ||||
|           { | ||||
|             id: "0101010301", | ||||
|             parentId: "01010103", | ||||
|             title: "退货包裹管理:对应“库存管理”->“退货包裹管理”,支持导出" | ||||
|           }, | ||||
|           { | ||||
|             id: "0101010302", | ||||
|             parentId: "01010103", | ||||
|             title: "退货明细:对应“库存管理”->“退货明细”,支持导出" | ||||
|           }, | ||||
|           { | ||||
|             id: "01010104", | ||||
|             parentId: "010101", | ||||
|             title: "销售管理", | ||||
|             isFolded: true | ||||
|           }, | ||||
|           { | ||||
|             id: "0101010401", | ||||
|             parentId: "01010104", | ||||
|             title: "成本管理:维护SKU的成本价格,用于成本、利润的计算和统计" | ||||
|           }, | ||||
|           { | ||||
|             id: "0101010402", | ||||
|             parentId: "01010104", | ||||
|             title: "销售管理:对应“销售管理”->“销售管理”,统计今日销量/销售额、今日利润/利润率、库存/在途库存,支持数据导出" | ||||
|           }, | ||||
|           { | ||||
|             id: "0101010403", | ||||
|             parentId: "01010104", | ||||
|             title: "销售统计:统计过去一段时间内,总体销售额/单量/成本/利润/利润率的统计,以及SKC/SKU维度的销售额/利润/单量的统计,支持导出" | ||||
|           }, | ||||
|           { | ||||
|             id: "0101010404", | ||||
|             parentId: "01010104", | ||||
|             title: "售罄看板:对应“销售管理”->“售罄看板”,支持导出" | ||||
|           }, | ||||
|           { | ||||
|             id: "0101010405", | ||||
|             parentId: "01010104", | ||||
|             title: "售后统计:对应“结算管理”->“售后管理”,计算预计扣款,白卖件数,支持导出" | ||||
|           }, | ||||
|           { | ||||
|             id: "0101010406", | ||||
|             parentId: "01010104", | ||||
|             title: "售后赔付统计:对应“结算管理”->“对账中心”->“扣款详情”,统计过去一段时间内店铺的扣款总金额/次数,支持导出" | ||||
|           }, | ||||
|           { | ||||
|             id: "01010105", | ||||
|             parentId: "010101", | ||||
|             title: "其他", | ||||
|             isFolded: true | ||||
|           }, | ||||
|           { | ||||
|             id: "0101010501", | ||||
|             parentId: "01010105", | ||||
|             title: "弹窗消息:支持一键已读所有店铺的弹窗消息" | ||||
|           }, | ||||
|           { | ||||
|             id: "0101010502", | ||||
|             parentId: "01010105", | ||||
|             title: "拒绝调价:辅助批量点击“我不接受”按钮,减轻工作量,避免遗漏", | ||||
|             resources: [{ | ||||
|               type: "PIC", | ||||
|               url: "http://temu.jjcp52.com/dist/refuse-price.png" | ||||
|             }] | ||||
|           }, | ||||
|           { | ||||
|             id: "010102", | ||||
|             parentId: "0101", | ||||
|             title: "选品采集" | ||||
|           }, | ||||
|           { | ||||
|             id: "01010201", | ||||
|             parentId: "010102", | ||||
|             title: "商品采集:根据TEMU前端地址,采集商品信息到店铺草稿箱,减轻上品工作量", | ||||
|             resources: [{ | ||||
|               type: "VIDEO", | ||||
|               url: "http://temu.jjcp52.com/dist/xuanpin.mp4" | ||||
|             }] | ||||
|           }, | ||||
|           { | ||||
|             id: "01010202", | ||||
|             parentId: "010102", | ||||
|             title: "速卖通采集:根据“速卖通”前端地址,采集商品信息到店铺草稿箱,减轻上品工作量" | ||||
|           }, | ||||
|           { | ||||
|             id: "01010203", | ||||
|             parentId: "010102", | ||||
|             title: "选品跟踪", | ||||
|             isFolded: true | ||||
|           }, | ||||
|           { | ||||
|             id: "0101020301", | ||||
|             parentId: "01010203", | ||||
|             title: "店铺跟踪:跟踪指定店铺的销售趋势、价格趋势,采集跟卖。(暂时不可用)" | ||||
|           }, | ||||
|           { | ||||
|             id: "0101020302", | ||||
|             parentId: "01010203", | ||||
|             title: "关键字跟踪:根据筛选关键字,跟踪该关键字在TEMU前端搜索结果的销售趋势、价格趋势,采集跟卖" | ||||
|           }, | ||||
|           { | ||||
|             id: "0101020303", | ||||
|             parentId: "01010203", | ||||
|             title: "新品跟踪:跟踪TEMU前端“Best Sellers”->“Within last 7 days”的新品,采集跟卖" | ||||
|           }, | ||||
|           { | ||||
|             id: "0101020304", | ||||
|             parentId: "01010203", | ||||
|             title: "单品跟踪:根据TEMU前端地址,采集销售趋势、价格趋势" | ||||
|           }, | ||||
|           { | ||||
|             id: "0102", | ||||
|             parentId: "01", | ||||
|             title: "SHEIN(希音)" | ||||
|           }, | ||||
|           { | ||||
|             id: "010201", | ||||
|             parentId: "0102", | ||||
|             title: "辅助运营", | ||||
|             isFolded: true | ||||
|           }, | ||||
|           { | ||||
|             id: "01020101", | ||||
|             parentId: "010201", | ||||
|             title: "成本管理:维护SKU的成本价格,用于成本、利润的计算和统计" | ||||
|           }, | ||||
|           { | ||||
|             id: "01020102", | ||||
|             parentId: "010201", | ||||
|             title: "销售管理:对应SHEIN商家后台“商品管理”->“备货信息”,统计当天的销售额、销量、库存等信息,计算成本和利润" | ||||
|           }, | ||||
|           { | ||||
|             id: "01020103", | ||||
|             parentId: "010201", | ||||
|             title: "证书中心:对应SHEIN商家后台“商品管理”->“证书中心”,导出已驳回和待补充的证书列表,线下跟踪" | ||||
|           }, | ||||
|           { | ||||
|             id: "01020104", | ||||
|             parentId: "010201", | ||||
|             title: "商品复制:希音店铺间商品进行快速复制,节省上品时间" | ||||
|           }, | ||||
|           { | ||||
|             id: "01020105", | ||||
|             parentId: "010201", | ||||
|             title: "商家账单统计:对应SHEIN商家后台“财务管理”->“商家账单”,统计一段时期内销售额、单量、成本、利润、利润率,SKC/SKU维度统计排名,支持导出" | ||||
|           }, | ||||
|         ], | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|   | ||||
| @@ -93,9 +93,12 @@ import CryptoJS from 'crypto-js' | ||||
|               this.$message.success('两次密码输入不一致'); | ||||
|               return; | ||||
|             } | ||||
|             const devVersion = require('../../manifest.development.json').version | ||||
|             const prodVersion = require('../../manifest.production.json').version | ||||
|             this.btnLoading = true | ||||
|             this.$http.post(`/api/malluser/reg`, { | ||||
|               ...this.form | ||||
|               ...this.form, | ||||
|               version: process.env.NODE_ENV === 'production' ? prodVersion : devVersion | ||||
|             }, { | ||||
|               headers: { | ||||
|                 Authorization: 'Basic cGM6cGM=' | ||||
|   | ||||
| @@ -26,6 +26,7 @@ | ||||
|             style="margin-top: 8px;" | ||||
|             :current.sync="search.current" :size.sync="search.size" | ||||
|             @selection-change="handleSelectionChange" | ||||
|             height="700" | ||||
|             @getList="getList"> | ||||
|           </ai-table> | ||||
|         </div> | ||||
| @@ -545,6 +546,7 @@ import AiLazyCascader from "@/components/AiLazyCascader.vue" | ||||
|                   bindSiteIds: this.form.siteId | ||||
|                 } | ||||
|               } | ||||
|               content.personalizationSwitch = content.personalizationSwitch || 0 | ||||
|               setTimeout(() => { | ||||
|                 sendChromeAPIMessage({ | ||||
|                   url: 'bg-visage-mms/product/draft/add', | ||||
|   | ||||
| @@ -323,7 +323,8 @@ import JsonExcel from 'vue-json-excel' | ||||
|                     supplierPrice: item.productSkuSummaries[k].supplierPrice / 100, | ||||
|                     specName: temp.join(","), | ||||
|                     skuStockQuantity, | ||||
|                     todaySalesVolume: item.productSkuSummaries[k].todaySalesVolume} | ||||
|                     todaySalesVolume: item.productSkuSummaries[k].todaySalesVolume | ||||
|                   } | ||||
|  | ||||
|                     this.tableData.push(data) | ||||
|                 } | ||||
|   | ||||
| @@ -226,25 +226,6 @@ import JsonExcel from 'vue-json-excel' | ||||
|           } | ||||
|         } | ||||
|       }, | ||||
|       async getSkuCostList() { | ||||
|         this.$http.post(`/api/skuCost/listAll`, null, { | ||||
|           params: { | ||||
|             mallId: this.mallId | ||||
|           } | ||||
|         }).then(res => { | ||||
|           if (res.code == 0) { | ||||
|             this.costList = res.data | ||||
|             this.tableData.map(item => { | ||||
|               for (let i = 0; i < this.costList.length; i++) { | ||||
|                 if (item.productSkuId == this.costList[i].sku) { | ||||
|                   item.cost = this.costList[i].costPrice | ||||
|                   item.profitTimes = Math.round((item.supplierPrice * item.punishRatio + item.cost * item.times) / (item.supplierPrice - item.cost) * 100) / 100 | ||||
|                 } | ||||
|               } | ||||
|             }) | ||||
|           } | ||||
|         }) | ||||
|       }, | ||||
|     } | ||||
|   } | ||||
| </script> | ||||
|   | ||||
| @@ -3,6 +3,7 @@ | ||||
|     <ai-title | ||||
|       slot="title" | ||||
|       title="售后统计" | ||||
|       tips="请事先在“成本管理”维护好成本,否则部分计算不准确" | ||||
|       isShowBottomBorder> | ||||
|       <template #rightBtn> | ||||
|         <div class="title-right"> | ||||
| @@ -172,8 +173,7 @@ import JsonExcel from 'vue-json-excel' | ||||
|         this.reqData.pageNo = 1 | ||||
|  | ||||
|         await this.getProductList({page: this.reqData.pageNo, | ||||
|           pageSize: this.reqData.pageSize, | ||||
|           productSkuIds: skuIds}) | ||||
|           pageSize: this.reqData.pageSize}, skuIds) | ||||
|            | ||||
|           this.costList = [] | ||||
|           await this.getSkuCostList() | ||||
| @@ -227,13 +227,24 @@ import JsonExcel from 'vue-json-excel' | ||||
|           this.$store.commit("setTemuAlertShow", true) | ||||
|         } | ||||
|       }, | ||||
|       async getProductList(params) { | ||||
|       async getProductList(params, skuIds) { | ||||
|         let productSkuIds = [] | ||||
|         let i = (params.page - 1) * params.pageSize | ||||
|         let j = 0 | ||||
|         for (; i < skuIds.length; i++) { | ||||
|           productSkuIds.push(skuIds[i]) | ||||
|           j ++ | ||||
|           if (j == params.pageSize) break | ||||
|         } | ||||
|         if (productSkuIds.length == 0) return | ||||
|         let res = await sendChromeAPIMessage({ | ||||
|           url: 'bg-visage-mms/product/skc/pageQuery', | ||||
|           needMallId: true, | ||||
|           mallId: this.mallId, | ||||
|           data: { | ||||
|             ...params | ||||
|             page: 1, | ||||
|             pageSize: params.pageSize, | ||||
|             productSkuIds | ||||
|         }}) | ||||
|         if (res.errorCode == 1000000) { | ||||
|           res.result.pageItems.map((item) => { | ||||
| @@ -251,10 +262,8 @@ import JsonExcel from 'vue-json-excel' | ||||
|             }) | ||||
|           }) | ||||
|  | ||||
|           if ((params.page * params.pageSize) < res.result.total) { | ||||
|             params.page ++ | ||||
|             await this.getProductList(params) | ||||
|           } | ||||
|           params.page ++ | ||||
|           await this.getProductList(params, skuIds) | ||||
|         } | ||||
|       }, | ||||
|       async getSkuCostList() { | ||||
|   | ||||
| @@ -206,6 +206,7 @@ import { saveAs } from 'file-saver' | ||||
|           this.isLoading = true | ||||
|           this.getList() | ||||
|         }).catch((err) => { | ||||
|           this.mallId = '' | ||||
|           this.isLoading = false | ||||
|         })  | ||||
|       }, | ||||
|   | ||||
| @@ -3,6 +3,7 @@ | ||||
|     <ai-title | ||||
|       slot="title" | ||||
|       title="销售数据" | ||||
|       tips="请事先在“成本管理”维护好成本,否则部分计算不准确" | ||||
|       isShowBottomBorder> | ||||
|       <template #rightBtn> | ||||
|         <div class="title-right"> | ||||
| @@ -133,7 +134,7 @@ | ||||
|           ref="table0" | ||||
|           :isShowPagination="false" | ||||
|           :tableData="filteredData" | ||||
|           height="500" | ||||
|           height="700" | ||||
|           :col-configs="colConfigs" | ||||
|           :total="filteredData.length" | ||||
|           style="margin-top: 8px;" | ||||
| @@ -706,6 +707,7 @@ import { Message } from 'element-ui' | ||||
|           this.getSkuCostList() | ||||
|           this.getList() | ||||
|         }).catch((err) => { | ||||
|           this.mallId = '' | ||||
|           console.log(err) | ||||
|           this.isLoading = false | ||||
|         }) | ||||
|   | ||||
| @@ -47,7 +47,7 @@ | ||||
|           :tableData="tableData" | ||||
|           :col-configs="colConfigs" | ||||
|           :total="tableData.length" | ||||
|           height="500" | ||||
|           height="700" | ||||
|           style="margin-top: 8px;" | ||||
|           @getList="() => {}"> | ||||
|         </ai-table> | ||||
| @@ -150,6 +150,7 @@ import { Message } from 'element-ui' | ||||
|             this.getList(2) | ||||
|           } | ||||
|         }).catch((err) => { | ||||
|           this.mallId = '' | ||||
|           this.isLoading = false | ||||
|         }) | ||||
|       }, | ||||
|   | ||||
							
								
								
									
										888
									
								
								src/view/sale/ExportSaleStatTemu.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										888
									
								
								src/view/sale/ExportSaleStatTemu.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,888 @@ | ||||
| <template> | ||||
|   <ai-list class="list" v-loading="isLoading" element-loading-text="拼命加载中" element-loading-spinner="el-icon-loading"> | ||||
|     <ai-title | ||||
|       slot="title" | ||||
|       title="销售统计" | ||||
|       tips="最多只能统计近60天的销售数据" | ||||
|       isShowBottomBorder> | ||||
|       <template #rightBtn> | ||||
|         <div class="title-right"> | ||||
|           <div> | ||||
|             <label style="width:90px">时间范围:</label> | ||||
|             <el-date-picker | ||||
|               v-model="dateRange" | ||||
|               type="daterange" | ||||
|               start-placeholder="开始日期" | ||||
|               end-placeholder="结束日期" | ||||
|               format="yyyy-MM-dd" | ||||
|               value-format="yyyy-MM-dd"> | ||||
|             </el-date-picker> | ||||
|           </div> | ||||
|           <div> | ||||
|             <label style="width:90px">店铺:</label> | ||||
|             <el-select v-model="mallId" 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> | ||||
|           <el-button type="button" :class="'el-button el-button--primary'" @click="toBeginStat">开始统计</el-button> | ||||
|           <el-button type="primary" icon="el-icon-download" @click="downloadPicture">下载图片</el-button> | ||||
|           <json-excel | ||||
|               :data="skcList" | ||||
|               :fields="skcJsonFields" | ||||
|               name="SKC销售统计.xls" | ||||
|               worksheet="SKC销售统计"> | ||||
|             <el-button type="primary" icon="el-icon-download">下载SKC统计</el-button> | ||||
|           </json-excel> | ||||
|           <json-excel | ||||
|               :data="skuList" | ||||
|               :fields="skuJsonFields" | ||||
|               name="SKU销售统计.xls" | ||||
|               worksheet="SKU销售统计"> | ||||
|             <el-button type="primary" icon="el-icon-download">下载SKU统计</el-button> | ||||
|           </json-excel> | ||||
|         </div> | ||||
|       </template> | ||||
|     </ai-title> | ||||
|     <template slot="content"> | ||||
|       <div  id="app-content"> | ||||
|         <ai-card title="数据概览" style="padding-bottom: 40px;"> | ||||
|           <div> | ||||
|             <el-row :gutter="20"> | ||||
|               <el-col :span="5"> | ||||
|                 <div> | ||||
|                   <el-statistic | ||||
|                     group-separator="," | ||||
|                     :precision="2" | ||||
|                     :value="saleAmount" | ||||
|                     title="销售额" | ||||
|                   > | ||||
|                   </el-statistic> | ||||
|                 </div> | ||||
|               </el-col> | ||||
|               <el-col :span="5"> | ||||
|                 <div> | ||||
|                   <el-statistic | ||||
|                     group-separator="," | ||||
|                     :value="saleCount" | ||||
|                     title="单量" | ||||
|                   > | ||||
|                   </el-statistic> | ||||
|                 </div> | ||||
|               </el-col> | ||||
|               <el-col :span="5"> | ||||
|                 <div> | ||||
|                   <el-statistic | ||||
|                     group-separator="," | ||||
|                     :precision="2" | ||||
|                     :value="costAmount" | ||||
|                     title="成本" | ||||
|                   ></el-statistic> | ||||
|                 </div> | ||||
|               </el-col> | ||||
|               <el-col :span="5"> | ||||
|                 <div> | ||||
|                   <el-statistic | ||||
|                     group-separator="," | ||||
|                     :precision="2" | ||||
|                     :value="profitAmount" | ||||
|                     title="利润" | ||||
|                   ></el-statistic> | ||||
|                 </div> | ||||
|               </el-col> | ||||
|               <el-col :span="4"> | ||||
|                 <div> | ||||
|                   <el-statistic | ||||
|                     group-separator="," | ||||
|                     :precision="2" | ||||
|                     :value="profitPercent" | ||||
|                     title="利润率" | ||||
|                   > | ||||
|                   <template slot="suffix">%</template> | ||||
|                 </el-statistic> | ||||
|                 </div> | ||||
|               </el-col> | ||||
|             </el-row> | ||||
|           </div> | ||||
|         </ai-card> | ||||
|         <ai-card title="趋势分析" style="padding-bottom: 40px;"> | ||||
|           <div> | ||||
|             <div id="chart1"></div> | ||||
|           </div> | ||||
|         </ai-card> | ||||
|         <div> | ||||
|           <el-row :gutter="20"> | ||||
|             <el-col :span="12"> | ||||
|               <ai-card title="SKC销售额TOP10排行"> | ||||
|                 <ai-table | ||||
|                   ref="table0" | ||||
|                   :isShowPagination="false" | ||||
|                   :tableData="topSaleAmountSkcList" | ||||
|                   :col-configs="skcColConfigs" | ||||
|                   style="margin-top: 8px;"> | ||||
|                   <el-table-column slot="saleAmount" label="销售额"> | ||||
|                     <template slot-scope="scope"> | ||||
|                       <div style="color: red">{{ scope.row.saleAmount }}</div> | ||||
|                     </template> | ||||
|                   </el-table-column> | ||||
|                   <el-table-column slot="profitAmount" label="利润"> | ||||
|                     <template slot-scope="scope"> | ||||
|                       <div>{{ scope.row.profitAmount }}</div> | ||||
|                     </template> | ||||
|                   </el-table-column> | ||||
|                   <el-table-column slot="saleCount" label="单量"> | ||||
|                     <template slot-scope="scope"> | ||||
|                       <div>{{ scope.row.saleCount }}</div> | ||||
|                     </template> | ||||
|                   </el-table-column> | ||||
|                 </ai-table> | ||||
|               </ai-card> | ||||
|             </el-col> | ||||
|             <el-col :span="12"> | ||||
|               <ai-card title="SKC利润TOP10排行"> | ||||
|                 <ai-table | ||||
|                   ref="table1" | ||||
|                   :isShowPagination="false" | ||||
|                   :tableData="topSaleProfitSkcList" | ||||
|                   :col-configs="skcColConfigs" | ||||
|                   style="margin-top: 8px;"> | ||||
|                   <el-table-column slot="saleAmount" label="销售额"> | ||||
|                     <template slot-scope="scope"> | ||||
|                       <div>{{ scope.row.saleAmount }}</div> | ||||
|                     </template> | ||||
|                   </el-table-column> | ||||
|                   <el-table-column slot="profitAmount" label="利润"> | ||||
|                     <template slot-scope="scope"> | ||||
|                       <div style="color: red">{{ scope.row.profitAmount }}</div> | ||||
|                     </template> | ||||
|                   </el-table-column> | ||||
|                   <el-table-column slot="saleCount" label="单量"> | ||||
|                     <template slot-scope="scope"> | ||||
|                       <div>{{ scope.row.saleCount }}</div> | ||||
|                     </template> | ||||
|                   </el-table-column> | ||||
|                 </ai-table> | ||||
|               </ai-card> | ||||
|             </el-col> | ||||
|           </el-row> | ||||
|           <el-row :gutter="20"> | ||||
|             <el-col :span="12"> | ||||
|               <ai-card title="SKC单量TOP10排行"> | ||||
|                 <ai-table | ||||
|                   ref="table2" | ||||
|                   :isShowPagination="false" | ||||
|                   :tableData="topSaleCountSkcList" | ||||
|                   :col-configs="skcColConfigs" | ||||
|                   style="margin-top: 8px;"> | ||||
|                   <el-table-column slot="saleAmount" label="销售额"> | ||||
|                     <template slot-scope="scope"> | ||||
|                       <div>{{ scope.row.saleAmount }}</div> | ||||
|                     </template> | ||||
|                   </el-table-column> | ||||
|                   <el-table-column slot="profitAmount" label="利润"> | ||||
|                     <template slot-scope="scope"> | ||||
|                       <div>{{ scope.row.profitAmount }}</div> | ||||
|                     </template> | ||||
|                   </el-table-column> | ||||
|                   <el-table-column slot="saleCount" label="单量"> | ||||
|                     <template slot-scope="scope"> | ||||
|                       <div style="color: red">{{ scope.row.saleCount }}</div> | ||||
|                     </template> | ||||
|                   </el-table-column> | ||||
|                 </ai-table> | ||||
|               </ai-card> | ||||
|             </el-col> | ||||
|             <el-col :span="12"> | ||||
|               <ai-card title="SKU销售额TOP10排行"> | ||||
|                 <ai-table | ||||
|                   ref="table3" | ||||
|                   :isShowPagination="false" | ||||
|                   :tableData="topSaleAmountSkuList" | ||||
|                   :col-configs="skuColConfigs" | ||||
|                   style="margin-top: 8px;"> | ||||
|                   <el-table-column slot="skuExtCode" label="SKC属性/SKU属性" width="250px" :show-overflow-tooltip="true"> | ||||
|                     <template slot-scope="scope"> | ||||
|                       <div>{{ scope.row.skcExtCode + '/' + scope.row.skuExtCode }}</div> | ||||
|                     </template> | ||||
|                   </el-table-column> | ||||
|                   <el-table-column slot="saleAmount" label="销售额"> | ||||
|                     <template slot-scope="scope"> | ||||
|                       <div style="color: red">{{ scope.row.saleAmount }}</div> | ||||
|                     </template> | ||||
|                   </el-table-column> | ||||
|                   <el-table-column slot="profitAmount" label="利润"> | ||||
|                     <template slot-scope="scope"> | ||||
|                       <div>{{ scope.row.profitAmount }}</div> | ||||
|                     </template> | ||||
|                   </el-table-column> | ||||
|                   <el-table-column slot="saleCount" label="单量"> | ||||
|                     <template slot-scope="scope"> | ||||
|                       <div>{{ scope.row.saleCount }}</div> | ||||
|                     </template> | ||||
|                   </el-table-column> | ||||
|                 </ai-table> | ||||
|               </ai-card> | ||||
|             </el-col> | ||||
|           </el-row> | ||||
|           <el-row :gutter="20"> | ||||
|             <el-col :span="12"> | ||||
|               <ai-card title="SKU利润TOP10排行"> | ||||
|                 <ai-table | ||||
|                   ref="table4" | ||||
|                   :isShowPagination="false" | ||||
|                   :tableData="topSaleProfitSkuList" | ||||
|                   :col-configs="skuColConfigs" | ||||
|                   style="margin-top: 8px;"> | ||||
|                   <el-table-column slot="skuExtCode" label="SKC属性/SKU属性" width="250px" :show-overflow-tooltip="true"> | ||||
|                     <template slot-scope="scope"> | ||||
|                       <div>{{ scope.row.skcExtCode + '/' + scope.row.skuExtCode }}</div> | ||||
|                     </template> | ||||
|                   </el-table-column> | ||||
|                   <el-table-column slot="saleAmount" label="销售额"> | ||||
|                     <template slot-scope="scope"> | ||||
|                       <div>{{ scope.row.saleAmount }}</div> | ||||
|                     </template> | ||||
|                   </el-table-column> | ||||
|                   <el-table-column slot="profitAmount" label="利润"> | ||||
|                     <template slot-scope="scope"> | ||||
|                       <div style="color: red">{{ scope.row.profitAmount }}</div> | ||||
|                     </template> | ||||
|                   </el-table-column> | ||||
|                   <el-table-column slot="saleCount" label="单量"> | ||||
|                     <template slot-scope="scope"> | ||||
|                       <div>{{ scope.row.saleCount }}</div> | ||||
|                     </template> | ||||
|                   </el-table-column> | ||||
|                 </ai-table> | ||||
|               </ai-card> | ||||
|             </el-col> | ||||
|             <el-col :span="12"> | ||||
|               <ai-card title="SKU单量TOP10排行"> | ||||
|                 <ai-table | ||||
|                   ref="table5" | ||||
|                   :isShowPagination="false" | ||||
|                   :tableData="topSaleCountSkuList" | ||||
|                   :col-configs="skuColConfigs" | ||||
|                   style="margin-top: 8px;"> | ||||
|                   <el-table-column slot="skuExtCode" label="SKC属性/SKU属性" width="250px" :show-overflow-tooltip="true"> | ||||
|                     <template slot-scope="scope"> | ||||
|                       <div>{{ scope.row.skcExtCode + '/' + scope.row.skuExtCode }}</div> | ||||
|                     </template> | ||||
|                   </el-table-column> | ||||
|                   <el-table-column slot="saleAmount" label="销售额"> | ||||
|                     <template slot-scope="scope"> | ||||
|                       <div>{{ scope.row.saleAmount }}</div> | ||||
|                     </template> | ||||
|                   </el-table-column> | ||||
|                   <el-table-column slot="profitAmount" label="利润"> | ||||
|                     <template slot-scope="scope"> | ||||
|                       <div>{{ scope.row.profitAmount }}</div> | ||||
|                     </template> | ||||
|                   </el-table-column> | ||||
|                   <el-table-column slot="saleCount" label="单量"> | ||||
|                     <template slot-scope="scope"> | ||||
|                       <div style="color: red">{{ scope.row.saleCount }}</div> | ||||
|                     </template> | ||||
|                   </el-table-column> | ||||
|                 </ai-table> | ||||
|               </ai-card> | ||||
|             </el-col> | ||||
|           </el-row> | ||||
|         </div> | ||||
|       </div> | ||||
|     </template> | ||||
|  | ||||
|      | ||||
|   </ai-list> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import {sendChromeAPIMessage } from '@/api/chromeApi' | ||||
| import JsonExcel from 'vue-json-excel' | ||||
| import { Message } from 'element-ui' | ||||
| import {formatDate} from '@/utils/date' | ||||
| import html2canvas from 'html2canvas' | ||||
| import { DualAxes } from '@antv/g2plot' | ||||
|  | ||||
|   export default { | ||||
|     name: 'ExportSaleStatTemu', | ||||
|  | ||||
|     data () { | ||||
|       return { | ||||
|         mallId: null, | ||||
|         storeCode: '', | ||||
|          | ||||
|         dateRange: null, | ||||
|          | ||||
|         currentPage: 1, | ||||
|         pageSize: 100, | ||||
|         productList: [], | ||||
|         productCostList: [], | ||||
|         saleAmount: 0.0, | ||||
|         saleCount: 0, | ||||
|         costAmount: 0.0, | ||||
|         profitAmount: 0.0, | ||||
|         profitPercent: 0.0, | ||||
|         deductionAmount: 0.0, | ||||
|         skcList: [], | ||||
|         skuList: [], | ||||
|  | ||||
|         leftChartData: [], | ||||
|         rightChartData: [], | ||||
|  | ||||
|         isLoading: false, | ||||
|  | ||||
|         skcColConfigs: [ | ||||
|           { prop: 'skcExtCode', label: 'SKC货号', width: '250px' }, | ||||
|           { slot: 'saleAmount', label: '销售额', align: 'center' }, | ||||
|           { slot: 'saleCount', label: '单量', align: 'center' }, | ||||
|           { prop: 'costAmount', label: '成本', align: 'center'}, | ||||
|           { slot: 'profitAmount', label: '利润', align: 'center' } | ||||
|         ], | ||||
|         skcJsonFields: { | ||||
|           "SKC": "productSkcId", | ||||
|           "SKC货号": "skcExtCode", | ||||
|           "销售额": "saleAmount", | ||||
|           "单量": "saleCount", | ||||
|           "成本": "costAmount", | ||||
|           "利润": "profitAmount" | ||||
|         }, | ||||
|         skuColConfigs: [ | ||||
|           { slot: 'skuExtCode', label: 'SKC货号/SKU货号' }, | ||||
|           { slot: 'saleAmount', label: '销售额', align: 'center' }, | ||||
|           { slot: 'saleCount', label: '单量', align: 'center' }, | ||||
|           { prop: 'costAmount', label: '成本', align: 'center'}, | ||||
|           { slot: 'profitAmount', label: '利润', align: 'center' } | ||||
|         ], | ||||
|         skuJsonFields: { | ||||
|           "SKC": "productSkcId", | ||||
|           "SKU": "productSkuId", | ||||
|           "SKC货号": "skcExtCode", | ||||
|           "SKU货号": "skuExtCode", | ||||
|           "销售额": "saleAmount", | ||||
|           "单量": "saleCount", | ||||
|           "成本": "costAmount", | ||||
|           "利润": "profitAmount" | ||||
|         }, | ||||
|  | ||||
|         chartObj: null | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     computed: { | ||||
|       topSaleAmountSkcList() { | ||||
|         const list = Object.assign([], this.skcList) | ||||
|         list.sort((a, b) => b.amount - a.amount) | ||||
|         return list.slice(0, 10) | ||||
|       }, | ||||
|       topSaleProfitSkcList() { | ||||
|         const list = Object.assign([], this.skcList) | ||||
|         list.sort((a, b) => b.profitAmount - a.profitAmount) | ||||
|         return list.slice(0, 10) | ||||
|       }, | ||||
|       topSaleCountSkcList() { | ||||
|         const list = Object.assign([], this.skcList) | ||||
|         list.sort((a, b) => b.saleCount - a.saleCount) | ||||
|         return list.slice(0, 10) | ||||
|       }, | ||||
|       topSaleAmountSkuList() { | ||||
|         const list = Object.assign([], this.skuList) | ||||
|         list.sort((a, b) => b.saleAmount - a.saleAmount) | ||||
|         return list.slice(0, 10) | ||||
|       }, | ||||
|       topSaleProfitSkuList() { | ||||
|         const list = Object.assign([], this.skuList) | ||||
|         list.sort((a, b) => b.profitAmount - a.profitAmount) | ||||
|         return list.slice(0, 10) | ||||
|       }, | ||||
|       topSaleCountSkuList() { | ||||
|         const list = Object.assign([], this.skuList) | ||||
|         list.sort((a, b) => b.saleCount - a.saleCount) | ||||
|         return list.slice(0, 10) | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     components: { | ||||
|       JsonExcel | ||||
|     }, | ||||
|     mounted () { | ||||
|       this.initChart1() | ||||
|     }, | ||||
|     methods: { | ||||
|       initChart1 () { | ||||
|         this.chartObj = new DualAxes('chart1', { | ||||
|           data: [this.leftChartData, this.rightChartData], | ||||
|           xField: 'day', | ||||
|           yField: ['value', 'value1'], | ||||
|           yAxis: { | ||||
|             value: { | ||||
|               title: { | ||||
|                 text: '金额' | ||||
|               }, | ||||
|               label: { | ||||
|                 formatter: (value) => { | ||||
|                   return `${value}元`; | ||||
|                 } | ||||
|               } | ||||
|             }, | ||||
|             value1: { | ||||
|               max: 100, | ||||
|               title: { | ||||
|                 text: '利润率' | ||||
|               }, | ||||
|               label: { | ||||
|                 formatter: (value) => { | ||||
|                   return `${value}%`; | ||||
|                 } | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           geometryOptions: [ | ||||
|           { | ||||
|             geometry: 'line', | ||||
|             color: ['#FF9A49', '#7A8AA1', '#1EEB73', '#C947AE' ], | ||||
|             isGroup: true, | ||||
|             smooth: true, // 是否平滑 | ||||
|             seriesField: 'type' | ||||
|           }, | ||||
|           { | ||||
|             geometry: 'line', | ||||
|             color: ['red' ], | ||||
|             lineStyle: { | ||||
|               fill: 'red', | ||||
|               fillOpacity: 0.5, | ||||
|               stroke: 'red', | ||||
|               lineWidth: 4, | ||||
|               strokeOpacity: 0.7, | ||||
|               shadowColor: 'black', | ||||
|               shadowBlur: 10, | ||||
|               shadowOffsetX: 5, | ||||
|               shadowOffsetY: 5, | ||||
|               cursor: 'pointer' | ||||
|             }, | ||||
|             isStack: true, | ||||
|             smooth: true, // 是否平滑 | ||||
|             seriesField: 'type', // 指定使用第二个Y轴字段 | ||||
|           }], | ||||
|         }); | ||||
|  | ||||
|         this.chartObj.render(); | ||||
|       }, | ||||
|       toBeginStat() { | ||||
|         if (!this.dateRange) { | ||||
|           Message.error("请选择统计时间范围") | ||||
|           return | ||||
|         } | ||||
|         if (!this.mallId) { | ||||
|           Message.error("请选择店铺") | ||||
|           return | ||||
|         } | ||||
|         this.$userCheck(this.mallId).then(() => { | ||||
|           this.beginStat() | ||||
|         }).catch((err) => { | ||||
|           this.mallId = '' | ||||
|           this.isLoading = false | ||||
|         }) | ||||
|       }, | ||||
|       async beginStat() { | ||||
|         this.currentPage = 1 | ||||
|         this.isLoading = true | ||||
|         this.saleAmount = 0.0 | ||||
|         this.saleCount = 0 | ||||
|         this.costAmount = 0.0 | ||||
|         this.profitAmount = 0.0 | ||||
|         this.profitPercent = 0.0 | ||||
|         this.productList = [] | ||||
|         this.productCostList = [] | ||||
|         this.skcList = [] | ||||
|         this.skuList = [] | ||||
|         this.leftChartData = [] | ||||
|         this.rightChartData = [] | ||||
|         this.chartObj.changeData([this.leftChartData, this.rightChartData]) | ||||
|         await this.getProductList() | ||||
|         await this.getSkuCostList() | ||||
|         await this.getSkuSaleNumber(0) | ||||
|         this.leftChartData.sort((a, b) => { | ||||
|           let leftDate = new Date(a.day) | ||||
|           let rightDate = new Date(b.day) | ||||
|           return leftDate.getTime() - rightDate.getTime() | ||||
|         }) | ||||
|         this.leftChartData.map(item => { | ||||
|           if (item.type == '销售额' || item.type == '成本' || item.type == '利润') { | ||||
|             item.value = Math.round(item.value * 100) / 100 | ||||
|           } | ||||
|  | ||||
|           if (item.type == '销售额') { | ||||
|             this.leftChartData.map(item1 => { | ||||
|               if (item1.type == '成本' && item1.day == item.day) { | ||||
|                 this.rightChartData.push({ | ||||
|                   day: item1.day, | ||||
|                   value1: Math.round((item.value - item1.value) / item.value * 10000) / 100, | ||||
|                   type: '利润率' | ||||
|                 }) | ||||
|               } | ||||
|             }) | ||||
|           } | ||||
|         }) | ||||
|         this.rightChartData.sort((a, b) => { | ||||
|           let leftDate = new Date(a.day) | ||||
|           let rightDate = new Date(b.day) | ||||
|           return leftDate.getTime() - rightDate.getTime() | ||||
|         }) | ||||
|         this.skuList = this.skuList.filter(item => { | ||||
|           return item.saleCount > 0 | ||||
|         }) | ||||
|          | ||||
|         this.skuList.map(item => { | ||||
|           item.saleAmount = Math.round(item.saleAmount * 100) / 100 | ||||
|           item.costAmount = Math.round(item.costAmount * 100) / 100 | ||||
|           item.profitAmount = Math.round(item.profitAmount * 100) / 100 | ||||
|         }) | ||||
|         this.skuList.map(item => { | ||||
|           let flag = false | ||||
|           for (let i = 0; i < this.skcList.length; i++) { | ||||
|             if (item.productSkcId == this.skcList[i].productSkcId) { | ||||
|               this.skcList[i].saleAmount = this.skcList[i].saleAmount + item.saleAmount | ||||
|               this.skcList[i].costAmount = this.skcList[i].costAmount + item.costAmount | ||||
|               this.skcList[i].profitAmount = this.skcList[i].profitAmount + item.profitAmount | ||||
|               flag = true | ||||
|               break | ||||
|             } | ||||
|           } | ||||
|           if (!flag) { | ||||
|             this.skcList.push({ | ||||
|               productSkcId: item.productSkcId, | ||||
|               skcExtCode: item.skcExtCode, | ||||
|               saleAmount: item.saleAmount, | ||||
|               saleCount: item.saleCount, | ||||
|               costAmount: item.costAmount, | ||||
|               profitAmount: item.profitAmount, | ||||
|               profitPercent: item.profitPercent | ||||
|             }) | ||||
|           } | ||||
|         }) | ||||
|          | ||||
|         this.skcList.map(item => { | ||||
|           item.saleAmount = Math.round(item.saleAmount * 100) / 100 | ||||
|           item.costAmount = Math.round(item.costAmount * 100) / 100 | ||||
|           item.profitAmount = Math.round(item.profitAmount * 100) / 100 | ||||
|         }) | ||||
|         this.leftChartData.map(item => { | ||||
|           if (item.type == '销售额') { | ||||
|             this.saleAmount = this.saleAmount + item.value | ||||
|           } | ||||
|           if (item.type == '成本') { | ||||
|             this.costAmount = this.costAmount + item.value | ||||
|           } | ||||
|           if (item.type == '利润') { | ||||
|             this.profitAmount = this.profitAmount + item.value | ||||
|           } | ||||
|           if (item.type == '单量') { | ||||
|             this.saleCount = this.saleCount + item.value | ||||
|           } | ||||
|         }) | ||||
|         this.saleAmount = Math.round(this.saleAmount * 100) / 100 | ||||
|         this.costAmount = Math.round(this.costAmount * 100) / 100 | ||||
|         this.profitAmount = Math.round(this.profitAmount * 100) / 100 | ||||
|         this.profitPercent = Math.round((this.saleAmount - this.costAmount) / this.saleAmount * 10000) / 100 | ||||
|         this.chartObj.changeData([this.leftChartData, this.rightChartData]) | ||||
|         this.isLoading = false | ||||
|       }, | ||||
|       getPorductList() { | ||||
|         this.$http.post(`/api/skuCost/listAll`, null, { | ||||
|           params: { | ||||
|             mallId: this.storeCode | ||||
|           } | ||||
|         }).then(res => { | ||||
|           if (res.code == 0) { | ||||
|             this.productList = res.data | ||||
|           } | ||||
|         }) | ||||
|       }, | ||||
|       async getProductList() { | ||||
|         let res = await sendChromeAPIMessage({ | ||||
|           url: 'marvel-mms/cn/api/kiana/venom/sales/management/listWarehouse', | ||||
|           needMallId: true, | ||||
|           mallId: this.mallId, | ||||
|           data: { | ||||
|             pageNo: this.currentPage, | ||||
|             pageSize: this.pageSize, | ||||
|             isLack: 0, | ||||
|             priceAdjustRecentDays: 7 | ||||
|         }}) | ||||
|  | ||||
|         if (res.errorCode == 1000000) { | ||||
|           for(let i = 0;i < res.result.subOrderList.length; i++) { | ||||
|             let item = res.result.subOrderList[i] | ||||
|               let data = {} | ||||
|               data.productName = item.productName | ||||
|               data.productId = item.productId | ||||
|               data.productSkcId = item.productSkcId | ||||
|               data.skcExtCode = item.skcExtCode | ||||
|               for(let j = 0;j < item.skuQuantityDetailList.length; j++) { | ||||
|                 data = {...data,  | ||||
|                   skuExtCode: item.skuQuantityDetailList[j].skuExtCode, | ||||
|                   supplierPrice: item.skuQuantityDetailList[j].supplierPrice / 100, | ||||
|                   productSkuId: item.skuQuantityDetailList[j].productSkuId, | ||||
|                   className: item.skuQuantityDetailList[j].className | ||||
|                 } | ||||
|                 this.productList.push(data) | ||||
|               } | ||||
|           } | ||||
|  | ||||
|           if ((this.currentPage * this.pageSize) < res.result.total) { | ||||
|             this.currentPage ++ | ||||
|             await this.getProductList() | ||||
|           } | ||||
|         } else { | ||||
|           await this.getProductList() | ||||
|         } | ||||
|       }, | ||||
|       async getSkuSaleNumber (page) { | ||||
|         let tempSkuId = [] | ||||
|         let i = page * 500 | ||||
|         let j = 0 | ||||
|         for (; i < this.productList.length; i++) { | ||||
|           tempSkuId.push(this.productList[i].productSkuId) | ||||
|           j ++ | ||||
|           if (j == 500) break | ||||
|         } | ||||
|         if (tempSkuId.length == 0) return | ||||
|         let res = await sendChromeAPIMessage({ | ||||
|           url: 'oms/bg/venom/api/supplier/sales/management/querySkuSalesNumber', | ||||
|           needMallId: true, | ||||
|           mallId: this.mallId, | ||||
|           data: { | ||||
|             productSkuIds: tempSkuId, | ||||
|             startDate: this.dateRange[0], | ||||
|             endDate: this.dateRange[1] | ||||
|           }}) | ||||
|           if (res.errorCode == 1000000) { | ||||
|             for (let i = 0; i < res.result.length; i++) { | ||||
|               let cost = this.getCost(res.result[i].prodSkuId) | ||||
|  | ||||
|               let flag = false | ||||
|               // 计算每日销售额 | ||||
|               let skuObj = 0 | ||||
|               for (let k = 0; k < this.productList.length; k++) { | ||||
|                 if (this.productList[k].productSkuId == res.result[i].prodSkuId) { | ||||
|                   skuObj = this.productList[k] | ||||
|                   break | ||||
|                 } | ||||
|               } | ||||
|               for (let j = 0; j < this.leftChartData.length; j++) { | ||||
|                 if (this.leftChartData[j].type == '销售额' && this.leftChartData[j].day == res.result[i].date) { | ||||
|                   this.leftChartData[j].value = this.leftChartData[j].value + skuObj.supplierPrice * res.result[i].salesNumber | ||||
|                   flag = true | ||||
|                   break | ||||
|                 } | ||||
|               } | ||||
|               if (!flag) { | ||||
|                 this.leftChartData.push({ | ||||
|                   type: '销售额', | ||||
|                   value: skuObj.supplierPrice * res.result[i].salesNumber, | ||||
|                   day: res.result[i].date | ||||
|                 }) | ||||
|               } | ||||
|  | ||||
|               // 计算每日销量 | ||||
|               flag = false | ||||
|               for (let j = 0; j < this.leftChartData.length; j++) { | ||||
|                 if (this.leftChartData[j].type == '单量' && this.leftChartData[j].day == res.result[i].date) { | ||||
|                   this.leftChartData[j].value = this.leftChartData[j].value + res.result[i].salesNumber | ||||
|                   flag = true | ||||
|                   break | ||||
|                 } | ||||
|               } | ||||
|               if (!flag) { | ||||
|                 this.leftChartData.push({ | ||||
|                   type: '单量', | ||||
|                   value: res.result[i].salesNumber, | ||||
|                   day: res.result[i].date | ||||
|                 }) | ||||
|               } | ||||
|  | ||||
|               // 计算每日成本 | ||||
|               flag = false | ||||
|               for (let j = 0; j < this.leftChartData.length; j++) { | ||||
|                 if (this.leftChartData[j].type == '成本' && this.leftChartData[j].day == res.result[i].date) { | ||||
|                   this.leftChartData[j].value = this.leftChartData[j].value + cost * res.result[i].salesNumber | ||||
|                   flag = true | ||||
|                   break | ||||
|                 } | ||||
|               } | ||||
|               if (!flag) { | ||||
|                 this.leftChartData.push({ | ||||
|                   type: '成本', | ||||
|                   value: cost * res.result[i].salesNumber, | ||||
|                   day: res.result[i].date | ||||
|                 }) | ||||
|               } | ||||
|                | ||||
|               // 计算每日利润 | ||||
|               flag = false | ||||
|               for (let j = 0; j < this.leftChartData.length; j++) { | ||||
|                 if (this.leftChartData[j].type == '利润' && this.leftChartData[j].day == res.result[i].date) { | ||||
|                   this.leftChartData[j].value = this.leftChartData[j].value + (skuObj.supplierPrice - cost) * res.result[i].salesNumber | ||||
|                   flag = true | ||||
|                   break | ||||
|                 } | ||||
|               } | ||||
|               if (!flag) { | ||||
|                 this.leftChartData.push({ | ||||
|                   type: '利润', | ||||
|                   value: (skuObj.supplierPrice - cost) * res.result[i].salesNumber, | ||||
|                   day: res.result[i].date | ||||
|                 }) | ||||
|               } | ||||
|  | ||||
|               // 计算SKU维度销售额 | ||||
|               flag = false | ||||
|               for (let j = 0; j < this.skuList.length; j++) { | ||||
|                 if (this.skuList[j].productSkuId == res.result[i].prodSkuId) { | ||||
|                   this.skuList[j].saleAmount = this.skuList[j].saleAmount + skuObj.supplierPrice * res.result[i].salesNumber | ||||
|                   this.skuList[j].costAmount = this.skuList[j].costAmount + cost * res.result[i].salesNumber | ||||
|                   this.skuList[j].saleCount = this.skuList[j].saleCount + res.result[i].salesNumber | ||||
|                   this.skuList[j].profitAmount = this.skuList[j].profitAmount + (skuObj.supplierPrice - cost) * res.result[i].salesNumber | ||||
|                   flag = true | ||||
|                   break | ||||
|                 } | ||||
|               } | ||||
|               if (!flag) { | ||||
|                 this.skuList.push({ | ||||
|                   productSkcId: skuObj.productSkcId, | ||||
|                   productSkuId: skuObj.productSkuId, | ||||
|                   skcExtCode: skuObj.skcExtCode, | ||||
|                   skuExtCode: skuObj.skuExtCode, | ||||
|                   saleAmount: skuObj.supplierPrice * res.result[i].salesNumber, | ||||
|                   costAmount: cost * res.result[i].salesNumber, | ||||
|                   profitAmount: (skuObj.supplierPrice - cost) * res.result[i].salesNumber, | ||||
|                   saleCount: res.result[i].salesNumber, | ||||
|                   profitPercent: Math.round((skuObj.supplierPrice - cost) / skuObj.supplierPrice * 10000) / 100 | ||||
|                 }) | ||||
|               } | ||||
|             } | ||||
|             await this.getSkuSaleNumber(page + 1) | ||||
|           } else { | ||||
|             await this.getSkuSaleNumber(page) | ||||
|           } | ||||
|       }, | ||||
|       async getSkuCostList() { | ||||
|         let res = await this.$http.post(`/api/skuCost/listAll`, null, { | ||||
|           params: { | ||||
|             mallId: this.mallId | ||||
|           } | ||||
|         }) | ||||
|         if (res.code == 0) { | ||||
|           this.productCostList = res.data | ||||
|         } | ||||
|       }, | ||||
|       getCost(sku) { | ||||
|         for (let i = 0; i < this.productCostList.length; i++) { | ||||
|           if (sku == this.productCostList[i].sku) { | ||||
|             return this.productCostList[i].costPrice | ||||
|           } | ||||
|         } | ||||
|         return 0 | ||||
|       }, | ||||
|       sleepSync(milliseconds) { | ||||
|         return new Promise(resolve => setTimeout(resolve, milliseconds)); | ||||
|       }, | ||||
|       async downloadPicture() { | ||||
|         try { | ||||
|           const element = document.getElementById('app-content'); | ||||
|           const canvas = await html2canvas(element); | ||||
|           // 创建一个图片元素 | ||||
|           const img = new Image(); | ||||
|           img.src = canvas.toDataURL('image/png'); | ||||
|           // 添加到body中以便下载 | ||||
|           document.body.appendChild(img); | ||||
|           // 触发下载 | ||||
|           const a = document.createElement('a'); | ||||
|           a.style.display = 'none' | ||||
|           a.href = img.src; | ||||
|           a.download = '近60天销售统计.png'; | ||||
|           a.click(); | ||||
|           document.body.removeChild(img); | ||||
|         } catch (error) { | ||||
|           console.error('Error saving image:', error); | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| </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; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     .top { | ||||
|       display: flex; | ||||
|       justify-content: space-between; | ||||
|       margin-bottom: 24px; | ||||
|  | ||||
|       .item { | ||||
|         flex: 1; | ||||
|         margin-right: 20px; | ||||
|         padding: 16px 24px; | ||||
|         background: #FFF; | ||||
|         box-shadow: 0px 4px 6px -2px rgba(15, 15, 21, 0.15); | ||||
|         border-radius: 4px; | ||||
|  | ||||
|         &:last-child { | ||||
|           margin-right: 0; | ||||
|         } | ||||
|  | ||||
|         &:nth-of-type(1) { | ||||
|           color: #2266ff; | ||||
|         } | ||||
|  | ||||
|         &:nth-of-type(2) { | ||||
|           color: #f8b426; | ||||
|         } | ||||
|         &:nth-of-type(3) { | ||||
|           color: #21aa99; | ||||
|         } | ||||
|         &:nth-of-type(4) { | ||||
|           color: #F46; | ||||
|         } | ||||
|         &:nth-of-type(5) { | ||||
|           color: #11A265; | ||||
|         } | ||||
|         h2 { | ||||
|           margin-bottom: 30px; | ||||
|           font-size: 16px; | ||||
|           color: #999; | ||||
|         } | ||||
|  | ||||
|         p { | ||||
|           font-weight: 600; | ||||
|           font-size: 28px; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| .like { | ||||
|     cursor: pointer; | ||||
|     font-size: 25px; | ||||
|     display: inline-block; | ||||
|   } | ||||
| </style> | ||||
| @@ -6,15 +6,50 @@ | ||||
|       isShowBottomBorder> | ||||
|     </ai-title> | ||||
|     <template slot="content"> | ||||
|       <ai-card title="待补充证书列表" style="padding-bottom: 40px;"> | ||||
|       <ai-search-bar> | ||||
|         <template #left> | ||||
|           <el-radio-group v-model="certStatus" @change="getList"> | ||||
|             <el-radio-button label="refused">已驳回</el-radio-button> | ||||
|             <el-radio-button label="waitUpload">待补充</el-radio-button> | ||||
|           </el-radio-group> | ||||
|         </template> | ||||
|         <template #right> | ||||
|           <el-button type="primary" @click="exportToExcel">导出</el-button> | ||||
|         </template> | ||||
|       </ai-search-bar> | ||||
|       <ai-card v-if="certStatus == 'refused'" title="已驳回证书列表" style="padding-bottom: 40px;"> | ||||
|         <template #right> | ||||
|           <el-button type="primary" @click="exportRefusedToExcel">导出</el-button> | ||||
|         </template> | ||||
|         <ai-table | ||||
|           :isShowPagination="false" | ||||
|           :tableData="list" | ||||
|           :col-configs="colConfigs" | ||||
|           height="600" | ||||
|           :tableData="refusedList" | ||||
|           :col-configs="refusedColConfigs" | ||||
|           height="700" | ||||
|           style="margin-top: 8px;" | ||||
|           @getList="() => {}"> | ||||
|           <el-table-column slot="auditStatus" width="120px" label="状态" align="left"> | ||||
|             <template slot-scope="scope"> | ||||
|               <div style="color: red"> | ||||
|                 审批失败 | ||||
|               </div> | ||||
|             </template> | ||||
|           </el-table-column> | ||||
|           <el-table-column slot="certName" label="证书名称" align="left"> | ||||
|             <template slot-scope="scope"> | ||||
|               <a v-for="item in scope.row.certName" :href="item.certificate_url" target="_blank">{{ item.certificate_url_name }}</a> | ||||
|             </template> | ||||
|           </el-table-column> | ||||
|         </ai-table> | ||||
|       </ai-card> | ||||
|       <ai-card v-if="certStatus == 'waitUpload'" title="待补充证书列表" style="padding-bottom: 40px;"> | ||||
|         <template #right> | ||||
|           <el-button type="primary" @click="exportWaitUploadToExcel">导出</el-button> | ||||
|         </template> | ||||
|         <ai-table | ||||
|           :isShowPagination="false" | ||||
|           :tableData="waitUploadList" | ||||
|           :col-configs="waitUploadColConfigs" | ||||
|           height="700" | ||||
|           style="margin-top: 8px;" | ||||
|           @getList="() => {}"> | ||||
|         </ai-table> | ||||
| @@ -36,9 +71,10 @@ import { saveAs } from 'file-saver' | ||||
|     data () { | ||||
|       return { | ||||
|         isLoading: false, | ||||
|         list: [], | ||||
|         mallId: '', | ||||
|         colConfigs: [ | ||||
|         certStatus: 'refused', | ||||
|         waitUploadList: [], | ||||
|         waitUploadColConfigs: [ | ||||
|           { prop: 'spu', label: 'SPU', align: 'left' }, | ||||
|           { prop: 'productName', label: '商品标题', align: 'left' }, | ||||
|           { prop: 'skc', label: 'SKC ID', align: 'left' }, | ||||
| @@ -46,7 +82,20 @@ import { saveAs } from 'file-saver' | ||||
|           { prop: 'certificateTypeName', label: '证书类型', align: 'left' }, | ||||
|           { prop: 'mergeSiteName', label: '管控地区', align: 'left' }, | ||||
|           { prop: 'subSite', label: '管控子站点', align: 'left' }, | ||||
|           { slot: 'uploadEndTime', label: '上传截止时间', align: 'left' } | ||||
|           { prop: 'uploadEndTime', label: '上传截止时间', align: 'left' } | ||||
|         ], | ||||
|         refusedList: [], | ||||
|         refusedColConfigs: [ | ||||
|           { prop: 'spu', label: 'SPU', align: 'left' }, | ||||
|           { prop: 'productName', label: '商品标题', align: 'left' }, | ||||
|           { prop: 'skc', label: 'SKC ID', align: 'left' }, | ||||
|           { prop: 'mainAttrName', label: '主规格', align: 'left' }, | ||||
|           { slot: 'auditStatus', label: '状态' }, | ||||
|           { prop: 'certificateTypeName', label: '证书类型', align: 'left' }, | ||||
|           { slot: 'certName', label: '证书名称' }, | ||||
|           { prop: 'refusedReason', label: '审核备注', align: 'left' }, | ||||
|           { prop: 'mergeSiteName', label: '管控地区', align: 'left' }, | ||||
|           { prop: 'subSite', label: '管控子站点', align: 'left' } | ||||
|         ], | ||||
|  | ||||
|         tableData: [], | ||||
| @@ -55,12 +104,33 @@ import { saveAs } from 'file-saver' | ||||
|     }, | ||||
|  | ||||
|     mounted () { | ||||
|       this.isLoading = true | ||||
|       this.getList() | ||||
|       this.$http.post('/api/malluser/info').then(res => { | ||||
|         if (res.code == 0) { | ||||
|           this.$store.commit('setUserInfo', res.data) | ||||
|           if (res.data.flag != 1) { | ||||
|             Message.error('您的账号未激活或已失效,请激活后使用') | ||||
|             this.$store.commit('setActiveDlgShow', true) | ||||
|             return; | ||||
|           } | ||||
|           this.getList() | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
|  | ||||
|     methods: { | ||||
|       async getList () { | ||||
|         this.isLoading = true | ||||
|         this.currentPage = 1 | ||||
|         if (this.certStatus == 'refused') { | ||||
|           this.refusedList = [] | ||||
|           await this.getRefusedList() | ||||
|         } else { | ||||
|           this.waitUploadList = [] | ||||
|           await this.getWaitUploadList() | ||||
|         } | ||||
|         this.isLoading = false | ||||
|       }, | ||||
|       async getWaitUploadList() { | ||||
|         let res = await sendGeiwohuoAPIMessage({ | ||||
|           url: `spmp-api-prefix/spmp/certificate/get_skc_certificate_miss_list?page_num=${this.currentPage}&page_size=200`, | ||||
|           method: 'POST', | ||||
| @@ -84,30 +154,95 @@ import { saveAs } from 'file-saver' | ||||
|               subSite: subSite.join(',') | ||||
|             } | ||||
|      | ||||
|             this.list.push(data) | ||||
|             this.waitUploadList.push(data) | ||||
|           } | ||||
|           if (res.info.data.length == 200 && (res.info.meta.count > 200*this.currentPage)) { | ||||
|             this.currentPage++ | ||||
|             await this.sleepSync(200) | ||||
|             await this.getList() | ||||
|           } else { | ||||
|             this.isLoading = false | ||||
|             await this.getWaitUploadList() | ||||
|           } | ||||
|         } else if (res.code == 100004 || res.code == 20302) { | ||||
|           this.isLoading = false | ||||
|           this.$store.commit("setSheinAlertShow", true) | ||||
|         } | ||||
|       }, | ||||
|       async getRefusedList() { | ||||
|         let res = await sendGeiwohuoAPIMessage({ | ||||
|           url: `spmp-api-prefix/spmp/certificate/get_skc_certificate_list?page_num=${this.currentPage}&page_size=200`, | ||||
|           method: 'POST', | ||||
|           data: { | ||||
|             audit_status: 3 | ||||
|           }}) | ||||
|         if (res.code == '0') { | ||||
|           for(let i = 0;i < res.info.data.length; i++) { | ||||
|             let item = res.info.data[i]; | ||||
|             let mainSite = [] | ||||
|             let subSite = [] | ||||
|             item.merge_site_info_list.map(e => { | ||||
|               mainSite.push(e.merge_site_name) | ||||
|               subSite = subSite.concat(e.sub_site_list) | ||||
|             }) | ||||
|             let data = { | ||||
|               pqmsCertificateSn: item.pqms_certificate_sn, | ||||
|               auditStatus: item.audit_status, | ||||
|               spu: item.spu_name, | ||||
|               productName: item.skc_name_cn, | ||||
|               skc: item.skc_name, | ||||
|               mainAttrName: item.main_attribute_name, | ||||
|               mergeSiteName: mainSite.join(','), | ||||
|               certificateTypeName: item.certificate_type_name, | ||||
|               certName: item.cert_file_list, | ||||
|               refusedReason: null, | ||||
|               subSite: subSite.join(',') | ||||
|             } | ||||
|      | ||||
|             this.refusedList.push(data) | ||||
|           } | ||||
|           if (res.info.data.length == 200 && (res.info.meta.count > 200*this.currentPage)) { | ||||
|             this.currentPage++ | ||||
|             await this.sleepSync(200) | ||||
|             await this.getRefusedList() | ||||
|           } else { | ||||
|             await this.getAuditInfo() | ||||
|           } | ||||
|         } else if (res.code == 100004 || res.code == 20302) { | ||||
|           this.$store.commit("setSheinAlertShow", true) | ||||
|         } | ||||
|       }, | ||||
|       async getAuditInfo() { | ||||
|         let pqmsList = [] | ||||
|         this.refusedList.map(item => { | ||||
|           pqmsList.push(item.pqmsCertificateSn) | ||||
|         }) | ||||
|  | ||||
|         let res = await sendGeiwohuoAPIMessage({ | ||||
|           url: `spmp-api-prefix/spmp/certificate/get_cert_audit_fail_reason`, | ||||
|           method: 'POST', | ||||
|           data: { | ||||
|             pqms_certificate_sn_list: pqmsList | ||||
|           }}) | ||||
|         if (res.code == '0') { | ||||
|           res.info.data.map(item => { | ||||
|             for (let i = 0; i < this.refusedList.length; i++) { | ||||
|               if (this.refusedList[i].pqmsCertificateSn == item.certificate_sn) { | ||||
|                 this.refusedList[i].refusedReason = item.fail_reason | ||||
|                 break | ||||
|               } | ||||
|             } | ||||
|           }) | ||||
|         } else if (res.code == 100004 || res.code == 20302) { | ||||
|           this.$store.commit("setSheinAlertShow", true) | ||||
|         } | ||||
|       }, | ||||
|       sleepSync(milliseconds) { | ||||
|         return new Promise(resolve => setTimeout(resolve, milliseconds)); | ||||
|       }, | ||||
|       exportToExcel() { | ||||
|       exportWaitUploadToExcel() { | ||||
|         // 假设你有一个表格数据的数组 | ||||
|         const data = [ | ||||
|           ["SPU", "商品标题", "SKC ID", "主规格", "证书类型", "管控地区", "管控子站点", "上传截止时间"] | ||||
|         ] | ||||
|  | ||||
|         this.list.map(item => { | ||||
|         this.waitUploadList.map(item => { | ||||
|           data.push([item.spu, item.productName, item.skc, item.mainAttrName, item.certificateTypeName, item.mergeSiteName, item.subSite, item.uploadEndTime]) | ||||
|         }) | ||||
|    | ||||
| @@ -128,6 +263,41 @@ import { saveAs } from 'file-saver' | ||||
|         // 使用saveAs下载文件 | ||||
|         saveAs(dataBlob, '待补充证书列表.xlsx'); | ||||
|    | ||||
|         // 清理 | ||||
|         window.URL.revokeObjectURL(blobUrl); | ||||
|       }, | ||||
|       exportRefusedToExcel() { | ||||
|         // 假设你有一个表格数据的数组 | ||||
|         const data = [ | ||||
|           ["SPU", "商品标题", "SKC ID", "主规格", "证书类型","证书名称", "证书地址", "审核备注", "管控地区", "管控子站点"] | ||||
|         ] | ||||
|  | ||||
|         this.refusedList.map(item => { | ||||
|           let certName = [], certUrl = [] | ||||
|           item.certName.map(item1 => { | ||||
|             certName.push(item1.certificate_url_name) | ||||
|             certUrl.push(item1.certificate_url) | ||||
|           }) | ||||
|           data.push([item.spu, item.productName, item.skc, item.mainAttrName, item.certificateTypeName, certName.join(','), certUrl.join(','), item.refusedReason, item.mergeSiteName, item.subSite]) | ||||
|         }) | ||||
|    | ||||
|         // 将数据转换为工作表 | ||||
|         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); | ||||
|       } | ||||
|   | ||||
| @@ -26,6 +26,7 @@ | ||||
|             style="margin-top: 8px;" | ||||
|             :current.sync="search.current" :size.sync="search.size" | ||||
|             @selection-change="handleSelectionChange" | ||||
|             height="700" | ||||
|             @getList="getList"> | ||||
|           </ai-table> | ||||
|         </div> | ||||
| @@ -140,7 +141,17 @@ import { Message } from 'element-ui' | ||||
|     }, | ||||
|  | ||||
|     created () { | ||||
|       this.getList() | ||||
|       this.$http.post('/api/malluser/info').then(res => { | ||||
|         if (res.code == 0) { | ||||
|           this.$store.commit('setUserInfo', res.data) | ||||
|           if (res.data.flag != 1) { | ||||
|             Message.error('您的账号未激活或已失效,请激活后使用') | ||||
|             this.$store.commit('setActiveDlgShow', true) | ||||
|             return; | ||||
|           } | ||||
|           this.getList() | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
|  | ||||
|     methods: { | ||||
|   | ||||
| @@ -179,9 +179,19 @@ import { saveAs } from 'file-saver' | ||||
|     }, | ||||
|  | ||||
|     mounted () { | ||||
|       this.getUserInfo() | ||||
|       this.isLoading = true | ||||
|       this.getList() | ||||
|       this.$http.post('/api/malluser/info').then(res => { | ||||
|         if (res.code == 0) { | ||||
|           this.$store.commit('setUserInfo', res.data) | ||||
|           if (res.data.flag != 1) { | ||||
|             Message.error('您的账号未激活或已失效,请激活后使用') | ||||
|             this.$store.commit('setActiveDlgShow', true) | ||||
|             return; | ||||
|           } | ||||
|           this.getUserInfo() | ||||
|           this.isLoading = true | ||||
|           this.getList() | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
|  | ||||
|     methods: { | ||||
|   | ||||
| @@ -54,7 +54,7 @@ | ||||
|           ref="table0" | ||||
|           :isShowPagination="false" | ||||
|           :tableData="filteredData" | ||||
|           height="500" | ||||
|           height="700" | ||||
|           :col-configs="colConfigs" | ||||
|           :total="filteredData.length" | ||||
|           style="margin-top: 8px;" | ||||
| @@ -134,7 +134,9 @@ import { Message } from 'element-ui' | ||||
|           {prop: 'ableSaleDays',label: '可售天数',align: 'center'}, | ||||
|           {prop: 'cost',label: '价格',width: '120px',align: 'center'}, | ||||
|           {prop: 'costPrice',label: '成本',width: '120px',align: 'center'}, | ||||
|           {prop: 'todaySale',label: '今日销量',width: '120px',align: 'center'}, | ||||
|           {prop: 'todaySale',label: '今日销量',width: '120px',align: 'center',sortable: true,'sort-method': (a, b) => { | ||||
|               return a.todaySale - b.todaySale | ||||
|             }}, | ||||
|           {prop: 'todayProfit',label: '利润',width: '120px',align: 'center',sortable: true,'sort-method': (a, b) => { | ||||
|               return a.todayProfit - b.todayProfit | ||||
|             }}, | ||||
|   | ||||
| @@ -30,8 +30,8 @@ | ||||
|           <json-excel | ||||
|               :data="skuList" | ||||
|               :fields="skuJsonFields" | ||||
|               name="SKC账单数据.xls" | ||||
|               worksheet="SKC账单数据"> | ||||
|               name="SKU账单数据.xls" | ||||
|               worksheet="SKU账单数据"> | ||||
|             <el-button type="primary" icon="el-icon-download">下载SKU统计</el-button> | ||||
|           </json-excel> | ||||
|         </div> | ||||
| @@ -310,7 +310,7 @@ import { DualAxes } from '@antv/g2plot' | ||||
|         isLoading: false, | ||||
|  | ||||
|         skcColConfigs: [ | ||||
|           { prop: 'skcCode', label: '货号', width: '180px' }, | ||||
|           { prop: 'skcCode', label: '货号', width: '250px' }, | ||||
|           { slot: 'amount', label: '销售额', align: 'center' }, | ||||
|           { prop: 'quantity', label: '单数', align: 'center' }, | ||||
|           { prop: 'cost', label: '成本', align: 'center'}, | ||||
| @@ -327,7 +327,7 @@ import { DualAxes } from '@antv/g2plot' | ||||
|           "利润率": "profitPercent", | ||||
|         }, | ||||
|         skuColConfigs: [ | ||||
|           { prop: 'skuCode', label: '属性集', width: '220px' }, | ||||
|           { prop: 'skuCode', label: '属性集', width: '250px' }, | ||||
|           { slot: 'amount', label: '销售额', align: 'center' }, | ||||
|           { prop: 'quantity', label: '单数', align: 'center' }, | ||||
|           { prop: 'cost', label: '成本', align: 'center'}, | ||||
| @@ -602,7 +602,6 @@ import { DualAxes } from '@antv/g2plot' | ||||
|                 } | ||||
|               } | ||||
|             } | ||||
|             console.log(this.leftChartData) | ||||
|             this.chartObj.changeData([this.leftChartData, this.rightChartData]) | ||||
|             this.isLoading = false | ||||
|           } | ||||
| @@ -665,6 +664,9 @@ import { DualAxes } from '@antv/g2plot' | ||||
|                   } else { | ||||
|                     break | ||||
|                   } | ||||
|                 } else if (res2.code == 100004 || res2.code == 20302) { | ||||
|                   this.isLoading = false | ||||
|                   this.$store.commit("setSheinAlertShow", true) | ||||
|                 } | ||||
|               } | ||||
|             } | ||||
|   | ||||
| @@ -21,26 +21,36 @@ | ||||
|       </template> | ||||
|     </ai-title> | ||||
|     <template slot="content"> | ||||
|       <ai-search-bar> | ||||
|         <template #left> | ||||
|           <div class="search-item"> | ||||
|             <label>状态:</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> | ||||
|           </div> | ||||
|           <div class="search-item"> | ||||
|             <label style="width:120px">备货单创建时间:</label> | ||||
|             <el-date-picker | ||||
|               v-model="form.date" | ||||
|               type="daterange" | ||||
|               range-separator="至" | ||||
|               start-placeholder="开始日期" | ||||
|               end-placeholder="结束日期"> | ||||
|             </el-date-picker> | ||||
|           </div> | ||||
|         </template> | ||||
|         <template #right> | ||||
|           <el-button type="primary" @click="toLoad">加载</el-button> | ||||
|         </template> | ||||
|       </ai-search-bar> | ||||
|       <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" | ||||
| @@ -59,6 +69,26 @@ | ||||
|           @getList="() => {}"> | ||||
|         </ai-table> | ||||
|       </ai-card> | ||||
|       <ai-card title="数据统计" style="padding-bottom: 40px;"> | ||||
|         <template #right> | ||||
|           <json-excel | ||||
|               :data="sumTableData" | ||||
|               :fields="sumJsonFields" | ||||
|               name="普通备货单统计.xls" | ||||
|               worksheet="普通备货单统计"> | ||||
|               <el-button type="primary" :disabled="sumTableData.length == 0">下载数据</el-button> | ||||
|             </json-excel> | ||||
|         </template> | ||||
|         <ai-table | ||||
|           :isShowPagination="false" | ||||
|           :tableData="sumTableData" | ||||
|           :col-configs="sumColConfigs" | ||||
|           :total="sumTableData.length" | ||||
|           height="500" | ||||
|           style="margin-top: 8px;" | ||||
|           @getList="() => {}"> | ||||
|         </ai-table> | ||||
|       </ai-card> | ||||
|     </template> | ||||
|   </ai-list> | ||||
| </template> | ||||
| @@ -116,6 +146,7 @@ import JsonExcel from 'vue-json-excel' | ||||
|           { 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: 'cost', label: '成本价格(CNY)', width: '180px', align: 'left' }, | ||||
|           { prop: 'purchaseQuantity', label: '备货件数', width: '100px', align: 'left' }, | ||||
|           { prop: 'xiadan', label: '送货数量', width: '100px', align: 'left' }, | ||||
|           { prop: 'skuNum', label: '入库数量', width: '100px', align: 'left' }, | ||||
| @@ -123,8 +154,25 @@ import JsonExcel from 'vue-json-excel' | ||||
|           { prop: 'deliverTime', label: '发货时间', width: '160px', align: 'left' }, | ||||
|           { prop: 'receiveTime', label: '收货时间', width: '160px', align: 'left' } | ||||
|         ], | ||||
|         sumTableData: [], | ||||
|         sumColConfigs: [ | ||||
|           { prop: 'productName', label: '商品名称', width: '240px', align: 'left', fixed: '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: 'cost', label: '成本价格(CNY)', width: '180px', align: 'left', sortable: true, 'sort-method': (a, b) => a.cost - b.cost }, | ||||
|           { prop: 'purchaseQuantity', label: '备货总件数', width: '100px', align: 'left', sortable: true, 'sort-method': (a, b) => a.purchaseQuantity - b.purchaseQuantity }, | ||||
|           { prop: 'xiadan', label: '送货总数量', width: '100px', align: 'left', sortable: true, 'sort-method': (a, b) => a.xiadan - b.xiadan }, | ||||
|           { prop: 'skuNum', label: '实际入库总数量', width: '100px', align: 'left', sortable: true, 'sort-method': (a, b) => a.skuNum - b.skuNum }, | ||||
|           { prop: 'costAmount', label: '成本总额', width: '140px', align: 'left', sortable: true, 'sort-method': (a, b) => a.costAmount - b.costAmount }, | ||||
|           { prop: 'profit', label: '预计利润总额', width: '160px', align: 'left', sortable: true, 'sort-method': (a, b) => a.profit - b.profit }, | ||||
|         ], | ||||
|         isLoading: false, | ||||
|         tableData: [], | ||||
|         costList: [], | ||||
|         jsonFields: { | ||||
|           "备货单创建时间": "purchaseTime", | ||||
|           "备货单号": "subPurchaseOrderSn", | ||||
| @@ -137,6 +185,7 @@ import JsonExcel from 'vue-json-excel' | ||||
|           "SKU货号": "extCode", | ||||
|           "SKU属性": "specName", | ||||
|           "申报价格(CNY)": "supplierPrice", | ||||
|           "成本价格(CNY)": "cost", | ||||
|           "备货件数": "purchaseQuantity", | ||||
|           "下单数量": "xiadan", | ||||
|           "实际入库数量": "skuNum", | ||||
| @@ -144,7 +193,22 @@ import JsonExcel from 'vue-json-excel' | ||||
|           "发货时间": "deliverTime", | ||||
|           "收货时间": "receiveTime" | ||||
|         }, | ||||
|         snList: [], | ||||
|         sumJsonFields: { | ||||
|           "商品名称": "productName", | ||||
|           "商品图片": "productSkcPicture", | ||||
|           "SKC ID": "productSkcId", | ||||
|           "SKC货号": "skcExtCode", | ||||
|           "SKU ID": "productSkuId", | ||||
|           "SKU货号": "extCode", | ||||
|           "SKU属性": "specName", | ||||
|           "申报价格(CNY)": "supplierPrice", | ||||
|           "成本价格(CNY)": "cost", | ||||
|           "备货总件数": "purchaseQuantity", | ||||
|           "送货总数量": "xiadan", | ||||
|           "实际入库总数量": "skuNum", | ||||
|           "成本总额": "costAmount", | ||||
|           "预计利润总额": "profit" | ||||
|         }, | ||||
|         currentIndex: 0 | ||||
|       } | ||||
|     }, | ||||
| @@ -168,64 +232,123 @@ import JsonExcel from 'vue-json-excel' | ||||
|           Message.error("请选择时间") | ||||
|           return | ||||
|         } | ||||
|         this.getSkuCostList() | ||||
|         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.sumTableData = [] | ||||
|         this.packageNumber = 0 | ||||
|         this.snList = [] | ||||
|         this.currentIndex = 0 | ||||
|         this.costList = [] | ||||
|         this.isLoading = true | ||||
|         this.load() | ||||
|       }, | ||||
|       load() { | ||||
|         sendChromeAPIMessage({ | ||||
|       async load() { | ||||
|         let res = await 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, | ||||
|                     purchaseQuantity: item.skuQuantityDetailList[k].purchaseQuantity, | ||||
|                     xiadan: item.skuQuantityDetailList[k].deliverQuantity, | ||||
|                     skuNum: item.skuQuantityDetailList[k].realReceiveAuthenticQuantity} | ||||
|           data: this.reqData}) | ||||
|         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, | ||||
|                 purchaseQuantity: item.skuQuantityDetailList[k].purchaseQuantity, | ||||
|                 xiadan: item.skuQuantityDetailList[k].deliverQuantity, | ||||
|                 skuNum: item.skuQuantityDetailList[k].realReceiveAuthenticQuantity, | ||||
|                 cost: null} | ||||
|  | ||||
|                     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 | ||||
|               } | ||||
|                 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.tableData.map(item => { | ||||
|               for (let i = 0; i < this.costList.length; i++) { | ||||
|                 if (this.costList[i].sku == item.productSkuId) { | ||||
|                   item.cost = this.costList[i].costPrice | ||||
|                   break | ||||
|                 } | ||||
|               } | ||||
|  | ||||
|               let flag = false | ||||
|               for (let i = 0; i < this.sumTableData.length; i++) { | ||||
|                 if (this.sumTableData[i].productSkuId == item.productSkuId) { | ||||
|                   this.sumTableData[i].xiadan += item.xiadan | ||||
|                   this.sumTableData[i].purchaseQuantity += item.purchaseQuantity | ||||
|                   this.sumTableData[i].skuNum += item.skuNum | ||||
|                   flag = true | ||||
|                   break | ||||
|                 } | ||||
|               } | ||||
|               if (!flag) { | ||||
|                 this.sumTableData.push({ | ||||
|                   productName: item.productName, | ||||
|                   productSkcPicture: item.productSkcPicture, | ||||
|                   productSkcId: item.productSkcId, | ||||
|                   productSkuId: item.productSkuId, | ||||
|                   xiadan: item.xiadan, | ||||
|                   purchaseQuantity: item.purchaseQuantity, | ||||
|                   skuNum: item.skuNum, | ||||
|                   skcExtCode: item.skcExtCode, | ||||
|                   extCode: item.extCode, | ||||
|                   supplierPrice: item.supplierPrice, | ||||
|                   specName: item.specName, | ||||
|                   cost: null, | ||||
|                   costAmount: null, | ||||
|                   profit: null | ||||
|                 }) | ||||
|               } | ||||
|             }) | ||||
|             this.sumTableData.map(item => { | ||||
|               for (let i = 0; i < this.costList.length; i++) { | ||||
|                 if (this.costList[i].sku == item.productSkuId) { | ||||
|                   item.cost = this.costList[i].costPrice | ||||
|                   item.costAmount = Math.round(this.costList[i].costPrice * item.skuNum * 100) / 100 | ||||
|                   item.profit = Math.round((item.supplierPrice - item.cost) * item.skuNum * 100) / 100 | ||||
|                   break | ||||
|                 } | ||||
|               } | ||||
|             }) | ||||
|             this.isLoading = false | ||||
|           } | ||||
|         } | ||||
|       }, | ||||
|       async getSkuCostList() { | ||||
|         let res = await this.$http.post(`/api/skuCost/listAll`, null, { | ||||
|           params: { | ||||
|             mallId: this.form.mallId | ||||
|           } | ||||
|         }) | ||||
|         if (res.code == 0) { | ||||
|           this.costList = res.data | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   | ||||
| @@ -21,26 +21,36 @@ | ||||
|       </template> | ||||
|     </ai-title> | ||||
|     <template slot="content"> | ||||
|       <ai-search-bar> | ||||
|         <template #left> | ||||
|           <div class="search-item"> | ||||
|             <label>状态:</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> | ||||
|           </div> | ||||
|           <div class="search-item"> | ||||
|             <label style="width:120px">备货单创建时间:</label> | ||||
|             <el-date-picker | ||||
|               v-model="form.date" | ||||
|               type="daterange" | ||||
|               range-separator="至" | ||||
|               start-placeholder="开始日期" | ||||
|               end-placeholder="结束日期"> | ||||
|             </el-date-picker> | ||||
|           </div> | ||||
|         </template> | ||||
|         <template #right> | ||||
|           <el-button type="primary" @click="toLoad">加载</el-button> | ||||
|         </template> | ||||
|       </ai-search-bar> | ||||
|       <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" | ||||
| @@ -59,6 +69,26 @@ | ||||
|           @getList="() => {}"> | ||||
|         </ai-table> | ||||
|       </ai-card> | ||||
|       <ai-card title="数据统计" style="padding-bottom: 40px;"> | ||||
|         <template #right> | ||||
|           <json-excel | ||||
|               :data="sumTableData" | ||||
|               :fields="sumJsonFields" | ||||
|               name="紧急备货单统计.xls" | ||||
|               worksheet="紧急备货单统计"> | ||||
|               <el-button type="primary" :disabled="sumTableData.length == 0">下载数据</el-button> | ||||
|             </json-excel> | ||||
|         </template> | ||||
|         <ai-table | ||||
|           :isShowPagination="false" | ||||
|           :tableData="sumTableData" | ||||
|           :col-configs="sumColConfigs" | ||||
|           :total="sumTableData.length" | ||||
|           height="500" | ||||
|           style="margin-top: 8px;" | ||||
|           @getList="() => {}"> | ||||
|         </ai-table> | ||||
|       </ai-card> | ||||
|     </template> | ||||
|   </ai-list> | ||||
| </template> | ||||
| @@ -123,8 +153,24 @@ import JsonExcel from 'vue-json-excel' | ||||
|           { prop: 'deliverTime', label: '发货时间', width: '160px', align: 'left' }, | ||||
|           { prop: 'receiveTime', label: '收货时间', width: '160px', align: 'left' } | ||||
|         ], | ||||
|         sumTableData: [], | ||||
|         sumColConfigs: [ | ||||
|           { prop: 'productName', label: '商品名称', width: '240px', align: 'left', fixed: '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: 'cost', label: '成本价格(CNY)', width: '180px', align: 'left', sortable: true, 'sort-method': (a, b) => a.cost - b.cost }, | ||||
|           { prop: 'xiadan', label: '送货总数量', width: '100px', align: 'left', sortable: true, 'sort-method': (a, b) => a.xiadan - b.xiadan }, | ||||
|           { prop: 'skuNum', label: '实际入库总数量', width: '100px', align: 'left', sortable: true, 'sort-method': (a, b) => a.skuNum - b.skuNum }, | ||||
|           { prop: 'costAmount', label: '成本总额', width: '140px', align: 'left', sortable: true, 'sort-method': (a, b) => a.costAmount - b.costAmount }, | ||||
|           { prop: 'profit', label: '预计利润总额', width: '160px', align: 'left', sortable: true, 'sort-method': (a, b) => a.profit - b.profit }, | ||||
|         ], | ||||
|         isLoading: false, | ||||
|         tableData: [], | ||||
|         costList: [], | ||||
|         jsonFields: { | ||||
|           "备货单创建时间": "purchaseTime", | ||||
|           "备货单号": "subPurchaseOrderSn", | ||||
| @@ -143,7 +189,21 @@ import JsonExcel from 'vue-json-excel' | ||||
|           "发货时间": "deliverTime", | ||||
|           "收货时间": "receiveTime" | ||||
|         }, | ||||
|         snList: [], | ||||
|         sumJsonFields: { | ||||
|           "商品名称": "productName", | ||||
|           "商品图片": "productSkcPicture", | ||||
|           "SKC ID": "productSkcId", | ||||
|           "SKC货号": "skcExtCode", | ||||
|           "SKU ID": "productSkuId", | ||||
|           "SKU货号": "extCode", | ||||
|           "SKU属性": "specName", | ||||
|           "申报价格(CNY)": "supplierPrice", | ||||
|           "成本价格(CNY)": "cost", | ||||
|           "送货总数量": "xiadan", | ||||
|           "实际入库总数量": "skuNum", | ||||
|           "成本总额": "costAmount", | ||||
|           "预计利润总额": "profit" | ||||
|         }, | ||||
|         currentIndex: 0 | ||||
|       } | ||||
|     }, | ||||
| @@ -167,13 +227,14 @@ import JsonExcel from 'vue-json-excel' | ||||
|           Message.error("请选择时间") | ||||
|           return | ||||
|         } | ||||
|         this.getSkuCostList() | ||||
|         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.costList = [] | ||||
|         this.packageNumber = 0 | ||||
|         this.snList = [] | ||||
|         this.currentIndex = 0 | ||||
|         this.isLoading = true | ||||
|         this.load() | ||||
| @@ -220,10 +281,59 @@ import JsonExcel from 'vue-json-excel' | ||||
|                 this.reqData.pageNo ++ | ||||
|                 this.load() | ||||
|               } else { | ||||
|                 this.tableData.map(item => { | ||||
|                   let flag = false | ||||
|                   for (let i = 0; i < this.sumTableData.length; i++) { | ||||
|                     if (this.sumTableData[i].productSkuId == item.productSkuId) { | ||||
|                       this.sumTableData[i].xiadan += item.xiadan | ||||
|                       this.sumTableData[i].purchaseQuantity += item.purchaseQuantity | ||||
|                       this.sumTableData[i].skuNum += item.skuNum | ||||
|                       flag = true | ||||
|                       break | ||||
|                     } | ||||
|                   } | ||||
|                   if (!flag) { | ||||
|                     this.sumTableData.push({ | ||||
|                       productName: item.productName, | ||||
|                       productSkcPicture: item.productSkcPicture, | ||||
|                       productSkcId: item.productSkcId, | ||||
|                       productSkuId: item.productSkuId, | ||||
|                       xiadan: item.xiadan, | ||||
|                       skuNum: item.skuNum, | ||||
|                       skcExtCode: item.skcExtCode, | ||||
|                       extCode: item.extCode, | ||||
|                       supplierPrice: item.supplierPrice, | ||||
|                       specName: item.specName, | ||||
|                       cost: null, | ||||
|                       costAmount: null, | ||||
|                       profit: null | ||||
|                     }) | ||||
|                   } | ||||
|                 }) | ||||
|                 this.sumTableData.map(item => { | ||||
|                   for (let i = 0; i < this.costList.length; i++) { | ||||
|                     if (this.costList[i].sku == item.productSkuId) { | ||||
|                       item.cost = this.costList[i].costPrice | ||||
|                       item.costAmount = Math.round(this.costList[i].costPrice * item.skuNum * 100) / 100 | ||||
|                       item.profit = Math.round((item.supplierPrice - item.cost) * item.skuNum * 100) / 100 | ||||
|                       break | ||||
|                     } | ||||
|                   } | ||||
|                 }) | ||||
|                 this.isLoading = false | ||||
|               } | ||||
|             } | ||||
|           }) | ||||
|       }, | ||||
|       async getSkuCostList() { | ||||
|         let res = await this.$http.post(`/api/skuCost/listAll`, null, { | ||||
|           params: { | ||||
|             mallId: this.form.mallId | ||||
|           } | ||||
|         }) | ||||
|         if (res.code == 0) { | ||||
|           this.costList = res.data | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   | ||||
| @@ -432,6 +432,7 @@ | ||||
|           this.isDlgLoading = true | ||||
|           this.getList(this.tableData, this.mallId, this.mallName, 1) | ||||
|         }).catch((err) => { | ||||
|           this.mallId = '' | ||||
|           console.log(err) | ||||
|         }) | ||||
|       }, | ||||
| @@ -688,11 +689,19 @@ | ||||
|                 this.createDeliveryBill(sn, mallId) | ||||
|               } | ||||
|             } else { | ||||
|               this.choosedSnMallList.push(obj) | ||||
|               for (let j = 0; j < this.choosedList.length; j++) { | ||||
|                 if (this.choosedList[j].subPurchaseOrderSn == sn) { | ||||
|                   this.choosedList[j].robTotal ++; | ||||
|                   break; | ||||
|               if (res.result?.errorInfoList[0] && res.result?.errorInfoList[0].errorCode == 60002) { | ||||
|                 for (let j = 0; j < this.choosedList.length; j++) { | ||||
|                   if (this.choosedList[j].subPurchaseOrderSn == sn) { | ||||
|                     this.choosedList.splice(j, 1); | ||||
|                   } | ||||
|                 } | ||||
|               } else { | ||||
|                 this.choosedSnMallList.push(obj) | ||||
|                 for (let j = 0; j < this.choosedList.length; j++) { | ||||
|                   if (this.choosedList[j].subPurchaseOrderSn == sn) { | ||||
|                     this.choosedList[j].robTotal ++; | ||||
|                     break; | ||||
|                   } | ||||
|                 } | ||||
|               } | ||||
|             } | ||||
|   | ||||
							
								
								
									
										237
									
								
								src/view/shipping/ProductLabel.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										237
									
								
								src/view/shipping/ProductLabel.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,237 @@ | ||||
| <template> | ||||
|   <ai-list class="list" v-loading="isLoading" element-loading-text="拼命加载中" element-loading-spinner="el-icon-loading"> | ||||
|     <ai-title | ||||
|       slot="title" | ||||
|       title="商品条码管理" | ||||
|       tips="每页为100条商品数据" | ||||
|       isShowBottomBorder> | ||||
|       <template #rightBtn> | ||||
|         <div class="title-right"> | ||||
|           <div> | ||||
|             <label style="width:90px">店铺:</label> | ||||
|             <el-select v-model="form.mallId" 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"> | ||||
|       <div class="content"> | ||||
|         <ai-search-bar> | ||||
|           <template #left> | ||||
|             <div class="search-item"> | ||||
|               <label>起始页:</label> | ||||
|               <el-input size="small"  placeholder="请输入起始页" type="number" v-model="startPage"></el-input> | ||||
|             </div> | ||||
|             <div class="search-item"> | ||||
|               <label>结束页:</label> | ||||
|               <el-input size="small"  placeholder="请输入起始页" type="number" v-model="endPage"></el-input> | ||||
|             </div> | ||||
|           </template> | ||||
|           <template #right> | ||||
|             <el-button type="primary" @click="toLoad">加载</el-button> | ||||
|           </template> | ||||
|         </ai-search-bar> | ||||
|         <ai-card title="数据明细" style="padding-bottom: 40px;"> | ||||
|           <template #right> | ||||
|             <el-button type="primary" :disabled="tableData.length == 0" @click="exportWaitUploadToExcel">导出</el-button> | ||||
|           </template> | ||||
|           <ai-table | ||||
|             :isShowPagination="false" | ||||
|             :tableData="tableData" | ||||
|             :col-configs="colConfigs" | ||||
|             :total="tableData.length" | ||||
|             height="700" | ||||
|             style="margin-top: 8px;" | ||||
|             @getList="() => {}"> | ||||
|  | ||||
|             <el-table-column slot="productName" width="300px" :show-overflow-tooltip='true' label="商品名称"  fixed="left"> | ||||
|               <template slot-scope="scope"> | ||||
|                 <div> | ||||
|                   <el-image :src="scope.row.mainImageUrl" style="width: 40px; height: 40px" class="image" :preview-src-list="[scope.row.mainImageUrl]" /> | ||||
|                   {{ scope.row.productName }} | ||||
|                 </div> | ||||
|               </template> | ||||
|             </el-table-column> | ||||
|           </ai-table> | ||||
|         </ai-card> | ||||
|       </div> | ||||
|     </template> | ||||
|   </ai-list> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import { Message } from 'element-ui' | ||||
| import {sendChromeAPIMessage} from '@/api/chromeApi' | ||||
| import {timestampToTime} from '@/utils/date' | ||||
| import * as XLSX from 'xlsx' | ||||
| import { saveAs } from 'file-saver' | ||||
|  | ||||
|   export default { | ||||
|     name: 'ProductLabel', | ||||
|  | ||||
|     data () { | ||||
|       return { | ||||
|         form: { | ||||
|           mallId: '' | ||||
|         }, | ||||
|         startPage: 1, | ||||
|         endPage: 10, | ||||
|         reqData: { | ||||
|           page: 1, | ||||
|           pageSize: 100 | ||||
|         }, | ||||
|         colConfigs: [ | ||||
|           { slot: 'productName', label: '商品名称', width: '300px', align: 'left', fixed: 'left' }, | ||||
|           { prop: 'category', label: '分类', width: '140px', align: 'left', fixed: 'left' }, | ||||
|           { prop: 'labelCode', label: '条码编码', align: 'left' }, | ||||
|           { prop: 'productSkcId', label: 'SKC', align: 'left' }, | ||||
|           { prop: 'productSkuId', label: 'SKU', align: 'left' }, | ||||
|           { prop: 'extCode', label: 'SKC货号', align: 'left' }, | ||||
|           { prop: 'skuExtCode', label: 'SKU货号',  align: 'left' }, | ||||
|           { prop: 'skcSpecName', label: '主销售属性',  align: 'left' }, | ||||
|           { prop: 'skuSpecName', label: '次销售属性', width: '100px', align: 'left' } | ||||
|         ], | ||||
|         isLoading: false, | ||||
|         tableData: [], | ||||
|         currentIndex: 0 | ||||
|       } | ||||
|     }, | ||||
|     created () { | ||||
|     }, | ||||
|     methods: { | ||||
|       beforeGetList() { | ||||
|         this.$userCheck(this.form.mallId).then(() => { | ||||
|           this.toLoad() | ||||
|         }).catch((err) => { | ||||
|           this.form.mallId = '' | ||||
|         }) | ||||
|       }, | ||||
|       toLoad() { | ||||
|         if (!this.form.mallId) { | ||||
|           Message.error("请选择店铺") | ||||
|           return | ||||
|         } | ||||
|         if (!this.startPage || (this.startPage < 1)) { | ||||
|           Message.error("起始页不能为空,且不能小于1") | ||||
|           return | ||||
|         } | ||||
|         if (!this.endPage || (this.startPage < 1)) { | ||||
|           Message.error("结束页不能为空") | ||||
|           return | ||||
|         } | ||||
|         if (this.startPage > this.endPage) { | ||||
|           Message.error("起始页不能大于结束页") | ||||
|           return | ||||
|         } | ||||
|         this.$userCheck(this.form.mallId).then(() => { | ||||
|           this.reqData.page = this.startPage | ||||
|           this.tableData = [] | ||||
|           this.currentIndex = 0 | ||||
|           this.isLoading = true | ||||
|           this.load() | ||||
|         }).catch((err) => { | ||||
|           this.form.mallId = '' | ||||
|         }) | ||||
|       }, | ||||
|       load() { | ||||
|         sendChromeAPIMessage({ | ||||
|           url: 'bg-visage-mms/labelcode/pageQuery', | ||||
|           needMallId: true, | ||||
|           mallId: this.form.mallId, | ||||
|           anti: true, | ||||
|           data: this.reqData}).then((res) => { | ||||
|             if (res.errorCode == 1000000) { | ||||
|               for(let i = 0;i < res.result.pageItems.length; i++) { | ||||
|                 let item = res.result.pageItems[i]; | ||||
|                 let data = {}; | ||||
|                 data.productName = item.productName | ||||
|                 data.mainImageUrl = item.displayImage | ||||
|                 data.productSkcId = item.labelCodeVO.productSkcId | ||||
|                 data.productSkuId = item.labelCodeVO.productSkuId | ||||
|                 data.labelCode = item.labelCodeVO.labelCode | ||||
|                 data.extCode = item.labelCodeVO.skcExtCode | ||||
|                 data.skuExtCode = item.labelCodeVO.skuExtCode | ||||
|                 data.category = item.leafCat.catName | ||||
|  | ||||
|                 let temp = item.productSkcSpecList.map(item2 => { | ||||
|                   return item2.specName | ||||
|                 }) | ||||
|                 data.skcSpecName = temp.join(',') | ||||
|  | ||||
|                 temp = item.productSkuSpecList.map(item2 => { | ||||
|                   return item2.specName | ||||
|                 }) | ||||
|                 data.skuSpecName = temp.join(',') | ||||
|  | ||||
|                 this.tableData.push(data) | ||||
|  | ||||
|               } | ||||
|               if (res.result.pageItems.length == this.reqData.pageSize && this.reqData.page < this.endPage) { | ||||
|                 this.reqData.page ++ | ||||
|                 this.load() | ||||
|               } else { | ||||
|                 this.isLoading = false | ||||
|               } | ||||
|             } | ||||
|           }) | ||||
|       }, | ||||
|       exportWaitUploadToExcel() { | ||||
|         // 假设你有一个表格数据的数组 | ||||
|         const data = [ | ||||
|           ["商品名称", "分类", "条码编码", "SKC","SKU", "SKC货号", "SKU货号", "主销售属性", "次销售属性"] | ||||
|         ] | ||||
|  | ||||
|         this.tableData.map(item => { | ||||
|           data.push([item.productName, item.category, item.labelCode, item.productSkcId, item.productSkuId, item.extCode, item.skuExtCode, item.skcSpecName, item.skuSpecName]) | ||||
|         }) | ||||
|    | ||||
|         // 将数据转换为工作表 | ||||
|         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); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| </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> | ||||
| @@ -256,6 +256,7 @@ | ||||
|           this.isDlgLoading = true | ||||
|           this.getList(this.tableData, this.mallId, this.mallName, 1) | ||||
|         }).catch((err) => { | ||||
|           this.mallId = '' | ||||
|           console.log(err) | ||||
|         }) | ||||
|       }, | ||||
|   | ||||
| @@ -216,6 +216,7 @@ | ||||
|           this.isDlgLoading = true | ||||
|           this.getList(this.tableData, this.mallId, this.mallName, 1) | ||||
|         }).catch((err) => { | ||||
|           this.mallId = '' | ||||
|           console.log(err) | ||||
|         }) | ||||
|       }, | ||||
|   | ||||
| @@ -123,6 +123,7 @@ import { Message } from 'element-ui' | ||||
|           this.skcIds = [] | ||||
|           this.getList() | ||||
|         }).catch((err) => { | ||||
|           this.mallId = '' | ||||
|           this.isLoading = false | ||||
|         }) | ||||
|       }, | ||||
|   | ||||
| @@ -121,6 +121,7 @@ import { Message } from 'element-ui' | ||||
|           this.isLoading = true | ||||
|           this.getList() | ||||
|         }).catch((err) => { | ||||
|           this.mallId = '' | ||||
|           this.isLoading = false | ||||
|         }) | ||||
|       }, | ||||
|   | ||||
| @@ -51,6 +51,7 @@ | ||||
|             </json-excel> | ||||
|           </template> | ||||
|           <ai-table | ||||
|               :isShowPagination="false" | ||||
|               :tableData="tableData" | ||||
|               :col-configs="colConfigs" | ||||
|               :total="total" | ||||
| @@ -70,6 +71,26 @@ | ||||
|               </el-table-column> | ||||
|             </ai-table> | ||||
|         </ai-card> | ||||
|         <ai-card title="数据统计" style="padding-bottom: 40px;"> | ||||
|           <template #right> | ||||
|             <json-excel | ||||
|                 :data="sumTableData" | ||||
|                 :fields="sumJsonFields" | ||||
|                 name="退货统计.xls" | ||||
|                 worksheet="退货统计"> | ||||
|                 <el-button type="primary" :disabled="sumTableData.length == 0">下载数据</el-button> | ||||
|               </json-excel> | ||||
|           </template> | ||||
|           <ai-table | ||||
|             :isShowPagination="false" | ||||
|             :tableData="sumTableData" | ||||
|             :col-configs="sumColConfigs" | ||||
|             :total="sumTableData.length" | ||||
|             height="500" | ||||
|             style="margin-top: 8px;" | ||||
|             @getList="() => {}"> | ||||
|           </ai-table> | ||||
|         </ai-card> | ||||
|       </div> | ||||
|     </template> | ||||
|   </ai-list> | ||||
| @@ -98,8 +119,18 @@ import { Message } from 'element-ui' | ||||
|           { prop: 'orderTypeDesc', label: '退货原因',width: '220px', align: 'left' }, | ||||
|           { prop: 'packageSn', label: '退货包裹号', width: '200px',align: 'left' }, | ||||
|           { prop: 'quantity', label: 'SKU件数',width: '100px', }, | ||||
|           { prop: 'cost', label: '成本单价' }, | ||||
|           { prop: 'outboundTime', label: '出库时间', width: '160px'} | ||||
|         ], | ||||
|         sumColConfigs: [ | ||||
|           { prop: 'productSkcId', label: 'SKC', align: 'left', fixed: 'left' }, | ||||
|           { prop: 'productSkuId', label: 'SKU', align: 'left', fixed: 'left' }, | ||||
|           { prop: 'skuExtCode', label: 'SKU属性', align: 'left', fixed: 'left' }, | ||||
|           { prop: 'secondarySaleSpec', label: '属性集', align: 'left', fixed: 'left' }, | ||||
|           { prop: 'quantity', label: 'SKU总件数', sortable: true, 'sort-method': (a, b) => a.quantity - b.quantity }, | ||||
|           { prop: 'costPrice', label: '成本价', sortable: true, 'sort-method': (a, b) => a.costPrice - b.costPrice}, | ||||
|           { prop: 'costAmount', label: '成本总额', sortable: true, 'sort-method': (a, b) => a.costAmount - b.costAmount} | ||||
|         ], | ||||
|         jsonFields: { | ||||
|           "SPU": "productSpuId", | ||||
|           "SKC": "productSkcId", | ||||
| @@ -112,8 +143,19 @@ import { Message } from 'element-ui' | ||||
|           "退货原因": "orderTypeDesc", | ||||
|           "退货包裹号": "packageSn", | ||||
|           "SKU件数": "quantity", | ||||
|           "成本单价": "cost", | ||||
|           "出库时间": "outboundTime" | ||||
|         }, | ||||
|         sumJsonFields: { | ||||
|           "SKC": "productSkcId", | ||||
|           "SKU": "productSkuId", | ||||
|           "SKU属性": "skuExtCode", | ||||
|           "图片地址": "thumbUrl", | ||||
|           "属性集": "secondarySaleSpec", | ||||
|           "SKU总件数": "quantity", | ||||
|           "成本价": "costPrice", | ||||
|           "成本总额": "costAmount" | ||||
|         }, | ||||
|         form: { | ||||
|           mallId: '', | ||||
|           date: '' | ||||
| @@ -122,6 +164,8 @@ import { Message } from 'element-ui' | ||||
|         pageSize: 100, | ||||
|  | ||||
|         tableData: [], | ||||
|         sumTableData: [], | ||||
|         costList: [], | ||||
|         total: 0, | ||||
|         search: { | ||||
|           current: 1, | ||||
| @@ -163,6 +207,7 @@ import { Message } from 'element-ui' | ||||
|         } | ||||
|         this.currentPage = 1 | ||||
|         this.tableData = [] | ||||
|         this.sumTableData = [] | ||||
|  | ||||
|         let startTime = this.form.date[1].getTime() - 30 * 24 * 60 * 60 * 1000 | ||||
|         if (startTime < this.form.date[0].getTime()) { | ||||
| @@ -196,6 +241,7 @@ import { Message } from 'element-ui' | ||||
|               data.packageSn = item.packageSn | ||||
|               data.quantity = item.quantity | ||||
|               data.outboundTime = timestampToTime(item.outboundTime) | ||||
|               data.cost = null | ||||
|                | ||||
|               this.tableData.push(data) | ||||
|             } | ||||
| @@ -215,7 +261,8 @@ import { Message } from 'element-ui' | ||||
|                 this.getList(startTimeTemp, endTimeTemp) | ||||
|               } else { | ||||
|                 this.getDeliverySn(1) | ||||
|                 this.getSkuExtCode(1) | ||||
|                  | ||||
|                 this.getSkuCostList() | ||||
|                 this.isLoading = false | ||||
|               } | ||||
|             } | ||||
| @@ -288,6 +335,58 @@ import { Message } from 'element-ui' | ||||
|           await getSkuExtCode(pageNo + 1) | ||||
|         } | ||||
|       }, | ||||
|       calcAmount() { | ||||
|         this.tableData.map(item => { | ||||
|           for (let i = 0; i < this.costList.length; i++) { | ||||
|             if (item.productSkuId == this.costList[i].sku) { | ||||
|               item.cost = this.costList[i].costPrice | ||||
|               break | ||||
|             } | ||||
|           } | ||||
|  | ||||
|           let flag = false | ||||
|           for (let i = 0; i < this.sumTableData.length; i++) { | ||||
|             if (item.productSkuId == this.sumTableData[i].productSkuId) { | ||||
|               this.sumTableData[i].quantity += item.quantity | ||||
|               flag = true | ||||
|               break | ||||
|             } | ||||
|           } | ||||
|           if (!flag) { | ||||
|             this.sumTableData.push({ | ||||
|               productSkcId: item.productSkcId, | ||||
|               productSkuId: item.productSkuId, | ||||
|               skuExtCode: item.skuExtCode, | ||||
|               secondarySaleSpec: item.secondarySaleSpec, | ||||
|               thumbUrl: item.thumbUrl, | ||||
|               quantity: item.quantity, | ||||
|               costPrice: null, | ||||
|               costAmount: null | ||||
|             }) | ||||
|           } | ||||
|         }) | ||||
|         this.sumTableData.map(item => { | ||||
|           for (let i = 0; i < this.costList.length; i++) { | ||||
|             if (this.costList[i].sku == item.productSkuId) { | ||||
|               item.costPrice = this.costList[i].costPrice | ||||
|               item.costAmount = Math.round(this.costList[i].costPrice * item.quantity * 100) / 100 | ||||
|               break | ||||
|             } | ||||
|           } | ||||
|         }) | ||||
|       }, | ||||
|       async getSkuCostList() { | ||||
|         await this.getSkuExtCode(1) | ||||
|         let res = await this.$http.post(`/api/skuCost/listAll`, null, { | ||||
|           params: { | ||||
|             mallId: this.form.mallId | ||||
|           } | ||||
|         }) | ||||
|         if (res.code == 0) { | ||||
|           this.costList = res.data | ||||
|           this.calcAmount() | ||||
|         } | ||||
|       }, | ||||
|       startDownload() { | ||||
|         this.$http.post('/api/malluser/info').then(res => { | ||||
|           if (res.code == 0) { | ||||
|   | ||||
| @@ -54,7 +54,7 @@ | ||||
|               :tableData="tableData" | ||||
|               :col-configs="colConfigs" | ||||
|               :total="total" | ||||
|               height="500" | ||||
|               height="700" | ||||
|               style="margin-top: 8px;" | ||||
|               @getList="getList"> | ||||
|             </ai-table> | ||||
|   | ||||
							
								
								
									
										39
									
								
								yarn.lock
									
									
									
									
									
								
							
							
						
						
									
										39
									
								
								yarn.lock
									
									
									
									
									
								
							| @@ -492,6 +492,11 @@ | ||||
|   resolved "https://registry.npmmirror.com/@babel/parser/-/parser-7.22.10.tgz" | ||||
|   integrity sha512-lNbdGsQb9ekfsnjFGhEiF4hfFqGgfOP3H3d27re3n+CGhNuTSUEQdfWk556sTLNTloczcdM5TYF2LhzmDQKyvQ== | ||||
|  | ||||
| "@babel/parser@^7.23.5": | ||||
|   version "7.24.8" | ||||
|   resolved "https://registry.npmmirror.com/@babel/parser/-/parser-7.24.8.tgz#58a4dbbcad7eb1d48930524a3fd93d93e9084c6f" | ||||
|   integrity sha512-WzfbgXOkGzZiXXCqk43kKwZjzwx4oulxZi3nq2TYL9mOjQv6kYwul9mz6ID36njuL7Xkp6nJEfok848Zj10j/w== | ||||
|  | ||||
| "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.22.5": | ||||
|   version "7.22.5" | ||||
|   resolved "https://registry.npmmirror.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.22.5.tgz" | ||||
| @@ -1848,6 +1853,17 @@ | ||||
|     postcss "^8.4.14" | ||||
|     source-map "^0.6.1" | ||||
|  | ||||
| "@vue/compiler-sfc@2.7.16": | ||||
|   version "2.7.16" | ||||
|   resolved "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-2.7.16.tgz#ff81711a0fac9c68683d8bb00b63f857de77dc83" | ||||
|   integrity sha512-KWhJ9k5nXuNtygPU7+t1rX6baZeqOYLEforUPjgNDBnLicfHCoi48H87Q8XyLZOrNNsmhuwKqtpDQWjEFe6Ekg== | ||||
|   dependencies: | ||||
|     "@babel/parser" "^7.23.5" | ||||
|     postcss "^8.4.14" | ||||
|     source-map "^0.6.1" | ||||
|   optionalDependencies: | ||||
|     prettier "^1.18.2 || ^2.0.0" | ||||
|  | ||||
| "@vue/component-compiler-utils@^3.1.0", "@vue/component-compiler-utils@^3.3.0": | ||||
|   version "3.3.0" | ||||
|   resolved "https://registry.npmmirror.com/@vue/component-compiler-utils/-/component-compiler-utils-3.3.0.tgz" | ||||
| @@ -2378,6 +2394,16 @@ batch@0.6.1: | ||||
|   resolved "https://registry.npmmirror.com/batch/-/batch-0.6.1.tgz" | ||||
|   integrity sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw== | ||||
|  | ||||
| bi-vue-mindmap@^0.6.12: | ||||
|   version "0.6.12" | ||||
|   resolved "https://registry.npmmirror.com/bi-vue-mindmap/-/bi-vue-mindmap-0.6.12.tgz#092202bd224ed49dd133a1c6490fe7330848a280" | ||||
|   integrity sha512-cKfKB5rm3L+391iV9RPkfC8lIKx9xAhW6shpGnXHPwZcboIpW+ZjPpq2vaJ0qlXH96i4VMW2Xk6StBMVRQ2GDw== | ||||
|   dependencies: | ||||
|     core-js "^3.6.5" | ||||
|     vue "^2.6.11" | ||||
|     vue-router "^3.2.0" | ||||
|     vuex "^3.4.0" | ||||
|  | ||||
| big.js@^5.2.2: | ||||
|   version "5.2.2" | ||||
|   resolved "https://registry.npmmirror.com/big.js/-/big.js-5.2.2.tgz" | ||||
| @@ -2955,6 +2981,11 @@ core-js@^2.4.0: | ||||
|   resolved "https://registry.npmmirror.com/core-js/-/core-js-2.6.12.tgz" | ||||
|   integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ== | ||||
|  | ||||
| core-js@^3.6.5: | ||||
|   version "3.37.1" | ||||
|   resolved "https://registry.npmmirror.com/core-js/-/core-js-3.37.1.tgz#d21751ddb756518ac5a00e4d66499df981a62db9" | ||||
|   integrity sha512-Xn6qmxrQZyB0FFY8E3bgRXei3lWDJHhvI+u0q9TKIYM49G8pAr0FgnnrFRAmsbptZL1yxRADVXn+x5AGsbBfyw== | ||||
|  | ||||
| core-js@^3.8.3: | ||||
|   version "3.32.0" | ||||
|   resolved "https://registry.npmmirror.com/core-js/-/core-js-3.32.0.tgz" | ||||
| @@ -7536,6 +7567,14 @@ vue-template-es2015-compiler@^1.9.0: | ||||
|   resolved "https://registry.npmmirror.com/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.9.1.tgz" | ||||
|   integrity sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw== | ||||
|  | ||||
| vue@^2.6.11: | ||||
|   version "2.7.16" | ||||
|   resolved "https://registry.npmmirror.com/vue/-/vue-2.7.16.tgz#98c60de9def99c0e3da8dae59b304ead43b967c9" | ||||
|   integrity sha512-4gCtFXaAA3zYZdTp5s4Hl2sozuySsgz4jy1EnpBHNfpMa9dK1ZCG7viqBPCwXtmgc8nHqUsAu3G4gtmXkkY3Sw== | ||||
|   dependencies: | ||||
|     "@vue/compiler-sfc" "2.7.16" | ||||
|     csstype "^3.1.0" | ||||
|  | ||||
| vue@^2.6.14: | ||||
|   version "2.7.14" | ||||
|   resolved "https://registry.npmmirror.com/vue/-/vue-2.7.14.tgz" | ||||
|   | ||||
		Reference in New Issue
	
	Block a user