调整
This commit is contained in:
		| @@ -9,6 +9,7 @@ | |||||||
|   "dependencies": { |   "dependencies": { | ||||||
|     "@antv/g2plot": "^2.4.25", |     "@antv/g2plot": "^2.4.25", | ||||||
|     "axios": "^1.4.0", |     "axios": "^1.4.0", | ||||||
|  |     "bi-vue-mindmap": "^0.6.12", | ||||||
|     "core-js": "^3.8.3", |     "core-js": "^3.8.3", | ||||||
|     "crypto-js": "^4.0.0", |     "crypto-js": "^4.0.0", | ||||||
|     "dayjs": "^1.11.9", |     "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] |               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 |             content['cat'+(++i)+'Id'] = reqData.catId | ||||||
|           } |           } | ||||||
|           for (; i < 10; i++) { |           for (; i < 10; i++) { | ||||||
|             content['cat' + (i+1) + 'Id'] = '' |             content['cat' + (i+1) + 'Id'] = '' | ||||||
|           } |           } | ||||||
|  |  | ||||||
|  |           content.personalizationSwitch = 0 | ||||||
|           content.productDraftId = draftId |           content.productDraftId = draftId | ||||||
|  |  | ||||||
|           this.createProduct(content) |           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/jszip.min.js'), 'body'); | ||||||
| injectScript( chrome.runtime.getURL('/js/FileSaver.js'), 'body'); | injectScript( chrome.runtime.getURL('/js/FileSaver.js'), 'body'); | ||||||
| injectScript( chrome.runtime.getURL('/js/download.js'), 'body'); | injectScript( chrome.runtime.getURL('/js/download.js'), 'body'); | ||||||
|  | injectScript( chrome.runtime.getURL('/js/temuSeller.js'), 'body'); | ||||||
|   | |||||||
| @@ -76,12 +76,24 @@ | |||||||
|       "js": [ |       "js": [ | ||||||
|         "/content.js" |         "/content.js" | ||||||
|       ] |       ] | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "matches": [ | ||||||
|  |         "*://*.kuajingmaihuo.com/*" | ||||||
|  |       ], | ||||||
|  |       "js": [ | ||||||
|  |         "/js/temuSellerContent.js" | ||||||
|  |       ] | ||||||
|     } |     } | ||||||
|   ], |   ], | ||||||
|   "web_accessible_resources": [ |   "web_accessible_resources": [ | ||||||
|     { |     { | ||||||
|       "resources": [ "js/download.js","js/jszip.min.js","js/FileSaver.js" ], |       "resources": [ "js/download.js","js/jszip.min.js","js/FileSaver.js" ], | ||||||
|       "matches": [ "*://*.aliexpress.com/*", "*://*.amazon.com/*", "*://*.shein.com/*" ] |       "matches": [ "*://*.aliexpress.com/*", "*://*.amazon.com/*", "*://*.shein.com/*" ] | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "resources": [ "js/temuSeller.js" ], | ||||||
|  |       "matches": [ "*://*.kuajingmaihuo.com/*" ] | ||||||
|     } |     } | ||||||
|   ] |   ] | ||||||
| } | } | ||||||
|   | |||||||
| @@ -2,7 +2,7 @@ | |||||||
|   "manifest_version": 3, |   "manifest_version": 3, | ||||||
|   "name": "TEMU助手", |   "name": "TEMU助手", | ||||||
|   "description": "TEMU助手 - 自动化提高生产效率", |   "description": "TEMU助手 - 自动化提高生产效率", | ||||||
|   "version": "3.2.3", |   "version": "3.2.8", | ||||||
|   "background": { |   "background": { | ||||||
|     "service_worker": "/background.js" |     "service_worker": "/background.js" | ||||||
|   }, |   }, | ||||||
| @@ -80,12 +80,24 @@ | |||||||
|       "js": [ |       "js": [ | ||||||
|         "/content.js" |         "/content.js" | ||||||
|       ] |       ] | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "matches": [ | ||||||
|  |         "*://*.kuajingmaihuo.com/*" | ||||||
|  |       ], | ||||||
|  |       "js": [ | ||||||
|  |         "/js/temuSellerContent.js" | ||||||
|  |       ] | ||||||
|     } |     } | ||||||
|   ], |   ], | ||||||
|   "web_accessible_resources": [ |   "web_accessible_resources": [ | ||||||
|     { |     { | ||||||
|       "resources": [ "js/download.js","js/jszip.min.js","js/FileSaver.js" ], |       "resources": [ "js/download.js","js/jszip.min.js","js/FileSaver.js" ], | ||||||
|       "matches": [ "*://*.aliexpress.com/*", "*://*.amazon.com/*", "*://*.shein.com/*" ] |       "matches": [ "*://*.aliexpress.com/*", "*://*.amazon.com/*", "*://*.shein.com/*" ] | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "resources": [ "js/temuSeller.js" ], | ||||||
|  |       "matches": [ "*://*.kuajingmaihuo.com/*" ] | ||||||
|     } |     } | ||||||
|   ] |   ] | ||||||
| } | } | ||||||
|   | |||||||
| @@ -65,6 +65,11 @@ const router = new VueRouter({ | |||||||
|           name: 'myUrgencyOrder', |           name: 'myUrgencyOrder', | ||||||
|           component: () => import('../view/shipping/MyUrgencyOrder.vue') |           component: () => import('../view/shipping/MyUrgencyOrder.vue') | ||||||
|         }, |         }, | ||||||
|  |         { | ||||||
|  |           path: 'productLabel', | ||||||
|  |           name: 'productLabel', | ||||||
|  |           component: () => import('../view/shipping/ProductLabel.vue') | ||||||
|  |         }, | ||||||
|         { |         { | ||||||
|           path: 'returnPackage', |           path: 'returnPackage', | ||||||
|           name: 'returnPackage', |           name: 'returnPackage', | ||||||
| @@ -202,6 +207,11 @@ const router = new VueRouter({ | |||||||
|           name: 'afterSaleDeductStat', |           name: 'afterSaleDeductStat', | ||||||
|           component: () => import('../view/sale/AfterSaleDeductStat.vue') |           component: () => import('../view/sale/AfterSaleDeductStat.vue') | ||||||
|         }, |         }, | ||||||
|  |         { | ||||||
|  |           path: 'saleStatTemu', | ||||||
|  |           name: 'saleStatTemu', | ||||||
|  |           component: () => import('../view/sale/ExportSaleStatTemu.vue') | ||||||
|  |         }, | ||||||
|         { |         { | ||||||
|           path: 'costManageShein', |           path: 'costManageShein', | ||||||
|           name: 'costManageShein', |           name: 'costManageShein', | ||||||
|   | |||||||
| @@ -135,6 +135,7 @@ export function transform(leftData) { | |||||||
|       countryShortName: leftData.productWhExtAttr.productOrigin ? leftData.productWhExtAttr.productOrigin.countryShortName: 'CN' |       countryShortName: leftData.productWhExtAttr.productOrigin ? leftData.productWhExtAttr.productOrigin.countryShortName: 'CN' | ||||||
|     } |     } | ||||||
|   }; |   }; | ||||||
|  |   rightData.personalizationSwitch = leftData.productWhExtAttr.personalizationSwitch || "0" | ||||||
|   rightData.productCarouseVideoReqList = leftData.carouseVideoVOList; |   rightData.productCarouseVideoReqList = leftData.carouseVideoVOList; | ||||||
|   rightData.goodsAdvantageLabelTypes = leftData.goodsAdvantageLabelVOList; |   rightData.goodsAdvantageLabelTypes = leftData.goodsAdvantageLabelVOList; | ||||||
|   rightData.productDetailVideoReqList = leftData.detailVideoVOList; |   rightData.productDetailVideoReqList = leftData.detailVideoVOList; | ||||||
| @@ -297,6 +298,7 @@ export function transformSubmitForHalf(leftData, config, draftId) { | |||||||
|       countryShortName: leftData.productWhExtAttr.productOrigin ? leftData.productWhExtAttr.productOrigin.countryShortName: 'CN' |       countryShortName: leftData.productWhExtAttr.productOrigin ? leftData.productWhExtAttr.productOrigin.countryShortName: 'CN' | ||||||
|     } |     } | ||||||
|   }; |   }; | ||||||
|  |   rightData.personalizationSwitch = leftData.productWhExtAttr.personalizationSwitch || 0 | ||||||
|   rightData.productCarouseVideoReqList = leftData.carouseVideoVOList; |   rightData.productCarouseVideoReqList = leftData.carouseVideoVOList; | ||||||
|   rightData.goodsAdvantageLabelTypes = leftData.goodsAdvantageLabelVOList; |   rightData.goodsAdvantageLabelTypes = leftData.goodsAdvantageLabelVOList; | ||||||
|   rightData.productDetailVideoReqList = leftData.detailVideoVOList; |   rightData.productDetailVideoReqList = leftData.detailVideoVOList; | ||||||
| @@ -323,14 +325,20 @@ export function transformSubmitForHalf(leftData, config, draftId) { | |||||||
|     freightTemplateId: config.freightTemplateId, |     freightTemplateId: config.freightTemplateId, | ||||||
|     shipmentLimitSecond: config.sendGoodsSecond |     shipmentLimitSecond: config.sendGoodsSecond | ||||||
|   } |   } | ||||||
|  |   let bindSiteIds = [] | ||||||
|  |   if (leftData.productSaleExtAttr?.productSemiManaged?.bindSites) { | ||||||
|  |     leftData.productSaleExtAttr?.productSemiManaged?.bindSites.map(ii => { | ||||||
|  |       bindSiteIds.push(ii.siteId) | ||||||
|  |     }) | ||||||
|  |   } | ||||||
|   rightData.productSemiManagedReq = { |   rightData.productSemiManagedReq = { | ||||||
|     bindSiteIds: config.siteList |     bindSiteIds: bindSiteIds | ||||||
|   } |   } | ||||||
|   let targetRouteList = [] |   let targetRouteList = [] | ||||||
|   for (let m = 0; m < config.wareHouseList.length; m++) { |   for (let m = 0; m < config.wareHouseList.length; m++) { | ||||||
|     targetRouteList.push({ |     targetRouteList.push({ | ||||||
|       warehouseId: config.wareHouseList[m], |       warehouseId: config.wareHouseList[m], | ||||||
|       siteIdList: config.siteList |       siteIdList: bindSiteIds | ||||||
|     }) |     }) | ||||||
|   } |   } | ||||||
|   rightData.productWarehouseRouteReq = { |   rightData.productWarehouseRouteReq = { | ||||||
|   | |||||||
| @@ -61,6 +61,7 @@ | |||||||
|             <el-menu-item index="/shippingList">已收货发货单</el-menu-item> |             <el-menu-item index="/shippingList">已收货发货单</el-menu-item> | ||||||
|             <el-menu-item index="/myNormalOrder">普通备货单</el-menu-item> |             <el-menu-item index="/myNormalOrder">普通备货单</el-menu-item> | ||||||
|             <el-menu-item index="/myUrgencyOrder">紧急备货单</el-menu-item> |             <el-menu-item index="/myUrgencyOrder">紧急备货单</el-menu-item> | ||||||
|  |             <el-menu-item index="/productLabel">商品条码管理</el-menu-item> | ||||||
|           </el-submenu> |           </el-submenu> | ||||||
|  |  | ||||||
|           <el-submenu index="/copyProduct"> |           <el-submenu index="/copyProduct"> | ||||||
| @@ -131,6 +132,7 @@ | |||||||
|             </template> |             </template> | ||||||
|             <el-menu-item index="/costManageTemu">成本管理</el-menu-item> |             <el-menu-item index="/costManageTemu">成本管理</el-menu-item> | ||||||
|             <el-menu-item index="/saleData">销售管理</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="/saleOut">售罄看板</el-menu-item> | ||||||
|             <el-menu-item index="/afterSaleStat">售后统计</el-menu-item> |             <el-menu-item index="/afterSaleStat">售后统计</el-menu-item> | ||||||
|             <el-menu-item index="/afterSaleDeductStat">售后赔付统计</el-menu-item> |             <el-menu-item index="/afterSaleDeductStat">售后赔付统计</el-menu-item> | ||||||
|   | |||||||
| @@ -106,6 +106,7 @@ | |||||||
|                       productName: item.productName, |                       productName: item.productName, | ||||||
|                       skcId: item.skcId, |                       skcId: item.skcId, | ||||||
|                       popUpType: 1, |                       popUpType: 1, | ||||||
|  |                       createTime: res.result.createTime, | ||||||
|                       versionId: res.result.popUpAutoPass12.versionId, |                       versionId: res.result.popUpAutoPass12.versionId, | ||||||
|                       newSupplyPrice: item.newSupplyPrice / 100, |                       newSupplyPrice: item.newSupplyPrice / 100, | ||||||
|                     } |                     } | ||||||
| @@ -119,6 +120,7 @@ | |||||||
|                       productName: item.productName, |                       productName: item.productName, | ||||||
|                       skcId: item.skcId, |                       skcId: item.skcId, | ||||||
|                       popUpType: 2, |                       popUpType: 2, | ||||||
|  |                       createTime: res.result.createTime, | ||||||
|                       versionId: res.result.popUpAutoPass24.versionId, |                       versionId: res.result.popUpAutoPass24.versionId, | ||||||
|                       newSupplyPrice: item.newSupplyPrice / 100, |                       newSupplyPrice: item.newSupplyPrice / 100, | ||||||
|                     } |                     } | ||||||
| @@ -132,6 +134,7 @@ | |||||||
|                       productName: item.productName, |                       productName: item.productName, | ||||||
|                       skcId: item.skcId, |                       skcId: item.skcId, | ||||||
|                       popUpType: 3, |                       popUpType: 3, | ||||||
|  |                       createTime: res.result.createTime, | ||||||
|                       versionId: res.result.popUpOthers.versionId, |                       versionId: res.result.popUpOthers.versionId, | ||||||
|                       newSupplyPrice: item.newSupplyPrice / 100, |                       newSupplyPrice: item.newSupplyPrice / 100, | ||||||
|                     } |                     } | ||||||
| @@ -166,10 +169,12 @@ | |||||||
|             let popUpType1VersionId = '' |             let popUpType1VersionId = '' | ||||||
|             let popUpType2VersionId = '' |             let popUpType2VersionId = '' | ||||||
|             let popUpType3VersionId = '' |             let popUpType3VersionId = '' | ||||||
|  |             let createTime = null | ||||||
|             let ids = [] |             let ids = [] | ||||||
|             this.priceList.map(item => { |             this.priceList.map(item => { | ||||||
|               if (item.popUpType == 1) { |               if (item.popUpType == 1) { | ||||||
|                 popUpType1VersionId = item.versionId |                 popUpType1VersionId = item.versionId | ||||||
|  |                 createTime = item.createTime | ||||||
|                 ids.push(item.id) |                 ids.push(item.id) | ||||||
|               } |               } | ||||||
|             }) |             }) | ||||||
| @@ -183,12 +188,13 @@ | |||||||
|                   "rejectOrderIdList": ids, |                   "rejectOrderIdList": ids, | ||||||
|                   "maxOrderId": popUpType1VersionId, |                   "maxOrderId": popUpType1VersionId, | ||||||
|                   "popUpType": 1, |                   "popUpType": 1, | ||||||
|                   "createTime": new Date().getTime() |                   "createTime": createTime | ||||||
|                 }}) |                 }}) | ||||||
|             } |             } | ||||||
|             ids = [] |             ids = [] | ||||||
|             this.priceList.map(item => { |             this.priceList.map(item => { | ||||||
|               if (item.popUpType == 2) { |               if (item.popUpType == 2) { | ||||||
|  |                 createTime = item.createTime | ||||||
|                 popUpType2VersionId = item.versionId |                 popUpType2VersionId = item.versionId | ||||||
|                 ids.push(item.id) |                 ids.push(item.id) | ||||||
|               } |               } | ||||||
| @@ -202,12 +208,13 @@ | |||||||
|                   "rejectOrderIdList": ids, |                   "rejectOrderIdList": ids, | ||||||
|                   "maxOrderId": popUpType2VersionId, |                   "maxOrderId": popUpType2VersionId, | ||||||
|                   "popUpType": 2, |                   "popUpType": 2, | ||||||
|                   "createTime": new Date().getTime() |                   "createTime": createTime | ||||||
|                 }}) |                 }}) | ||||||
|             } |             } | ||||||
|             ids = [] |             ids = [] | ||||||
|             this.priceList.map(item => { |             this.priceList.map(item => { | ||||||
|               if (item.popUpType == 3) { |               if (item.popUpType == 3) { | ||||||
|  |                 createTime = item.createTime | ||||||
|                 popUpType3VersionId = item.versionId |                 popUpType3VersionId = item.versionId | ||||||
|                 ids.push(item.id) |                 ids.push(item.id) | ||||||
|               } |               } | ||||||
| @@ -221,7 +228,7 @@ | |||||||
|                   "rejectOrderIdList": ids, |                   "rejectOrderIdList": ids, | ||||||
|                   "maxOrderId": popUpType3VersionId, |                   "maxOrderId": popUpType3VersionId, | ||||||
|                   "popUpType": 3, |                   "popUpType": 3, | ||||||
|                   "createTime": new Date().getTime() |                   "createTime": createTime | ||||||
|                 }}) |                 }}) | ||||||
|             } |             } | ||||||
|             if (res.success && res.errorCode == 1000000) { |             if (res.success && res.errorCode == 1000000) { | ||||||
|   | |||||||
| @@ -32,9 +32,12 @@ | |||||||
|         </div> |         </div> | ||||||
|       </ai-card> |       </ai-card> | ||||||
|     </div> |     </div> | ||||||
|     <ai-card title="常用工具" v-if="false"> |     <ai-card title="TEMU助手功能概览"> | ||||||
|       <div class=""> |       <template #right> | ||||||
|         dsad |         <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> |       </div> | ||||||
|     </ai-card> |     </ai-card> | ||||||
|     <AiDialog |     <AiDialog | ||||||
| @@ -58,9 +61,13 @@ | |||||||
| </template> | </template> | ||||||
|  |  | ||||||
| <script> | <script> | ||||||
|  | import BiVueMindmap from "bi-vue-mindmap"; | ||||||
|  |  | ||||||
|   export default { |   export default { | ||||||
|     name: 'AdminHome', |     name: 'AdminHome', | ||||||
|  |     components: { | ||||||
|  |       BiVueMindmap, | ||||||
|  |     }, | ||||||
|     data () { |     data () { | ||||||
|       return { |       return { | ||||||
|         noticeList: [], |         noticeList: [], | ||||||
| @@ -70,7 +77,258 @@ | |||||||
|         changeLogList: [], |         changeLogList: [], | ||||||
|         isImportant: false, |         isImportant: false, | ||||||
|         version: '', |         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('两次密码输入不一致'); |               this.$message.success('两次密码输入不一致'); | ||||||
|               return; |               return; | ||||||
|             } |             } | ||||||
|  |             const devVersion = require('../../manifest.development.json').version | ||||||
|  |             const prodVersion = require('../../manifest.production.json').version | ||||||
|             this.btnLoading = true |             this.btnLoading = true | ||||||
|             this.$http.post(`/api/malluser/reg`, { |             this.$http.post(`/api/malluser/reg`, { | ||||||
|               ...this.form |               ...this.form, | ||||||
|  |               version: process.env.NODE_ENV === 'production' ? prodVersion : devVersion | ||||||
|             }, { |             }, { | ||||||
|               headers: { |               headers: { | ||||||
|                 Authorization: 'Basic cGM6cGM=' |                 Authorization: 'Basic cGM6cGM=' | ||||||
|   | |||||||
| @@ -26,6 +26,7 @@ | |||||||
|             style="margin-top: 8px;" |             style="margin-top: 8px;" | ||||||
|             :current.sync="search.current" :size.sync="search.size" |             :current.sync="search.current" :size.sync="search.size" | ||||||
|             @selection-change="handleSelectionChange" |             @selection-change="handleSelectionChange" | ||||||
|  |             height="700" | ||||||
|             @getList="getList"> |             @getList="getList"> | ||||||
|           </ai-table> |           </ai-table> | ||||||
|         </div> |         </div> | ||||||
| @@ -545,6 +546,7 @@ import AiLazyCascader from "@/components/AiLazyCascader.vue" | |||||||
|                   bindSiteIds: this.form.siteId |                   bindSiteIds: this.form.siteId | ||||||
|                 } |                 } | ||||||
|               } |               } | ||||||
|  |               content.personalizationSwitch = content.personalizationSwitch || 0 | ||||||
|               setTimeout(() => { |               setTimeout(() => { | ||||||
|                 sendChromeAPIMessage({ |                 sendChromeAPIMessage({ | ||||||
|                   url: 'bg-visage-mms/product/draft/add', |                   url: 'bg-visage-mms/product/draft/add', | ||||||
|   | |||||||
| @@ -323,7 +323,8 @@ import JsonExcel from 'vue-json-excel' | |||||||
|                     supplierPrice: item.productSkuSummaries[k].supplierPrice / 100, |                     supplierPrice: item.productSkuSummaries[k].supplierPrice / 100, | ||||||
|                     specName: temp.join(","), |                     specName: temp.join(","), | ||||||
|                     skuStockQuantity, |                     skuStockQuantity, | ||||||
|                     todaySalesVolume: item.productSkuSummaries[k].todaySalesVolume} |                     todaySalesVolume: item.productSkuSummaries[k].todaySalesVolume | ||||||
|  |                   } | ||||||
|  |  | ||||||
|                     this.tableData.push(data) |                     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> | </script> | ||||||
|   | |||||||
| @@ -3,6 +3,7 @@ | |||||||
|     <ai-title |     <ai-title | ||||||
|       slot="title" |       slot="title" | ||||||
|       title="售后统计" |       title="售后统计" | ||||||
|  |       tips="请事先在“成本管理”维护好成本,否则部分计算不准确" | ||||||
|       isShowBottomBorder> |       isShowBottomBorder> | ||||||
|       <template #rightBtn> |       <template #rightBtn> | ||||||
|         <div class="title-right"> |         <div class="title-right"> | ||||||
| @@ -172,8 +173,7 @@ import JsonExcel from 'vue-json-excel' | |||||||
|         this.reqData.pageNo = 1 |         this.reqData.pageNo = 1 | ||||||
|  |  | ||||||
|         await this.getProductList({page: this.reqData.pageNo, |         await this.getProductList({page: this.reqData.pageNo, | ||||||
|           pageSize: this.reqData.pageSize, |           pageSize: this.reqData.pageSize}, skuIds) | ||||||
|           productSkuIds: skuIds}) |  | ||||||
|            |            | ||||||
|           this.costList = [] |           this.costList = [] | ||||||
|           await this.getSkuCostList() |           await this.getSkuCostList() | ||||||
| @@ -227,13 +227,24 @@ import JsonExcel from 'vue-json-excel' | |||||||
|           this.$store.commit("setTemuAlertShow", true) |           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({ |         let res = await sendChromeAPIMessage({ | ||||||
|           url: 'bg-visage-mms/product/skc/pageQuery', |           url: 'bg-visage-mms/product/skc/pageQuery', | ||||||
|           needMallId: true, |           needMallId: true, | ||||||
|           mallId: this.mallId, |           mallId: this.mallId, | ||||||
|           data: { |           data: { | ||||||
|             ...params |             page: 1, | ||||||
|  |             pageSize: params.pageSize, | ||||||
|  |             productSkuIds | ||||||
|         }}) |         }}) | ||||||
|         if (res.errorCode == 1000000) { |         if (res.errorCode == 1000000) { | ||||||
|           res.result.pageItems.map((item) => { |           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 ++ | ||||||
|             params.page ++ |           await this.getProductList(params, skuIds) | ||||||
|             await this.getProductList(params) |  | ||||||
|           } |  | ||||||
|         } |         } | ||||||
|       }, |       }, | ||||||
|       async getSkuCostList() { |       async getSkuCostList() { | ||||||
|   | |||||||
| @@ -206,6 +206,7 @@ import { saveAs } from 'file-saver' | |||||||
|           this.isLoading = true |           this.isLoading = true | ||||||
|           this.getList() |           this.getList() | ||||||
|         }).catch((err) => { |         }).catch((err) => { | ||||||
|  |           this.mallId = '' | ||||||
|           this.isLoading = false |           this.isLoading = false | ||||||
|         })  |         })  | ||||||
|       }, |       }, | ||||||
|   | |||||||
| @@ -3,6 +3,7 @@ | |||||||
|     <ai-title |     <ai-title | ||||||
|       slot="title" |       slot="title" | ||||||
|       title="销售数据" |       title="销售数据" | ||||||
|  |       tips="请事先在“成本管理”维护好成本,否则部分计算不准确" | ||||||
|       isShowBottomBorder> |       isShowBottomBorder> | ||||||
|       <template #rightBtn> |       <template #rightBtn> | ||||||
|         <div class="title-right"> |         <div class="title-right"> | ||||||
| @@ -133,7 +134,7 @@ | |||||||
|           ref="table0" |           ref="table0" | ||||||
|           :isShowPagination="false" |           :isShowPagination="false" | ||||||
|           :tableData="filteredData" |           :tableData="filteredData" | ||||||
|           height="500" |           height="700" | ||||||
|           :col-configs="colConfigs" |           :col-configs="colConfigs" | ||||||
|           :total="filteredData.length" |           :total="filteredData.length" | ||||||
|           style="margin-top: 8px;" |           style="margin-top: 8px;" | ||||||
| @@ -706,6 +707,7 @@ import { Message } from 'element-ui' | |||||||
|           this.getSkuCostList() |           this.getSkuCostList() | ||||||
|           this.getList() |           this.getList() | ||||||
|         }).catch((err) => { |         }).catch((err) => { | ||||||
|  |           this.mallId = '' | ||||||
|           console.log(err) |           console.log(err) | ||||||
|           this.isLoading = false |           this.isLoading = false | ||||||
|         }) |         }) | ||||||
|   | |||||||
| @@ -47,7 +47,7 @@ | |||||||
|           :tableData="tableData" |           :tableData="tableData" | ||||||
|           :col-configs="colConfigs" |           :col-configs="colConfigs" | ||||||
|           :total="tableData.length" |           :total="tableData.length" | ||||||
|           height="500" |           height="700" | ||||||
|           style="margin-top: 8px;" |           style="margin-top: 8px;" | ||||||
|           @getList="() => {}"> |           @getList="() => {}"> | ||||||
|         </ai-table> |         </ai-table> | ||||||
| @@ -150,6 +150,7 @@ import { Message } from 'element-ui' | |||||||
|             this.getList(2) |             this.getList(2) | ||||||
|           } |           } | ||||||
|         }).catch((err) => { |         }).catch((err) => { | ||||||
|  |           this.mallId = '' | ||||||
|           this.isLoading = false |           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> |       isShowBottomBorder> | ||||||
|     </ai-title> |     </ai-title> | ||||||
|     <template slot="content"> |     <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> |         <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> |         </template> | ||||||
|         <ai-table |         <ai-table | ||||||
|           :isShowPagination="false" |           :isShowPagination="false" | ||||||
|           :tableData="list" |           :tableData="refusedList" | ||||||
|           :col-configs="colConfigs" |           :col-configs="refusedColConfigs" | ||||||
|           height="600" |           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;" |           style="margin-top: 8px;" | ||||||
|           @getList="() => {}"> |           @getList="() => {}"> | ||||||
|         </ai-table> |         </ai-table> | ||||||
| @@ -36,9 +71,10 @@ import { saveAs } from 'file-saver' | |||||||
|     data () { |     data () { | ||||||
|       return { |       return { | ||||||
|         isLoading: false, |         isLoading: false, | ||||||
|         list: [], |  | ||||||
|         mallId: '', |         mallId: '', | ||||||
|         colConfigs: [ |         certStatus: 'refused', | ||||||
|  |         waitUploadList: [], | ||||||
|  |         waitUploadColConfigs: [ | ||||||
|           { prop: 'spu', label: 'SPU', align: 'left' }, |           { prop: 'spu', label: 'SPU', align: 'left' }, | ||||||
|           { prop: 'productName', label: '商品标题', align: 'left' }, |           { prop: 'productName', label: '商品标题', align: 'left' }, | ||||||
|           { prop: 'skc', label: 'SKC ID', align: 'left' }, |           { prop: 'skc', label: 'SKC ID', align: 'left' }, | ||||||
| @@ -46,7 +82,20 @@ import { saveAs } from 'file-saver' | |||||||
|           { prop: 'certificateTypeName', label: '证书类型', align: 'left' }, |           { prop: 'certificateTypeName', label: '证书类型', align: 'left' }, | ||||||
|           { prop: 'mergeSiteName', label: '管控地区', align: 'left' }, |           { prop: 'mergeSiteName', label: '管控地区', align: 'left' }, | ||||||
|           { prop: 'subSite', 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: [], |         tableData: [], | ||||||
| @@ -55,12 +104,33 @@ import { saveAs } from 'file-saver' | |||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     mounted () { |     mounted () { | ||||||
|       this.isLoading = true |       this.$http.post('/api/malluser/info').then(res => { | ||||||
|       this.getList() |         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: { |     methods: { | ||||||
|       async getList () { |       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({ |         let res = await sendGeiwohuoAPIMessage({ | ||||||
|           url: `spmp-api-prefix/spmp/certificate/get_skc_certificate_miss_list?page_num=${this.currentPage}&page_size=200`, |           url: `spmp-api-prefix/spmp/certificate/get_skc_certificate_miss_list?page_num=${this.currentPage}&page_size=200`, | ||||||
|           method: 'POST', |           method: 'POST', | ||||||
| @@ -84,30 +154,95 @@ import { saveAs } from 'file-saver' | |||||||
|               subSite: subSite.join(',') |               subSite: subSite.join(',') | ||||||
|             } |             } | ||||||
|      |      | ||||||
|             this.list.push(data) |             this.waitUploadList.push(data) | ||||||
|           } |           } | ||||||
|           if (res.info.data.length == 200 && (res.info.meta.count > 200*this.currentPage)) { |           if (res.info.data.length == 200 && (res.info.meta.count > 200*this.currentPage)) { | ||||||
|             this.currentPage++ |             this.currentPage++ | ||||||
|             await this.sleepSync(200) |             await this.sleepSync(200) | ||||||
|             await this.getList() |             await this.getWaitUploadList() | ||||||
|           } else { |  | ||||||
|             this.isLoading = false |  | ||||||
|           } |           } | ||||||
|         } else if (res.code == 100004 || res.code == 20302) { |         } 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) |           this.$store.commit("setSheinAlertShow", true) | ||||||
|         } |         } | ||||||
|       }, |       }, | ||||||
|       sleepSync(milliseconds) { |       sleepSync(milliseconds) { | ||||||
|         return new Promise(resolve => setTimeout(resolve, milliseconds)); |         return new Promise(resolve => setTimeout(resolve, milliseconds)); | ||||||
|       }, |       }, | ||||||
|       exportToExcel() { |       exportWaitUploadToExcel() { | ||||||
|         // 假设你有一个表格数据的数组 |         // 假设你有一个表格数据的数组 | ||||||
|         const data = [ |         const data = [ | ||||||
|           ["SPU", "商品标题", "SKC ID", "主规格", "证书类型", "管控地区", "管控子站点", "上传截止时间"] |           ["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]) |           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下载文件 | ||||||
|         saveAs(dataBlob, '待补充证书列表.xlsx'); |         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); |         window.URL.revokeObjectURL(blobUrl); | ||||||
|       } |       } | ||||||
|   | |||||||
| @@ -26,6 +26,7 @@ | |||||||
|             style="margin-top: 8px;" |             style="margin-top: 8px;" | ||||||
|             :current.sync="search.current" :size.sync="search.size" |             :current.sync="search.current" :size.sync="search.size" | ||||||
|             @selection-change="handleSelectionChange" |             @selection-change="handleSelectionChange" | ||||||
|  |             height="700" | ||||||
|             @getList="getList"> |             @getList="getList"> | ||||||
|           </ai-table> |           </ai-table> | ||||||
|         </div> |         </div> | ||||||
| @@ -140,7 +141,17 @@ import { Message } from 'element-ui' | |||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     created () { |     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: { |     methods: { | ||||||
|   | |||||||
| @@ -179,9 +179,19 @@ import { saveAs } from 'file-saver' | |||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     mounted () { |     mounted () { | ||||||
|       this.getUserInfo() |       this.$http.post('/api/malluser/info').then(res => { | ||||||
|       this.isLoading = true |         if (res.code == 0) { | ||||||
|       this.getList() |           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: { |     methods: { | ||||||
|   | |||||||
| @@ -54,7 +54,7 @@ | |||||||
|           ref="table0" |           ref="table0" | ||||||
|           :isShowPagination="false" |           :isShowPagination="false" | ||||||
|           :tableData="filteredData" |           :tableData="filteredData" | ||||||
|           height="500" |           height="700" | ||||||
|           :col-configs="colConfigs" |           :col-configs="colConfigs" | ||||||
|           :total="filteredData.length" |           :total="filteredData.length" | ||||||
|           style="margin-top: 8px;" |           style="margin-top: 8px;" | ||||||
| @@ -134,7 +134,9 @@ import { Message } from 'element-ui' | |||||||
|           {prop: 'ableSaleDays',label: '可售天数',align: 'center'}, |           {prop: 'ableSaleDays',label: '可售天数',align: 'center'}, | ||||||
|           {prop: 'cost',label: '价格',width: '120px',align: 'center'}, |           {prop: 'cost',label: '价格',width: '120px',align: 'center'}, | ||||||
|           {prop: 'costPrice',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) => { |           {prop: 'todayProfit',label: '利润',width: '120px',align: 'center',sortable: true,'sort-method': (a, b) => { | ||||||
|               return a.todayProfit - b.todayProfit |               return a.todayProfit - b.todayProfit | ||||||
|             }}, |             }}, | ||||||
|   | |||||||
| @@ -30,8 +30,8 @@ | |||||||
|           <json-excel |           <json-excel | ||||||
|               :data="skuList" |               :data="skuList" | ||||||
|               :fields="skuJsonFields" |               :fields="skuJsonFields" | ||||||
|               name="SKC账单数据.xls" |               name="SKU账单数据.xls" | ||||||
|               worksheet="SKC账单数据"> |               worksheet="SKU账单数据"> | ||||||
|             <el-button type="primary" icon="el-icon-download">下载SKU统计</el-button> |             <el-button type="primary" icon="el-icon-download">下载SKU统计</el-button> | ||||||
|           </json-excel> |           </json-excel> | ||||||
|         </div> |         </div> | ||||||
| @@ -310,7 +310,7 @@ import { DualAxes } from '@antv/g2plot' | |||||||
|         isLoading: false, |         isLoading: false, | ||||||
|  |  | ||||||
|         skcColConfigs: [ |         skcColConfigs: [ | ||||||
|           { prop: 'skcCode', label: '货号', width: '180px' }, |           { prop: 'skcCode', label: '货号', width: '250px' }, | ||||||
|           { slot: 'amount', label: '销售额', align: 'center' }, |           { slot: 'amount', label: '销售额', align: 'center' }, | ||||||
|           { prop: 'quantity', label: '单数', align: 'center' }, |           { prop: 'quantity', label: '单数', align: 'center' }, | ||||||
|           { prop: 'cost', label: '成本', align: 'center'}, |           { prop: 'cost', label: '成本', align: 'center'}, | ||||||
| @@ -327,7 +327,7 @@ import { DualAxes } from '@antv/g2plot' | |||||||
|           "利润率": "profitPercent", |           "利润率": "profitPercent", | ||||||
|         }, |         }, | ||||||
|         skuColConfigs: [ |         skuColConfigs: [ | ||||||
|           { prop: 'skuCode', label: '属性集', width: '220px' }, |           { prop: 'skuCode', label: '属性集', width: '250px' }, | ||||||
|           { slot: 'amount', label: '销售额', align: 'center' }, |           { slot: 'amount', label: '销售额', align: 'center' }, | ||||||
|           { prop: 'quantity', label: '单数', align: 'center' }, |           { prop: 'quantity', label: '单数', align: 'center' }, | ||||||
|           { prop: 'cost', 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.chartObj.changeData([this.leftChartData, this.rightChartData]) | ||||||
|             this.isLoading = false |             this.isLoading = false | ||||||
|           } |           } | ||||||
| @@ -665,6 +664,9 @@ import { DualAxes } from '@antv/g2plot' | |||||||
|                   } else { |                   } else { | ||||||
|                     break |                     break | ||||||
|                   } |                   } | ||||||
|  |                 } else if (res2.code == 100004 || res2.code == 20302) { | ||||||
|  |                   this.isLoading = false | ||||||
|  |                   this.$store.commit("setSheinAlertShow", true) | ||||||
|                 } |                 } | ||||||
|               } |               } | ||||||
|             } |             } | ||||||
|   | |||||||
| @@ -21,26 +21,36 @@ | |||||||
|       </template> |       </template> | ||||||
|     </ai-title> |     </ai-title> | ||||||
|     <template slot="content"> |     <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;"> |       <ai-card title="数据明细" style="padding-bottom: 40px;"> | ||||||
|         <template #right> |         <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 |           <json-excel | ||||||
|               :data="tableData" |               :data="tableData" | ||||||
|               :fields="jsonFields" |               :fields="jsonFields" | ||||||
| @@ -59,6 +69,26 @@ | |||||||
|           @getList="() => {}"> |           @getList="() => {}"> | ||||||
|         </ai-table> |         </ai-table> | ||||||
|       </ai-card> |       </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> |     </template> | ||||||
|   </ai-list> |   </ai-list> | ||||||
| </template> | </template> | ||||||
| @@ -116,6 +146,7 @@ import JsonExcel from 'vue-json-excel' | |||||||
|           { prop: 'extCode', label: 'SKU货号', width: '160px', align: 'left' }, |           { prop: 'extCode', label: 'SKU货号', width: '160px', align: 'left' }, | ||||||
|           { prop: 'specName', label: 'SKU属性', width: '100px', align: 'left' }, |           { prop: 'specName', label: 'SKU属性', width: '100px', align: 'left' }, | ||||||
|           { prop: 'supplierPrice', label: '申报价格(CNY)', width: '180px', 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: 'purchaseQuantity', label: '备货件数', width: '100px', align: 'left' }, | ||||||
|           { prop: 'xiadan', label: '送货数量', width: '100px', align: 'left' }, |           { prop: 'xiadan', label: '送货数量', width: '100px', align: 'left' }, | ||||||
|           { prop: 'skuNum', 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: 'deliverTime', label: '发货时间', width: '160px', align: 'left' }, | ||||||
|           { prop: 'receiveTime', 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, |         isLoading: false, | ||||||
|         tableData: [], |         tableData: [], | ||||||
|  |         costList: [], | ||||||
|         jsonFields: { |         jsonFields: { | ||||||
|           "备货单创建时间": "purchaseTime", |           "备货单创建时间": "purchaseTime", | ||||||
|           "备货单号": "subPurchaseOrderSn", |           "备货单号": "subPurchaseOrderSn", | ||||||
| @@ -137,6 +185,7 @@ import JsonExcel from 'vue-json-excel' | |||||||
|           "SKU货号": "extCode", |           "SKU货号": "extCode", | ||||||
|           "SKU属性": "specName", |           "SKU属性": "specName", | ||||||
|           "申报价格(CNY)": "supplierPrice", |           "申报价格(CNY)": "supplierPrice", | ||||||
|  |           "成本价格(CNY)": "cost", | ||||||
|           "备货件数": "purchaseQuantity", |           "备货件数": "purchaseQuantity", | ||||||
|           "下单数量": "xiadan", |           "下单数量": "xiadan", | ||||||
|           "实际入库数量": "skuNum", |           "实际入库数量": "skuNum", | ||||||
| @@ -144,7 +193,22 @@ import JsonExcel from 'vue-json-excel' | |||||||
|           "发货时间": "deliverTime", |           "发货时间": "deliverTime", | ||||||
|           "收货时间": "receiveTime" |           "收货时间": "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 |         currentIndex: 0 | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
| @@ -168,64 +232,123 @@ import JsonExcel from 'vue-json-excel' | |||||||
|           Message.error("请选择时间") |           Message.error("请选择时间") | ||||||
|           return |           return | ||||||
|         } |         } | ||||||
|  |         this.getSkuCostList() | ||||||
|         this.reqData.purchaseTimeFrom = this.form.date[0].getTime() |         this.reqData.purchaseTimeFrom = this.form.date[0].getTime() | ||||||
|         this.reqData.purchaseTimeTo = this.form.date[1].getTime() + 86400 * 1000 |         this.reqData.purchaseTimeTo = this.form.date[1].getTime() + 86400 * 1000 | ||||||
|         this.reqData.pageNo = 1 |         this.reqData.pageNo = 1 | ||||||
|         this.reqData.statusList = this.form.status |         this.reqData.statusList = this.form.status | ||||||
|         this.tableData = [] |         this.tableData = [] | ||||||
|  |         this.sumTableData = [] | ||||||
|         this.packageNumber = 0 |         this.packageNumber = 0 | ||||||
|         this.snList = [] |  | ||||||
|         this.currentIndex = 0 |         this.currentIndex = 0 | ||||||
|  |         this.costList = [] | ||||||
|         this.isLoading = true |         this.isLoading = true | ||||||
|         this.load() |         this.load() | ||||||
|       }, |       }, | ||||||
|       load() { |       async load() { | ||||||
|         sendChromeAPIMessage({ |         let res = await sendChromeAPIMessage({ | ||||||
|           url: 'oms/bg/venom/api/supplier/purchase/manager/querySubOrderList', |           url: 'oms/bg/venom/api/supplier/purchase/manager/querySubOrderList', | ||||||
|           needMallId: true, |           needMallId: true, | ||||||
|           mallId: this.form.mallId, |           mallId: this.form.mallId, | ||||||
|           anti: true, |           anti: true, | ||||||
|           data: this.reqData}).then((res) => { |           data: this.reqData}) | ||||||
|             if (res.errorCode == 1000000) { |         if (res.errorCode == 1000000) { | ||||||
|               for(let i = 0;i < res.result.subOrderForSupplierList.length; i++) { |           for(let i = 0;i < res.result.subOrderForSupplierList.length; i++) { | ||||||
|                 let item = res.result.subOrderForSupplierList[i]; |             let item = res.result.subOrderForSupplierList[i]; | ||||||
|                 let data = {}; |             let data = {}; | ||||||
|                 data.purchaseTime = timestampToTime(item.purchaseTime)  |             data.purchaseTime = timestampToTime(item.purchaseTime)  | ||||||
|                 data.subPurchaseOrderSn = item.subPurchaseOrderSn |             data.subPurchaseOrderSn = item.subPurchaseOrderSn | ||||||
|                 data.productName = item.productName |             data.productName = item.productName | ||||||
|                 data.productSkcPicture = item.productSkcPicture |             data.productSkcPicture = item.productSkcPicture | ||||||
|                 data.productSkcId = item.productSkcId |             data.productSkcId = item.productSkcId | ||||||
|                 data.skcExtCode = item.productSn |             data.skcExtCode = item.productSn | ||||||
|                 data.status = this.options.filter(i => {return  i.value == item.status})[0].label |             data.status = this.options.filter(i => {return  i.value == item.status})[0].label | ||||||
|                 data.deliveryOrderSn = item.deliverInfo.deliveryOrderSn |             data.deliveryOrderSn = item.deliverInfo.deliveryOrderSn | ||||||
|                 data.deliverTime = timestampToTime(item.deliverInfo.deliverTime) |             data.deliverTime = timestampToTime(item.deliverInfo.deliverTime) | ||||||
|                 data.receiveTime = timestampToTime(item.deliverInfo.receiveTime) |             data.receiveTime = timestampToTime(item.deliverInfo.receiveTime) | ||||||
|                  |              | ||||||
|                 for(let k = 0; k < item.skuQuantityDetailList.length; k++) { |             for(let k = 0; k < item.skuQuantityDetailList.length; k++) { | ||||||
|                   data = {...data, |               data = {...data, | ||||||
|                     productSkuId: item.skuQuantityDetailList[k].productSkuId, |                 productSkuId: item.skuQuantityDetailList[k].productSkuId, | ||||||
|                     specName: item.skuQuantityDetailList[k].className, |                 specName: item.skuQuantityDetailList[k].className, | ||||||
|                     extCode: item.skuQuantityDetailList[k].extCode, |                 extCode: item.skuQuantityDetailList[k].extCode, | ||||||
|                     supplierPrice: item.skuQuantityDetailList[k].supplierPrice / 100, |                 supplierPrice: item.skuQuantityDetailList[k].supplierPrice / 100, | ||||||
|                     purchaseQuantity: item.skuQuantityDetailList[k].purchaseQuantity, |                 purchaseQuantity: item.skuQuantityDetailList[k].purchaseQuantity, | ||||||
|                     xiadan: item.skuQuantityDetailList[k].deliverQuantity, |                 xiadan: item.skuQuantityDetailList[k].deliverQuantity, | ||||||
|                     skuNum: item.skuQuantityDetailList[k].realReceiveAuthenticQuantity} |                 skuNum: item.skuQuantityDetailList[k].realReceiveAuthenticQuantity, | ||||||
|  |                 cost: null} | ||||||
|  |  | ||||||
|                     this.tableData.push(data) |                 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 |  | ||||||
|               } |  | ||||||
|             } |             } | ||||||
|           }) |  | ||||||
|  |           } | ||||||
|  |           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> |       </template> | ||||||
|     </ai-title> |     </ai-title> | ||||||
|     <template slot="content"> |     <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;"> |       <ai-card title="数据明细" style="padding-bottom: 40px;"> | ||||||
|         <template #right> |         <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 |           <json-excel | ||||||
|               :data="tableData" |               :data="tableData" | ||||||
|               :fields="jsonFields" |               :fields="jsonFields" | ||||||
| @@ -59,6 +69,26 @@ | |||||||
|           @getList="() => {}"> |           @getList="() => {}"> | ||||||
|         </ai-table> |         </ai-table> | ||||||
|       </ai-card> |       </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> |     </template> | ||||||
|   </ai-list> |   </ai-list> | ||||||
| </template> | </template> | ||||||
| @@ -123,8 +153,24 @@ import JsonExcel from 'vue-json-excel' | |||||||
|           { prop: 'deliverTime', label: '发货时间', width: '160px', align: 'left' }, |           { prop: 'deliverTime', label: '发货时间', width: '160px', align: 'left' }, | ||||||
|           { prop: 'receiveTime', 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, |         isLoading: false, | ||||||
|         tableData: [], |         tableData: [], | ||||||
|  |         costList: [], | ||||||
|         jsonFields: { |         jsonFields: { | ||||||
|           "备货单创建时间": "purchaseTime", |           "备货单创建时间": "purchaseTime", | ||||||
|           "备货单号": "subPurchaseOrderSn", |           "备货单号": "subPurchaseOrderSn", | ||||||
| @@ -143,7 +189,21 @@ import JsonExcel from 'vue-json-excel' | |||||||
|           "发货时间": "deliverTime", |           "发货时间": "deliverTime", | ||||||
|           "收货时间": "receiveTime" |           "收货时间": "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 |         currentIndex: 0 | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
| @@ -167,13 +227,14 @@ import JsonExcel from 'vue-json-excel' | |||||||
|           Message.error("请选择时间") |           Message.error("请选择时间") | ||||||
|           return |           return | ||||||
|         } |         } | ||||||
|  |         this.getSkuCostList() | ||||||
|         this.reqData.purchaseTimeFrom = this.form.date[0].getTime() |         this.reqData.purchaseTimeFrom = this.form.date[0].getTime() | ||||||
|         this.reqData.purchaseTimeTo = this.form.date[1].getTime() + 86400 * 1000 |         this.reqData.purchaseTimeTo = this.form.date[1].getTime() + 86400 * 1000 | ||||||
|         this.reqData.pageNo = 1 |         this.reqData.pageNo = 1 | ||||||
|         this.reqData.statusList = this.form.status |         this.reqData.statusList = this.form.status | ||||||
|         this.tableData = [] |         this.tableData = [] | ||||||
|  |         this.costList = [] | ||||||
|         this.packageNumber = 0 |         this.packageNumber = 0 | ||||||
|         this.snList = [] |  | ||||||
|         this.currentIndex = 0 |         this.currentIndex = 0 | ||||||
|         this.isLoading = true |         this.isLoading = true | ||||||
|         this.load() |         this.load() | ||||||
| @@ -220,10 +281,59 @@ import JsonExcel from 'vue-json-excel' | |||||||
|                 this.reqData.pageNo ++ |                 this.reqData.pageNo ++ | ||||||
|                 this.load() |                 this.load() | ||||||
|               } else { |               } 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 |                 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.isDlgLoading = true | ||||||
|           this.getList(this.tableData, this.mallId, this.mallName, 1) |           this.getList(this.tableData, this.mallId, this.mallName, 1) | ||||||
|         }).catch((err) => { |         }).catch((err) => { | ||||||
|  |           this.mallId = '' | ||||||
|           console.log(err) |           console.log(err) | ||||||
|         }) |         }) | ||||||
|       }, |       }, | ||||||
| @@ -688,11 +689,19 @@ | |||||||
|                 this.createDeliveryBill(sn, mallId) |                 this.createDeliveryBill(sn, mallId) | ||||||
|               } |               } | ||||||
|             } else { |             } else { | ||||||
|               this.choosedSnMallList.push(obj) |               if (res.result?.errorInfoList[0] && res.result?.errorInfoList[0].errorCode == 60002) { | ||||||
|               for (let j = 0; j < this.choosedList.length; j++) { |                 for (let j = 0; j < this.choosedList.length; j++) { | ||||||
|                 if (this.choosedList[j].subPurchaseOrderSn == sn) { |                   if (this.choosedList[j].subPurchaseOrderSn == sn) { | ||||||
|                   this.choosedList[j].robTotal ++; |                     this.choosedList.splice(j, 1); | ||||||
|                   break; |                   } | ||||||
|  |                 } | ||||||
|  |               } 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.isDlgLoading = true | ||||||
|           this.getList(this.tableData, this.mallId, this.mallName, 1) |           this.getList(this.tableData, this.mallId, this.mallName, 1) | ||||||
|         }).catch((err) => { |         }).catch((err) => { | ||||||
|  |           this.mallId = '' | ||||||
|           console.log(err) |           console.log(err) | ||||||
|         }) |         }) | ||||||
|       }, |       }, | ||||||
|   | |||||||
| @@ -216,6 +216,7 @@ | |||||||
|           this.isDlgLoading = true |           this.isDlgLoading = true | ||||||
|           this.getList(this.tableData, this.mallId, this.mallName, 1) |           this.getList(this.tableData, this.mallId, this.mallName, 1) | ||||||
|         }).catch((err) => { |         }).catch((err) => { | ||||||
|  |           this.mallId = '' | ||||||
|           console.log(err) |           console.log(err) | ||||||
|         }) |         }) | ||||||
|       }, |       }, | ||||||
|   | |||||||
| @@ -123,6 +123,7 @@ import { Message } from 'element-ui' | |||||||
|           this.skcIds = [] |           this.skcIds = [] | ||||||
|           this.getList() |           this.getList() | ||||||
|         }).catch((err) => { |         }).catch((err) => { | ||||||
|  |           this.mallId = '' | ||||||
|           this.isLoading = false |           this.isLoading = false | ||||||
|         }) |         }) | ||||||
|       }, |       }, | ||||||
|   | |||||||
| @@ -121,6 +121,7 @@ import { Message } from 'element-ui' | |||||||
|           this.isLoading = true |           this.isLoading = true | ||||||
|           this.getList() |           this.getList() | ||||||
|         }).catch((err) => { |         }).catch((err) => { | ||||||
|  |           this.mallId = '' | ||||||
|           this.isLoading = false |           this.isLoading = false | ||||||
|         }) |         }) | ||||||
|       }, |       }, | ||||||
|   | |||||||
| @@ -51,6 +51,7 @@ | |||||||
|             </json-excel> |             </json-excel> | ||||||
|           </template> |           </template> | ||||||
|           <ai-table |           <ai-table | ||||||
|  |               :isShowPagination="false" | ||||||
|               :tableData="tableData" |               :tableData="tableData" | ||||||
|               :col-configs="colConfigs" |               :col-configs="colConfigs" | ||||||
|               :total="total" |               :total="total" | ||||||
| @@ -70,6 +71,26 @@ | |||||||
|               </el-table-column> |               </el-table-column> | ||||||
|             </ai-table> |             </ai-table> | ||||||
|         </ai-card> |         </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> |       </div> | ||||||
|     </template> |     </template> | ||||||
|   </ai-list> |   </ai-list> | ||||||
| @@ -98,8 +119,18 @@ import { Message } from 'element-ui' | |||||||
|           { prop: 'orderTypeDesc', label: '退货原因',width: '220px', align: 'left' }, |           { prop: 'orderTypeDesc', label: '退货原因',width: '220px', align: 'left' }, | ||||||
|           { prop: 'packageSn', label: '退货包裹号', width: '200px',align: 'left' }, |           { prop: 'packageSn', label: '退货包裹号', width: '200px',align: 'left' }, | ||||||
|           { prop: 'quantity', label: 'SKU件数',width: '100px', }, |           { prop: 'quantity', label: 'SKU件数',width: '100px', }, | ||||||
|  |           { prop: 'cost', label: '成本单价' }, | ||||||
|           { prop: 'outboundTime', label: '出库时间', width: '160px'} |           { 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: { |         jsonFields: { | ||||||
|           "SPU": "productSpuId", |           "SPU": "productSpuId", | ||||||
|           "SKC": "productSkcId", |           "SKC": "productSkcId", | ||||||
| @@ -112,8 +143,19 @@ import { Message } from 'element-ui' | |||||||
|           "退货原因": "orderTypeDesc", |           "退货原因": "orderTypeDesc", | ||||||
|           "退货包裹号": "packageSn", |           "退货包裹号": "packageSn", | ||||||
|           "SKU件数": "quantity", |           "SKU件数": "quantity", | ||||||
|  |           "成本单价": "cost", | ||||||
|           "出库时间": "outboundTime" |           "出库时间": "outboundTime" | ||||||
|         }, |         }, | ||||||
|  |         sumJsonFields: { | ||||||
|  |           "SKC": "productSkcId", | ||||||
|  |           "SKU": "productSkuId", | ||||||
|  |           "SKU属性": "skuExtCode", | ||||||
|  |           "图片地址": "thumbUrl", | ||||||
|  |           "属性集": "secondarySaleSpec", | ||||||
|  |           "SKU总件数": "quantity", | ||||||
|  |           "成本价": "costPrice", | ||||||
|  |           "成本总额": "costAmount" | ||||||
|  |         }, | ||||||
|         form: { |         form: { | ||||||
|           mallId: '', |           mallId: '', | ||||||
|           date: '' |           date: '' | ||||||
| @@ -122,6 +164,8 @@ import { Message } from 'element-ui' | |||||||
|         pageSize: 100, |         pageSize: 100, | ||||||
|  |  | ||||||
|         tableData: [], |         tableData: [], | ||||||
|  |         sumTableData: [], | ||||||
|  |         costList: [], | ||||||
|         total: 0, |         total: 0, | ||||||
|         search: { |         search: { | ||||||
|           current: 1, |           current: 1, | ||||||
| @@ -163,6 +207,7 @@ import { Message } from 'element-ui' | |||||||
|         } |         } | ||||||
|         this.currentPage = 1 |         this.currentPage = 1 | ||||||
|         this.tableData = [] |         this.tableData = [] | ||||||
|  |         this.sumTableData = [] | ||||||
|  |  | ||||||
|         let startTime = this.form.date[1].getTime() - 30 * 24 * 60 * 60 * 1000 |         let startTime = this.form.date[1].getTime() - 30 * 24 * 60 * 60 * 1000 | ||||||
|         if (startTime < this.form.date[0].getTime()) { |         if (startTime < this.form.date[0].getTime()) { | ||||||
| @@ -196,6 +241,7 @@ import { Message } from 'element-ui' | |||||||
|               data.packageSn = item.packageSn |               data.packageSn = item.packageSn | ||||||
|               data.quantity = item.quantity |               data.quantity = item.quantity | ||||||
|               data.outboundTime = timestampToTime(item.outboundTime) |               data.outboundTime = timestampToTime(item.outboundTime) | ||||||
|  |               data.cost = null | ||||||
|                |                | ||||||
|               this.tableData.push(data) |               this.tableData.push(data) | ||||||
|             } |             } | ||||||
| @@ -215,7 +261,8 @@ import { Message } from 'element-ui' | |||||||
|                 this.getList(startTimeTemp, endTimeTemp) |                 this.getList(startTimeTemp, endTimeTemp) | ||||||
|               } else { |               } else { | ||||||
|                 this.getDeliverySn(1) |                 this.getDeliverySn(1) | ||||||
|                 this.getSkuExtCode(1) |                  | ||||||
|  |                 this.getSkuCostList() | ||||||
|                 this.isLoading = false |                 this.isLoading = false | ||||||
|               } |               } | ||||||
|             } |             } | ||||||
| @@ -288,6 +335,58 @@ import { Message } from 'element-ui' | |||||||
|           await getSkuExtCode(pageNo + 1) |           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() { |       startDownload() { | ||||||
|         this.$http.post('/api/malluser/info').then(res => { |         this.$http.post('/api/malluser/info').then(res => { | ||||||
|           if (res.code == 0) { |           if (res.code == 0) { | ||||||
|   | |||||||
| @@ -54,7 +54,7 @@ | |||||||
|               :tableData="tableData" |               :tableData="tableData" | ||||||
|               :col-configs="colConfigs" |               :col-configs="colConfigs" | ||||||
|               :total="total" |               :total="total" | ||||||
|               height="500" |               height="700" | ||||||
|               style="margin-top: 8px;" |               style="margin-top: 8px;" | ||||||
|               @getList="getList"> |               @getList="getList"> | ||||||
|             </ai-table> |             </ai-table> | ||||||
|   | |||||||
							
								
								
									
										39
									
								
								yarn.lock
									
									
									
									
									
								
							
							
						
						
									
										39
									
								
								yarn.lock
									
									
									
									
									
								
							| @@ -492,6 +492,11 @@ | |||||||
|   resolved "https://registry.npmmirror.com/@babel/parser/-/parser-7.22.10.tgz" |   resolved "https://registry.npmmirror.com/@babel/parser/-/parser-7.22.10.tgz" | ||||||
|   integrity sha512-lNbdGsQb9ekfsnjFGhEiF4hfFqGgfOP3H3d27re3n+CGhNuTSUEQdfWk556sTLNTloczcdM5TYF2LhzmDQKyvQ== |   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": | "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.22.5": | ||||||
|   version "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" |   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" |     postcss "^8.4.14" | ||||||
|     source-map "^0.6.1" |     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": | "@vue/component-compiler-utils@^3.1.0", "@vue/component-compiler-utils@^3.3.0": | ||||||
|   version "3.3.0" |   version "3.3.0" | ||||||
|   resolved "https://registry.npmmirror.com/@vue/component-compiler-utils/-/component-compiler-utils-3.3.0.tgz" |   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" |   resolved "https://registry.npmmirror.com/batch/-/batch-0.6.1.tgz" | ||||||
|   integrity sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw== |   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: | big.js@^5.2.2: | ||||||
|   version "5.2.2" |   version "5.2.2" | ||||||
|   resolved "https://registry.npmmirror.com/big.js/-/big.js-5.2.2.tgz" |   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" |   resolved "https://registry.npmmirror.com/core-js/-/core-js-2.6.12.tgz" | ||||||
|   integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ== |   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: | core-js@^3.8.3: | ||||||
|   version "3.32.0" |   version "3.32.0" | ||||||
|   resolved "https://registry.npmmirror.com/core-js/-/core-js-3.32.0.tgz" |   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" |   resolved "https://registry.npmmirror.com/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.9.1.tgz" | ||||||
|   integrity sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw== |   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: | vue@^2.6.14: | ||||||
|   version "2.7.14" |   version "2.7.14" | ||||||
|   resolved "https://registry.npmmirror.com/vue/-/vue-2.7.14.tgz" |   resolved "https://registry.npmmirror.com/vue/-/vue-2.7.14.tgz" | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user