调整
This commit is contained in:
@@ -13,6 +13,8 @@
|
|||||||
"crypto-js": "^4.0.0",
|
"crypto-js": "^4.0.0",
|
||||||
"dayjs": "^1.11.9",
|
"dayjs": "^1.11.9",
|
||||||
"element-ui": "^2.15.13",
|
"element-ui": "^2.15.13",
|
||||||
|
"file-saver": "^2.0.5",
|
||||||
|
"html2canvas": "^1.4.1",
|
||||||
"query-string": "^9.0.0",
|
"query-string": "^9.0.0",
|
||||||
"spark-md5": "^3.0.2",
|
"spark-md5": "^3.0.2",
|
||||||
"v-viewer": "^1.6.4",
|
"v-viewer": "^1.6.4",
|
||||||
@@ -22,7 +24,8 @@
|
|||||||
"vue-qr": "^4.0.9",
|
"vue-qr": "^4.0.9",
|
||||||
"vue-router": "^3.2.0",
|
"vue-router": "^3.2.0",
|
||||||
"vuex": "^3.4.0",
|
"vuex": "^3.4.0",
|
||||||
"vuex-persistedstate": "^4.1.0"
|
"vuex-persistedstate": "^4.1.0",
|
||||||
|
"xlsx": "^0.18.5"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.12.16",
|
"@babel/core": "^7.12.16",
|
||||||
|
|||||||
@@ -1,3 +1,8 @@
|
|||||||
|
function matchSheinDomain(url) {
|
||||||
|
const urlPattern = /https:\/\/([\da-z\.-]+)\.shein\.com\/([\S.-]+)-p-([\S.-]+)/
|
||||||
|
return urlPattern.test(url);
|
||||||
|
}
|
||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
if (window.location.href.startsWith('https://www.aliexpress.com/item/')) {
|
if (window.location.href.startsWith('https://www.aliexpress.com/item/')) {
|
||||||
const popup = document.createElement("div")
|
const popup = document.createElement("div")
|
||||||
@@ -187,6 +192,111 @@ function init() {
|
|||||||
})
|
})
|
||||||
document.body.appendChild(popup)
|
document.body.appendChild(popup)
|
||||||
}
|
}
|
||||||
|
} else if (matchSheinDomain(window.location.href)) {
|
||||||
|
const popup = document.createElement("div")
|
||||||
|
popup.innerText = "下载图片"
|
||||||
|
const styles = {
|
||||||
|
position: "fixed",
|
||||||
|
right: '10px',
|
||||||
|
top: '60px',
|
||||||
|
zIndex: 9999,
|
||||||
|
padding: "8px",
|
||||||
|
background: "#409EFF",
|
||||||
|
color: "#fff",
|
||||||
|
borderRadius: "8px",
|
||||||
|
cursor: "pointer"
|
||||||
|
}
|
||||||
|
for (const e in styles) {
|
||||||
|
popup.style[e] = styles[e]
|
||||||
|
}
|
||||||
|
|
||||||
|
popup.addEventListener('click', async () => {
|
||||||
|
var baseList = [];
|
||||||
|
var downloadList = []
|
||||||
|
|
||||||
|
let bannerIdx = 1, detailIdx = 1
|
||||||
|
baseList.push({type: 0, index: bannerIdx++, src: window.gbRawData.productIntroData.goods_imgs.main_image.origin_image})
|
||||||
|
var detailImages = window.gbRawData.productIntroData.goods_imgs.detail_image
|
||||||
|
|
||||||
|
for (var i = 0; i < detailImages.length; i++) {
|
||||||
|
if (!(detailImages[i].isMoreDetail)) {
|
||||||
|
baseList.push({type: 0, index: bannerIdx++, src: detailImages[i].origin_image})
|
||||||
|
} else {
|
||||||
|
baseList.push({type: 1, index: detailIdx++, src: detailImages[i].origin_image})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var video = document.querySelector('video')
|
||||||
|
if (window.gbRawData.productIntroData.goods_imgs.video_url) {
|
||||||
|
baseList.push({type: 2, index: 1, src: window.gbRawData.productIntroData.goods_imgs.video_url})
|
||||||
|
}
|
||||||
|
|
||||||
|
var zip = new JSZip();
|
||||||
|
var imgsBanner = zip.folder("轮播图");
|
||||||
|
var imgsDetail = zip.folder("详情图");
|
||||||
|
var videos = zip.folder("视频");
|
||||||
|
|
||||||
|
for (var k = 0; k < baseList.length; k++) {
|
||||||
|
let type = baseList[k].type
|
||||||
|
let index = baseList[k].index
|
||||||
|
if (type == 2) {
|
||||||
|
let x = new XMLHttpRequest()
|
||||||
|
x.open('GET', baseList[k].src, true)
|
||||||
|
x.responseType = 'blob'
|
||||||
|
x.onload = (e) => {
|
||||||
|
downloadList.push({type: type, index: index, data: x.response});
|
||||||
|
if (downloadList.length === baseList.length && downloadList.length > 0) {
|
||||||
|
for (let l = 0; l < downloadList.length; l++) {
|
||||||
|
if (downloadList[l].type == '0') {
|
||||||
|
imgsDetail.file(`详情图${downloadList[l].index}.png`, downloadList[l].data, { base64: true });
|
||||||
|
} else if (downloadList[l].type == '1') {
|
||||||
|
imgsBanner.file(`轮播图${downloadList[l].index}.png`, downloadList[l].data, { base64: true });
|
||||||
|
} else if (downloadList[l].type == '2') {
|
||||||
|
videos.file(`视频.mp4`, downloadList[l].data, { Blob: true });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
zip.generateAsync({ type: "blob" }).then(function (content) {
|
||||||
|
// see FileSaver.js
|
||||||
|
saveAs(content, "shein_" + id + ".zip");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
x.send()
|
||||||
|
} else {
|
||||||
|
let image = new Image();
|
||||||
|
// 解决跨域 Canvas 污染问题
|
||||||
|
image.setAttribute("crossOrigin", "anonymous");
|
||||||
|
image.onload = function () {
|
||||||
|
let canvas = document.createElement("canvas");
|
||||||
|
canvas.width = image.width;
|
||||||
|
canvas.height = image.height;
|
||||||
|
let context = canvas.getContext("2d");
|
||||||
|
context.drawImage(image, 0, 0, image.width, image.height);
|
||||||
|
let url = canvas.toDataURL(); // 得到图片的base64编码数据
|
||||||
|
canvas.toDataURL("image/png");
|
||||||
|
downloadList.push({type: type, index: index, data: url.substring(22)}); // 去掉base64编码前的 data:image/png;base64,
|
||||||
|
if (downloadList.length === baseList.length && downloadList.length > 0) {
|
||||||
|
for (let l = 0; l < downloadList.length; l++) {
|
||||||
|
if (downloadList[l].type == '0') {
|
||||||
|
imgsDetail.file(`详情图${downloadList[l].index}.png`, downloadList[l].data, { base64: true });
|
||||||
|
} else if (downloadList[l].type == '1') {
|
||||||
|
imgsBanner.file(`轮播图${downloadList[l].index}.png`, downloadList[l].data, { base64: true });
|
||||||
|
} else if (downloadList[l].type == '2') {
|
||||||
|
videos.file(`视频.mp4`, downloadList[l].data, { Blob: true });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
zip.generateAsync({ type: "blob" }).then(function (content) {
|
||||||
|
// see FileSaver.js
|
||||||
|
saveAs(content, "shein_" + id + ".zip");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
image.src = baseList[k].src;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
document.body.appendChild(popup)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
29
public/rules_7.json
Normal file
29
public/rules_7.json
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"id": 18,
|
||||||
|
"priority": 1,
|
||||||
|
"action": {
|
||||||
|
"type": "modifyHeaders",
|
||||||
|
"requestHeaders": [
|
||||||
|
{
|
||||||
|
"header": "Origin",
|
||||||
|
"operation": "set",
|
||||||
|
"value": "https://img.ltwebstatic.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"header": "Referer",
|
||||||
|
"operation": "set",
|
||||||
|
"value": "https://img.ltwebstatic.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"header": "Sec-Fetch-Mode",
|
||||||
|
"operation": "set",
|
||||||
|
"value": "no-cors"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"condition": {
|
||||||
|
"urlFilter": "||img.ltwebstatic.com"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
24
public/rules_8.json
Normal file
24
public/rules_8.json
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"id": 19,
|
||||||
|
"priority": 1,
|
||||||
|
"action": {
|
||||||
|
"type": "modifyHeaders",
|
||||||
|
"requestHeaders": [
|
||||||
|
{
|
||||||
|
"header": "Origin",
|
||||||
|
"operation": "set",
|
||||||
|
"value": "https://www.geiwohuo.com/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"header": "Referer",
|
||||||
|
"operation": "set",
|
||||||
|
"value": "https://www.geiwohuo.com/"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"condition": {
|
||||||
|
"urlFilter": "||www.geiwohuo.com"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
24
public/rules_9.json
Normal file
24
public/rules_9.json
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"id": 20,
|
||||||
|
"priority": 1,
|
||||||
|
"action": {
|
||||||
|
"type": "modifyHeaders",
|
||||||
|
"requestHeaders": [
|
||||||
|
{
|
||||||
|
"header": "Origin",
|
||||||
|
"operation": "set",
|
||||||
|
"value": "https://agentseller.temu.com/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"header": "Referer",
|
||||||
|
"operation": "set",
|
||||||
|
"value": "https://agentseller.temu.com/"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"condition": {
|
||||||
|
"urlFilter": "||agentseller.temu.com"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
@@ -26,6 +26,32 @@ export async function sendChromeAPIMessage(message) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 向Chrome发送消息
|
||||||
|
* @param message 消息
|
||||||
|
*/
|
||||||
|
export async function sendTemuSellerAgentMessage(message) {
|
||||||
|
message.type = 'api'
|
||||||
|
if (!message.url.startsWith('http')) {
|
||||||
|
message.url = "https://agentseller.temu.com/" + message.url;
|
||||||
|
}
|
||||||
|
message.anti = message.anti || false
|
||||||
|
if (message.needMallId) {
|
||||||
|
// 如果参数中没有携带MallId,则从state中获取
|
||||||
|
if (!message.mallId) {
|
||||||
|
message.mallId = store.state.mallId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (message.anti) {
|
||||||
|
message.anti = await genAnti.a()
|
||||||
|
}
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
// @ts-ignore
|
||||||
|
chrome.runtime.sendMessage(message, resolve)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 向Chrome发送消息
|
* 向Chrome发送消息
|
||||||
* @param message 消息
|
* @param message 消息
|
||||||
@@ -74,7 +100,11 @@ export async function sendSheinAPIMessage(message) {
|
|||||||
*/
|
*/
|
||||||
export async function sendGeiwohuoAPIMessage(message) {
|
export async function sendGeiwohuoAPIMessage(message) {
|
||||||
message.type = 'geiwohuoApi'
|
message.type = 'geiwohuoApi'
|
||||||
message.url = "https://sso.geiwohuo.com/" + message.url;
|
if (message.isWWW) {
|
||||||
|
message.url = "https://www.geiwohuo.com/" + message.url;
|
||||||
|
} else {
|
||||||
|
message.url = "https://sso.geiwohuo.com/" + message.url;
|
||||||
|
}
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
chrome.runtime.sendMessage(message, resolve)
|
chrome.runtime.sendMessage(message, resolve)
|
||||||
|
|||||||
@@ -368,13 +368,17 @@ export default {
|
|||||||
let content = data
|
let content = data
|
||||||
let i = 0
|
let i = 0
|
||||||
if (this.form.isSameCategory) {
|
if (this.form.isSameCategory) {
|
||||||
let res2 = await this.$http.post('/api/innerCategory/fullById',null , {
|
/*let res2 = await this.$http.post('/api/innerCategory/fullById',null , {
|
||||||
params: {
|
params: {
|
||||||
id: reqData.catId
|
id: reqData.catId
|
||||||
}
|
}
|
||||||
})
|
})*/
|
||||||
for (; i < res2.data.length; i++) {
|
for (; i < 10; i++) {
|
||||||
content['cat' + (i+1) + 'Id'] = res2.data[i]
|
if (content['cat' + (i+1) + 'Id']) {
|
||||||
|
continue
|
||||||
|
}else {
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let res3 = await sendChromeAPIMessage({
|
let res3 = await sendChromeAPIMessage({
|
||||||
@@ -422,6 +426,9 @@ 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) {
|
||||||
|
content['cat'+(++i)+'Id'] = reqData.catId
|
||||||
|
}
|
||||||
for (; i < 10; i++) {
|
for (; i < 10; i++) {
|
||||||
content['cat' + (i+1) + 'Id'] = ''
|
content['cat' + (i+1) + 'Id'] = ''
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,8 @@
|
|||||||
"*://*.alicdn.com/",
|
"*://*.alicdn.com/",
|
||||||
"*://*.amazon.com/",
|
"*://*.amazon.com/",
|
||||||
"*://*.shein.com/",
|
"*://*.shein.com/",
|
||||||
"*://*.geiwohuo.com/"
|
"*://*.geiwohuo.com/",
|
||||||
|
"*://*.ltwebstatic.com/"
|
||||||
],
|
],
|
||||||
"permissions": [
|
"permissions": [
|
||||||
"cookies",
|
"cookies",
|
||||||
@@ -51,13 +52,26 @@
|
|||||||
"id": "6",
|
"id": "6",
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"path": "rules_6.json"
|
"path": "rules_6.json"
|
||||||
|
},{
|
||||||
|
"id": "7",
|
||||||
|
"enabled": true,
|
||||||
|
"path": "rules_7.json"
|
||||||
|
},{
|
||||||
|
"id": "8",
|
||||||
|
"enabled": true,
|
||||||
|
"path": "rules_8.json"
|
||||||
|
},{
|
||||||
|
"id": "9",
|
||||||
|
"enabled": true,
|
||||||
|
"path": "rules_9.json"
|
||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
"content_scripts": [
|
"content_scripts": [
|
||||||
{
|
{
|
||||||
"matches": [
|
"matches": [
|
||||||
"*://*.aliexpress.com/item/*",
|
"*://*.aliexpress.com/item/*",
|
||||||
"*://*.amazon.com/*"
|
"*://*.amazon.com/*",
|
||||||
|
"*://*.shein.com/*"
|
||||||
],
|
],
|
||||||
"js": [
|
"js": [
|
||||||
"/content.js"
|
"/content.js"
|
||||||
@@ -67,7 +81,7 @@
|
|||||||
"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/*" ]
|
"matches": [ "*://*.aliexpress.com/*", "*://*.amazon.com/*", "*://*.shein.com/*" ]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
"manifest_version": 3,
|
"manifest_version": 3,
|
||||||
"name": "TEMU助手",
|
"name": "TEMU助手",
|
||||||
"description": "TEMU助手 - 自动化提高生产效率",
|
"description": "TEMU助手 - 自动化提高生产效率",
|
||||||
"version": "3.2.1",
|
"version": "3.2.3",
|
||||||
"background": {
|
"background": {
|
||||||
"service_worker": "/background.js"
|
"service_worker": "/background.js"
|
||||||
},
|
},
|
||||||
@@ -21,7 +21,8 @@
|
|||||||
"*://*.alicdn.com/",
|
"*://*.alicdn.com/",
|
||||||
"*://*.amazon.com/",
|
"*://*.amazon.com/",
|
||||||
"*://*.shein.com/",
|
"*://*.shein.com/",
|
||||||
"*://*.geiwohuo.com/"
|
"*://*.geiwohuo.com/",
|
||||||
|
"*://*.ltwebstatic.com/"
|
||||||
],
|
],
|
||||||
"permissions": [
|
"permissions": [
|
||||||
"cookies",
|
"cookies",
|
||||||
@@ -55,13 +56,26 @@
|
|||||||
"id": "6",
|
"id": "6",
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"path": "rules_6.json"
|
"path": "rules_6.json"
|
||||||
|
},{
|
||||||
|
"id": "7",
|
||||||
|
"enabled": true,
|
||||||
|
"path": "rules_7.json"
|
||||||
|
},{
|
||||||
|
"id": "8",
|
||||||
|
"enabled": true,
|
||||||
|
"path": "rules_8.json"
|
||||||
|
},{
|
||||||
|
"id": "9",
|
||||||
|
"enabled": true,
|
||||||
|
"path": "rules_9.json"
|
||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
"content_scripts": [
|
"content_scripts": [
|
||||||
{
|
{
|
||||||
"matches": [
|
"matches": [
|
||||||
"*://*.aliexpress.com/item/*",
|
"*://*.aliexpress.com/item/*",
|
||||||
"*://*.amazon.com/*"
|
"*://*.amazon.com/*",
|
||||||
|
"*://*.shein.com/*"
|
||||||
],
|
],
|
||||||
"js": [
|
"js": [
|
||||||
"/content.js"
|
"/content.js"
|
||||||
@@ -71,7 +85,7 @@
|
|||||||
"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/*" ]
|
"matches": [ "*://*.aliexpress.com/*", "*://*.amazon.com/*", "*://*.shein.com/*" ]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -85,15 +85,20 @@ const router = new VueRouter({
|
|||||||
name: 'copyProduct',
|
name: 'copyProduct',
|
||||||
component: () => import('../view/product/CopyProduct.vue')
|
component: () => import('../view/product/CopyProduct.vue')
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: 'sellerSelect',
|
||||||
|
name: 'sellerSelect',
|
||||||
|
component: () => import('../view/product/SellerSelect.vue')
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: 'draft',
|
path: 'draft',
|
||||||
name: 'draft',
|
name: 'draft',
|
||||||
component: () => import('../view/product/Draft.vue')
|
component: () => import('../view/product/Draft.vue')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'copyProductShein',
|
path: 'findSeller',
|
||||||
name: 'copyProductShein',
|
name: 'findSeller',
|
||||||
component: () => import('../view/product/CopyProductShein.vue')
|
component: () => import('../view/product/FindSeller.vue')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'copyProductAliExpress',
|
path: 'copyProductAliExpress',
|
||||||
@@ -172,21 +177,56 @@ const router = new VueRouter({
|
|||||||
component: () => import('../view/CoinFlow.vue')
|
component: () => import('../view/CoinFlow.vue')
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
path: 'costManageTemu',
|
||||||
|
name: 'costManageTemu',
|
||||||
|
component: () => import('../view/sale/CostManageTemu.vue')
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: 'saleData',
|
path: 'saleData',
|
||||||
name: 'saleData',
|
name: 'saleData',
|
||||||
component: () => import('../view/sale/ExportSaleData.vue')
|
component: () => import('../view/sale/ExportSaleData.vue')
|
||||||
},
|
},
|
||||||
{
|
|
||||||
path: 'saleDataShein',
|
|
||||||
name: 'saleDataShein',
|
|
||||||
component: () => import('../view/sale/ExportSaleDataShein.vue')
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
path: 'saleOut',
|
path: 'saleOut',
|
||||||
name: 'saleOut',
|
name: 'saleOut',
|
||||||
component: () => import('../view/sale/ExportSaleOutData.vue')
|
component: () => import('../view/sale/ExportSaleOutData.vue')
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: 'afterSaleStat',
|
||||||
|
name: 'afterSaleStat',
|
||||||
|
component: () => import('../view/sale/AfterSaleStat.vue')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'afterSaleDeductStat',
|
||||||
|
name: 'afterSaleDeductStat',
|
||||||
|
component: () => import('../view/sale/AfterSaleDeductStat.vue')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'costManageShein',
|
||||||
|
name: 'costManageShein',
|
||||||
|
component: () => import('../view/shein/CostManageShein.vue')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'certCenterShein',
|
||||||
|
name: 'certCenterShein',
|
||||||
|
component: () => import('../view/shein/CertCenterShein.vue')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'saleDataShein',
|
||||||
|
name: 'saleDataShein',
|
||||||
|
component: () => import('../view/shein/ExportSaleDataShein.vue')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'saleStatShein',
|
||||||
|
name: 'saleStatShein',
|
||||||
|
component: () => import('../view/shein/ExportSaleStatShein.vue')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'copyProductShein',
|
||||||
|
name: 'copyProductShein',
|
||||||
|
component: () => import('../view/shein/CopyProductShein.vue')
|
||||||
|
},
|
||||||
|
|
||||||
// {
|
// {
|
||||||
// path: 'statistics',
|
// path: 'statistics',
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ export default new Vuex.Store({
|
|||||||
mallName: '',
|
mallName: '',
|
||||||
mallList: [],
|
mallList: [],
|
||||||
activeDlgShow: false,
|
activeDlgShow: false,
|
||||||
|
showSheinAlert: false,
|
||||||
|
showTemuAlert: false,
|
||||||
userInfo: {}
|
userInfo: {}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -46,6 +48,12 @@ export default new Vuex.Store({
|
|||||||
},
|
},
|
||||||
setActiveDlgShow(state, flag) {
|
setActiveDlgShow(state, flag) {
|
||||||
state.activeDlgShow = flag
|
state.activeDlgShow = flag
|
||||||
|
},
|
||||||
|
setSheinAlertShow(state, flag) {
|
||||||
|
state.showSheinAlert = flag
|
||||||
|
},
|
||||||
|
setTemuAlertShow(state, flag) {
|
||||||
|
state.showTemuAlert = flag
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -18,8 +18,9 @@ export function transform(leftData) {
|
|||||||
rightData.materialMultiLanguages = leftData.productLocalExtAttr.materialMultiLanguages;
|
rightData.materialMultiLanguages = leftData.productLocalExtAttr.materialMultiLanguages;
|
||||||
rightData.productI18nReqs = leftData.productI18nList;
|
rightData.productI18nReqs = leftData.productI18nList;
|
||||||
rightData.productPropertyReqs = [];
|
rightData.productPropertyReqs = [];
|
||||||
|
let flag = false
|
||||||
for (let i = 0; i < leftData.productPropertyList.length; i++) {
|
for (let i = 0; i < leftData.productPropertyList.length; i++) {
|
||||||
rightData.productPropertyReqs.push({
|
let val = {
|
||||||
valueUnit: leftData.productPropertyList[i].valueUnit,
|
valueUnit: leftData.productPropertyList[i].valueUnit,
|
||||||
propValue: leftData.productPropertyList[i].propValue,
|
propValue: leftData.productPropertyList[i].propValue,
|
||||||
propName: leftData.productPropertyList[i].propName,
|
propName: leftData.productPropertyList[i].propName,
|
||||||
@@ -29,9 +30,31 @@ export function transform(leftData) {
|
|||||||
pid: leftData.productPropertyList[i].pid,
|
pid: leftData.productPropertyList[i].pid,
|
||||||
templatePid: leftData.productPropertyList[i].templatePid,
|
templatePid: leftData.productPropertyList[i].templatePid,
|
||||||
valueExtendInfo: leftData.productPropertyList[i].valueExtendInfo
|
valueExtendInfo: leftData.productPropertyList[i].valueExtendInfo
|
||||||
});
|
}
|
||||||
|
/*if (leftData.productPropertyList[i].vid == 41500) {
|
||||||
|
if (config.brandId) {
|
||||||
|
flag = true
|
||||||
|
val.pid = 41500
|
||||||
|
val.propName = config.brandName
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
rightData.productPropertyReqs.push(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*if (config.brandId && !flag) {
|
||||||
|
rightData.productPropertyReqs.push({
|
||||||
|
"valueUnit": "",
|
||||||
|
"propValue": config.brandName,
|
||||||
|
"propName": "品牌名",
|
||||||
|
"refPid": 1960,
|
||||||
|
"vid": 41500,
|
||||||
|
"controlType": 1,
|
||||||
|
"pid": config.brandId,
|
||||||
|
"templatePid": 1151553,
|
||||||
|
"valueExtendInfo": ""
|
||||||
|
})
|
||||||
|
}*/
|
||||||
|
|
||||||
// SKC
|
// SKC
|
||||||
let rightSkc = [];
|
let rightSkc = [];
|
||||||
let leftSkc = leftData.productSkcList;
|
let leftSkc = leftData.productSkcList;
|
||||||
@@ -159,6 +182,7 @@ export function transformSubmitForHalf(leftData, config, draftId) {
|
|||||||
rightData.materialMultiLanguages = leftData.productLocalExtAttr.materialMultiLanguages;
|
rightData.materialMultiLanguages = leftData.productLocalExtAttr.materialMultiLanguages;
|
||||||
rightData.productI18nReqs = leftData.productI18nList;
|
rightData.productI18nReqs = leftData.productI18nList;
|
||||||
rightData.productPropertyReqs = [];
|
rightData.productPropertyReqs = [];
|
||||||
|
if (!leftData.productPropertyList) return rightData
|
||||||
for (let i = 0; i < leftData.productPropertyList.length; i++) {
|
for (let i = 0; i < leftData.productPropertyList.length; i++) {
|
||||||
rightData.productPropertyReqs.push({
|
rightData.productPropertyReqs.push({
|
||||||
valueUnit: leftData.productPropertyList[i].valueUnit,
|
valueUnit: leftData.productPropertyList[i].valueUnit,
|
||||||
@@ -240,6 +264,7 @@ export function transformSubmitForHalf(leftData, config, draftId) {
|
|||||||
}
|
}
|
||||||
rightSkuItem.productSkuStockQuantityReq = productSkuStockQuantityReq
|
rightSkuItem.productSkuStockQuantityReq = productSkuStockQuantityReq
|
||||||
rightSkuItem.currencyType = leftSkuItem.currencyType;
|
rightSkuItem.currencyType = leftSkuItem.currencyType;
|
||||||
|
rightSkuItem.supplierPrice = leftSkuItem.supplierPrice + config.upMoney * 100;
|
||||||
|
|
||||||
rightSkcItem.productSkuReqs.push(rightSkuItem);
|
rightSkcItem.productSkuReqs.push(rightSkuItem);
|
||||||
}
|
}
|
||||||
@@ -255,6 +280,14 @@ export function transformSubmitForHalf(leftData, config, draftId) {
|
|||||||
rightData.carouselImageI18nReqs = leftData.carouselImageI18nVOList;
|
rightData.carouselImageI18nReqs = leftData.carouselImageI18nVOList;
|
||||||
rightData.materialImgUrl = leftData.materialImgUrl;
|
rightData.materialImgUrl = leftData.materialImgUrl;
|
||||||
rightData.goodsLayerDecorationReqs = leftData.goodsLayerDecorationVOList;
|
rightData.goodsLayerDecorationReqs = leftData.goodsLayerDecorationVOList;
|
||||||
|
rightData.goodsLayerDecorationReqs.map(item => {
|
||||||
|
if (item.type == 'image') {
|
||||||
|
item.contentList.map(item1 => {
|
||||||
|
delete item1.text
|
||||||
|
delete item1.textModuleDetails
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
rightData.sizeTemplateIds = !leftData.sizeTemplateIds ? []: leftData.sizeTemplateIds;
|
rightData.sizeTemplateIds = !leftData.sizeTemplateIds ? []: leftData.sizeTemplateIds;
|
||||||
rightData.showSizeTemplateIds = !leftData.showSizeTemplateIds ? []: leftData.showSizeTemplateIds;
|
rightData.showSizeTemplateIds = !leftData.showSizeTemplateIds ? []: leftData.showSizeTemplateIds;
|
||||||
rightData.goodsModelReqs = !leftData.goodsModelList ? []: leftData.goodsModelList;
|
rightData.goodsModelReqs = !leftData.goodsModelList ? []: leftData.goodsModelList;
|
||||||
|
|||||||
@@ -70,8 +70,11 @@
|
|||||||
</template>
|
</template>
|
||||||
<el-menu-item index="/productList">商品列表</el-menu-item>
|
<el-menu-item index="/productList">商品列表</el-menu-item>
|
||||||
<el-menu-item index="/copyProduct">商品复制</el-menu-item>
|
<el-menu-item index="/copyProduct">商品复制</el-menu-item>
|
||||||
<el-menu-item index="/draft">草稿箱管理</el-menu-item>
|
<el-menu-item index="/findSeller">查找买手</el-menu-item>
|
||||||
<el-menu-item index="/copyProductShein">商品复制(希音)</el-menu-item>
|
<el-menu-item v-if="$store.state.userInfo.phone == '18610967550' || $store.state.userInfo.phone == '18571466720'" index="/draft">
|
||||||
|
草稿箱管理
|
||||||
|
</el-menu-item>
|
||||||
|
<el-menu-item index="/sellerSelect">上新生命周期管理</el-menu-item>
|
||||||
<!--<el-menu-item index="/copyProductAliExpress">商品复制(速卖通)</el-menu-item>-->
|
<!--<el-menu-item index="/copyProductAliExpress">商品复制(速卖通)</el-menu-item>-->
|
||||||
</el-submenu>
|
</el-submenu>
|
||||||
<el-submenu index="/stock">
|
<el-submenu index="/stock">
|
||||||
@@ -126,18 +129,31 @@
|
|||||||
<i class="el-icon-s-data"></i>
|
<i class="el-icon-s-data"></i>
|
||||||
<span slot="title">销售管理</span>
|
<span slot="title">销售管理</span>
|
||||||
</template>
|
</template>
|
||||||
<el-menu-item index="/saleData">销售管理(TEMU)</el-menu-item>
|
<el-menu-item index="/costManageTemu">成本管理</el-menu-item>
|
||||||
<el-menu-item index="/saleDataShein">销售数据(SHEIN)</el-menu-item>
|
<el-menu-item index="/saleData">销售管理</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="/afterSaleDeductStat">售后赔付统计</el-menu-item>
|
||||||
|
</el-submenu>
|
||||||
|
<el-submenu index="/shein">
|
||||||
|
<template slot="title">
|
||||||
|
<i class="el-icon-s-goods"></i>
|
||||||
|
<span slot="title">SHEIN希音</span>
|
||||||
|
</template>
|
||||||
|
<el-menu-item index="/costManageShein">成本管理</el-menu-item>
|
||||||
|
<el-menu-item index="/saleDataShein">销售数据</el-menu-item>
|
||||||
|
<el-menu-item index="/certCenterShein">证书中心</el-menu-item>
|
||||||
|
<el-menu-item index="/copyProductShein">商品复制</el-menu-item>
|
||||||
|
<el-menu-item index="/saleStatShein">商家账单统计</el-menu-item>
|
||||||
</el-submenu>
|
</el-submenu>
|
||||||
<el-menu-item index="/info">
|
<el-menu-item index="/info">
|
||||||
<i class="el-icon-info"></i>
|
<i class="el-icon-info"></i>
|
||||||
<span slot="title">弹窗消息</span>
|
<span slot="title">弹窗消息</span>
|
||||||
</el-menu-item>
|
</el-menu-item>
|
||||||
<el-menu-item index="/priceFollow">
|
<!--<el-menu-item index="/priceFollow">
|
||||||
<i class="el-icon-money"></i>
|
<i class="el-icon-money"></i>
|
||||||
<span slot="title">调价管理</span>
|
<span slot="title">调价管理</span>
|
||||||
</el-menu-item>
|
</el-menu-item>-->
|
||||||
<el-menu-item index="/learning">
|
<el-menu-item index="/learning">
|
||||||
<i class="el-icon-eleme"></i>
|
<i class="el-icon-eleme"></i>
|
||||||
<span slot="title">新手园地</span>
|
<span slot="title">新手园地</span>
|
||||||
@@ -164,6 +180,27 @@
|
|||||||
:before-close="handleClose">
|
:before-close="handleClose">
|
||||||
<ai-payment/>
|
<ai-payment/>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
<el-dialog
|
||||||
|
title="温馨提示"
|
||||||
|
:visible="$store.state.showSheinAlert"
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
width="1200">
|
||||||
|
<span style="font-size: large">1、检查“SHEIN商家后台”是否登录,如没登录,请先登录,之后再刷新助手<br></span>
|
||||||
|
<span style="font-size: large">2、如果SHEIN商家后台已经登录,仍然弹出当前窗口,则需要SHEIN进行二次授权,二次授权可在菜单“商品管理->商品列表”,任意选择一个商品,在“价格”一栏,点击修改,在新打开的页面中可看到“正在鉴权”的字样,即可完成二次授权</span>
|
||||||
|
<span slot="footer" class="dialog-footer">
|
||||||
|
<el-button @click="closeSheinAlert">关 闭</el-button>
|
||||||
|
</span>
|
||||||
|
</el-dialog>
|
||||||
|
<el-dialog
|
||||||
|
title="温馨提示"
|
||||||
|
:visible="$store.state.showTemuAlert"
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
width="1200">
|
||||||
|
<span style="font-size: large">请先打开卖家中心“结算数据->售后管理”页面进行二次授权,<a target="_blank" style="text-decoration: underline" href="https://seller.kuajingmaihuo.com/main/aftersales/information">去打开</a><br></span>
|
||||||
|
<span slot="footer" class="dialog-footer">
|
||||||
|
<el-button @click="closeTemuAlert">关 闭</el-button>
|
||||||
|
</span>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
<div id="kefu" @click="gotoKefu">
|
<div id="kefu" @click="gotoKefu">
|
||||||
<label slot="reference" class="topBtn" title="联系客服"></label>
|
<label slot="reference" class="topBtn" title="联系客服"></label>
|
||||||
@@ -174,7 +211,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import {mapMutations, mapState} from 'vuex'
|
import {mapMutations, mapState} from 'vuex'
|
||||||
import AiPayment from "@/components/AiPayment.vue";
|
import AiPayment from "@/components/AiPayment.vue";
|
||||||
import {sendAliexpressAPIMessage} from "@/api/chromeApi";
|
import {sendAliexpressAPIMessage, sendTemuSellerAgentMessage} from "@/api/chromeApi";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {AiPayment},
|
components: {AiPayment},
|
||||||
@@ -222,6 +259,7 @@ export default {
|
|||||||
const prodVersion = require('../manifest.production.json').version
|
const prodVersion = require('../manifest.production.json').version
|
||||||
this.version = process.env.NODE_ENV === 'production' ? prodVersion : devVersion
|
this.version = process.env.NODE_ENV === 'production' ? prodVersion : devVersion
|
||||||
this.activePath = this.$route.fullPath
|
this.activePath = this.$route.fullPath
|
||||||
|
//this.getAfterSalesList()
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
@@ -293,6 +331,12 @@ export default {
|
|||||||
gotoKefu() {
|
gotoKefu() {
|
||||||
window.open('https://work.weixin.qq.com/kfid/kfcaa4208f661131eba', '_blank')
|
window.open('https://work.weixin.qq.com/kfid/kfcaa4208f661131eba', '_blank')
|
||||||
},
|
},
|
||||||
|
closeSheinAlert() {
|
||||||
|
this.$store.commit('setSheinAlertShow', false)
|
||||||
|
},
|
||||||
|
closeTemuAlert() {
|
||||||
|
this.$store.commit('setTemuAlertShow', false)
|
||||||
|
},
|
||||||
getAliexpressGoodsList() {
|
getAliexpressGoodsList() {
|
||||||
let url = "https://seller-acs.aliexpress.com/h5/mtop.global.merchant.self.product.manager.render.list/1.0/?jsv=2.7.2&appKey=30267743&t=1713978403051&sign=ba2bda69b4a2695c7279d4bc05f51741&v=1.0&timeout=15000&H5Request=true&url=mtop.global.merchant.self.product.manager.render.list&__channel-id__=701301&api=mtop.global.merchant.self.product.manager.render.list&type=originaljson&dataType=json&valueType=original&x-i18n-regionID=AE"
|
let url = "https://seller-acs.aliexpress.com/h5/mtop.global.merchant.self.product.manager.render.list/1.0/?jsv=2.7.2&appKey=30267743&t=1713978403051&sign=ba2bda69b4a2695c7279d4bc05f51741&v=1.0&timeout=15000&H5Request=true&url=mtop.global.merchant.self.product.manager.render.list&__channel-id__=701301&api=mtop.global.merchant.self.product.manager.render.list&type=originaljson&dataType=json&valueType=original&x-i18n-regionID=AE"
|
||||||
url = url + "&data=" + encodeURIComponent(
|
url = url + "&data=" + encodeURIComponent(
|
||||||
@@ -322,7 +366,7 @@ export default {
|
|||||||
}).then(res => {
|
}).then(res => {
|
||||||
//console.log(res)
|
//console.log(res)
|
||||||
})
|
})
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
// this.getAliexpressGoodsList()
|
// this.getAliexpressGoodsList()
|
||||||
|
|||||||
@@ -106,6 +106,7 @@
|
|||||||
productName: item.productName,
|
productName: item.productName,
|
||||||
skcId: item.skcId,
|
skcId: item.skcId,
|
||||||
popUpType: 1,
|
popUpType: 1,
|
||||||
|
versionId: res.result.popUpAutoPass12.versionId,
|
||||||
newSupplyPrice: item.newSupplyPrice / 100,
|
newSupplyPrice: item.newSupplyPrice / 100,
|
||||||
}
|
}
|
||||||
item.skuInfoItemList.map(item1 => {
|
item.skuInfoItemList.map(item1 => {
|
||||||
@@ -118,6 +119,7 @@
|
|||||||
productName: item.productName,
|
productName: item.productName,
|
||||||
skcId: item.skcId,
|
skcId: item.skcId,
|
||||||
popUpType: 2,
|
popUpType: 2,
|
||||||
|
versionId: res.result.popUpAutoPass24.versionId,
|
||||||
newSupplyPrice: item.newSupplyPrice / 100,
|
newSupplyPrice: item.newSupplyPrice / 100,
|
||||||
}
|
}
|
||||||
item.skuInfoItemList.map(item1 => {
|
item.skuInfoItemList.map(item1 => {
|
||||||
@@ -130,6 +132,7 @@
|
|||||||
productName: item.productName,
|
productName: item.productName,
|
||||||
skcId: item.skcId,
|
skcId: item.skcId,
|
||||||
popUpType: 3,
|
popUpType: 3,
|
||||||
|
versionId: res.result.popUpOthers.versionId,
|
||||||
newSupplyPrice: item.newSupplyPrice / 100,
|
newSupplyPrice: item.newSupplyPrice / 100,
|
||||||
}
|
}
|
||||||
item.skuInfoItemList.map(item1 => {
|
item.skuInfoItemList.map(item1 => {
|
||||||
@@ -160,11 +163,14 @@
|
|||||||
Message.success("该店铺无调价通知,无需处理")
|
Message.success("该店铺无调价通知,无需处理")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let maxOrderId = 0
|
let popUpType1VersionId = ''
|
||||||
let ids = this.priceList.map(item => {
|
let popUpType2VersionId = ''
|
||||||
|
let popUpType3VersionId = ''
|
||||||
|
let ids = []
|
||||||
|
this.priceList.map(item => {
|
||||||
if (item.popUpType == 1) {
|
if (item.popUpType == 1) {
|
||||||
if (maxOrderId < item.id) maxOrderId = item.id
|
popUpType1VersionId = item.versionId
|
||||||
return item.id
|
ids.push(item.id)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
let res = null
|
let res = null
|
||||||
@@ -175,16 +181,16 @@
|
|||||||
mallId: this.currentMallId,
|
mallId: this.currentMallId,
|
||||||
data: {
|
data: {
|
||||||
"rejectOrderIdList": ids,
|
"rejectOrderIdList": ids,
|
||||||
"maxOrderId": maxOrderId,
|
"maxOrderId": popUpType1VersionId,
|
||||||
"popUpType": 1,
|
"popUpType": 1,
|
||||||
"createTime": new Date().getTime() * 1000
|
"createTime": new Date().getTime()
|
||||||
}})
|
}})
|
||||||
}
|
}
|
||||||
maxOrderId = 0
|
ids = []
|
||||||
ids = this.priceList.map(item => {
|
this.priceList.map(item => {
|
||||||
if (item.popUpType == 2) {
|
if (item.popUpType == 2) {
|
||||||
if (maxOrderId < item.id) maxOrderId = item.id
|
popUpType2VersionId = item.versionId
|
||||||
return item.id
|
ids.push(item.id)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
if (ids.length > 0) {
|
if (ids.length > 0) {
|
||||||
@@ -194,16 +200,16 @@
|
|||||||
mallId: this.currentMallId,
|
mallId: this.currentMallId,
|
||||||
data: {
|
data: {
|
||||||
"rejectOrderIdList": ids,
|
"rejectOrderIdList": ids,
|
||||||
"maxOrderId": maxOrderId,
|
"maxOrderId": popUpType2VersionId,
|
||||||
"popUpType": 2,
|
"popUpType": 2,
|
||||||
"createTime": new Date().getTime() * 1000
|
"createTime": new Date().getTime()
|
||||||
}})
|
}})
|
||||||
}
|
}
|
||||||
maxOrderId = 0
|
ids = []
|
||||||
ids = this.priceList.map(item => {
|
this.priceList.map(item => {
|
||||||
if (item.popUpType == 3) {
|
if (item.popUpType == 3) {
|
||||||
if (maxOrderId < item.id) maxOrderId = item.id
|
popUpType3VersionId = item.versionId
|
||||||
return item.id
|
ids.push(item.id)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
if (ids.length > 0) {
|
if (ids.length > 0) {
|
||||||
@@ -213,9 +219,9 @@
|
|||||||
mallId: this.currentMallId,
|
mallId: this.currentMallId,
|
||||||
data: {
|
data: {
|
||||||
"rejectOrderIdList": ids,
|
"rejectOrderIdList": ids,
|
||||||
"maxOrderId": maxOrderId,
|
"maxOrderId": popUpType3VersionId,
|
||||||
"popUpType": 3,
|
"popUpType": 3,
|
||||||
"createTime": new Date().getTime() * 1000
|
"createTime": new Date().getTime()
|
||||||
}})
|
}})
|
||||||
}
|
}
|
||||||
if (res.success && res.errorCode == 1000000) {
|
if (res.success && res.errorCode == 1000000) {
|
||||||
|
|||||||
@@ -18,6 +18,15 @@
|
|||||||
:value="item.mallId">
|
:value="item.mallId">
|
||||||
</el-option>
|
</el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
|
<label style="width:90px">站点:</label>
|
||||||
|
<el-select v-model="siteId" placeholder="请选择" size="small">
|
||||||
|
<el-option
|
||||||
|
v-for="item in siteList"
|
||||||
|
:key="item.siteId"
|
||||||
|
:label="item.siteName"
|
||||||
|
:value="item.siteId">
|
||||||
|
</el-option>
|
||||||
|
</el-select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -29,6 +38,10 @@
|
|||||||
<el-button v-if="$store.state.mallName" type="button" :class="'el-button el-button--primary'" @click="batchSubmitConfig()">批量提交</el-button>
|
<el-button v-if="$store.state.mallName" type="button" :class="'el-button el-button--primary'" @click="batchSubmitConfig()">批量提交</el-button>
|
||||||
</template>
|
</template>
|
||||||
<template #right>
|
<template #right>
|
||||||
|
<label style="width:140px; text-align: right;">起始页:</label>
|
||||||
|
<el-input size="small" placeholder="请输入起始页" style="width: 100px; display: inline" type="number" v-model="search.startPage"></el-input>
|
||||||
|
<label style="width:140px; text-align: right;">结束页:</label>
|
||||||
|
<el-input size="small" placeholder="请输入起始页" style="width: 100px; display: inline" type="number" v-model="search.endPage"></el-input>
|
||||||
<label style="width:120px">商品名称:</label>
|
<label style="width:120px">商品名称:</label>
|
||||||
<el-input clearable size="small" style="display: inline" placeholder="请输入商品名称" v-model="search.productName"></el-input>
|
<el-input clearable size="small" style="display: inline" placeholder="请输入商品名称" v-model="search.productName"></el-input>
|
||||||
<el-button type="primary" @click="toLoad">查询</el-button>
|
<el-button type="primary" @click="toLoad">查询</el-button>
|
||||||
@@ -37,7 +50,6 @@
|
|||||||
<ai-table
|
<ai-table
|
||||||
:tableData="tableData"
|
:tableData="tableData"
|
||||||
:col-configs="colConfigs"
|
:col-configs="colConfigs"
|
||||||
:total="total"
|
|
||||||
style="margin-top: 8px;"
|
style="margin-top: 8px;"
|
||||||
@selection-change="handleSelectionChange"
|
@selection-change="handleSelectionChange"
|
||||||
:isShowPagination="false">
|
:isShowPagination="false">
|
||||||
@@ -52,7 +64,12 @@
|
|||||||
:close-on-click-modal="false"
|
:close-on-click-modal="false"
|
||||||
width="790px"
|
width="790px"
|
||||||
customFooter
|
customFooter
|
||||||
@close="handleClose">
|
@close="dlgShow = false">
|
||||||
|
<el-alert
|
||||||
|
title="默认“承诺发货时效”为“2个工作日内发货”"
|
||||||
|
type="success"
|
||||||
|
:closable="false">
|
||||||
|
</el-alert>
|
||||||
<el-form class="ai-form" :model="configForm" label-width="160px" ref="configForm">
|
<el-form class="ai-form" :model="configForm" label-width="160px" ref="configForm">
|
||||||
<el-form-item label="运费模板" style="width: 100%;" prop="freightTemplateId" :rules="[{ required: true, message: '请选择运费模板', trigger: 'blur' }]">
|
<el-form-item label="运费模板" style="width: 100%;" prop="freightTemplateId" :rules="[{ required: true, message: '请选择运费模板', trigger: 'blur' }]">
|
||||||
<el-select style="width: 380px" v-model="configForm.freightTemplateId" placeholder="请选择运费模板">
|
<el-select style="width: 380px" v-model="configForm.freightTemplateId" placeholder="请选择运费模板">
|
||||||
@@ -64,12 +81,6 @@
|
|||||||
</el-option>
|
</el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item
|
|
||||||
prop="stockNumber"
|
|
||||||
label="库存数量:"
|
|
||||||
:rules="[{ required: true, message: '请输入库存数量', trigger: 'blur' }]">
|
|
||||||
<el-input size="small" placeholder="请输入库存数量" type="number" v-model="configForm.stockNumber"></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="发货仓" style="width: 100%;" prop="wareHouseList" :rules="[{ required: true, message: '请选择发货仓', trigger: 'blur' }]">
|
<el-form-item label="发货仓" style="width: 100%;" prop="wareHouseList" :rules="[{ required: true, message: '请选择发货仓', trigger: 'blur' }]">
|
||||||
<el-select style="width: 380px" multiple v-model="configForm.wareHouseList" placeholder="请选择发货仓">
|
<el-select style="width: 380px" multiple v-model="configForm.wareHouseList" placeholder="请选择发货仓">
|
||||||
<el-option
|
<el-option
|
||||||
@@ -80,6 +91,30 @@
|
|||||||
</el-option>
|
</el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item
|
||||||
|
prop="stockNumber"
|
||||||
|
label="库存数量:"
|
||||||
|
:rules="[{ required: true, message: '请输入库存数量', trigger: 'blur' }]">
|
||||||
|
<el-input size="small" placeholder="请输入库存数量" type="number" v-model="configForm.stockNumber"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item
|
||||||
|
prop="upMoney"
|
||||||
|
label="上浮金额:"
|
||||||
|
:rules="[{ required: true, message: '请输入上浮金额', trigger: 'blur' }]">
|
||||||
|
<el-input size="small" placeholder="请输入上浮金额" type="number" v-model="configForm.upMoney"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item
|
||||||
|
prop="brand"
|
||||||
|
label="品牌:">
|
||||||
|
<el-select style="width: 380px" clearable v-model="configForm.brandId" placeholder="请选择品牌">
|
||||||
|
<el-option
|
||||||
|
v-for="item in brandList"
|
||||||
|
:key="item.vid"
|
||||||
|
:label="item.brandNameEn"
|
||||||
|
:value="item.vid">
|
||||||
|
</el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<div class="dialog-footer" slot="footer">
|
<div class="dialog-footer" slot="footer">
|
||||||
<el-button @click="dlgShow = false">取 消</el-button>
|
<el-button @click="dlgShow = false">取 消</el-button>
|
||||||
@@ -92,15 +127,19 @@
|
|||||||
<script>
|
<script>
|
||||||
import {sendChromeAPIMessage} from '@/api/chromeApi'
|
import {sendChromeAPIMessage} from '@/api/chromeApi'
|
||||||
import {timestampToTime} from '@/utils/date'
|
import {timestampToTime} from '@/utils/date'
|
||||||
import {transform, transformSubmitForHalf} from '@/utils/product'
|
import {transformSubmitForHalf} from '@/utils/product'
|
||||||
import { Message } from 'element-ui'
|
import { Message, MessageBox } from 'element-ui'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'CopyProduct',
|
name: 'Draft',
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
mallId: '',
|
mallId: '',
|
||||||
|
siteId: '',
|
||||||
|
siteList: [],
|
||||||
search: {
|
search: {
|
||||||
|
startPage: 1,
|
||||||
|
endPage: 10,
|
||||||
productName: ''
|
productName: ''
|
||||||
},
|
},
|
||||||
colConfigs: [
|
colConfigs: [
|
||||||
@@ -115,7 +154,6 @@ import { Message } from 'element-ui'
|
|||||||
page: 1,
|
page: 1,
|
||||||
pageSize: 100,
|
pageSize: 100,
|
||||||
tableData: [],
|
tableData: [],
|
||||||
total: 0,
|
|
||||||
|
|
||||||
dlgShow: false,
|
dlgShow: false,
|
||||||
|
|
||||||
@@ -124,7 +162,10 @@ import { Message } from 'element-ui'
|
|||||||
freightTemplateId: '',
|
freightTemplateId: '',
|
||||||
stockNumber: 5,
|
stockNumber: 5,
|
||||||
siteList: [],
|
siteList: [],
|
||||||
wareHouseList: []
|
upMoney: 0.0,
|
||||||
|
wareHouseList: [],
|
||||||
|
brandId: '',
|
||||||
|
brandName: ''
|
||||||
},
|
},
|
||||||
|
|
||||||
wareHouseList: [],
|
wareHouseList: [],
|
||||||
@@ -133,11 +174,16 @@ import { Message } from 'element-ui'
|
|||||||
ids: [],
|
ids: [],
|
||||||
|
|
||||||
sites: [],
|
sites: [],
|
||||||
loadingText: '拼命加载中……'
|
loadingText: '拼命加载中……',
|
||||||
|
|
||||||
|
successNumber: 0,
|
||||||
|
errorNumber: 0,
|
||||||
|
brandList: [],
|
||||||
|
selectBrand: {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created () {
|
created () {
|
||||||
// this.getDraftList()
|
this.getSiteList()
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
@@ -146,11 +192,33 @@ import { Message } from 'element-ui'
|
|||||||
Message.error("请选择店铺")
|
Message.error("请选择店铺")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if (!this.siteId) {
|
||||||
|
Message.error("请选择站点")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!this.search.startPage || (this.search.startPage < 1)) {
|
||||||
|
Message.error("起始页不能为空,且不能小于1")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!this.search.endPage || (this.search.startPage < 1)) {
|
||||||
|
Message.error("结束页不能为空")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (this.search.startPage > this.search.endPage) {
|
||||||
|
Message.error("起始页不能大于结束页")
|
||||||
|
return
|
||||||
|
}
|
||||||
this.isLoading = true
|
this.isLoading = true
|
||||||
this.loadingText = '拼命加载中……'
|
this.loadingText = '拼命加载中……'
|
||||||
|
this.tableData = []
|
||||||
|
this.page = this.search.startPage
|
||||||
this.getDraftList()
|
this.getDraftList()
|
||||||
},
|
},
|
||||||
async getDraftList () {
|
async getDraftList () {
|
||||||
|
let sites = []
|
||||||
|
if (this.siteId) {
|
||||||
|
sites.push(this.siteId)
|
||||||
|
}
|
||||||
let res = await sendChromeAPIMessage({
|
let res = await sendChromeAPIMessage({
|
||||||
url: 'bg-visage-mms/product/draft/pageQuery',
|
url: 'bg-visage-mms/product/draft/pageQuery',
|
||||||
needMallId: true,
|
needMallId: true,
|
||||||
@@ -158,7 +226,8 @@ import { Message } from 'element-ui'
|
|||||||
data: {
|
data: {
|
||||||
page: this.page,
|
page: this.page,
|
||||||
pageSize: this.pageSize,
|
pageSize: this.pageSize,
|
||||||
...this.search
|
...this.search,
|
||||||
|
bindSiteIds: sites
|
||||||
}})
|
}})
|
||||||
|
|
||||||
if (res.success && res.errorCode == 1000000) {
|
if (res.success && res.errorCode == 1000000) {
|
||||||
@@ -191,7 +260,7 @@ import { Message } from 'element-ui'
|
|||||||
if (this.page == 1 && res.result.pageItems.length == 0) {
|
if (this.page == 1 && res.result.pageItems.length == 0) {
|
||||||
this.isLoading = false
|
this.isLoading = false
|
||||||
}
|
}
|
||||||
else if (res.result.pageItems.length == this.pageSize) {
|
else if (res.result.pageItems.length == this.pageSize && this.page < this.search.endPage) {
|
||||||
this.page ++
|
this.page ++
|
||||||
this.getDraftList()
|
this.getDraftList()
|
||||||
} else {
|
} else {
|
||||||
@@ -205,32 +274,51 @@ import { Message } from 'element-ui'
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let id = this.ids[0]
|
|
||||||
this.sites = []
|
this.sites = []
|
||||||
for (let i = 0; i < this.tableData.length; i++) {
|
this.sites.push(this.siteId)
|
||||||
if (this.tableData[i].spuId == id) {
|
|
||||||
this.sites = this.tableData[i].bindSiteIds.split(',')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.configForm.siteList = this.sites
|
this.configForm.siteList = this.sites
|
||||||
|
this.freightTmplList = []
|
||||||
|
this.wareHouseList = []
|
||||||
|
this.configForm.freightTemplateId = ''
|
||||||
|
this.configForm.wareHouseList = []
|
||||||
await this.getFreightTmplList(this.sites)
|
await this.getFreightTmplList(this.sites)
|
||||||
await this.getWareahouseList(this.sites)
|
await this.getWareahouseList(this.sites)
|
||||||
|
await this.getBrandList()
|
||||||
this.dlgShow = true
|
this.dlgShow = true
|
||||||
},
|
},
|
||||||
async toBtachSubmit() {
|
async toBtachSubmit() {
|
||||||
this.$refs.configForm.validate((valid) => {
|
this.$refs.configForm.validate((valid) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
|
if (this.configForm.brandId) {
|
||||||
|
this.brandList.map(item => {
|
||||||
|
if (item.vid == this.configForm.brandId) {
|
||||||
|
this.selectBrand = item
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
this.isLoading = true
|
this.isLoading = true
|
||||||
this.dlgShow = false
|
this.dlgShow = false
|
||||||
for(let i = 0; i < this.ids.length; i++) {
|
this.successNumber = 0
|
||||||
this.loadingText = '正在提交第' + (i+1) + '/' + this.ids.length + '个商品'
|
this.errorNumber = 0
|
||||||
this.submitSpu(this.ids[i])
|
this.submitSpu(0)
|
||||||
}
|
|
||||||
this.isLoading = false
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
async submitSpu(spuId) {
|
async submitSpu(idx) {
|
||||||
|
if (idx == this.ids.length) {
|
||||||
|
this.isLoading = false
|
||||||
|
MessageBox.alert('总共提交' + this.ids.length + '个商品,成功' + this.successNumber + '个,失败' + this.errorNumber + '个', '提示', {
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
callback: action => {
|
||||||
|
this.toLoad()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
this.loadingText = '正在提交第' + (idx+1) + '/' + this.ids.length + '个商品,成功' + this.successNumber + '个,失败' + this.errorNumber + '个'
|
||||||
|
}
|
||||||
|
let spuId = this.ids[idx]
|
||||||
let res = await sendChromeAPIMessage({
|
let res = await sendChromeAPIMessage({
|
||||||
url: 'bg-visage-mms/product/draft/query',
|
url: 'bg-visage-mms/product/draft/query',
|
||||||
needMallId: true,
|
needMallId: true,
|
||||||
@@ -239,15 +327,53 @@ import { Message } from 'element-ui'
|
|||||||
productDraftId: spuId
|
productDraftId: spuId
|
||||||
}})
|
}})
|
||||||
if (res.success && res.errorCode == 1000000) {
|
if (res.success && res.errorCode == 1000000) {
|
||||||
|
let catId = this.getCategoryId(res.result)
|
||||||
|
let brandProperty = await this.queryProperty(catId)
|
||||||
|
|
||||||
let content = transformSubmitForHalf(res.result, this.configForm, spuId)
|
let content = transformSubmitForHalf(res.result, this.configForm, spuId)
|
||||||
|
|
||||||
|
if (this.configForm.brandId && brandProperty) {
|
||||||
|
let flag = false
|
||||||
|
content.productPropertyReqs.map(item => {
|
||||||
|
if (item.propName == '品牌名') {
|
||||||
|
flag = true
|
||||||
|
item.pid = brandProperty.pid
|
||||||
|
item.refPid = brandProperty.refPid
|
||||||
|
item.templatePid = brandProperty.templatePid
|
||||||
|
item.propValue = this.selectBrand.brandNameEn
|
||||||
|
item.vid = this.selectBrand.vid
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (!flag) {
|
||||||
|
content.productPropertyReqs.push({
|
||||||
|
"templatePid": brandProperty.templatePid,
|
||||||
|
"pid": brandProperty.pid,
|
||||||
|
"refPid": brandProperty.refPid,
|
||||||
|
"propName": "品牌名",
|
||||||
|
"vid": this.selectBrand.vid,
|
||||||
|
"propValue": this.selectBrand.brandNameEn,
|
||||||
|
"valueUnit": "",
|
||||||
|
"valueExtendInfo": "",
|
||||||
|
"numberInputValue": ""
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let res1 = await sendChromeAPIMessage({
|
let res1 = await sendChromeAPIMessage({
|
||||||
url: 'bg-visage-mms/product/add',
|
url: 'bg-visage-mms/product/add',
|
||||||
needMallId: true,
|
needMallId: true,
|
||||||
mallId: this.mallId,
|
mallId: this.mallId,
|
||||||
data: content})
|
data: content})
|
||||||
|
|
||||||
console.log(res1)
|
if (res1.success && res1.errorCode == 1000000) {
|
||||||
|
this.successNumber += 1
|
||||||
|
} else {
|
||||||
|
this.errorNumber += 1
|
||||||
|
}
|
||||||
|
setTimeout(() => {
|
||||||
|
idx ++
|
||||||
|
this.submitSpu(idx)
|
||||||
|
}, 1000)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async getFreightTmplList(siteId) {
|
async getFreightTmplList(siteId) {
|
||||||
@@ -294,39 +420,6 @@ import { Message } from 'element-ui'
|
|||||||
this.ids.push(e.spuId);
|
this.ids.push(e.spuId);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
saveDraftTemplate(spu, index) {
|
|
||||||
sendChromeAPIMessage({
|
|
||||||
url: 'bg-visage-mms/product/draft/query',
|
|
||||||
needMallId: true,
|
|
||||||
mallId: this.productPage.mallId,
|
|
||||||
data: {
|
|
||||||
productDraftId: spu
|
|
||||||
}}).then((res) => {
|
|
||||||
if (res.errorCode == 1000000) {
|
|
||||||
let content = transform(res.result)
|
|
||||||
let mallInfo = this.$store.state.mallList.filter(item => {
|
|
||||||
return item.mallId == this.productPage.mallId
|
|
||||||
})
|
|
||||||
this.$http.post('/api/product/add', {
|
|
||||||
mallId: mallInfo[0].mallId,
|
|
||||||
mallName: mallInfo[0].mallName,
|
|
||||||
productSpu: spu,
|
|
||||||
productName: res.result.productName,
|
|
||||||
type: 0,
|
|
||||||
content: content
|
|
||||||
}).then(res1 => {
|
|
||||||
if (res1.code == 0) {
|
|
||||||
Message.success("商品【" + res.result.productName + "】成功添加为商品模板")
|
|
||||||
if (index == this.productIds.length - 1) {
|
|
||||||
this.getList()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
this.saveDraftTemplate(spu, index)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
async getSiteList() {
|
async getSiteList() {
|
||||||
let res = await sendChromeAPIMessage({
|
let res = await sendChromeAPIMessage({
|
||||||
url: 'bg-visage-mms/config/common/site/query',
|
url: 'bg-visage-mms/config/common/site/query',
|
||||||
@@ -339,6 +432,52 @@ import { Message } from 'element-ui'
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
async getBrandList() {
|
||||||
|
let res = await sendChromeAPIMessage({
|
||||||
|
url: 'bg-anniston-mms/category/brand/property/value/pageQuery',
|
||||||
|
needMallId: true,
|
||||||
|
mallId: this.mallId,
|
||||||
|
data: {
|
||||||
|
"page": 1,
|
||||||
|
"pageSize": 50
|
||||||
|
}})
|
||||||
|
if (res.success && res.errorCode == 1000000) {
|
||||||
|
this.brandList = res.result.pageItems
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async queryProperty(catId) {
|
||||||
|
let res = await sendChromeAPIMessage({
|
||||||
|
url: 'bg-anniston-mms/category/template/query',
|
||||||
|
needMallId: true,
|
||||||
|
mallId: this.mallId,
|
||||||
|
data: {
|
||||||
|
"catId": catId,
|
||||||
|
"productCreateTime": null,
|
||||||
|
"langList": [
|
||||||
|
"en"
|
||||||
|
]
|
||||||
|
}})
|
||||||
|
if (res.success && res.errorCode == 1000000) {
|
||||||
|
let properties = res.result.properties.filter(item => {
|
||||||
|
return item.name == '品牌名'
|
||||||
|
})
|
||||||
|
if (properties && properties.length > 0) {
|
||||||
|
return properties[0]
|
||||||
|
} else {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getCategoryId(obj) {
|
||||||
|
let i = 1
|
||||||
|
while(true) {
|
||||||
|
if (!obj.categories['cat'+i].catId) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
return obj.categories['cat'+(i-1)].catId
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
118
src/view/product/FindSeller.vue
Normal file
118
src/view/product/FindSeller.vue
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
<template>
|
||||||
|
<ai-list class="list" v-loading="isLoading" element-loading-text="拼命加载中" element-loading-spinner="el-icon-loading">
|
||||||
|
<ai-title
|
||||||
|
slot="title"
|
||||||
|
title="查找买手"
|
||||||
|
isShowBottomBorder>
|
||||||
|
</ai-title>
|
||||||
|
<template slot="content">
|
||||||
|
<div class="content">
|
||||||
|
<ai-card title="查找买手" style="padding-bottom: 40px;">
|
||||||
|
<div style="text-align: center; display: flex; flex-wrap: nowrap;justify-content: center;">
|
||||||
|
<label style="width:90px; height: 25px; font-size: 25px">店铺:</label>
|
||||||
|
<el-select style="width:180px;" v-model="form.mallId" placeholder="请选择" clearable size="small">
|
||||||
|
<el-option
|
||||||
|
v-for="item in $store.state.mallList"
|
||||||
|
:key="item.mallId"
|
||||||
|
:label="item.mallName"
|
||||||
|
:value="item.mallId">
|
||||||
|
</el-option>
|
||||||
|
</el-select>
|
||||||
|
<label style="width:120px; height: 25px; font-size: 25px">SKC ID:</label>
|
||||||
|
<el-input style="width:250px; " clearable size="small" placeholder="请输入SKC ID" v-model="form.skc"></el-input>
|
||||||
|
<el-button style="margin-left: 5px" type="primary" @click="beforeFind">查找</el-button>
|
||||||
|
</div>
|
||||||
|
</ai-card>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</ai-list>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { Message } from 'element-ui'
|
||||||
|
import {sendChromeAPIMessage} from '@/api/chromeApi'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'FindSeller',
|
||||||
|
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
form: {
|
||||||
|
mallId: '',
|
||||||
|
skc: ''
|
||||||
|
},
|
||||||
|
isLoading: false,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created () {
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
beforeFind() {
|
||||||
|
this.$userCheck(this.form.mallId).then(() => {
|
||||||
|
this.toFind()
|
||||||
|
}).catch((err) => {
|
||||||
|
this.form.mallId = ''
|
||||||
|
})
|
||||||
|
},
|
||||||
|
async toFind() {
|
||||||
|
if (!this.form.mallId) {
|
||||||
|
Message.error("请选择店铺")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!this.form.skc || (this.form.skc < 1)) {
|
||||||
|
Message.error("请输入SKC")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.isLoading = true
|
||||||
|
|
||||||
|
let res = await sendChromeAPIMessage({
|
||||||
|
url: 'marvel-mms/cn/api/kiana/venom/sales/management/listWarehouse',
|
||||||
|
needMallId: true,
|
||||||
|
mallId: this.form.mallId,
|
||||||
|
data: {
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
isLack: 0,
|
||||||
|
priceAdjustRecentDays: 7,
|
||||||
|
productSkcIdList: [this.form.skc]
|
||||||
|
}})
|
||||||
|
if (res.errorCode == 1000000) {
|
||||||
|
if (res.result.subOrderList.length == 0) {
|
||||||
|
Message.error("没有查询结果,请检查店铺和SKC是否正确")
|
||||||
|
} else {
|
||||||
|
this.$confirm(res.result.subOrderList[0].buyerName, '查询结果', {
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning',
|
||||||
|
center: true
|
||||||
|
}).then(() => {
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.isLoading = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</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>
|
||||||
@@ -3,12 +3,13 @@
|
|||||||
<ai-title
|
<ai-title
|
||||||
slot="title"
|
slot="title"
|
||||||
title="商品列表"
|
title="商品列表"
|
||||||
|
tips="每页为100条商品数据"
|
||||||
isShowBottomBorder>
|
isShowBottomBorder>
|
||||||
<template #rightBtn>
|
<template #rightBtn>
|
||||||
<div class="title-right">
|
<div class="title-right">
|
||||||
<div>
|
<div>
|
||||||
<label style="width:90px">店铺:</label>
|
<label style="width:90px">店铺:</label>
|
||||||
<el-select v-model="form.mallId" @change="beforeGetList" placeholder="请选择" size="small">
|
<el-select v-model="form.mallId" placeholder="请选择" size="small">
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in $store.state.mallList"
|
v-for="item in $store.state.mallList"
|
||||||
:key="item.mallId"
|
:key="item.mallId"
|
||||||
@@ -21,47 +22,108 @@
|
|||||||
</template>
|
</template>
|
||||||
</ai-title>
|
</ai-title>
|
||||||
<template slot="content">
|
<template slot="content">
|
||||||
<ai-card title="数据明细" style="padding-bottom: 40px;">
|
<div class="content">
|
||||||
<template #right>
|
<ai-search-bar>
|
||||||
<label style="width:140px">是否在售:</label>
|
<template #left>
|
||||||
<el-select clearable v-model="reqData.skcSiteStatus" placeholder="请选择">
|
<div class="search-item">
|
||||||
<el-option
|
<label>起始页:</label>
|
||||||
v-for="item in options"
|
<el-input size="small" placeholder="请输入起始页" type="number" v-model="startPage"></el-input>
|
||||||
:key="item.value"
|
</div>
|
||||||
:label="item.label"
|
<div class="search-item">
|
||||||
:value="item.value">
|
<label>结束页:</label>
|
||||||
</el-option>
|
<el-input size="small" placeholder="请输入起始页" type="number" v-model="endPage"></el-input>
|
||||||
</el-select>
|
</div>
|
||||||
<label style="width:140px">商品名称:</label>
|
<div class="search-item">
|
||||||
<el-input clearable size="small" style="display: inline" placeholder="请输入商品名称" v-model="reqData.productName"></el-input>
|
<label>是否在售:</label>
|
||||||
<el-button type="primary" @click="toLoad">加载</el-button>
|
<el-select clearable v-model="reqData.skcSiteStatus" placeholder="请选择">
|
||||||
<json-excel
|
<el-option
|
||||||
:data="tableData"
|
v-for="item in options"
|
||||||
:fields="jsonFields"
|
:key="item.value"
|
||||||
name="商品列表.xls"
|
:label="item.label"
|
||||||
worksheet="商品列表">
|
:value="item.value">
|
||||||
<el-button type="primary" :disabled="tableData.length == 0">下载数据</el-button>
|
</el-option>
|
||||||
</json-excel>
|
</el-select>
|
||||||
</template>
|
</div>
|
||||||
<ai-table
|
<div class="search-item">
|
||||||
:isShowPagination="false"
|
<label>站点:</label>
|
||||||
:tableData="tableData"
|
<el-select v-model="reqData.bindSiteId" placeholder="请选择" size="small">
|
||||||
:col-configs="colConfigs"
|
<el-option
|
||||||
:total="tableData.length"
|
v-for="item in siteList"
|
||||||
height="500"
|
:key="item.siteId"
|
||||||
style="margin-top: 8px;"
|
:label="item.siteName"
|
||||||
@getList="() => {}">
|
:value="item.siteId">
|
||||||
|
</el-option>
|
||||||
|
</el-select>
|
||||||
|
</div>
|
||||||
|
<div class="search-item">
|
||||||
|
<label>合规下架风险:</label>
|
||||||
|
<el-select v-model="reqData.certPunishTypes" multiple placeholder="请选择" size="small">
|
||||||
|
<el-option
|
||||||
|
v-for="item in certPunishTypes"
|
||||||
|
:key="item.id"
|
||||||
|
:label="item.name"
|
||||||
|
:value="item.id">
|
||||||
|
</el-option>
|
||||||
|
</el-select>
|
||||||
|
</div>
|
||||||
|
<div class="search-item">
|
||||||
|
<label>资质上传状态:</label>
|
||||||
|
<el-select v-model="reqData.productCertAuditStatuses" multiple placeholder="请选择" size="small">
|
||||||
|
<el-option
|
||||||
|
v-for="item in productCertAuditStatusList"
|
||||||
|
:key="item.id"
|
||||||
|
:label="item.name"
|
||||||
|
:value="item.id">
|
||||||
|
</el-option>
|
||||||
|
</el-select>
|
||||||
|
</div>
|
||||||
|
<div class="search-item">
|
||||||
|
<label>商品名称:</label>
|
||||||
|
<el-input clearable size="small" placeholder="请输入商品名称" v-model="reqData.productName"></el-input>
|
||||||
|
</div>
|
||||||
|
<div class="search-item">
|
||||||
|
<label>库存起始值:</label>
|
||||||
|
<el-input size="small" placeholder="请输入库存起始值" type="number" v-model="reqData.jitStockQuantitySection.leftValue"></el-input>
|
||||||
|
</div>
|
||||||
|
<div class="search-item">
|
||||||
|
<label>库存结束值:</label>
|
||||||
|
<el-input size="small" placeholder="请输入库存结束值" type="number" v-model="reqData.jitStockQuantitySection.rightValue"></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>
|
||||||
|
<json-excel
|
||||||
|
:data="tableData"
|
||||||
|
:fields="jsonFields"
|
||||||
|
name="商品列表.xls"
|
||||||
|
worksheet="商品列表">
|
||||||
|
<el-button type="primary" :disabled="tableData.length == 0">下载数据</el-button>
|
||||||
|
</json-excel>
|
||||||
|
</template>
|
||||||
|
<ai-table
|
||||||
|
:isShowPagination="false"
|
||||||
|
:tableData="tableData"
|
||||||
|
:col-configs="colConfigs"
|
||||||
|
:total="tableData.length"
|
||||||
|
height="500"
|
||||||
|
style="margin-top: 8px;"
|
||||||
|
@getList="() => {}">
|
||||||
|
|
||||||
<el-table-column slot="productName" width="200px" :show-overflow-tooltip='true' label="商品名称" fixed="left">
|
<el-table-column slot="productName" width="200px" :show-overflow-tooltip='true' label="商品名称" fixed="left">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<div>
|
<div>
|
||||||
<el-image :src="scope.row.mainImageUrl" style="width: 40px; height: 40px" class="image" :preview-src-list="[scope.row.mainImageUrl]" />
|
<el-image :src="scope.row.mainImageUrl" style="width: 40px; height: 40px" class="image" :preview-src-list="[scope.row.mainImageUrl]" />
|
||||||
{{ scope.row.productName }}
|
{{ scope.row.productName }}
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</ai-table>
|
</ai-table>
|
||||||
</ai-card>
|
</ai-card>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</ai-list>
|
</ai-list>
|
||||||
</template>
|
</template>
|
||||||
@@ -80,11 +142,20 @@ import JsonExcel from 'vue-json-excel'
|
|||||||
form: {
|
form: {
|
||||||
mallId: ''
|
mallId: ''
|
||||||
},
|
},
|
||||||
|
startPage: 1,
|
||||||
|
endPage: 10,
|
||||||
reqData: {
|
reqData: {
|
||||||
productName: '',
|
productName: '',
|
||||||
page: 1,
|
page: 1,
|
||||||
pageSize: 100,
|
pageSize: 100,
|
||||||
skcSiteStatus: ''
|
skcSiteStatus: '',
|
||||||
|
bindSiteId: '',
|
||||||
|
certPunishTypes: [],
|
||||||
|
productCertAuditStatuses: [],
|
||||||
|
jitStockQuantitySection: {
|
||||||
|
leftValue: '',
|
||||||
|
rightValue: ''
|
||||||
|
}
|
||||||
},
|
},
|
||||||
options: [
|
options: [
|
||||||
{label: '是', value: 1},
|
{label: '是', value: 1},
|
||||||
@@ -100,6 +171,9 @@ import JsonExcel from 'vue-json-excel'
|
|||||||
{ prop: 'extCode', label: 'SKC货号', width: '100px', align: 'left' },
|
{ prop: 'extCode', label: 'SKC货号', width: '100px', align: 'left' },
|
||||||
{ prop: 'skuExtCode', label: 'SKU货号', width: '160px', align: 'left' },
|
{ prop: 'skuExtCode', label: 'SKU货号', width: '160px', align: 'left' },
|
||||||
{ prop: 'specName', label: 'SKU属性', width: '100px', align: 'left' },
|
{ prop: 'specName', label: 'SKU属性', width: '100px', align: 'left' },
|
||||||
|
{ prop: 'skuStockQuantity', label: '库存', width: '100px', align: 'left' },
|
||||||
|
{ prop: 'productCertAuditStatus', label: '资质上传状态', width: '120px', align: 'left' },
|
||||||
|
{ prop: 'certPunishType', label: '合规下架风险', width: '120px', align: 'left' },
|
||||||
{ prop: 'supplierPrice', label: '申报价格(CNY)', width: '180px', align: 'left' },
|
{ prop: 'supplierPrice', label: '申报价格(CNY)', width: '180px', align: 'left' },
|
||||||
{ prop: 'todaySalesVolume', label: '今日销量', width: '100px', align: 'left' },
|
{ prop: 'todaySalesVolume', label: '今日销量', width: '100px', align: 'left' },
|
||||||
{ prop: 'createdAt', label: '上架时间', width: '160px', align: 'left' }
|
{ prop: 'createdAt', label: '上架时间', width: '160px', align: 'left' }
|
||||||
@@ -117,17 +191,47 @@ import JsonExcel from 'vue-json-excel'
|
|||||||
"SKC货号": "extCode",
|
"SKC货号": "extCode",
|
||||||
"SKU货号": "skuExtCode",
|
"SKU货号": "skuExtCode",
|
||||||
"SKU属性": "specName",
|
"SKU属性": "specName",
|
||||||
|
"库存": "skuStockQuantity",
|
||||||
|
"资质上传状态": "productCertAuditStatus",
|
||||||
|
"合规下架风险": "certPunishType",
|
||||||
"申报价格(CNY)": "supplierPrice",
|
"申报价格(CNY)": "supplierPrice",
|
||||||
"今日销量": "todaySalesVolume",
|
"今日销量": "todaySalesVolume",
|
||||||
"上架时间": "createdAt"
|
"上架时间": "createdAt"
|
||||||
},
|
},
|
||||||
currentIndex: 0
|
certPunishTypes: [
|
||||||
|
{id: 1, name: '已经处罚'},
|
||||||
|
{id: 2, name: '即将下架'},
|
||||||
|
{id: 3, name: '下架风险预警'},
|
||||||
|
],
|
||||||
|
productCertAuditStatusList: [
|
||||||
|
{id: 1, name: '待上传'},
|
||||||
|
{id: 2, name: '上传中'},
|
||||||
|
{id: 3, name: '上传失败'},
|
||||||
|
{id: 4, name: '上传成功'},
|
||||||
|
],
|
||||||
|
currentIndex: 0,
|
||||||
|
siteList: []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
JsonExcel
|
JsonExcel
|
||||||
},
|
},
|
||||||
|
created () {
|
||||||
|
this.getSiteList()
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
async getSiteList() {
|
||||||
|
let res = await sendChromeAPIMessage({
|
||||||
|
url: 'bg-visage-mms/config/common/site/query',
|
||||||
|
needMallId: true,
|
||||||
|
mallId: this.$store.state.mallList[0].mallId,
|
||||||
|
data: {}})
|
||||||
|
if (res.success && res.errorCode == 1000000) {
|
||||||
|
this.siteList = res.result.siteBaseList.filter(item => {
|
||||||
|
return item.matchSemiManaged
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
beforeGetList() {
|
beforeGetList() {
|
||||||
this.$userCheck(this.form.mallId).then(() => {
|
this.$userCheck(this.form.mallId).then(() => {
|
||||||
this.toLoad()
|
this.toLoad()
|
||||||
@@ -140,7 +244,19 @@ import JsonExcel from 'vue-json-excel'
|
|||||||
Message.error("请选择店铺")
|
Message.error("请选择店铺")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.reqData.page = 1
|
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.reqData.page = this.startPage
|
||||||
this.tableData = []
|
this.tableData = []
|
||||||
this.currentIndex = 0
|
this.currentIndex = 0
|
||||||
this.isLoading = true
|
this.isLoading = true
|
||||||
@@ -164,6 +280,24 @@ import JsonExcel from 'vue-json-excel'
|
|||||||
data.skcSiteStatus = item.skcSiteStatus == '1'? '在售': ''
|
data.skcSiteStatus = item.skcSiteStatus == '1'? '在售': ''
|
||||||
data.createdAt = timestampToTime(item.createdAt)
|
data.createdAt = timestampToTime(item.createdAt)
|
||||||
data.extCode = item.extCode
|
data.extCode = item.extCode
|
||||||
|
data.productCertAuditStatus = '-'
|
||||||
|
if (item.productCertAuditStatus == 1) {
|
||||||
|
data.productCertAuditStatus = '待上传'
|
||||||
|
} else if (item.productCertAuditStatus == 2) {
|
||||||
|
data.productCertAuditStatus = '上传中'
|
||||||
|
} else if (item.productCertAuditStatus == 3) {
|
||||||
|
data.productCertAuditStatus = '上传失败'
|
||||||
|
} else if (item.productCertAuditStatus == 4) {
|
||||||
|
data.productCertAuditStatus = '上传成功'
|
||||||
|
}
|
||||||
|
data.certPunishType = '-'
|
||||||
|
if (item.productCertPunish?.certPunishType == 1) {
|
||||||
|
data.certPunishType = '已经处罚'
|
||||||
|
} else if (item.productCertPunish?.certPunishType == 2) {
|
||||||
|
data.certPunishType = '即将下架'
|
||||||
|
} else if (item.productCertPunish?.certPunishType == 3) {
|
||||||
|
data.certPunishType = '下架风险预警'
|
||||||
|
}
|
||||||
|
|
||||||
data.category = ''
|
data.category = ''
|
||||||
for (let i = 1; i < 11; i++) {
|
for (let i = 1; i < 11; i++) {
|
||||||
@@ -179,21 +313,23 @@ import JsonExcel from 'vue-json-excel'
|
|||||||
let temp = item.productSkuSummaries[k].productSkuSpecList.map(item2 => {
|
let temp = item.productSkuSummaries[k].productSkuSpecList.map(item2 => {
|
||||||
return item2.parentSpecName + ":" + item2.specName
|
return item2.parentSpecName + ":" + item2.specName
|
||||||
})
|
})
|
||||||
|
let skuStockQuantity = '-'
|
||||||
|
if (item.productSkuSummaries[k].productSkuSemiManagedStock) {
|
||||||
|
skuStockQuantity = item.productSkuSummaries[k].productSkuSemiManagedStock.skuStockQuantity
|
||||||
|
}
|
||||||
data = {...data,
|
data = {...data,
|
||||||
productSkuId: item.productSkuSummaries[k].productSkuId,
|
productSkuId: item.productSkuSummaries[k].productSkuId,
|
||||||
skuExtCode: item.productSkuSummaries[k].extCode,
|
skuExtCode: item.productSkuSummaries[k].extCode,
|
||||||
supplierPrice: item.productSkuSummaries[k].supplierPrice / 100,
|
supplierPrice: item.productSkuSummaries[k].supplierPrice / 100,
|
||||||
specName: temp.join(","),
|
specName: temp.join(","),
|
||||||
|
skuStockQuantity,
|
||||||
todaySalesVolume: item.productSkuSummaries[k].todaySalesVolume}
|
todaySalesVolume: item.productSkuSummaries[k].todaySalesVolume}
|
||||||
|
|
||||||
this.tableData.push(data)
|
this.tableData.push(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
if (this.reqData.page == 1 && res.result.pageItems.length == 0) {
|
if (res.result.pageItems.length == this.reqData.pageSize && this.reqData.page < this.endPage) {
|
||||||
this.isLoading = false
|
|
||||||
}
|
|
||||||
else if (res.result.pageItems.length == 100) {
|
|
||||||
this.reqData.page ++
|
this.reqData.page ++
|
||||||
this.load()
|
this.load()
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
272
src/view/product/SellerSelect.vue
Normal file
272
src/view/product/SellerSelect.vue
Normal file
@@ -0,0 +1,272 @@
|
|||||||
|
<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>
|
||||||
|
<div class="search-item">
|
||||||
|
<label>状态:</label>
|
||||||
|
<el-select v-model="status" placeholder="请选择" size="small">
|
||||||
|
<el-option
|
||||||
|
v-for="item in statusList"
|
||||||
|
:key="item.id"
|
||||||
|
:label="item.name"
|
||||||
|
:value="item.id">
|
||||||
|
</el-option>
|
||||||
|
</el-select>
|
||||||
|
</div>
|
||||||
|
<div class="search-item">
|
||||||
|
<label>是否合规待办:</label>
|
||||||
|
<el-select v-model="isViolationInfo" placeholder="请选择" size="small">
|
||||||
|
<el-option
|
||||||
|
v-for="item in options"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value">
|
||||||
|
</el-option>
|
||||||
|
</el-select>
|
||||||
|
</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>
|
||||||
|
<json-excel
|
||||||
|
:data="tableData"
|
||||||
|
:fields="jsonFields"
|
||||||
|
name="商品列表.xls"
|
||||||
|
worksheet="商品列表">
|
||||||
|
<el-button type="primary" :disabled="tableData.length == 0">下载数据</el-button>
|
||||||
|
</json-excel>
|
||||||
|
</template>
|
||||||
|
<ai-table
|
||||||
|
:isShowPagination="false"
|
||||||
|
:tableData="tableData"
|
||||||
|
:col-configs="colConfigs"
|
||||||
|
:total="tableData.length"
|
||||||
|
height="800"
|
||||||
|
style="margin-top: 8px;"
|
||||||
|
@getList="() => {}">
|
||||||
|
|
||||||
|
<el-table-column slot="productName" width="200px" :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 JsonExcel from 'vue-json-excel'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'SellerSelect',
|
||||||
|
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
form: {
|
||||||
|
mallId: ''
|
||||||
|
},
|
||||||
|
startPage: 1,
|
||||||
|
endPage: 10,
|
||||||
|
reqData: {
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 100,
|
||||||
|
secondarySelectStatusList: []
|
||||||
|
},
|
||||||
|
colConfigs: [
|
||||||
|
{ slot: 'productName', label: '商品名称', width: '180px', align: 'left', fixed: 'left' },
|
||||||
|
{ prop: 'category', label: '分类', width: '220px', align: 'left', fixed: 'left' },
|
||||||
|
{ prop: 'siteName', label: '站点', width: '140px', align: 'left', fixed: 'left' },
|
||||||
|
{ prop: 'productId', label: 'SPU ID', width: '120px', align: 'left' },
|
||||||
|
{ prop: 'productSkcId', label: 'SKC ID', width: '120px', align: 'left' },
|
||||||
|
{ prop: 'extCode', label: 'SKC货号', width: '120px', align: 'left' },
|
||||||
|
{ prop: 'punishInfo', label: '违规信息', width: '120px', align: 'left' },
|
||||||
|
{ prop: 'violationInfo', label: '合规待办项', width: '200px', align: 'left' },
|
||||||
|
{ prop: 'supplierPrice', label: '申报价格(CNY)', width: '180px', align: 'left' },
|
||||||
|
{ prop: 'createdAt', label: '创建时间', width: '160px', align: 'left' }
|
||||||
|
],
|
||||||
|
isLoading: false,
|
||||||
|
tableData: [],
|
||||||
|
jsonFields: {
|
||||||
|
"商品名称": "productName",
|
||||||
|
"图片": "mainImageUrl",
|
||||||
|
"分类": "category",
|
||||||
|
"站点": "siteName",
|
||||||
|
"SPU ID": "productId",
|
||||||
|
"SKC ID": "productSkcId",
|
||||||
|
"SKC货号": "extCode",
|
||||||
|
"违规信息": "punishInfo",
|
||||||
|
"合规待办项": "violationInfo",
|
||||||
|
"申报价格(CNY)": "supplierPrice",
|
||||||
|
"创建时间": "createdAt"
|
||||||
|
},
|
||||||
|
statusList: [
|
||||||
|
{id: 1, name: '未发布到站点'},
|
||||||
|
{id: 2, name: '已下架/终止'}
|
||||||
|
],
|
||||||
|
options: [
|
||||||
|
{label: '是', value: 1},
|
||||||
|
{label: '否', value: 0}
|
||||||
|
],
|
||||||
|
status: 1,
|
||||||
|
isViolationInfo: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
JsonExcel
|
||||||
|
},
|
||||||
|
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
|
||||||
|
}
|
||||||
|
if (this.status == 1) {
|
||||||
|
this.reqData.secondarySelectStatusList = [10, 11]
|
||||||
|
} else if (this.status == 2) {
|
||||||
|
this.reqData.secondarySelectStatusList = [13]
|
||||||
|
}
|
||||||
|
if (this.isViolationInfo == 0) {
|
||||||
|
this.reqData.supplierTodoTypeList = []
|
||||||
|
} else if (this.isViolationInfo == 1) {
|
||||||
|
this.reqData.supplierTodoTypeList = [7]
|
||||||
|
}
|
||||||
|
this.reqData.pageNum = this.startPage
|
||||||
|
this.tableData = []
|
||||||
|
this.isLoading = true
|
||||||
|
this.load()
|
||||||
|
},
|
||||||
|
load() {
|
||||||
|
sendChromeAPIMessage({
|
||||||
|
url: 'marvel-supplier/api/xmen/select/search',
|
||||||
|
needMallId: true,
|
||||||
|
mallId: this.form.mallId,
|
||||||
|
anti: true,
|
||||||
|
data: this.reqData}).then((res) => {
|
||||||
|
if (res.errorCode == 1000000) {
|
||||||
|
for(let i = 0;i < res.result.dataList.length; i++) {
|
||||||
|
let item = res.result.dataList[i];
|
||||||
|
let data = {};
|
||||||
|
data.productName = item.productName
|
||||||
|
data.mainImageUrl = item.carouselImageUrlList[0]
|
||||||
|
data.productId = item.productId
|
||||||
|
data.productSkcId = item.productSkcId
|
||||||
|
data.siteName = item.siteName
|
||||||
|
data.createdAt = timestampToTime(item.productCreatedAt)
|
||||||
|
|
||||||
|
data.category = item.fullCategoryName.join('->')
|
||||||
|
|
||||||
|
for (let k = 0; k < item.skcList.length; k++) {
|
||||||
|
data = {...data, productSkcId: item.skcList[k].skcId, punishInfo: item.skcList[k].punishInfo, extCode: item.skcList[k].extCode, supplierPrice: item.skcList[k].supplierPrice}
|
||||||
|
|
||||||
|
if (item.skcList[k].addSiteViolationInfoVO && item.skcList[k].addSiteViolationInfoVO.violationCodeList?.length > 0) {
|
||||||
|
let temp = ''
|
||||||
|
for (let j = 0; j < item.skcList[k].addSiteViolationInfoVO.violationCodeList.length; j++) {
|
||||||
|
if (item.skcList[k].addSiteViolationInfoVO.violationCodeList[j] == 1) {
|
||||||
|
temp += ',商品资质'
|
||||||
|
}
|
||||||
|
if (item.skcList[k].addSiteViolationInfoVO.violationCodeList[j] == 2) {
|
||||||
|
temp += ',商品标签实拍图'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
temp = temp.substring(1)
|
||||||
|
data.violationInfo = temp
|
||||||
|
}
|
||||||
|
|
||||||
|
this.tableData.push(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if (res.result.dataList.length == this.reqData.pageSize && this.reqData.pageNum < this.endPage) {
|
||||||
|
this.reqData.pageNum ++
|
||||||
|
this.load()
|
||||||
|
} else {
|
||||||
|
this.isLoading = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</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>
|
||||||
270
src/view/sale/AfterSaleDeductStat.vue
Normal file
270
src/view/sale/AfterSaleDeductStat.vue
Normal file
@@ -0,0 +1,270 @@
|
|||||||
|
<template>
|
||||||
|
<ai-list class="list" v-loading="isLoading" element-loading-text="拼命加载中" element-loading-spinner="el-icon-loading">
|
||||||
|
<ai-title
|
||||||
|
slot="title"
|
||||||
|
title="售后赔付统计"
|
||||||
|
isShowBottomBorder>
|
||||||
|
<template #rightBtn>
|
||||||
|
<div class="title-right">
|
||||||
|
<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>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</ai-title>
|
||||||
|
<template slot="content">
|
||||||
|
<div class="content">
|
||||||
|
<ai-search-bar>
|
||||||
|
<template #left>
|
||||||
|
<div class="search-item">
|
||||||
|
<label>账务时间:</label>
|
||||||
|
<el-date-picker
|
||||||
|
v-model="searchDate"
|
||||||
|
type="daterange"
|
||||||
|
range-separator="至"
|
||||||
|
start-placeholder="开始日期"
|
||||||
|
end-placeholder="结束日期">
|
||||||
|
</el-date-picker>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template #right>
|
||||||
|
<el-button type="primary" @click="beforeGetList">加载</el-button>
|
||||||
|
</template>
|
||||||
|
</ai-search-bar>
|
||||||
|
<ai-card title="数据明细" style="padding-bottom: 40px;">
|
||||||
|
<template #right>
|
||||||
|
<json-excel
|
||||||
|
:data="tableData"
|
||||||
|
:fields="jsonFields"
|
||||||
|
name="售后赔付统计列表.xls"
|
||||||
|
worksheet="售后赔付统计列表">
|
||||||
|
<el-button type="primary" :disabled="tableData.length == 0">下载数据</el-button>
|
||||||
|
</json-excel>
|
||||||
|
</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="400px" :show-overflow-tooltip='true' label="商品名称" fixed="left">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<div>
|
||||||
|
<el-image :src="scope.row.productUrl" style="width: 40px; height: 40px" class="image" :preview-src-list="[scope.row.productUrl]" />
|
||||||
|
{{ 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 JsonExcel from 'vue-json-excel'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'AfterSaleStat',
|
||||||
|
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
mallId: '',
|
||||||
|
searchDate: [],
|
||||||
|
reqData: {
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 100
|
||||||
|
},
|
||||||
|
colConfigs: [
|
||||||
|
{ prop: 'productName', label: '商品名称', width: '400px', align: 'left', fixed: 'left' },
|
||||||
|
{ prop: 'productSkuId', label: 'SKU ID', align: 'left' },
|
||||||
|
{ prop: 'skuCode', label: 'SKU货号', align: 'left' },
|
||||||
|
{ prop: 'deductionAmount', label: '扣款总金额', align: 'left', sortable: true, 'sort-method': (a, b) => a.deductionAmount - b.deductionAmount },
|
||||||
|
{ prop: 'times', label: '扣款次数', align: 'left', sortable: true, 'sort-method': (a, b) => a.times - b.times },
|
||||||
|
/*{ prop: 'supplierPrice', label: '供货价', align: 'left', sortable: true, 'sort-method': (a, b) => a.supplierPrice - b.supplierPrice },
|
||||||
|
{ prop: 'cost', label: '成本', align: 'left', sortable: true, 'sort-method': (a, b) => a.cost - b.cost },
|
||||||
|
{ prop: 'profitTimes', label: '相当于X件白卖', align: 'left', sortable: true, 'sort-method': (a, b) => a.profitTimes - b.profitTimes }*/
|
||||||
|
],
|
||||||
|
isLoading: false,
|
||||||
|
tableData: [],
|
||||||
|
jsonFields: {
|
||||||
|
"商品名称": "productName",
|
||||||
|
"SKU ID": "productSkuId",
|
||||||
|
"SKU货号": "skuCode",
|
||||||
|
"扣款总金额": "deductionAmount",
|
||||||
|
"扣款次数": "times"
|
||||||
|
},
|
||||||
|
costList: []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
JsonExcel
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
beforeGetList() {
|
||||||
|
this.$userCheck(this.mallId).then(() => {
|
||||||
|
this.toLoad()
|
||||||
|
}).catch((err) => {
|
||||||
|
this.mallId = ''
|
||||||
|
})
|
||||||
|
},
|
||||||
|
async toLoad() {
|
||||||
|
if (!this.mallId) {
|
||||||
|
Message.error("请选择店铺")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!this.searchDate) {
|
||||||
|
Message.error("请选择时间范围")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.reqData.pageNum = 1
|
||||||
|
this.tableData = []
|
||||||
|
this.isLoading = true
|
||||||
|
|
||||||
|
let startTime = this.searchDate[0].getTime()
|
||||||
|
let endTime = this.searchDate[1].getTime()
|
||||||
|
while(true) {
|
||||||
|
if ((endTime - startTime) > 2592000000) {
|
||||||
|
this.reqData.pageNum = 1
|
||||||
|
await this.getAfterSaleDeductList(startTime, startTime + 2592000000)
|
||||||
|
startTime = startTime + 2592000000
|
||||||
|
} else {
|
||||||
|
this.reqData.pageNum = 1
|
||||||
|
await this.getAfterSaleDeductList(startTime, endTime)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.isLoading = false
|
||||||
|
|
||||||
|
},
|
||||||
|
async getAfterSaleDeductList(startTime, endTime) {
|
||||||
|
let res = await sendChromeAPIMessage({
|
||||||
|
url: `api/merchant/fund/deduction/after-sales-compensation/query`,
|
||||||
|
needMallId: true,
|
||||||
|
mallId: this.mallId,
|
||||||
|
data: {
|
||||||
|
...this.reqData,
|
||||||
|
beginFundTime: startTime,
|
||||||
|
endFundTime: endTime
|
||||||
|
}})
|
||||||
|
if (res.errorCode == 1000000) {
|
||||||
|
for (let i = 0; i < res.result.resultList.length; i++) {
|
||||||
|
let item = res.result.resultList[i]
|
||||||
|
let flag = false
|
||||||
|
for (let j = 0; j < item.productSkuIdList.length; j++) {
|
||||||
|
for ( let k = 0; k < this.tableData.length; k++) {
|
||||||
|
if (item.productSkuIdList[j] == this.tableData[k].productSkuId) {
|
||||||
|
flag = true
|
||||||
|
this.tableData[k].times++
|
||||||
|
this.tableData[k].deductionAmount = Math.round((this.tableData[k].deductionAmount + new Number(item.deductionAmount.digitalText))*100)/100
|
||||||
|
if (!this.tableData[k].skuCode) {
|
||||||
|
this.tableData[k].skuCode = item.skuExtCodeList[j]
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!flag) {
|
||||||
|
this.tableData.push({
|
||||||
|
productName: item.goodsNameList[j],
|
||||||
|
productSkuId: item.productSkuIdList[j],
|
||||||
|
deductionAmount: new Number(item.deductionAmount.digitalText),
|
||||||
|
skuCode: item.skuExtCodeList[j],
|
||||||
|
times: 1,
|
||||||
|
supplierPrice: ''
|
||||||
|
})
|
||||||
|
flag = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((this.reqData.pageSize * this.reqData.pageNum) < res.result.total) {
|
||||||
|
this.reqData.pageNum ++
|
||||||
|
await this.getAfterSaleDeductList(startTime, endTime)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async getProductList(params) {
|
||||||
|
let res = await sendChromeAPIMessage({
|
||||||
|
url: 'bg-visage-mms/product/skc/pageQuery',
|
||||||
|
needMallId: true,
|
||||||
|
mallId: this.mallId,
|
||||||
|
data: {
|
||||||
|
...params
|
||||||
|
}})
|
||||||
|
if (res.errorCode == 1000000) {
|
||||||
|
res.result.pageItems.map((item) => {
|
||||||
|
item.productSkuSummaries.map(item1 => {
|
||||||
|
for (let i = 0; i < this.tableData.length; i++) {
|
||||||
|
if (this.tableData[i].productSkuId == item1.productSkuId) {
|
||||||
|
this.tableData[i].supplierPrice = item1.supplierPrice / 100
|
||||||
|
this.tableData[i].productUrl = item1.thumbUrl
|
||||||
|
this.tableData[i].skcCode = item.extCode
|
||||||
|
this.tableData[i].skuCode = item1.extCode
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
if ((params.page * params.pageSize) < res.result.total) {
|
||||||
|
params.page ++
|
||||||
|
await this.getProductList(params)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
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>
|
||||||
|
|
||||||
|
<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>
|
||||||
301
src/view/sale/AfterSaleStat.vue
Normal file
301
src/view/sale/AfterSaleStat.vue
Normal file
@@ -0,0 +1,301 @@
|
|||||||
|
<template>
|
||||||
|
<ai-list class="list" v-loading="isLoading" element-loading-text="拼命加载中" element-loading-spinner="el-icon-loading">
|
||||||
|
<ai-title
|
||||||
|
slot="title"
|
||||||
|
title="售后统计"
|
||||||
|
isShowBottomBorder>
|
||||||
|
<template #rightBtn>
|
||||||
|
<div class="title-right">
|
||||||
|
<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>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</ai-title>
|
||||||
|
<template slot="content">
|
||||||
|
<div class="content">
|
||||||
|
<ai-search-bar>
|
||||||
|
<template #left>
|
||||||
|
<div class="search-item">
|
||||||
|
<label>售后申请年份:</label>
|
||||||
|
<el-date-picker
|
||||||
|
v-model="reqData.afsApplyYear"
|
||||||
|
type="year"
|
||||||
|
value-format='yyyy'
|
||||||
|
placeholder="选择年">
|
||||||
|
</el-date-picker>
|
||||||
|
</div>
|
||||||
|
<div class="search-item">
|
||||||
|
<label>扣罚倍数:</label>
|
||||||
|
<el-select v-model="reqData.punishRatioList" multiple placeholder="请选择" size="small">
|
||||||
|
<el-option
|
||||||
|
v-for="item in punishRatioOptions"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value">
|
||||||
|
</el-option>
|
||||||
|
</el-select>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template #right>
|
||||||
|
<el-button type="primary" @click="beforeGetList">加载</el-button>
|
||||||
|
</template>
|
||||||
|
</ai-search-bar>
|
||||||
|
<ai-card title="数据明细" style="padding-bottom: 40px;">
|
||||||
|
<template #right>
|
||||||
|
<json-excel
|
||||||
|
:data="tableData"
|
||||||
|
:fields="jsonFields"
|
||||||
|
name="售后统计列表.xls"
|
||||||
|
worksheet="售后统计列表">
|
||||||
|
<el-button type="primary" :disabled="tableData.length == 0">下载数据</el-button>
|
||||||
|
</json-excel>
|
||||||
|
</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="400px" :show-overflow-tooltip='true' label="商品名称" fixed="left">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<div>
|
||||||
|
<el-image :src="scope.row.productUrl" style="width: 40px; height: 40px" class="image" :preview-src-list="[scope.row.productUrl]" />
|
||||||
|
{{ 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, sendTemuSellerAgentMessage } from '@/api/chromeApi'
|
||||||
|
import {timestampToTime} from '@/utils/date'
|
||||||
|
import JsonExcel from 'vue-json-excel'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'AfterSaleStat',
|
||||||
|
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
mallId: '',
|
||||||
|
reqData: {
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: 100,
|
||||||
|
afsApplyYear: '2024',
|
||||||
|
punishRatioList: []
|
||||||
|
},
|
||||||
|
punishRatioOptions: [
|
||||||
|
{label: '0', value: '0'},
|
||||||
|
{label: '1', value: '1'},
|
||||||
|
{label: '1.5', value: '1.5'},
|
||||||
|
{label: '2.5', value: '2.5'},
|
||||||
|
{label: '5', value: '5'},
|
||||||
|
],
|
||||||
|
colConfigs: [
|
||||||
|
{ slot: 'productName', label: '商品名称', width: '400px', align: 'left', fixed: 'left' },
|
||||||
|
{ prop: 'skcCode', label: 'SKC货号', align: 'left', height: '40px', fixed: 'left' },
|
||||||
|
{ prop: 'productSkuId', label: 'SKU ID', align: 'left' },
|
||||||
|
{ prop: 'skuCode', label: 'SKU货号', align: 'left' },
|
||||||
|
{ prop: 'rawQualityScore', label: '品质分', align: 'left', sortable: true, 'sort-method': (a, b) => a.rawQualityScore - b.rawQualityScore },
|
||||||
|
{ prop: 'punishRatio', label: '扣罚总倍数', align: 'left', sortable: true, 'sort-method': (a, b) => a.punishRatio - b.punishRatio },
|
||||||
|
{ prop: 'times', label: '扣罚次数', align: 'left', sortable: true, 'sort-method': (a, b) => a.times - b.times },
|
||||||
|
{ prop: 'supplierPrice', label: '供货价', align: 'left', sortable: true, 'sort-method': (a, b) => a.supplierPrice - b.supplierPrice },
|
||||||
|
{ prop: 'deductionAmount', label: '预计扣款', align: 'left', sortable: true, 'sort-method': (a, b) => a.deductionAmount - b.deductionAmount },
|
||||||
|
{ prop: 'cost', label: '成本', align: 'left', sortable: true, 'sort-method': (a, b) => a.cost - b.cost },
|
||||||
|
{ prop: 'profitTimes', label: '相当于X件白卖', align: 'left', sortable: true, 'sort-method': (a, b) => a.profitTimes - b.profitTimes }
|
||||||
|
],
|
||||||
|
isLoading: false,
|
||||||
|
tableData: [],
|
||||||
|
jsonFields: {
|
||||||
|
"商品名称": "productName",
|
||||||
|
"图片URL": "productUrl",
|
||||||
|
"SKC货号": "skcCode",
|
||||||
|
"SKU ID": "productSkuId",
|
||||||
|
"SKU货号": "skuCode",
|
||||||
|
"品质分": "rawQualityScore",
|
||||||
|
"扣罚总倍数": "punishRatio",
|
||||||
|
"扣罚次数": "times",
|
||||||
|
"供货价": "supplierPrice",
|
||||||
|
"预计扣款": "deductionAmount",
|
||||||
|
"成本": "cost",
|
||||||
|
"相当于X件白卖": "profitTimes"
|
||||||
|
},
|
||||||
|
costList: []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
JsonExcel
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
beforeGetList() {
|
||||||
|
this.$userCheck(this.mallId).then(() => {
|
||||||
|
this.toLoad()
|
||||||
|
}).catch((err) => {
|
||||||
|
this.mallId = ''
|
||||||
|
})
|
||||||
|
},
|
||||||
|
async toLoad() {
|
||||||
|
if (!this.mallId) {
|
||||||
|
Message.error("请选择店铺")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.reqData.pageNo = 1
|
||||||
|
this.tableData = []
|
||||||
|
this.currentIndex = 0
|
||||||
|
this.isLoading = true
|
||||||
|
await this.getAfterSalesList('101')
|
||||||
|
this.reqData.pageNo = 1
|
||||||
|
await this.getAfterSalesList('202')
|
||||||
|
this.reqData.pageNo = 1
|
||||||
|
await this.getAfterSalesList('102')
|
||||||
|
|
||||||
|
let skuIds = []
|
||||||
|
this.tableData.map(item => {
|
||||||
|
skuIds.push(item.productSkuId)
|
||||||
|
})
|
||||||
|
this.reqData.pageNo = 1
|
||||||
|
|
||||||
|
await this.getProductList({page: this.reqData.pageNo,
|
||||||
|
pageSize: this.reqData.pageSize,
|
||||||
|
productSkuIds: skuIds})
|
||||||
|
|
||||||
|
this.costList = []
|
||||||
|
await this.getSkuCostList()
|
||||||
|
this.isLoading = false
|
||||||
|
},
|
||||||
|
async getAfterSalesList(zone) {
|
||||||
|
this.reqData.bizDrType = zone
|
||||||
|
let res = await sendTemuSellerAgentMessage({
|
||||||
|
url: `mms/api/appalachian/afs/queryPageV2`,
|
||||||
|
needMallId: true,
|
||||||
|
mallId: this.mallId,
|
||||||
|
data: this.reqData})
|
||||||
|
if (res.errorCode == 1000000) {
|
||||||
|
for (let i = 0; i < res.result.list.length; i++) {
|
||||||
|
let item = res.result.list[i]
|
||||||
|
let flag = false
|
||||||
|
for (let j = 0; j < item.productSkuId.length; j++) {
|
||||||
|
for ( let k = 0; k < this.tableData.length; k++) {
|
||||||
|
if (item.productSkuId[j] == this.tableData[k].productSkuId) {
|
||||||
|
flag = true
|
||||||
|
this.tableData[k].times++
|
||||||
|
this.tableData[k].punishRatio = this.tableData[k].punishRatio + new Number(item.punishRatio)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!flag) {
|
||||||
|
this.tableData.push({
|
||||||
|
productName: item.goodsName,
|
||||||
|
productUrl: '',
|
||||||
|
skcCode: '',
|
||||||
|
productSkuId: item.productSkuId[j],
|
||||||
|
punishRatio: new Number(item.punishRatio),
|
||||||
|
rawQualityScore: item.rawQualityScore,
|
||||||
|
skuCode: '',
|
||||||
|
times: 1,
|
||||||
|
cost: '',
|
||||||
|
supplierPrice: '',
|
||||||
|
deductionAmount: null,
|
||||||
|
profitTimes: ''
|
||||||
|
})
|
||||||
|
flag = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((this.reqData.pageSize * this.reqData.pageNo) < res.result.total) {
|
||||||
|
this.reqData.pageNo ++
|
||||||
|
await this.getAfterSalesList(zone)
|
||||||
|
}
|
||||||
|
} else if (res.error_code == 40001) {
|
||||||
|
this.isLoading = false
|
||||||
|
this.$store.commit("setTemuAlertShow", true)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async getProductList(params) {
|
||||||
|
let res = await sendChromeAPIMessage({
|
||||||
|
url: 'bg-visage-mms/product/skc/pageQuery',
|
||||||
|
needMallId: true,
|
||||||
|
mallId: this.mallId,
|
||||||
|
data: {
|
||||||
|
...params
|
||||||
|
}})
|
||||||
|
if (res.errorCode == 1000000) {
|
||||||
|
res.result.pageItems.map((item) => {
|
||||||
|
item.productSkuSummaries.map(item1 => {
|
||||||
|
for (let i = 0; i < this.tableData.length; i++) {
|
||||||
|
if (this.tableData[i].productSkuId == item1.productSkuId) {
|
||||||
|
this.tableData[i].supplierPrice = item1.supplierPrice / 100
|
||||||
|
this.tableData[i].deductionAmount = Math.round((item1.supplierPrice / 100 * this.tableData[i].punishRatio) * 100)/ 100
|
||||||
|
this.tableData[i].productUrl = item1.thumbUrl
|
||||||
|
this.tableData[i].skcCode = item.extCode
|
||||||
|
this.tableData[i].skuCode = item1.extCode
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
if ((params.page * params.pageSize) < res.result.total) {
|
||||||
|
params.page ++
|
||||||
|
await this.getProductList(params)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
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>
|
||||||
|
|
||||||
|
<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>
|
||||||
361
src/view/sale/CostManageTemu.vue
Normal file
361
src/view/sale/CostManageTemu.vue
Normal file
@@ -0,0 +1,361 @@
|
|||||||
|
<template>
|
||||||
|
<ai-list class="list" v-loading="isLoading" element-loading-text="拼命加载中" element-loading-spinner="el-icon-loading">
|
||||||
|
<ai-title
|
||||||
|
slot="title"
|
||||||
|
title="成本管理"
|
||||||
|
isShowBottomBorder>
|
||||||
|
<template #rightBtn>
|
||||||
|
<div class="title-right">
|
||||||
|
<div>
|
||||||
|
<label style="width:90px">店铺:</label>
|
||||||
|
<el-select v-model="mallId" @change="beforeGetList" 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 style="margin-bottom: 5px">
|
||||||
|
<el-alert
|
||||||
|
title="郑重承诺:由于业务逻辑需要,TEMU助手将会以最小范围内存储SKU成本信息,平台将会做好保密,不泄露、不出售任何数据。使用与成本管理以及利润计算等相关功能,将视为授权TEMU助手存储相关信息。"
|
||||||
|
type="error"
|
||||||
|
:closable="false">
|
||||||
|
</el-alert>
|
||||||
|
</div>
|
||||||
|
<ai-search-bar>
|
||||||
|
<template #left>
|
||||||
|
<div class="search-item">
|
||||||
|
<el-checkbox v-model="search.unSet">只显示未填写</el-checkbox>
|
||||||
|
</div>
|
||||||
|
<div class="search-item">
|
||||||
|
<label>SKC ID:</label>
|
||||||
|
<el-input size="small" clearable placeholder="请输入SKC ID" v-model="search.skc"></el-input>
|
||||||
|
</div>
|
||||||
|
<div class="search-item">
|
||||||
|
<label>SKU ID:</label>
|
||||||
|
<el-input size="small" clearable placeholder="请输入SKU ID" v-model="search.sku"></el-input>
|
||||||
|
</div>
|
||||||
|
<div class="search-item">
|
||||||
|
<label>SKC货号:</label>
|
||||||
|
<el-input size="small" clearable placeholder="请输入SKC货号" v-model="search.skcCode"></el-input>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template #right>
|
||||||
|
<!--<el-button type="primary" @click="toLoad">加载</el-button>-->
|
||||||
|
</template>
|
||||||
|
</ai-search-bar>
|
||||||
|
<ai-card title="SKU明细" style="padding-bottom: 40px;">
|
||||||
|
<template #right>
|
||||||
|
<el-button type="primary" @click="exportToExcel">导出</el-button>
|
||||||
|
<el-button type="primary" @click="toUpload">导入</el-button>
|
||||||
|
</template>
|
||||||
|
<ai-table
|
||||||
|
:isShowPagination="false"
|
||||||
|
:tableData="filteredData"
|
||||||
|
:col-configs="colConfigs"
|
||||||
|
height="600"
|
||||||
|
style="margin-top: 8px;"
|
||||||
|
@getList="() => {}">
|
||||||
|
<el-table-column slot="costPrice" label="成本价格" :sortable="true" :sort-method="(a, b) => a.costPrice - b.costPrice">
|
||||||
|
<template slot-scope="{ row }">
|
||||||
|
<el-input
|
||||||
|
v-if="row.edit"
|
||||||
|
v-model="row.editValue"
|
||||||
|
type="number"
|
||||||
|
size="small"
|
||||||
|
></el-input>
|
||||||
|
<span v-else>{{ row.costPrice }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column slot="options" label="操作" width="80px" show-overflow-tooltip align="center" fixed="right">
|
||||||
|
<template slot-scope="{ row }">
|
||||||
|
<el-button
|
||||||
|
v-if="!row.edit"
|
||||||
|
size="small"
|
||||||
|
icon="el-icon-edit"
|
||||||
|
@click="row.edit = true"
|
||||||
|
></el-button>
|
||||||
|
<el-button
|
||||||
|
v-if="row.edit"
|
||||||
|
size="small"
|
||||||
|
type="success"
|
||||||
|
icon="el-icon-circle-check"
|
||||||
|
@click="handleSave(row)"
|
||||||
|
></el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</ai-table>
|
||||||
|
</ai-card>
|
||||||
|
|
||||||
|
<AiDialog
|
||||||
|
title="成本导入"
|
||||||
|
:visible.sync="costDlgShow"
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
customFooter
|
||||||
|
width="1290px">
|
||||||
|
<el-form :model="costForm" ref="costForm" label-width="180px" class="form">
|
||||||
|
<el-form-item label="上传excel" prop="file" :rules="[{ required: true, message: '请上传文件', trigger: 'blur' }]" style="width: 100%;">
|
||||||
|
<ai-uploader isImport v-model="costForm.file" fileType="file" :limit="1"
|
||||||
|
acceptType=".xlsx," :clearable="false">
|
||||||
|
<template #trigger>
|
||||||
|
<el-button icon="iconfont iconfangda">选择文件</el-button>
|
||||||
|
</template>
|
||||||
|
<template #tips>最多上传1个文件,单个文件最大10MB,仅支持Excel格式</template>
|
||||||
|
</ai-uploader>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<span slot="footer" class="dialog-footer">
|
||||||
|
<el-button @click="costDlgShow = false">关 闭</el-button>
|
||||||
|
<el-button type="primary" @click="importConfirm">确 定</el-button>
|
||||||
|
</span>
|
||||||
|
</AiDialog>
|
||||||
|
</template>
|
||||||
|
</ai-list>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import {sendChromeAPIMessage} from '@/api/chromeApi'
|
||||||
|
import {timestampToTime} from '@/utils/date'
|
||||||
|
import { Message } from 'element-ui'
|
||||||
|
import * as XLSX from 'xlsx'
|
||||||
|
import { saveAs } from 'file-saver'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'CostManageTemu',
|
||||||
|
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
isLoading: false,
|
||||||
|
list: [],
|
||||||
|
mallId: '',
|
||||||
|
colConfigs: [
|
||||||
|
{ prop: 'skc', label: 'SKC ID', align: 'left' },
|
||||||
|
{ prop: 'skcCode', label: 'SKC货号', align: 'left' },
|
||||||
|
{ prop: 'sku', label: 'SKU ID', align: 'left' },
|
||||||
|
{ prop: 'skuCode', label: 'SKU货号', align: 'left' },
|
||||||
|
{ prop: 'price', label: '申报价格', align: 'left', sortable: true, 'sort-method': (a, b) => a.price - b.price },
|
||||||
|
{ slot: 'costPrice', label: '成本价格', align: 'left' },
|
||||||
|
{ prop: 'profitPercent', label: '利润率(%)', align: 'left', sortable: true, 'sort-method': (a, b) => a.profitPercent - b.profitPercent }
|
||||||
|
],
|
||||||
|
search: {
|
||||||
|
unSet: false,
|
||||||
|
skc: '',
|
||||||
|
sku: '',
|
||||||
|
skcCode: ''
|
||||||
|
},
|
||||||
|
|
||||||
|
tableData: [],
|
||||||
|
currentPage: 1,
|
||||||
|
|
||||||
|
costList: [],
|
||||||
|
|
||||||
|
costDlgShow: false,
|
||||||
|
costForm: {
|
||||||
|
file: null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
filteredData() {
|
||||||
|
const filteredData = this.list.filter(item => {
|
||||||
|
let flag1 = true, flag2 = true, flag3 = true, flag4 = true
|
||||||
|
if (this.search.unSet) {
|
||||||
|
if (item.costPrice) flag1 = false
|
||||||
|
}
|
||||||
|
if (this.search.skc) {
|
||||||
|
if (!(item.skc == this.search.skc)) {
|
||||||
|
flag2 = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.search.sku) {
|
||||||
|
if (!(item.sku == this.search.sku)) {
|
||||||
|
flag3 = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.search.skcCode) {
|
||||||
|
if (!(item.skcCode == this.search.skcCode)) {
|
||||||
|
flag5 = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return flag1 && flag2 && flag3 && flag4
|
||||||
|
})
|
||||||
|
|
||||||
|
return filteredData
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
beforeGetList() {
|
||||||
|
this.list = []
|
||||||
|
this.currentPage = 1
|
||||||
|
this.costList = []
|
||||||
|
if (!this.mallId) {
|
||||||
|
Message.error("请先选择店铺")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.$userCheck(this.mallId).then(() => {
|
||||||
|
this.isLoading = true
|
||||||
|
this.getList()
|
||||||
|
}).catch((err) => {
|
||||||
|
this.isLoading = false
|
||||||
|
})
|
||||||
|
},
|
||||||
|
async getList () {
|
||||||
|
let res = await sendChromeAPIMessage({
|
||||||
|
url: `bg-visage-mms/product/skc/pageQuery`,
|
||||||
|
needMallId: true,
|
||||||
|
mallId: this.mallId,
|
||||||
|
data: {
|
||||||
|
page: this.currentPage,
|
||||||
|
pageSize: 100
|
||||||
|
}})
|
||||||
|
if (res.errorCode == 1000000) {
|
||||||
|
for(let i = 0;i < res.result.pageItems.length; i++) {
|
||||||
|
let item = res.result.pageItems[i];
|
||||||
|
let data = {skc: item.productSkcId,
|
||||||
|
skcCode: item.extCode
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let j = 0; j < item.productSkuSummaries.length; j++) {
|
||||||
|
let sku = item.productSkuSummaries[j]
|
||||||
|
data = {...data, sku: sku.productSkuId,
|
||||||
|
skuAttr: null,
|
||||||
|
skuCode: sku.extCode,
|
||||||
|
price: sku.supplierPrice / 100,
|
||||||
|
costPrice: '',
|
||||||
|
profitPercent: null,
|
||||||
|
edit: false,
|
||||||
|
editValue: null
|
||||||
|
}
|
||||||
|
|
||||||
|
this.list.push(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (res.result.pageItems.length == 100 && (res.result.total > 100*this.currentPage)) {
|
||||||
|
this.currentPage++
|
||||||
|
await this.sleepSync(200)
|
||||||
|
await this.getList()
|
||||||
|
} else {
|
||||||
|
this.getSkuCostList()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
sleepSync(milliseconds) {
|
||||||
|
return new Promise(resolve => setTimeout(resolve, milliseconds));
|
||||||
|
},
|
||||||
|
getSkuCostList() {
|
||||||
|
this.$http.post(`/api/skuCost/listAll`, null, {
|
||||||
|
params: {
|
||||||
|
mallId: this.mallId
|
||||||
|
}
|
||||||
|
}).then(res => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
this.costList = res.data
|
||||||
|
for (let i = 0; i < this.costList.length; i++) {
|
||||||
|
for (let j = 0; j < this.list.length; j++) {
|
||||||
|
if (this.costList[i].sku == this.list[j].sku) {
|
||||||
|
this.list[j].costPrice = this.costList[i].costPrice
|
||||||
|
this.list[j].editValue = this.costList[i].costPrice
|
||||||
|
this.list[j].profitPercent = Math.round((this.list[j].price - this.list[j].costPrice) / this.list[j].price * 10000) /100
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.isLoading = false
|
||||||
|
} else {
|
||||||
|
this.isLoading = false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleSave(row) {
|
||||||
|
this.$http.post(`/api/skuCost/addOrUpdate`, [{
|
||||||
|
mallId: this.mallId,
|
||||||
|
costPrice: row.editValue,
|
||||||
|
skc: row.skc,
|
||||||
|
sku: row.sku
|
||||||
|
}]).then((res) => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
row.edit = false
|
||||||
|
row.costPrice = row.editValue
|
||||||
|
row.profitPercent = Math.round((row.price - row.costPrice) / row.price * 10000) / 100
|
||||||
|
Message.success("修改成功")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
toUpload() {
|
||||||
|
this.costDlgShow = true
|
||||||
|
},
|
||||||
|
importConfirm() {
|
||||||
|
this.$refs.costForm.validate((valid) => {
|
||||||
|
const data = new FormData()
|
||||||
|
data.append('file', this.costForm.file[0].raw);
|
||||||
|
this.$http.post(`/api/skuCost/importStock`, data).then(res => {
|
||||||
|
if (res.code === 0) {
|
||||||
|
this.costDlgShow = false
|
||||||
|
this.$message.success('导入成功')
|
||||||
|
this.getList()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
exportToExcel() {
|
||||||
|
// 假设你有一个表格数据的数组
|
||||||
|
const data = [
|
||||||
|
["店铺ID", "SKC ID", "SKC货号", "SKU ID", "属性集", "SKU货号", "申报价格", "成本价格"]
|
||||||
|
]
|
||||||
|
|
||||||
|
this.filteredData.map(item => {
|
||||||
|
data.push([this.mallId, item.skc, item.skcCode, item.sku, item.skuAttr, item.skuCode, item.price, item.costPrice])
|
||||||
|
})
|
||||||
|
|
||||||
|
// 将数据转换为工作表
|
||||||
|
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, 'SKU列表.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>
|
||||||
@@ -68,12 +68,12 @@
|
|||||||
<template slot="content" v-if="type === '0'">
|
<template slot="content" v-if="type === '0'">
|
||||||
<div class="top">
|
<div class="top">
|
||||||
<div class="item">
|
<div class="item">
|
||||||
<h2>今日销量</h2>
|
<h2>今日销量/销售额</h2>
|
||||||
<p>{{ todayTotal }}</p>
|
<p>{{ todayTotal }}/{{ todayMoney }}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="item">
|
<div class="item">
|
||||||
<h2>今日销售额</h2>
|
<h2>今日利润/利润率</h2>
|
||||||
<p>{{ todayMoney }}</p>
|
<p>{{ profitMoney }}/{{ profitPercent }}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="item">
|
<div class="item">
|
||||||
<h2>可用库存总量(件)</h2>
|
<h2>可用库存总量(件)</h2>
|
||||||
@@ -103,17 +103,12 @@
|
|||||||
</el-tooltip></span></h2>
|
</el-tooltip></span></h2>
|
||||||
<p>{{ inroadTotalMoney }}</p>
|
<p>{{ inroadTotalMoney }}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="item">
|
|
||||||
<h2>已收货总量(件)</h2>
|
|
||||||
<p>{{ deliveryTotal }}</p>
|
|
||||||
</div>
|
|
||||||
<div class="item">
|
|
||||||
<h2>已收货总货值</h2>
|
|
||||||
<p>{{ deliveryMoney }}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<ai-card title="数据明细" style="padding-bottom: 40px;">
|
<ai-card title="数据明细" style="padding-bottom: 40px;">
|
||||||
<template #right>
|
<template #right>
|
||||||
|
<div class="search-item" style="width: 160px;">
|
||||||
|
<el-checkbox v-model="showTodaySale">只显示今日有销量</el-checkbox>
|
||||||
|
</div>
|
||||||
<json-excel
|
<json-excel
|
||||||
:data="list"
|
:data="list"
|
||||||
v-if="type === '0'"
|
v-if="type === '0'"
|
||||||
@@ -137,10 +132,10 @@
|
|||||||
<ai-table
|
<ai-table
|
||||||
ref="table0"
|
ref="table0"
|
||||||
:isShowPagination="false"
|
:isShowPagination="false"
|
||||||
:tableData="list"
|
:tableData="filteredData"
|
||||||
height="500"
|
height="500"
|
||||||
:col-configs="colConfigs"
|
:col-configs="colConfigs"
|
||||||
:total="list.length"
|
:total="filteredData.length"
|
||||||
style="margin-top: 8px;"
|
style="margin-top: 8px;"
|
||||||
@getList="() => {}">
|
@getList="() => {}">
|
||||||
</ai-table>
|
</ai-table>
|
||||||
@@ -224,13 +219,13 @@ import { Message } from 'element-ui'
|
|||||||
currentPage: 1,
|
currentPage: 1,
|
||||||
todayTotal: 0,
|
todayTotal: 0,
|
||||||
todayMoney: 0.0,
|
todayMoney: 0.0,
|
||||||
|
profitMoney: 0.0,
|
||||||
|
profitPercent: 0,
|
||||||
inventoryTotal: 0,
|
inventoryTotal: 0,
|
||||||
inventoryMoney: 0.0,
|
inventoryMoney: 0.0,
|
||||||
inroadTotal: 0,
|
inroadTotal: 0,
|
||||||
inroadTotalMoney: 0.0,
|
inroadTotalMoney: 0.0,
|
||||||
deliveryTotal: 0,
|
costList: [],
|
||||||
deliveryMoney: 0.0,
|
|
||||||
allProductList: [],
|
|
||||||
startDate: '',
|
startDate: '',
|
||||||
endDate: '',
|
endDate: '',
|
||||||
skuIds: [],
|
skuIds: [],
|
||||||
@@ -264,6 +259,9 @@ import { Message } from 'element-ui'
|
|||||||
"用户累计加购数量": "inCardNumber",
|
"用户累计加购数量": "inCardNumber",
|
||||||
"已订阅待提醒到货": "nomsgSubsCntCntSth",
|
"已订阅待提醒到货": "nomsgSubsCntCntSth",
|
||||||
"销售数据 - 今日": "todaySaleVolume",
|
"销售数据 - 今日": "todaySaleVolume",
|
||||||
|
"销售数据 - 今日销售额": "saleMoney",
|
||||||
|
"销售数据 - 利润": "profitMoney",
|
||||||
|
"销售数据 - 利润率": "profitPercent",
|
||||||
"销售数据 - 近7日": "lastSevenDaysSaleVolume",
|
"销售数据 - 近7日": "lastSevenDaysSaleVolume",
|
||||||
"销售数据 - 近30天": "lastThirtyDaysSaleVolume",
|
"销售数据 - 近30天": "lastThirtyDaysSaleVolume",
|
||||||
"库存数据 - 仓内可用库存": "inventoryNumInfo.warehouseInventoryNum",
|
"库存数据 - 仓内可用库存": "inventoryNumInfo.warehouseInventoryNum",
|
||||||
@@ -296,11 +294,22 @@ import { Message } from 'element-ui'
|
|||||||
skuDownloadForm: {
|
skuDownloadForm: {
|
||||||
date: ''
|
date: ''
|
||||||
},
|
},
|
||||||
|
showTodaySale: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(['mallList']),
|
...mapState(['mallList']),
|
||||||
|
filteredData() {
|
||||||
|
const filteredData = this.list.filter(item => {
|
||||||
|
if (this.showTodaySale) {
|
||||||
|
return item.todaySaleVolume > 0
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
|
||||||
|
return filteredData
|
||||||
|
},
|
||||||
colConfigs () {
|
colConfigs () {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
@@ -362,6 +371,38 @@ import { Message } from 'element-ui'
|
|||||||
width: '120px',
|
width: '120px',
|
||||||
align: 'center'
|
align: 'center'
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
prop: 'todaySaleVolume',
|
||||||
|
label: '今日销量',
|
||||||
|
width: '120px',
|
||||||
|
align: 'center',
|
||||||
|
sortable: true,
|
||||||
|
'sort-method': (a, b) => {
|
||||||
|
return a.todaySaleVolume - b.todaySaleVolume
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'saleMoney',
|
||||||
|
label: '销售额',
|
||||||
|
width: '120px',
|
||||||
|
align: 'center'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'profitMoney',
|
||||||
|
label: '利润',
|
||||||
|
width: '120px',
|
||||||
|
align: 'center',
|
||||||
|
sortable: true,
|
||||||
|
'sort-method': (a, b) => {
|
||||||
|
return a.profitMoney - b.profitMoney
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'profitPercent',
|
||||||
|
label: '利润率(%)',
|
||||||
|
width: '120px',
|
||||||
|
align: 'center'
|
||||||
|
},
|
||||||
{
|
{
|
||||||
prop: 'onSalesDurationOffline',
|
prop: 'onSalesDurationOffline',
|
||||||
label: '加入站点时长',
|
label: '加入站点时长',
|
||||||
@@ -388,7 +429,6 @@ import { Message } from 'element-ui'
|
|||||||
label: '仓内可用库存',
|
label: '仓内可用库存',
|
||||||
width: '160px',
|
width: '160px',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
fixed: "right",
|
|
||||||
sortable: true,
|
sortable: true,
|
||||||
'sort-method': (a, b) => {
|
'sort-method': (a, b) => {
|
||||||
return a.warehouseInventoryNum - b.warehouseInventoryNum
|
return a.warehouseInventoryNum - b.warehouseInventoryNum
|
||||||
@@ -550,6 +590,13 @@ import { Message } from 'element-ui'
|
|||||||
align: 'center',
|
align: 'center',
|
||||||
fixed: 'left'
|
fixed: 'left'
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
prop: 'supplierPrice',
|
||||||
|
label: '申报价格',
|
||||||
|
width: '120px',
|
||||||
|
align: 'center',
|
||||||
|
fixed: 'left'
|
||||||
|
},
|
||||||
{
|
{
|
||||||
prop: 'productSkuId',
|
prop: 'productSkuId',
|
||||||
label: 'SKU ID',
|
label: 'SKU ID',
|
||||||
@@ -599,6 +646,7 @@ import { Message } from 'element-ui'
|
|||||||
"SKC货号": "skcExtCode",
|
"SKC货号": "skcExtCode",
|
||||||
"SKU ID": "productSkuId",
|
"SKU ID": "productSkuId",
|
||||||
"SKU货号": "skuExtCode",
|
"SKU货号": "skuExtCode",
|
||||||
|
"申报价格": "supplierPrice",
|
||||||
"图片链接": "productSkcPicture"
|
"图片链接": "productSkcPicture"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -637,15 +685,13 @@ import { Message } from 'element-ui'
|
|||||||
this.currentPage = 1
|
this.currentPage = 1
|
||||||
this.todayMoney = 0.0
|
this.todayMoney = 0.0
|
||||||
this.todayTotal = 0
|
this.todayTotal = 0
|
||||||
|
this.profitMoney = 0.0
|
||||||
|
this.profitPercent = 0
|
||||||
this.inventoryMoney = 0.0
|
this.inventoryMoney = 0.0
|
||||||
this.inventoryTotal = 0
|
this.inventoryTotal = 0
|
||||||
this.inroadTotalMoney = 0.0
|
this.inroadTotalMoney = 0.0
|
||||||
this.inroadTotal = 0
|
this.inroadTotal = 0
|
||||||
this.deliveryTotal = 0
|
|
||||||
this.deliveryMoney = 0.0
|
|
||||||
this.allProductList = []
|
|
||||||
if (!this.mallId) {
|
if (!this.mallId) {
|
||||||
|
|
||||||
Message.error("请先选择店铺")
|
Message.error("请先选择店铺")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -657,33 +703,27 @@ import { Message } from 'element-ui'
|
|||||||
this.isLoading = true
|
this.isLoading = true
|
||||||
this.$userCheck(this.mallId).then(() => {
|
this.$userCheck(this.mallId).then(() => {
|
||||||
this.last30DaySkcList = []
|
this.last30DaySkcList = []
|
||||||
this.getAllProductList()
|
this.getSkuCostList()
|
||||||
this.getList()
|
this.getList()
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
console.log(err)
|
console.log(err)
|
||||||
this.isLoading = false
|
this.isLoading = false
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
getAllProductList() {
|
getSkuCostList() {
|
||||||
this.$http.post('/api/deliveryOrder/totalDelivery',null, {
|
this.$http.post(`/api/skuCost/listAll`, null, {
|
||||||
params: {mallId: this.mallId}
|
params: {
|
||||||
}).then(res => {
|
mallId: this.mallId
|
||||||
if (res.code === 0) {
|
|
||||||
this.deliveryTotal = res.data
|
|
||||||
}
|
}
|
||||||
})
|
|
||||||
|
|
||||||
this.$http.post('/api/deliveryOrder/getAllProductList', null, {
|
|
||||||
params: {mallId: this.mallId}
|
|
||||||
}).then(res => {
|
}).then(res => {
|
||||||
if (res.code == 0) {
|
if (res.code == 0) {
|
||||||
this.allProductList = res.data
|
this.costList = res.data
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
getList () {
|
getList () {
|
||||||
sendChromeAPIMessage({
|
sendChromeAPIMessage({
|
||||||
url: 'marvel-mms/cn/api/kiana/venom/sales/management/list',
|
url: 'marvel-mms/cn/api/kiana/venom/sales/management/listWarehouse',
|
||||||
needMallId: true,
|
needMallId: true,
|
||||||
mallId: this.mallId,
|
mallId: this.mallId,
|
||||||
data: {
|
data: {
|
||||||
@@ -724,32 +764,30 @@ import { Message } from 'element-ui'
|
|||||||
|
|
||||||
|
|
||||||
for(let j = 0;j < item.skuQuantityDetailList.length; j++) {
|
for(let j = 0;j < item.skuQuantityDetailList.length; j++) {
|
||||||
|
let costPrice = this.getCostPrice(item.skuQuantityDetailList[j].productSkuId)
|
||||||
|
let saleMoney = Math.round(item.skuQuantityDetailList[j].todaySaleVolume * item.skuQuantityDetailList[j].supplierPrice) /100
|
||||||
|
let profitMoney = Math.round(item.skuQuantityDetailList[j].todaySaleVolume * (item.skuQuantityDetailList[j].supplierPrice / 100 - costPrice) * 100) /100
|
||||||
|
let profitPercent = Math.round(profitMoney / saleMoney * 10000) /100
|
||||||
data = {...data, ...item.skuQuantityDetailList[j],
|
data = {...data, ...item.skuQuantityDetailList[j],
|
||||||
|
saleMoney: saleMoney,
|
||||||
|
profitMoney: profitMoney,
|
||||||
|
profitPercent: profitPercent,
|
||||||
productTotalPrice: ((item.skuQuantityDetailList[j].supplierPrice / 100) * item.skuQuantityDetailList[j].inventoryNumInfo.warehouseInventoryNum).toFixed(2),
|
productTotalPrice: ((item.skuQuantityDetailList[j].supplierPrice / 100) * item.skuQuantityDetailList[j].inventoryNumInfo.warehouseInventoryNum).toFixed(2),
|
||||||
inroadTotalPrice: ((item.skuQuantityDetailList[j].supplierPrice / 100) * (item.skuQuantityDetailList[j].inventoryNumInfo.waitOnShelfNum + item.skuQuantityDetailList[j].inventoryNumInfo.waitReceiveNum)).toFixed(2),
|
inroadTotalPrice: ((item.skuQuantityDetailList[j].supplierPrice / 100) * (item.skuQuantityDetailList[j].inventoryNumInfo.waitOnShelfNum + item.skuQuantityDetailList[j].inventoryNumInfo.waitReceiveNum)).toFixed(2),
|
||||||
warehouseInventoryNum: item.skuQuantityDetailList[j].inventoryNumInfo.warehouseInventoryNum}
|
warehouseInventoryNum: item.skuQuantityDetailList[j].inventoryNumInfo.warehouseInventoryNum}
|
||||||
|
|
||||||
this.todayTotal += item.skuQuantityDetailList[j].todaySaleVolume
|
this.todayTotal += item.skuQuantityDetailList[j].todaySaleVolume
|
||||||
this.todayMoney += new Number(((item.skuQuantityDetailList[j].supplierPrice / 100) * item.skuQuantityDetailList[j].todaySaleVolume).toFixed(2))
|
this.profitMoney += item.skuQuantityDetailList[j].todaySaleVolume * (item.skuQuantityDetailList[j].supplierPrice / 100 - costPrice)
|
||||||
this.todayMoney = new Number(this.todayMoney.toFixed(2))
|
this.todayMoney += (item.skuQuantityDetailList[j].supplierPrice / 100) * item.skuQuantityDetailList[j].todaySaleVolume
|
||||||
this.inventoryTotal += item.skuQuantityDetailList[j].inventoryNumInfo.warehouseInventoryNum
|
this.inventoryTotal += item.skuQuantityDetailList[j].inventoryNumInfo.warehouseInventoryNum
|
||||||
this.inventoryMoney += new Number(((item.skuQuantityDetailList[j].supplierPrice / 100) * item.skuQuantityDetailList[j].inventoryNumInfo.warehouseInventoryNum).toFixed(2))
|
this.inventoryMoney += (item.skuQuantityDetailList[j].supplierPrice / 100) * item.skuQuantityDetailList[j].inventoryNumInfo.warehouseInventoryNum
|
||||||
this.inventoryMoney = new Number(this.inventoryMoney.toFixed(2))
|
this.inroadTotal += (item.skuQuantityDetailList[j].inventoryNumInfo.waitOnShelfNum + item.skuQuantityDetailList[j].inventoryNumInfo.waitReceiveNum)
|
||||||
this.inroadTotal += (item.skuQuantityDetailList[j].inventoryNumInfo.waitOnShelfNum + item.skuQuantityDetailList[j].inventoryNumInfo.waitReceiveNum)
|
this.inroadTotalMoney += (item.skuQuantityDetailList[j].supplierPrice / 100) * (item.skuQuantityDetailList[j].inventoryNumInfo.waitOnShelfNum + item.skuQuantityDetailList[j].inventoryNumInfo.waitReceiveNum)
|
||||||
this.inroadTotalMoney += new Number(((item.skuQuantityDetailList[j].supplierPrice / 100) * (item.skuQuantityDetailList[j].inventoryNumInfo.waitOnShelfNum + item.skuQuantityDetailList[j].inventoryNumInfo.waitReceiveNum)).toFixed(2))
|
this.adviceProduceNum = item.skuQuantityDetailList[j].adviceProduceNum || '-'
|
||||||
this.inroadTotalMoney = new Number(this.inroadTotalMoney.toFixed(2))
|
this.availableProduceNum = item.skuQuantityDetailList[j].availableProduceNum || '-'
|
||||||
this.adviceProduceNum = item.skuQuantityDetailList[j].adviceProduceNum || '-'
|
this.list.push(data);
|
||||||
this.availableProduceNum = item.skuQuantityDetailList[j].availableProduceNum || '-'
|
|
||||||
this.list.push(data);
|
|
||||||
|
|
||||||
// 计算已发货货值
|
|
||||||
for(let k = 0; k < this.allProductList.length; k++) {
|
|
||||||
if (this.allProductList[k].product_sku_id == data.productSkuId) {
|
|
||||||
this.deliveryMoney += (item.skuQuantityDetailList[j].supplierPrice / 100) * this.allProductList[k].product_sku_number
|
|
||||||
this.deliveryMoney = new Number(this.deliveryMoney.toFixed(2))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
if (this.pageSize == res.result.subOrderList.length) {
|
if (this.pageSize == res.result.subOrderList.length) {
|
||||||
this.currentPage ++
|
this.currentPage ++
|
||||||
@@ -757,6 +795,12 @@ import { Message } from 'element-ui'
|
|||||||
this.getList()
|
this.getList()
|
||||||
}, 1500)
|
}, 1500)
|
||||||
} else {
|
} else {
|
||||||
|
this.profitMoney = Math.round(this.profitMoney * 100) / 100
|
||||||
|
this.todayMoney = Math.round(this.todayMoney * 100) / 100
|
||||||
|
this.profitPercent = Math.round((this.profitMoney / this.todayMoney) * 10000) /100 + '%'
|
||||||
|
this.inventoryMoney = Math.round(this.inventoryMoney * 100) / 100
|
||||||
|
this.inroadTotalMoney = Math.round(this.inroadTotalMoney * 100) / 100
|
||||||
|
|
||||||
this.isLoading = false
|
this.isLoading = false
|
||||||
Message.success('销售数据加载完成,可进行导出')
|
Message.success('销售数据加载完成,可进行导出')
|
||||||
|
|
||||||
@@ -782,7 +826,8 @@ import { Message } from 'element-ui'
|
|||||||
productSkuId: item.productSkuId,
|
productSkuId: item.productSkuId,
|
||||||
skuExtCode: item.skuExtCode,
|
skuExtCode: item.skuExtCode,
|
||||||
skcExtCode: item.skcExtCode,
|
skcExtCode: item.skcExtCode,
|
||||||
productSkcPicture: item.productSkcPicture
|
productSkcPicture: item.productSkcPicture,
|
||||||
|
supplierPrice: this.getSupplierPrice(item.productSkuId)
|
||||||
}
|
}
|
||||||
let date = new Date()
|
let date = new Date()
|
||||||
date.setDate(date.getDate() - 31)
|
date.setDate(date.getDate() - 31)
|
||||||
@@ -888,7 +933,8 @@ import { Message } from 'element-ui'
|
|||||||
temp = {
|
temp = {
|
||||||
'SKC': 'skc',
|
'SKC': 'skc',
|
||||||
'SKU': 'sku',
|
'SKU': 'sku',
|
||||||
'SKU货号': 'skuExtCode'
|
'SKU货号': 'skuExtCode',
|
||||||
|
'申报价格': 'supplierPrice'
|
||||||
}
|
}
|
||||||
let beginTime = new Date(this.skuDownloadForm.date[0])
|
let beginTime = new Date(this.skuDownloadForm.date[0])
|
||||||
let endTime = new Date(this.skuDownloadForm.date[1])
|
let endTime = new Date(this.skuDownloadForm.date[1])
|
||||||
@@ -914,7 +960,8 @@ import { Message } from 'element-ui'
|
|||||||
let temp = {
|
let temp = {
|
||||||
sku: item.productSkuId,
|
sku: item.productSkuId,
|
||||||
skc: item.productSkcId,
|
skc: item.productSkcId,
|
||||||
skuExtCode: item.skuExtCode
|
skuExtCode: item.skuExtCode,
|
||||||
|
supplierPrice: this.getSupplierPrice(item.productSkuId)
|
||||||
}
|
}
|
||||||
beginTime = new Date(this.skuDownloadForm.date[0])
|
beginTime = new Date(this.skuDownloadForm.date[0])
|
||||||
endTime = new Date(this.skuDownloadForm.date[1])
|
endTime = new Date(this.skuDownloadForm.date[1])
|
||||||
@@ -966,6 +1013,22 @@ import { Message } from 'element-ui'
|
|||||||
reqSkusIds = []
|
reqSkusIds = []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
getSupplierPrice(productSkuId) {
|
||||||
|
for (let i = 0; i < this.list.length; i++) {
|
||||||
|
if (this.list[i].productSkuId == productSkuId) {
|
||||||
|
return this.list[i].supplierPrice / 100
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
},
|
||||||
|
getCostPrice(productSkuId) {
|
||||||
|
for (let i = 0; i < this.costList.length; i++) {
|
||||||
|
if (this.costList[i].sku == productSkuId) {
|
||||||
|
return this.costList[i].costPrice
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
156
src/view/shein/CertCenterShein.vue
Normal file
156
src/view/shein/CertCenterShein.vue
Normal file
@@ -0,0 +1,156 @@
|
|||||||
|
<template>
|
||||||
|
<ai-list class="list" v-loading="isLoading" element-loading-text="拼命加载中" element-loading-spinner="el-icon-loading">
|
||||||
|
<ai-title
|
||||||
|
slot="title"
|
||||||
|
title="证书中心"
|
||||||
|
isShowBottomBorder>
|
||||||
|
</ai-title>
|
||||||
|
<template slot="content">
|
||||||
|
<ai-card title="待补充证书列表" style="padding-bottom: 40px;">
|
||||||
|
<template #right>
|
||||||
|
<el-button type="primary" @click="exportToExcel">导出</el-button>
|
||||||
|
</template>
|
||||||
|
<ai-table
|
||||||
|
:isShowPagination="false"
|
||||||
|
:tableData="list"
|
||||||
|
:col-configs="colConfigs"
|
||||||
|
height="600"
|
||||||
|
style="margin-top: 8px;"
|
||||||
|
@getList="() => {}">
|
||||||
|
</ai-table>
|
||||||
|
</ai-card>
|
||||||
|
</template>
|
||||||
|
</ai-list>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import {sendGeiwohuoAPIMessage} from '@/api/chromeApi'
|
||||||
|
import {timestampToTime} from '@/utils/date'
|
||||||
|
import { Message } from 'element-ui'
|
||||||
|
import * as XLSX from 'xlsx'
|
||||||
|
import { saveAs } from 'file-saver'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'CertCenterShein',
|
||||||
|
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
isLoading: false,
|
||||||
|
list: [],
|
||||||
|
mallId: '',
|
||||||
|
colConfigs: [
|
||||||
|
{ prop: 'spu', label: 'SPU', align: 'left' },
|
||||||
|
{ prop: 'productName', label: '商品标题', align: 'left' },
|
||||||
|
{ prop: 'skc', label: 'SKC ID', align: 'left' },
|
||||||
|
{ prop: 'mainAttrName', label: '主规格', align: 'left' },
|
||||||
|
{ prop: 'certificateTypeName', label: '证书类型', align: 'left' },
|
||||||
|
{ prop: 'mergeSiteName', label: '管控地区', align: 'left' },
|
||||||
|
{ prop: 'subSite', label: '管控子站点', align: 'left' },
|
||||||
|
{ slot: 'uploadEndTime', label: '上传截止时间', align: 'left' }
|
||||||
|
],
|
||||||
|
|
||||||
|
tableData: [],
|
||||||
|
currentPage: 1,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
mounted () {
|
||||||
|
this.isLoading = true
|
||||||
|
this.getList()
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
async getList () {
|
||||||
|
let res = await sendGeiwohuoAPIMessage({
|
||||||
|
url: `spmp-api-prefix/spmp/certificate/get_skc_certificate_miss_list?page_num=${this.currentPage}&page_size=200`,
|
||||||
|
method: 'POST',
|
||||||
|
data: {}})
|
||||||
|
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 = {spu: item.spu_name,
|
||||||
|
productName: item.skc_name_cn,
|
||||||
|
skc: item.skc_name,
|
||||||
|
mainAttrName: item.main_attribute_name,
|
||||||
|
uploadEndTime: item.upload_end_time,
|
||||||
|
mergeSiteName: mainSite.join(','),
|
||||||
|
certificateTypeName: item.certificate_type_name,
|
||||||
|
subSite: subSite.join(',')
|
||||||
|
}
|
||||||
|
|
||||||
|
this.list.push(data)
|
||||||
|
}
|
||||||
|
if (res.info.data.length == 200 && (res.info.meta.count > 200*this.currentPage)) {
|
||||||
|
this.currentPage++
|
||||||
|
await this.sleepSync(200)
|
||||||
|
await this.getList()
|
||||||
|
} else {
|
||||||
|
this.isLoading = false
|
||||||
|
}
|
||||||
|
} else if (res.code == 100004 || res.code == 20302) {
|
||||||
|
this.isLoading = false
|
||||||
|
this.$store.commit("setSheinAlertShow", true)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
sleepSync(milliseconds) {
|
||||||
|
return new Promise(resolve => setTimeout(resolve, milliseconds));
|
||||||
|
},
|
||||||
|
exportToExcel() {
|
||||||
|
// 假设你有一个表格数据的数组
|
||||||
|
const data = [
|
||||||
|
["SPU", "商品标题", "SKC ID", "主规格", "证书类型", "管控地区", "管控子站点", "上传截止时间"]
|
||||||
|
]
|
||||||
|
|
||||||
|
this.list.map(item => {
|
||||||
|
data.push([item.spu, item.productName, item.skc, item.mainAttrName, item.certificateTypeName, item.mergeSiteName, item.subSite, item.uploadEndTime])
|
||||||
|
})
|
||||||
|
|
||||||
|
// 将数据转换为工作表
|
||||||
|
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>
|
||||||
@@ -51,11 +51,11 @@
|
|||||||
label="商品列表"
|
label="商品列表"
|
||||||
value="0">
|
value="0">
|
||||||
</el-option>
|
</el-option>
|
||||||
<el-option
|
<!--<el-option
|
||||||
key="1"
|
key="1"
|
||||||
label="草稿箱列表"
|
label="草稿箱列表"
|
||||||
value="1">
|
value="1">
|
||||||
</el-option>
|
</el-option>-->
|
||||||
</el-select>
|
</el-select>
|
||||||
</div>
|
</div>
|
||||||
<div class="search-item">
|
<div class="search-item">
|
||||||
@@ -256,6 +256,9 @@ import { Message } from 'element-ui'
|
|||||||
createTime: item.create_time
|
createTime: item.create_time
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
|
} else if (res.code == 100004 || res.code == 20302) {
|
||||||
|
this.isLoading = false
|
||||||
|
this.$store.commit("setSheinAlertShow", true)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
productHandleSelectionChange(val) {
|
productHandleSelectionChange(val) {
|
||||||
354
src/view/shein/CostManageShein.vue
Normal file
354
src/view/shein/CostManageShein.vue
Normal file
@@ -0,0 +1,354 @@
|
|||||||
|
<template>
|
||||||
|
<ai-list class="list" v-loading="isLoading" element-loading-text="拼命加载中" element-loading-spinner="el-icon-loading">
|
||||||
|
<ai-title
|
||||||
|
slot="title"
|
||||||
|
title="成本管理"
|
||||||
|
isShowBottomBorder>
|
||||||
|
</ai-title>
|
||||||
|
<template slot="content">
|
||||||
|
<div style="margin-bottom: 5px">
|
||||||
|
<el-alert
|
||||||
|
title="郑重承诺:由于业务逻辑需要,TEMU助手将会以最小范围内存储SKU成本信息,平台将会做好保密,不泄露、不出售任何数据。使用与成本管理以及利润计算等相关功能,将视为授权TEMU助手存储相关信息。"
|
||||||
|
type="error"
|
||||||
|
:closable="false">
|
||||||
|
</el-alert>
|
||||||
|
</div>
|
||||||
|
<ai-search-bar>
|
||||||
|
<template #left>
|
||||||
|
<div class="search-item">
|
||||||
|
<el-checkbox v-model="search.unSet">只显示未填写</el-checkbox>
|
||||||
|
</div>
|
||||||
|
<div class="search-item">
|
||||||
|
<label>SKC ID:</label>
|
||||||
|
<el-input size="small" clearable placeholder="请输入SKC ID" v-model="search.skc"></el-input>
|
||||||
|
</div>
|
||||||
|
<div class="search-item">
|
||||||
|
<label>SKU ID:</label>
|
||||||
|
<el-input size="small" clearable placeholder="请输入SKU ID" v-model="search.sku"></el-input>
|
||||||
|
</div>
|
||||||
|
<div class="search-item">
|
||||||
|
<label>SKC货号:</label>
|
||||||
|
<el-input size="small" clearable placeholder="请输入SKC货号" v-model="search.skcCode"></el-input>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template #right>
|
||||||
|
<!--<el-button type="primary" @click="toLoad">加载</el-button>-->
|
||||||
|
</template>
|
||||||
|
</ai-search-bar>
|
||||||
|
<ai-card title="SKU明细" style="padding-bottom: 40px;">
|
||||||
|
<template #right>
|
||||||
|
<el-button type="primary" @click="exportToExcel">导出</el-button>
|
||||||
|
<el-button type="primary" @click="toUpload">导入</el-button>
|
||||||
|
</template>
|
||||||
|
<ai-table
|
||||||
|
:isShowPagination="false"
|
||||||
|
:tableData="filteredData"
|
||||||
|
:col-configs="colConfigs"
|
||||||
|
height="600"
|
||||||
|
style="margin-top: 8px;"
|
||||||
|
@getList="() => {}">
|
||||||
|
<el-table-column slot="costPrice" label="成本价格" :sortable="true" :sort-method="(a, b) => a.costPrice - b.costPrice">
|
||||||
|
<template slot-scope="{ row }">
|
||||||
|
<el-input
|
||||||
|
v-if="row.edit"
|
||||||
|
v-model="row.editValue"
|
||||||
|
type="number"
|
||||||
|
size="small"
|
||||||
|
></el-input>
|
||||||
|
<span v-else>{{ row.costPrice }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column slot="options" label="操作" width="80px" show-overflow-tooltip align="center" fixed="right">
|
||||||
|
<template slot-scope="{ row }">
|
||||||
|
<el-button
|
||||||
|
v-if="!row.edit"
|
||||||
|
size="small"
|
||||||
|
icon="el-icon-edit"
|
||||||
|
@click="row.edit = true"
|
||||||
|
></el-button>
|
||||||
|
<el-button
|
||||||
|
v-if="row.edit"
|
||||||
|
size="small"
|
||||||
|
type="success"
|
||||||
|
icon="el-icon-circle-check"
|
||||||
|
@click="handleSave(row)"
|
||||||
|
></el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</ai-table>
|
||||||
|
</ai-card>
|
||||||
|
|
||||||
|
<AiDialog
|
||||||
|
title="成本导入"
|
||||||
|
:visible.sync="costDlgShow"
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
customFooter
|
||||||
|
width="1290px">
|
||||||
|
<el-form :model="costForm" ref="costForm" label-width="180px" class="form">
|
||||||
|
<el-form-item label="上传excel" prop="file" :rules="[{ required: true, message: '请上传文件', trigger: 'blur' }]" style="width: 100%;">
|
||||||
|
<ai-uploader isImport v-model="costForm.file" fileType="file" :limit="1"
|
||||||
|
acceptType=".xlsx," :clearable="false">
|
||||||
|
<template #trigger>
|
||||||
|
<el-button icon="iconfont iconfangda">选择文件</el-button>
|
||||||
|
</template>
|
||||||
|
<template #tips>最多上传1个文件,单个文件最大10MB,仅支持Excel格式</template>
|
||||||
|
</ai-uploader>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<span slot="footer" class="dialog-footer">
|
||||||
|
<el-button @click="costDlgShow = false">关 闭</el-button>
|
||||||
|
<el-button type="primary" @click="importConfirm">确 定</el-button>
|
||||||
|
</span>
|
||||||
|
</AiDialog>
|
||||||
|
</template>
|
||||||
|
</ai-list>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import {sendGeiwohuoAPIMessage} from '@/api/chromeApi'
|
||||||
|
import {timestampToTime} from '@/utils/date'
|
||||||
|
import { Message } from 'element-ui'
|
||||||
|
import * as XLSX from 'xlsx'
|
||||||
|
import { saveAs } from 'file-saver'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'CostManageShein',
|
||||||
|
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
isLoading: false,
|
||||||
|
list: [],
|
||||||
|
mallId: '',
|
||||||
|
colConfigs: [
|
||||||
|
{ prop: 'skc', label: 'SKC ID', align: 'left' },
|
||||||
|
{ prop: 'skcCode', label: 'SKC货号', align: 'left' },
|
||||||
|
{ prop: 'sku', label: 'SKU ID', align: 'left' },
|
||||||
|
{ prop: 'skuAttr', label: '属性集', align: 'left' },
|
||||||
|
{ prop: 'skuCode', label: 'SKU货号', align: 'left' },
|
||||||
|
{ prop: 'price', label: '申报价格', align: 'left', sortable: true, 'sort-method': (a, b) => a.price - b.price },
|
||||||
|
{ slot: 'costPrice', label: '成本价格', align: 'left' },
|
||||||
|
{ prop: 'profitPercent', label: '利润率(%)', align: 'left', sortable: true, 'sort-method': (a, b) => a.profitPercent - b.profitPercent }
|
||||||
|
],
|
||||||
|
search: {
|
||||||
|
unSet: false,
|
||||||
|
skc: '',
|
||||||
|
sku: '',
|
||||||
|
skcCode: ''
|
||||||
|
},
|
||||||
|
|
||||||
|
tableData: [],
|
||||||
|
currentPage: 1,
|
||||||
|
|
||||||
|
costList: [],
|
||||||
|
|
||||||
|
costDlgShow: false,
|
||||||
|
costForm: {
|
||||||
|
file: null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
filteredData() {
|
||||||
|
const filteredData = this.list.filter(item => {
|
||||||
|
let flag1 = true, flag2 = true, flag3 = true, flag4 = true
|
||||||
|
if (this.search.unSet) {
|
||||||
|
if (item.costPrice) flag1 = false
|
||||||
|
}
|
||||||
|
if (this.search.skc) {
|
||||||
|
if (!item.skc.toLowerCase().includes(this.search.skc.toLowerCase())) {
|
||||||
|
flag2 = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.search.sku) {
|
||||||
|
if (!item.sku.toLowerCase().includes(this.search.sku.toLowerCase())) {
|
||||||
|
flag3 = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.search.skcCode) {
|
||||||
|
if (!item.skcCode.toLowerCase().includes(this.search.skcCode.toLowerCase())) {
|
||||||
|
flag4 = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return flag1 && flag2 && flag3 && flag4
|
||||||
|
})
|
||||||
|
|
||||||
|
return filteredData
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
mounted () {
|
||||||
|
this.getUserInfo()
|
||||||
|
this.isLoading = true
|
||||||
|
this.getList()
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
async getUserInfo() {
|
||||||
|
let res = await sendGeiwohuoAPIMessage({
|
||||||
|
url: 'sso-prefix/auth/getUser?uuid=' + Date.now(),
|
||||||
|
method: 'GET'
|
||||||
|
})
|
||||||
|
if (res.code == '0' && res.msg == "OK") {
|
||||||
|
this.mallId = res.info.merchantCode
|
||||||
|
} else if (res.code == 100004 || res.code == 20302) {
|
||||||
|
this.isLoading = false
|
||||||
|
this.$store.commit("setSheinAlertShow", true)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async getList () {
|
||||||
|
let res = await sendGeiwohuoAPIMessage({
|
||||||
|
url: `idms/goods-skc/list`,
|
||||||
|
method: 'POST',
|
||||||
|
data: {
|
||||||
|
pageNumber: this.currentPage,
|
||||||
|
pageSize: 100,
|
||||||
|
sortBy7dSaleCnt: 2
|
||||||
|
}})
|
||||||
|
if (res.code == '0') {
|
||||||
|
for(let i = 0;i < res.info.list.length; i++) {
|
||||||
|
let item = res.info.list[i];
|
||||||
|
let data = {skc: item.skc,
|
||||||
|
skcCode: item.supplierCode
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let j = 0; j < item.skuList.length; j++) {
|
||||||
|
let sku = item.skuList[j]
|
||||||
|
if (sku.attr == '合计') continue
|
||||||
|
data = {...data, sku: sku.skuCode,
|
||||||
|
skuAttr: sku.attr,
|
||||||
|
skuCode: sku.supplierSku,
|
||||||
|
price: sku.price,
|
||||||
|
costPrice: '',
|
||||||
|
profitPercent: null,
|
||||||
|
edit: false,
|
||||||
|
editValue: null
|
||||||
|
}
|
||||||
|
|
||||||
|
this.list.push(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (res.info.list.length == 100 && (res.info.count > 100*this.currentPage)) {
|
||||||
|
this.currentPage++
|
||||||
|
await this.sleepSync(200)
|
||||||
|
await this.getList()
|
||||||
|
} else {
|
||||||
|
this.getSkuCostList()
|
||||||
|
}
|
||||||
|
} else if (res.code == 100004 || res.code == 20302) {
|
||||||
|
this.isLoading = false
|
||||||
|
this.$store.commit("setSheinAlertShow", true)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
sleepSync(milliseconds) {
|
||||||
|
return new Promise(resolve => setTimeout(resolve, milliseconds));
|
||||||
|
},
|
||||||
|
getSkuCostList() {
|
||||||
|
this.$http.post(`/api/skuCost/listAll`, null, {
|
||||||
|
params: {
|
||||||
|
mallId: this.mallId
|
||||||
|
}
|
||||||
|
}).then(res => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
this.costList = res.data
|
||||||
|
for (let i = 0; i < this.costList.length; i++) {
|
||||||
|
for (let j = 0; j < this.list.length; j++) {
|
||||||
|
if (this.costList[i].sku == this.list[j].sku) {
|
||||||
|
this.list[j].costPrice = this.costList[i].costPrice
|
||||||
|
this.list[j].editValue = this.costList[i].costPrice
|
||||||
|
this.list[j].profitPercent = Math.round((this.list[j].price - this.list[j].costPrice) / this.list[j].price * 10000) /100
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.isLoading = false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleSave(row) {
|
||||||
|
this.$http.post(`/api/skuCost/addOrUpdate`, [{
|
||||||
|
mallId: this.mallId,
|
||||||
|
costPrice: row.editValue,
|
||||||
|
skc: row.skc,
|
||||||
|
sku: row.sku
|
||||||
|
}]).then((res) => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
row.edit = false
|
||||||
|
row.costPrice = row.editValue
|
||||||
|
row.profitPercent = Math.round((row.price - row.costPrice) / row.price * 10000) / 100
|
||||||
|
Message.success("修改成功")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
toUpload() {
|
||||||
|
this.costDlgShow = true
|
||||||
|
},
|
||||||
|
importConfirm() {
|
||||||
|
this.$refs.costForm.validate((valid) => {
|
||||||
|
const data = new FormData()
|
||||||
|
data.append('file', this.costForm.file[0].raw);
|
||||||
|
this.$http.post(`/api/skuCost/importStock`, data).then(res => {
|
||||||
|
if (res.code === 0) {
|
||||||
|
this.costDlgShow = false
|
||||||
|
this.$message.success('导入成功')
|
||||||
|
this.currentPage = 1
|
||||||
|
this.list = []
|
||||||
|
this.isLoading = true
|
||||||
|
this.getList()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
exportToExcel() {
|
||||||
|
// 假设你有一个表格数据的数组
|
||||||
|
const data = [
|
||||||
|
["店铺ID", "SKC ID", "SKC货号", "SKU ID", "属性集", "SKU货号", "申报价格", "成本价格"]
|
||||||
|
]
|
||||||
|
|
||||||
|
this.filteredData.map(item => {
|
||||||
|
data.push([this.mallId, item.skc, item.skcCode, item.sku, item.skuAttr, item.skuCode, item.price, item.costPrice])
|
||||||
|
})
|
||||||
|
|
||||||
|
// 将数据转换为工作表
|
||||||
|
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, 'SKU列表.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>
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
<ai-list class="list" v-loading="isLoading" element-loading-text="拼命加载中" element-loading-spinner="el-icon-loading">
|
<ai-list class="list" v-loading="isLoading" element-loading-text="拼命加载中" element-loading-spinner="el-icon-loading">
|
||||||
<ai-title
|
<ai-title
|
||||||
slot="title"
|
slot="title"
|
||||||
title="销售数据(希音)"
|
title="销售数据"
|
||||||
isShowBottomBorder>
|
isShowBottomBorder>
|
||||||
</ai-title>
|
</ai-title>
|
||||||
<template slot="content">
|
<template slot="content">
|
||||||
@@ -46,22 +46,17 @@
|
|||||||
</div>
|
</div>
|
||||||
<ai-card title="数据明细" style="padding-bottom: 40px;">
|
<ai-card title="数据明细" style="padding-bottom: 40px;">
|
||||||
<template #right>
|
<template #right>
|
||||||
<json-excel
|
<div class="search-item" style="width: 160px;">
|
||||||
:data="list"
|
<el-checkbox v-model="showTodaySale">只显示今日有销量</el-checkbox>
|
||||||
:fields="jsonFields"
|
</div>
|
||||||
:before-generate = "startDownload"
|
|
||||||
name="销售数据.xls"
|
|
||||||
worksheet="销售统计">
|
|
||||||
<el-button type="primary">导出数据</el-button>
|
|
||||||
</json-excel>
|
|
||||||
</template>
|
</template>
|
||||||
<ai-table
|
<ai-table
|
||||||
ref="table0"
|
ref="table0"
|
||||||
:isShowPagination="false"
|
:isShowPagination="false"
|
||||||
:tableData="list"
|
:tableData="filteredData"
|
||||||
height="500"
|
height="500"
|
||||||
:col-configs="colConfigs"
|
:col-configs="colConfigs"
|
||||||
:total="list.length"
|
:total="filteredData.length"
|
||||||
style="margin-top: 8px;"
|
style="margin-top: 8px;"
|
||||||
@getList="() => {}">
|
@getList="() => {}">
|
||||||
<el-table-column slot="goodsThumb" width="120px" label="商品图片" fixed="left">
|
<el-table-column slot="goodsThumb" width="120px" label="商品图片" fixed="left">
|
||||||
@@ -90,6 +85,7 @@ import { Message } from 'element-ui'
|
|||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
list: [],
|
list: [],
|
||||||
|
mallId: '',
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
pageSize: 100,
|
pageSize: 100,
|
||||||
currentPage: 1,
|
currentPage: 1,
|
||||||
@@ -104,61 +100,7 @@ import { Message } from 'element-ui'
|
|||||||
startDate: '',
|
startDate: '',
|
||||||
endDate: '',
|
endDate: '',
|
||||||
skuIds: [],
|
skuIds: [],
|
||||||
jsonFields: {
|
showTodaySale: false,
|
||||||
"商品名称": "productName",
|
|
||||||
"SPU": "productId",
|
|
||||||
"SKC": "productSkcId",
|
|
||||||
"SKU ID": "productSkuId",
|
|
||||||
"SKU属性": "className",
|
|
||||||
"SKU货号": "skuExtCode",
|
|
||||||
"加入站点时长": "onSalesDurationOffline",
|
|
||||||
"图片链接": "productSkcPicture",
|
|
||||||
"申报价格(CNY)": {
|
|
||||||
"field": "supplierPrice",
|
|
||||||
callback: (value) => {
|
|
||||||
return value /100;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"开款核价状态": {
|
|
||||||
"field": "isVerifyPrice",
|
|
||||||
callback: (value) => {
|
|
||||||
return value ? '核价通过': '核价未通过 / 无法备货';
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"缺货数量": "lackQuantity",
|
|
||||||
"建议备货量": "adviceQuantity",
|
|
||||||
"可售天数": "availableSaleDays",
|
|
||||||
"库存可售天数": "availableSaleDaysFromInventory",
|
|
||||||
"仓内库存可售天数": "warehouseAvailableSaleDays",
|
|
||||||
"近7日用户加购数量": "inCartNumber7d",
|
|
||||||
"用户累计加购数量": "inCardNumber",
|
|
||||||
"已订阅待提醒到货": "nomsgSubsCntCntSth",
|
|
||||||
"销售数据 - 今日": "todaySaleVolume",
|
|
||||||
"销售数据 - 近7日": "lastSevenDaysSaleVolume",
|
|
||||||
"销售数据 - 近30天": "lastThirtyDaysSaleVolume",
|
|
||||||
"库存数据 - 仓内可用库存": "inventoryNumInfo.warehouseInventoryNum",
|
|
||||||
"库存数据 - 仓内暂不可用库存": "inventoryNumInfo.waitOnShelfNum",
|
|
||||||
"库存数据 - 已发货库存": "inventoryNumInfo.waitReceiveNum",
|
|
||||||
"库存数据 - 已下单待发货库存": "inventoryNumInfo.waitDeliveryInventoryNum",
|
|
||||||
"库存数据 - 待审核备货库存": "inventoryNumInfo.waitApproveInventoryNum",
|
|
||||||
"VMI备货单数 - 待发货": "vmiOrderInfo.waitDeliveryNum",
|
|
||||||
"VMI备货单数 - 在途单数": "vmiOrderInfo.transportationNum",
|
|
||||||
"VMI备货单数 - 发货延迟": "vmiOrderInfo.deliveryDelayNum",
|
|
||||||
"VMI备货单数 - 到货延迟": "vmiOrderInfo.arrivalDelayNum",
|
|
||||||
"非VMI备货单数 - 待发货": "notVmiOrderInfo.waitDeliveryNum",
|
|
||||||
"非VMI备货单数 - 在途单数": "notVmiOrderInfo.transportationNum",
|
|
||||||
"非VMI备货单数 - 发货延迟": "notVmiOrderInfo.deliveryDelayNum",
|
|
||||||
"非VMI备货单数 - 到货延迟": "notVmiOrderInfo.arrivalDelayNum",
|
|
||||||
"备货逻辑": "purchaseConfig",
|
|
||||||
"可用库存货值(CNY)": "productTotalPrice",
|
|
||||||
"在途库存货值(CNY)": "inroadTotalPrice",
|
|
||||||
"店铺名称": "mallName",
|
|
||||||
"评分": "mark",
|
|
||||||
"是否热销": 'hotTag',
|
|
||||||
"生产建议信息 - 建议生产数": 'adviceProduceNum',
|
|
||||||
"生产建议信息 - 剩余件数": 'availableProduceNum',
|
|
||||||
"类目": 'category'
|
|
||||||
},
|
|
||||||
|
|
||||||
skuSaleNumberFields: {},
|
skuSaleNumberFields: {},
|
||||||
skuSaleNumberList: [],
|
skuSaleNumberList: [],
|
||||||
@@ -166,134 +108,52 @@ import { Message } from 'element-ui'
|
|||||||
skuDownloadForm: {
|
skuDownloadForm: {
|
||||||
date: ''
|
date: ''
|
||||||
},
|
},
|
||||||
|
costList: []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
|
filteredData() {
|
||||||
|
const filteredData = this.list.filter(item => {
|
||||||
|
if (this.showTodaySale) {
|
||||||
|
return item.todaySale > 0
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
|
||||||
|
return filteredData
|
||||||
|
},
|
||||||
colConfigs () {
|
colConfigs () {
|
||||||
return [
|
return [
|
||||||
{
|
{slot: 'goodsThumb',label: '图片'},
|
||||||
slot: 'goodsThumb',
|
{prop: 'supplierCode',label: '货号',width: '120px',align: 'center',fixed: 'left'},
|
||||||
label: '图片'
|
{prop: 'suffixZh',label: '规格',width: '160px',align: 'center',fixed: 'left'},
|
||||||
},
|
{prop: 'categoryName',label: '分类',"show-overflow-tooltip": true,width: '100px'},
|
||||||
{
|
{prop: 'mallStatusName',label: '状态',width: '120px',align: 'center'},
|
||||||
prop: 'supplierCode',
|
{prop: 'skc',label: 'SKC',width: '160px',align: 'center'},
|
||||||
label: '货号',
|
{prop: 'ableSaleDays',label: '可售天数',align: 'center'},
|
||||||
width: '120px',
|
{prop: 'cost',label: '价格',width: '120px',align: 'center'},
|
||||||
align: 'center',
|
{prop: 'costPrice',label: '成本',width: '120px',align: 'center'},
|
||||||
fixed: 'left'
|
{prop: 'todaySale',label: '今日销量',width: '120px',align: 'center'},
|
||||||
},
|
{prop: 'todayProfit',label: '利润',width: '120px',align: 'center',sortable: true,'sort-method': (a, b) => {
|
||||||
{
|
return a.todayProfit - b.todayProfit
|
||||||
prop: 'suffixZh',
|
}},
|
||||||
label: '规格',
|
{prop: 'saleInfoWeek',label: '近7天销量',width: '120px',align: 'center'},
|
||||||
width: '160px',
|
{prop: 'saleInfoMonth',label: '本月销量',width: '120px',align: 'center'},
|
||||||
align: 'center',
|
{prop: 'saleInfoPreMonth',label: '上月销量',width: '120px',align: 'center'},
|
||||||
fixed: 'left'
|
{prop: 'purchaseConfig',label: '备货逻辑',width: '160px',align: 'center'},
|
||||||
},
|
{prop: 'onWayNum',label: '在途数量',width: '160px',align: 'center'},
|
||||||
{
|
{prop: 'ivtNum',label: '库存数量',width: '160px',align: 'center'},
|
||||||
prop: 'categoryName',
|
{prop: 'productTotalPrice',label: '库存货值(CNY)',width: '180px',align: 'center',fixed: "right",sortable: true,'sort-method': (a, b) => {
|
||||||
label: '分类',
|
|
||||||
"show-overflow-tooltip": true,
|
|
||||||
width: '100px'
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
prop: 'mallStatusName',
|
|
||||||
label: '状态',
|
|
||||||
width: '120px',
|
|
||||||
align: 'center'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: 'skc',
|
|
||||||
label: 'SKC',
|
|
||||||
width: '160px',
|
|
||||||
align: 'center'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: 'ableSaleDays',
|
|
||||||
label: '可售天数',
|
|
||||||
align: 'center'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: 'cost',
|
|
||||||
label: '价格',
|
|
||||||
width: '120px',
|
|
||||||
align: 'center'
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
prop: 'todaySale',
|
|
||||||
label: '今日销量',
|
|
||||||
width: '120px',
|
|
||||||
align: 'center'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: 'saleInfoWeek',
|
|
||||||
label: '近7天销量',
|
|
||||||
width: '120px',
|
|
||||||
align: 'center'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: 'saleInfoMonth',
|
|
||||||
label: '本月销量',
|
|
||||||
width: '120px',
|
|
||||||
align: 'center'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: 'saleInfoPreMonth',
|
|
||||||
label: '上月销量',
|
|
||||||
width: '120px',
|
|
||||||
align: 'center'
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
prop: 'purchaseConfig',
|
|
||||||
label: '备货逻辑',
|
|
||||||
width: '160px',
|
|
||||||
align: 'center'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: 'onWayNum',
|
|
||||||
label: '在途数量',
|
|
||||||
width: '160px',
|
|
||||||
align: 'center'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: 'ivtNum',
|
|
||||||
label: '库存数量',
|
|
||||||
width: '160px',
|
|
||||||
align: 'center'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: 'productTotalPrice',
|
|
||||||
label: '库存货值(CNY)',
|
|
||||||
width: '180px',
|
|
||||||
align: 'center',
|
|
||||||
fixed: "right",
|
|
||||||
sortable: true,
|
|
||||||
'sort-method': (a, b) => {
|
|
||||||
return a.productTotalPrice - b.productTotalPrice
|
return a.productTotalPrice - b.productTotalPrice
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{prop: 'inroadTotalPrice',label: '在途货值(CNY)',width: '180px',align: 'center',fixed: "right",sortable: true,'sort-method': (a, b) => {
|
||||||
prop: 'inroadTotalPrice',
|
|
||||||
label: '在途货值(CNY)',
|
|
||||||
width: '180px',
|
|
||||||
align: 'center',
|
|
||||||
fixed: "right",
|
|
||||||
sortable: true,
|
|
||||||
'sort-method': (a, b) => {
|
|
||||||
return a.inroadTotalPrice - b.inroadTotalPrice
|
return a.inroadTotalPrice - b.inroadTotalPrice
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{prop: 'purchaseConfig',
|
||||||
{
|
label: '备货逻辑',align: 'center',width: '120px',fixed: "right",sortable: true,
|
||||||
prop: 'purchaseConfig',
|
|
||||||
label: '备货逻辑',
|
|
||||||
align: 'center',
|
|
||||||
width: '120px',
|
|
||||||
fixed: "right",
|
|
||||||
sortable: true,
|
|
||||||
'sort-method': (a, b) => {
|
'sort-method': (a, b) => {
|
||||||
if (a.purchaseConfig > b.purchaseConfig) {
|
if (a.purchaseConfig > b.purchaseConfig) {
|
||||||
return 1
|
return 1
|
||||||
@@ -304,8 +164,6 @@ import { Message } from 'element-ui'
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -329,7 +187,20 @@ import { Message } from 'element-ui'
|
|||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
beforeGetList() {
|
async getUserInfo() {
|
||||||
|
let res = await sendGeiwohuoAPIMessage({
|
||||||
|
url: 'sso-prefix/auth/getUser?uuid=' + Date.now(),
|
||||||
|
method: 'GET'
|
||||||
|
})
|
||||||
|
if (res.code == '0' && res.msg == "OK") {
|
||||||
|
this.mallId = res.info.merchantCode
|
||||||
|
} else if (res.code == 100004 || res.code == 20302) {
|
||||||
|
this.isLoading = false
|
||||||
|
this.$store.commit("setSheinAlertShow", true)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async beforeGetList() {
|
||||||
|
await this.getUserInfo()
|
||||||
this.list = []
|
this.list = []
|
||||||
this.currentPage = 1
|
this.currentPage = 1
|
||||||
this.todayMoney = 0.0
|
this.todayMoney = 0.0
|
||||||
@@ -339,6 +210,7 @@ import { Message } from 'element-ui'
|
|||||||
this.inroadTotalMoney = 0.0
|
this.inroadTotalMoney = 0.0
|
||||||
this.inroadTotal = 0
|
this.inroadTotal = 0
|
||||||
|
|
||||||
|
await this.getSkuCostList()
|
||||||
this.isLoading = true
|
this.isLoading = true
|
||||||
this.getList()
|
this.getList()
|
||||||
},
|
},
|
||||||
@@ -368,6 +240,7 @@ import { Message } from 'element-ui'
|
|||||||
data = {...data,
|
data = {...data,
|
||||||
ableSaleDays: sku.ableSaleDays,
|
ableSaleDays: sku.ableSaleDays,
|
||||||
cost: sku.cost,
|
cost: sku.cost,
|
||||||
|
skuCode: sku.skuCode,
|
||||||
purchaseConfig: (sku.operateTime?sku.operateTime:'/') + '+' + (sku.prepareDay?sku.prepareDay:'/'),
|
purchaseConfig: (sku.operateTime?sku.operateTime:'/') + '+' + (sku.prepareDay?sku.prepareDay:'/'),
|
||||||
saleInfoMonth: sku.saleInfoMonth,
|
saleInfoMonth: sku.saleInfoMonth,
|
||||||
saleInfoPreMonth: sku.saleInfoPreMonth,
|
saleInfoPreMonth: sku.saleInfoPreMonth,
|
||||||
@@ -376,18 +249,20 @@ import { Message } from 'element-ui'
|
|||||||
todaySale: sku.todaySale,
|
todaySale: sku.todaySale,
|
||||||
onWayNum: sku.onWayNum,
|
onWayNum: sku.onWayNum,
|
||||||
ivtNum: sku.ivtNum,
|
ivtNum: sku.ivtNum,
|
||||||
productTotalPrice: (sku.cost * sku.ivtNum).toFixed(2),
|
costPrice: null,
|
||||||
inroadTotalPrice: (sku.cost * sku.onWayNum).toFixed(2)}
|
todayProfit: null,
|
||||||
|
productTotalPrice: Math.round((sku.cost * sku.ivtNum)*100)/100,
|
||||||
|
inroadTotalPrice: Math.round((sku.cost * sku.onWayNum)*100)/100}
|
||||||
|
|
||||||
this.todayTotal += sku.todaySale
|
this.todayTotal += sku.todaySale
|
||||||
this.todayMoney += new Number((sku.cost * sku.todaySale).toFixed(2))
|
this.todayMoney += Math.round((sku.cost * sku.todaySale)*100)/100
|
||||||
this.todayMoney = new Number(this.todayMoney.toFixed(2))
|
this.todayMoney = Math.round(this.todayMoney * 100) / 100
|
||||||
this.inventoryTotal += sku.ivtNum
|
this.inventoryTotal += sku.ivtNum
|
||||||
this.inventoryMoney += new Number((sku.cost * sku.ivtNum).toFixed(2))
|
this.inventoryMoney += Math.round((sku.cost * sku.ivtNum)*100)/100
|
||||||
this.inventoryMoney = new Number(this.inventoryMoney.toFixed(2))
|
this.inventoryMoney = Math.round(this.inventoryMoney*100)/100
|
||||||
this.inroadTotal += sku.onWayNum
|
this.inroadTotal += sku.onWayNum
|
||||||
this.inroadTotalMoney += new Number((sku.cost * sku.onWayNum).toFixed(2))
|
this.inroadTotalMoney += Math.round((sku.cost * sku.onWayNum)*100)/100
|
||||||
this.inroadTotalMoney = new Number(this.inroadTotalMoney.toFixed(2))
|
this.inroadTotalMoney = Math.round(this.inroadTotalMoney*100)/100
|
||||||
this.list.push(data);
|
this.list.push(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -398,12 +273,24 @@ import { Message } from 'element-ui'
|
|||||||
this.getList()
|
this.getList()
|
||||||
}, 1500)
|
}, 1500)
|
||||||
} else {
|
} else {
|
||||||
|
for (let i = 0; i < this.list.length; i++) {
|
||||||
|
for (let j = 0; j < this.costList.length; j++) {
|
||||||
|
if (this.list[i].skuCode == this.costList[j].sku) {
|
||||||
|
this.list[i].costPrice = this.costList[j].costPrice
|
||||||
|
this.list[i].todayProfit = Math.round((this.list[i].cost - this.costList[j].costPrice) * this.list[i].todaySale * 100) / 100
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
this.isLoading = false
|
this.isLoading = false
|
||||||
Message.success('销售数据加载完成,可进行导出')
|
Message.success('销售数据加载完成,可进行导出')
|
||||||
this.$nextTick(() => { //在数据加载完,重新渲染表格
|
this.$nextTick(() => { //在数据加载完,重新渲染表格
|
||||||
this.$refs['table0'].doLayout();
|
this.$refs['table0'].doLayout();
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
} else if (res.code == 100004 || res.code == 20302) {
|
||||||
|
this.isLoading = false
|
||||||
|
this.$store.commit("setSheinAlertShow", true)
|
||||||
} else {
|
} else {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.getList()
|
this.getList()
|
||||||
@@ -413,18 +300,16 @@ import { Message } from 'element-ui'
|
|||||||
this.isLoading = false
|
this.isLoading = false
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
startDownload() {
|
async getSkuCostList() {
|
||||||
this.$http.post('/api/malluser/info').then(res => {
|
let res = await this.$http.post(`/api/skuCost/listAll`, null, {
|
||||||
if (res.code == 0) {
|
params: {
|
||||||
this.$store.commit('setUserInfo', res.data)
|
mallId: this.mallId
|
||||||
if (res.data.flag != 1) {
|
|
||||||
Message.error('您的账号未激活或已失效,请激活后使用')
|
|
||||||
this.$store.commit('setActiveDlgShow', true)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
if (res.code == 0) {
|
||||||
|
this.costList = res.data
|
||||||
|
}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
905
src/view/shein/ExportSaleStatShein.vue
Normal file
905
src/view/shein/ExportSaleStatShein.vue
Normal file
@@ -0,0 +1,905 @@
|
|||||||
|
<template>
|
||||||
|
<ai-list class="list" v-loading="isLoading" element-loading-text="拼命加载中" element-loading-spinner="el-icon-loading">
|
||||||
|
<ai-title
|
||||||
|
slot="title"
|
||||||
|
title="商家账单统计"
|
||||||
|
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 HH:mm:ss"
|
||||||
|
value-format="yyyy-MM-dd HH:mm:ss"
|
||||||
|
:default-time="['00:00:00', '23:59:59']">
|
||||||
|
</el-date-picker>
|
||||||
|
</div>
|
||||||
|
<el-button type="button" :class="'el-button el-button--primary'" @click="beginStat">开始统计</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="SKC账单数据.xls"
|
||||||
|
worksheet="SKC账单数据">
|
||||||
|
<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
|
||||||
|
title="销售额/单数"
|
||||||
|
>
|
||||||
|
<template slot="formatter">
|
||||||
|
{{ saleAmount }}/{{ saleCount }}
|
||||||
|
</template>
|
||||||
|
</el-statistic>
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="5">
|
||||||
|
<div>
|
||||||
|
<el-statistic
|
||||||
|
group-separator=","
|
||||||
|
:precision="2"
|
||||||
|
:value="deductionAmount"
|
||||||
|
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="amount" label="销售额">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<div style="color: red">{{ scope.row.amount }}</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="profitPercent" label="利润率">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<div>{{ scope.row.profitPercent + '%' }}</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="amount" label="销售额">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<div>{{ scope.row.amount }}</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="profitPercent" label="利润率">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<div>{{ scope.row.profitPercent + '%' }}</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="topProfitPercentSkcList"
|
||||||
|
:col-configs="skcColConfigs"
|
||||||
|
style="margin-top: 8px;">
|
||||||
|
<el-table-column slot="amount" label="销售额">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<div>{{ scope.row.amount }}</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="profitPercent" label="利润率">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<div style="color: red">{{ scope.row.profitPercent + '%' }}</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="amount" label="销售额">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<div style="color: red">{{ scope.row.amount }}</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="profitPercent" label="利润率">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<div>{{ scope.row.profitPercent + '%' }}</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="amount" label="销售额">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<div>{{ scope.row.amount }}</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="profitPercent" label="利润率">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<div>{{ scope.row.profitPercent + '%' }}</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="topProfitPercentSkuList"
|
||||||
|
:col-configs="skuColConfigs"
|
||||||
|
style="margin-top: 8px;">
|
||||||
|
<el-table-column slot="amount" label="销售额">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<div>{{ scope.row.amount }}</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="profitPercent" label="利润率">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<div style="color: red">{{ scope.row.profitPercent + '%' }}</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</ai-table>
|
||||||
|
</ai-card>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
|
||||||
|
</ai-list>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import {sendGeiwohuoAPIMessage} from '@/api/chromeApi'
|
||||||
|
import JsonExcel from 'vue-json-excel'
|
||||||
|
import { Message } from 'element-ui'
|
||||||
|
import html2canvas from 'html2canvas'
|
||||||
|
import { DualAxes } from '@antv/g2plot'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'ExportSaleStatShein',
|
||||||
|
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
storeCode: '',
|
||||||
|
productList: [],
|
||||||
|
|
||||||
|
dateRange: [],
|
||||||
|
|
||||||
|
page: 1,
|
||||||
|
perPage: 100,
|
||||||
|
orderList: [],
|
||||||
|
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: 'skcCode', label: '货号', width: '180px' },
|
||||||
|
{ slot: 'amount', label: '销售额', align: 'center' },
|
||||||
|
{ prop: 'quantity', label: '单数', align: 'center' },
|
||||||
|
{ prop: 'cost', label: '成本', align: 'center'},
|
||||||
|
{ slot: 'profitAmount', label: '利润', align: 'center' },
|
||||||
|
{ slot: 'profitPercent', label: '利润率', align: 'center'},
|
||||||
|
],
|
||||||
|
skcJsonFields: {
|
||||||
|
"SKC": "skc",
|
||||||
|
"货号": "skcCode",
|
||||||
|
"销售额": "amount",
|
||||||
|
"单数": "quantity",
|
||||||
|
"成本": "cost",
|
||||||
|
"利润": "profitAmount",
|
||||||
|
"利润率": "profitPercent",
|
||||||
|
},
|
||||||
|
skuColConfigs: [
|
||||||
|
{ prop: 'skuCode', label: '属性集', width: '220px' },
|
||||||
|
{ slot: 'amount', label: '销售额', align: 'center' },
|
||||||
|
{ prop: 'quantity', label: '单数', align: 'center' },
|
||||||
|
{ prop: 'cost', label: '成本', align: 'center'},
|
||||||
|
{ slot: 'profitAmount', label: '利润', align: 'center' },
|
||||||
|
{ slot: 'profitPercent', label: '利润率', align: 'center'},
|
||||||
|
],
|
||||||
|
skuJsonFields: {
|
||||||
|
"SKC": "skc",
|
||||||
|
"SKU": "sku",
|
||||||
|
"属性集": "skuCode",
|
||||||
|
"销售额": "amount",
|
||||||
|
"单数": "quantity",
|
||||||
|
"成本": "cost",
|
||||||
|
"利润": "profitAmount",
|
||||||
|
"利润率": "profitPercent",
|
||||||
|
},
|
||||||
|
|
||||||
|
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)
|
||||||
|
},
|
||||||
|
topProfitPercentSkcList() {
|
||||||
|
const list = Object.assign([], this.skcList)
|
||||||
|
list.sort((a, b) => b.profitPercent - a.profitPercent)
|
||||||
|
return list.slice(0, 10)
|
||||||
|
},
|
||||||
|
topSaleAmountSkuList() {
|
||||||
|
const list = Object.assign([], this.skuList)
|
||||||
|
list.sort((a, b) => b.amount - a.amount)
|
||||||
|
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)
|
||||||
|
},
|
||||||
|
topProfitPercentSkuList() {
|
||||||
|
const list = Object.assign([], this.skuList)
|
||||||
|
list.sort((a, b) => b.profitPercent - a.profitPercent)
|
||||||
|
return list.slice(0, 10)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
components: {
|
||||||
|
JsonExcel
|
||||||
|
},
|
||||||
|
mounted () {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.initChart1()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
created () {
|
||||||
|
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.getStoreCode()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
initChart1 () {
|
||||||
|
/*const data = [
|
||||||
|
{ year: '1991', value: 3, count: 11, type: '销售额' },
|
||||||
|
{ year: '1992', value: 4, count: 143, type: '销售额' },
|
||||||
|
{ year: '1993', value: 3.5, count: 143, type: '销售额' },
|
||||||
|
{ year: '1991', value: 5, count: 11, type: '利润' },
|
||||||
|
{ year: '1992', value: 4.9, count: 17, type: '利润' },
|
||||||
|
{ year: '1993', value: 6, count: 143, type: '利润' }
|
||||||
|
]
|
||||||
|
|
||||||
|
const data1 = [
|
||||||
|
{ year: '1991', value1: 30.1, count: 11, type: '利润率' },
|
||||||
|
{ year: '1992', value1: 32.1, count: 143, type: '利润率' },
|
||||||
|
{ year: '1993', value1: 44.1, count: 143, type: '利润率' }
|
||||||
|
]*/
|
||||||
|
|
||||||
|
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();
|
||||||
|
},
|
||||||
|
async beginStat() {
|
||||||
|
if (!this.dateRange) {
|
||||||
|
Message.error("请选择统计时间范围")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.page = 1
|
||||||
|
this.isLoading = true
|
||||||
|
this.saleAmount = 0.0
|
||||||
|
this.saleCount = 0
|
||||||
|
this.costAmount = 0.0
|
||||||
|
this.profitAmount = 0.0
|
||||||
|
this.profitPercent = 0.0
|
||||||
|
this.deductionAmount = 0.0
|
||||||
|
this.orderList = []
|
||||||
|
this.skcList = []
|
||||||
|
this.skuList = []
|
||||||
|
this.leftChartData = []
|
||||||
|
this.rightChartData = []
|
||||||
|
this.chartObj.changeData([this.leftChartData, this.rightChartData])
|
||||||
|
this.getOrderList()
|
||||||
|
},
|
||||||
|
async getStoreCode() {
|
||||||
|
let res = await sendGeiwohuoAPIMessage({
|
||||||
|
url: 'sso-prefix/auth/getUser?uuid=' + Date.now(),
|
||||||
|
method: 'GET'
|
||||||
|
})
|
||||||
|
if (res.code == '0' && res.msg == "OK") {
|
||||||
|
this.storeCode = res.info.merchantCode
|
||||||
|
this.getPorductList()
|
||||||
|
} else if (res.code == 100004 || res.code == 20302) {
|
||||||
|
this.isLoading = false
|
||||||
|
this.$store.commit("setSheinAlertShow", true)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getPorductList() {
|
||||||
|
this.$http.post(`/api/skuCost/listAll`, null, {
|
||||||
|
params: {
|
||||||
|
mallId: this.storeCode
|
||||||
|
}
|
||||||
|
}).then(res => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
this.productList = res.data
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
async getOrderList() {
|
||||||
|
let res = await sendGeiwohuoAPIMessage({
|
||||||
|
url: 'gsfs/finance/reportOrder/dualMode/reportOrderList',
|
||||||
|
method: 'POST',
|
||||||
|
data: {
|
||||||
|
"page": this.page,
|
||||||
|
"perPage": this.perPage,
|
||||||
|
"addTimeStart": this.dateRange[0],
|
||||||
|
"addTimeEnd": this.dateRange[1]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (res.code == '0' && res.msg == "OK") {
|
||||||
|
for (let i = 0; i < res.info.data.length; i++) {
|
||||||
|
this.orderList.push(res.info.data[i])
|
||||||
|
}
|
||||||
|
if (res.info.data.length == this.perPage && (res.info.meta.count > this.perPage*this.page)) {
|
||||||
|
this.page++
|
||||||
|
await this.sleepSync(200)
|
||||||
|
await this.getOrderList()
|
||||||
|
} else {
|
||||||
|
this.page = 1
|
||||||
|
await this.getDetail()
|
||||||
|
// 计算SKC维度利润
|
||||||
|
for (let i = 0; i < this.skcList.length; i++) {
|
||||||
|
this.skcList[i].amount = Math.round(this.skcList[i].amount * 100)/100
|
||||||
|
this.skcList[i].cost = Math.round(this.skcList[i].cost * 100)/100
|
||||||
|
this.skcList[i].profitAmount = Math.round((this.skcList[i].amount - this.skcList[i].cost)*100)/100
|
||||||
|
this.skcList[i].profitPercent = Math.round((this.skcList[i].profitAmount / this.skcList[i].amount)*10000)/100
|
||||||
|
|
||||||
|
this.saleAmount += this.skcList[i].amount
|
||||||
|
this.costAmount += this.skcList[i].cost
|
||||||
|
this.saleCount += this.skcList[i].quantity
|
||||||
|
}
|
||||||
|
this.saleAmount = Math.round(this.saleAmount*100)/100
|
||||||
|
this.profitAmount = this.saleAmount - this.costAmount
|
||||||
|
for (let i = 0; i < this.orderList.length; i++) {
|
||||||
|
let item = this.orderList[i]
|
||||||
|
let saleAmount = 0
|
||||||
|
for (let j = 0; j < item.details.length; j++) {
|
||||||
|
// this.saleAmount -= (item.details[j].deduction.funds ? item.details[j].deduction.funds: 0)
|
||||||
|
this.deductionAmount += (item.details[j].deduction.funds ? item.details[j].deduction.funds: 0)
|
||||||
|
saleAmount += item.details[j].income
|
||||||
|
}
|
||||||
|
this.leftChartData.push({day: item.addTime, value: Math.round(saleAmount*100)/100, type: '销售额'})
|
||||||
|
}
|
||||||
|
this.profitPercent = Math.round((this.profitAmount / this.saleAmount)*10000)/100
|
||||||
|
|
||||||
|
// 计算SKU维度利润
|
||||||
|
for (let i = 0; i < this.skuList.length; i++) {
|
||||||
|
this.skuList[i].amount = Math.round(this.skuList[i].amount * 100)/100
|
||||||
|
this.skuList[i].cost = Math.round(this.skuList[i].cost * 100)/100
|
||||||
|
this.skuList[i].profitAmount = Math.round((this.skuList[i].amount - this.skuList[i].cost)*100)/100
|
||||||
|
this.skuList[i].profitPercent = Math.round(((this.skuList[i].profitAmount / this.skuList[i].amount)*10000))/100
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算每天利润和利润率
|
||||||
|
const tempData = Object.assign([], this.leftChartData)
|
||||||
|
for (let i = 0; i < this.orderList.length; i++) {
|
||||||
|
for (let j = 0; j < tempData.length; j++) {
|
||||||
|
if ((tempData[j].type == '销售额') && (tempData[j].day == this.orderList[i].addTime)) {
|
||||||
|
for (let m = 0; m < tempData.length; m++) {
|
||||||
|
if ((tempData[m].type == '成本') && (tempData[m].day == this.orderList[i].addTime)) {
|
||||||
|
this.leftChartData.push({
|
||||||
|
day: this.orderList[i].addTime,
|
||||||
|
value: Math.round((tempData[j].value - tempData[m].value)*100)/100,
|
||||||
|
type: '利润'
|
||||||
|
})
|
||||||
|
|
||||||
|
this.rightChartData.push({
|
||||||
|
day: this.orderList[i].addTime,
|
||||||
|
value1: Math.round(((tempData[j].value - tempData[m].value)/tempData[j].value)*10000)/100,
|
||||||
|
type: '利润率'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(this.leftChartData)
|
||||||
|
this.chartObj.changeData([this.leftChartData, this.rightChartData])
|
||||||
|
this.isLoading = false
|
||||||
|
}
|
||||||
|
} else if (res.code == 100004 || res.code == 20302) {
|
||||||
|
this.isLoading = false
|
||||||
|
this.$store.commit("setSheinAlertShow", true)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async getDetail() {
|
||||||
|
for (let i = 0; i < this.orderList.length; i++) {
|
||||||
|
let item = this.orderList[i]
|
||||||
|
for (let j = 0; j < item.details.length; j++) {
|
||||||
|
if (item.details[j].sourceSystem == "GSFS") {
|
||||||
|
let currentPage = 1
|
||||||
|
while(true) {
|
||||||
|
await this.sleepSync(200)
|
||||||
|
let res = await sendGeiwohuoAPIMessage({
|
||||||
|
url: 'gsfs/finance/reportOrder/dualMode/checkOrderList/item',
|
||||||
|
method: 'POST',
|
||||||
|
data: {
|
||||||
|
"page": currentPage,
|
||||||
|
"perPage": this.perPage,
|
||||||
|
"reportOrderNo": item.details[j].reportOrderNo,
|
||||||
|
"secondOrderTypes": [1,2,41,42]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (res.code == '0' && res.msg == "OK") {
|
||||||
|
// calc
|
||||||
|
this.calculate(res.info.data, item.addTime)
|
||||||
|
if (res.info.data.length == this.perPage && (res.info.meta.count > this.perPage*currentPage)) {
|
||||||
|
currentPage ++
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
} else if (res.code == 100004 || res.code == 20302) {
|
||||||
|
this.isLoading = false
|
||||||
|
this.$store.commit("setSheinAlertShow", true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (item.details[j].sourceSystem == "PMS") {
|
||||||
|
let currentPage = 1
|
||||||
|
while(true) {
|
||||||
|
await this.sleepSync(200)
|
||||||
|
let res2 = await sendGeiwohuoAPIMessage({
|
||||||
|
url: 'gmpj/finance/incomeAndExpensesDetail',
|
||||||
|
isWWW: true,
|
||||||
|
method: 'POST',
|
||||||
|
data: {
|
||||||
|
"page": currentPage,
|
||||||
|
"perPage": this.perPage,
|
||||||
|
"reportOrderNo": item.details[j].reportOrderNo
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if (res2.code == '0' && res2.msg == "OK") {
|
||||||
|
// calc
|
||||||
|
this.calculate(res2.info.checkDetailList, item.addTime)
|
||||||
|
if (res2.info.checkDetailList.length == this.perPage && (res2.info.count > this.perPage*currentPage)) {
|
||||||
|
currentPage ++
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
calculate(data, addTime) {
|
||||||
|
for (let i = 0; i < data.length; i++) {
|
||||||
|
let exist = false
|
||||||
|
let cost = this.getCost(data[i].skuCode) * (data[i].goodsCount || data[i].quantity)
|
||||||
|
|
||||||
|
// 按SKC维度统计
|
||||||
|
for (let j = 0; j < this.skcList.length; j++) {
|
||||||
|
if (this.skcList[j].skc == (data[i].skc || data[i].skcName)) {
|
||||||
|
exist = true
|
||||||
|
if (data[i].incomeAndExpensesTypeName == '支出' || data[i].inAndOutName == '支出') {
|
||||||
|
this.skcList[j].amount -= data[i].amount || data[i].income
|
||||||
|
} else if (data[i].incomeAndExpensesTypeName == '收入' || data[i].inAndOutName == '收入') {
|
||||||
|
this.skcList[j].quantity += data[i].goodsCount || data[i].quantity
|
||||||
|
this.skcList[j].amount += data[i].amount || data[i].income
|
||||||
|
this.skcList[j].cost += cost
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!exist) {
|
||||||
|
if (data[i].incomeAndExpensesTypeName == '支出' || data[i].inAndOutName == '支出') {
|
||||||
|
this.skcList.push({
|
||||||
|
skc: (data[i].skc || data[i].skcName),
|
||||||
|
skcCode: (data[i].goodsSn || data[i].supplierCode),
|
||||||
|
amount: -(data[i].amount || data[i].income),
|
||||||
|
quantity: 0,
|
||||||
|
cost: 0,
|
||||||
|
profitPercent: 0.0,
|
||||||
|
profitAmount: 0.0
|
||||||
|
})
|
||||||
|
} else if (data[i].incomeAndExpensesTypeName == '收入' || data[i].inAndOutName == '收入') {
|
||||||
|
this.skcList.push({
|
||||||
|
skc: (data[i].skc || data[i].skcName),
|
||||||
|
skcCode: (data[i].goodsSn || data[i].supplierCode),
|
||||||
|
amount: data[i].amount || data[i].income,
|
||||||
|
quantity: data[i].goodsCount || data[i].quantity,
|
||||||
|
cost: cost,
|
||||||
|
profitPercent: 0.0,
|
||||||
|
profitAmount: 0.0
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 按SKU维度统计
|
||||||
|
exist = false
|
||||||
|
for (let j = 0; j < this.skuList.length; j++) {
|
||||||
|
if (this.skuList[j].sku == data[i].skuCode) {
|
||||||
|
exist = true
|
||||||
|
if (data[i].incomeAndExpensesTypeName == '支出' || data[i].inAndOutName == '支出') {
|
||||||
|
this.skuList[j].amount -= data[i].amount || data[i].income
|
||||||
|
} else if (data[i].incomeAndExpensesTypeName == '收入' || data[i].inAndOutName == '收入') {
|
||||||
|
this.skuList[j].quantity += data[i].goodsCount || data[i].quantity
|
||||||
|
this.skuList[j].amount += data[i].amount || data[i].income
|
||||||
|
this.skuList[j].cost += cost
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!exist) {
|
||||||
|
if (data[i].incomeAndExpensesTypeName == '支出' || data[i].inAndOutName == '支出') {
|
||||||
|
this.skuList.push({
|
||||||
|
skc: (data[i].skc || data[i].skcName),
|
||||||
|
sku: data[i].skuCode,
|
||||||
|
skuCode: (data[i].goodsSn || data[i].supplierCode) + '/' + (data[i].suffix || data[i].suffixZh),
|
||||||
|
amount: -(data[i].amount || data[i].income),
|
||||||
|
quantity: 0,
|
||||||
|
cost: 0,
|
||||||
|
profitPercent: 0.0,
|
||||||
|
profitAmount: 0.0
|
||||||
|
})
|
||||||
|
} else if (data[i].incomeAndExpensesTypeName == '收入' || data[i].inAndOutName == '收入') {
|
||||||
|
this.skuList.push({
|
||||||
|
skc: (data[i].skc || data[i].skcName),
|
||||||
|
sku: data[i].skuCode,
|
||||||
|
skuCode: (data[i].goodsSn || data[i].supplierCode) + '/' + (data[i].suffix || data[i].suffixZh),
|
||||||
|
amount: data[i].amount || data[i].income,
|
||||||
|
quantity: data[i].goodsCount || data[i].quantity,
|
||||||
|
cost: cost,
|
||||||
|
profitPercent: 0.0,
|
||||||
|
profitAmount: 0.0
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算每天的成本
|
||||||
|
exist = false
|
||||||
|
for (let x = 0; x < this.leftChartData.length; x++) {
|
||||||
|
if ((this.leftChartData[x].day == addTime) && (this.leftChartData[x].type == '成本')) {
|
||||||
|
exist = true
|
||||||
|
if (data[i].incomeAndExpensesTypeName == '收入' || data[i].inAndOutName == '收入') {
|
||||||
|
this.leftChartData[x].value = Math.round((this.leftChartData[x].value + cost)*100)/100
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!exist) {
|
||||||
|
if (data[i].incomeAndExpensesTypeName == '收入' || data[i].inAndOutName == '收入') {
|
||||||
|
this.leftChartData.push({
|
||||||
|
day: addTime,
|
||||||
|
type: '成本',
|
||||||
|
value: cost
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算每天的单数
|
||||||
|
exist = false
|
||||||
|
for (let x = 0; x < this.leftChartData.length; x++) {
|
||||||
|
if ((this.leftChartData[x].day == addTime) && (this.leftChartData[x].type == '单数')) {
|
||||||
|
exist = true
|
||||||
|
if (data[i].incomeAndExpensesTypeName == '收入' || data[i].inAndOutName == '收入') {
|
||||||
|
this.leftChartData[x].value += (data[i].goodsCount || data[i].quantity)
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!exist) {
|
||||||
|
if (data[i].incomeAndExpensesTypeName == '收入' || data[i].inAndOutName == '收入') {
|
||||||
|
this.leftChartData.push({
|
||||||
|
day: addTime,
|
||||||
|
type: '单数',
|
||||||
|
value: (data[i].goodsCount || data[i].quantity)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getCost(sku) {
|
||||||
|
for (let i = 0; i < this.productList.length; i++) {
|
||||||
|
if (sku == this.productList[i].sku) {
|
||||||
|
return this.productList[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 = '账单统计(希音).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>
|
||||||
@@ -19,8 +19,7 @@
|
|||||||
<!--<el-button type="primary" :disabled="isBegin" @click="isShow = true">添加备货单</el-button>
|
<!--<el-button type="primary" :disabled="isBegin" @click="isShow = true">添加备货单</el-button>
|
||||||
<el-button type="primary" :disabled="isBegin" @click="loadAll">一键加载全部</el-button>-->
|
<el-button type="primary" :disabled="isBegin" @click="loadAll">一键加载全部</el-button>-->
|
||||||
</el-dropdown>
|
</el-dropdown>
|
||||||
<el-button v-if="!isBegin" type="button" :class="'el-button el-button--primary'" @click="beginCreate">开始创建</el-button>
|
<el-button type="button" :class="'el-button el-button--primary'" @click="beginCreate">开始创建</el-button>
|
||||||
<el-button v-else type="button" :icon="isBegin? 'el-icon-loading': ''" :class="isBegin ? 'el-button el-button--danger': 'el-button el-button--primary'" @click="beginCreate()">{{ `结束创建(${choosedList.length}/${createTotal})` }}</el-button>
|
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
</ai-search-bar>
|
</ai-search-bar>
|
||||||
@@ -225,12 +224,10 @@
|
|||||||
Message.error("请选择待创建备货单")
|
Message.error("请选择待创建备货单")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
console.log(this.arr)
|
|
||||||
this.arr.map(item => {
|
this.arr.map(item => {
|
||||||
let temp = this.choosedList.filter(i => {
|
let temp = this.choosedList.filter(i => {
|
||||||
return i.subPurchaseOrderSn == item.subPurchaseOrderSn
|
return i.subPurchaseOrderSn == item.subPurchaseOrderSn
|
||||||
})
|
})
|
||||||
console.log(temp)
|
|
||||||
if (temp.length == 0) {
|
if (temp.length == 0) {
|
||||||
this.choosedList.push(item)
|
this.choosedList.push(item)
|
||||||
console.log(this.choosedList)
|
console.log(this.choosedList)
|
||||||
@@ -261,20 +258,12 @@
|
|||||||
this.loadAll()
|
this.loadAll()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
beginCreateConfirm() {
|
beforeBegin() {
|
||||||
if (this.choosedList.length <= 0) {
|
if (this.choosedList.length <= 0) {
|
||||||
Message.error('请先添加备货单');
|
Message.error('请先添加备货单');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.createDlgShow = true
|
this.beginCreate()
|
||||||
},
|
|
||||||
beforeBegin() {
|
|
||||||
this.$refs.robForm.validate((valid) => {
|
|
||||||
if (valid) {
|
|
||||||
this.createDlgShow = false
|
|
||||||
this.beginCreate()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
getList (data, mallId, mallName, currentPage) {
|
getList (data, mallId, mallName, currentPage) {
|
||||||
sendChromeAPIMessage({
|
sendChromeAPIMessage({
|
||||||
@@ -334,74 +323,43 @@
|
|||||||
getStyle(url) {
|
getStyle(url) {
|
||||||
return "background-image: url(" + url + "); width: 72px; height: 72px; cursor: pointer; border-radius: 6px; border: 1px solid rgba(0, 0, 0, 0.14);";
|
return "background-image: url(" + url + "); width: 72px; height: 72px; cursor: pointer; border-radius: 6px; border: 1px solid rgba(0, 0, 0, 0.14);";
|
||||||
},
|
},
|
||||||
beginCreate() {
|
async beginCreate() {
|
||||||
if (this.isBegin) {
|
let waitCreateList = []
|
||||||
this.isBegin = false;
|
for (let i = 0; i < this.mallList.length; i++) {
|
||||||
return;
|
let subPurchaseOrderSnList = []
|
||||||
|
this.choosedList.map(item => {
|
||||||
|
if (item.mallId == this.mallList[i].mallId) {
|
||||||
|
subPurchaseOrderSnList.push(item.subPurchaseOrderSn)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (subPurchaseOrderSnList.length > 0) {
|
||||||
|
waitCreateList.push({
|
||||||
|
mallId: this.mallList[i].mallId,
|
||||||
|
subPurchaseOrderSnList: subPurchaseOrderSnList
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.createTotal = this.choosedList.length
|
for (let j = 0; j < waitCreateList.length; j++) {
|
||||||
this.isBegin = true;
|
let res = await sendChromeAPIMessage({
|
||||||
|
url: 'oms/bg/venom/api/supplier/purchase/manager/batchAcceptSubPurchaseOrder',
|
||||||
|
needMallId: true,
|
||||||
|
anti: true,
|
||||||
|
mallId: waitCreateList[j].mallId,
|
||||||
|
data: {
|
||||||
|
subPurchaseOrderSnList: waitCreateList[j].subPurchaseOrderSnList,
|
||||||
|
confirmFulfilment: false
|
||||||
|
}})
|
||||||
|
|
||||||
this.choosedList.map((data, index) => {
|
if (res.success && res.errorCode == 1000000) {
|
||||||
let deliverOrderDetailInfos = data.skuQuantityDetailList.map(item => {
|
if (res.result.isSuccess) {
|
||||||
if (this.robForm.isModifyMaxNum) {
|
for (let n = 0; n < waitCreateList[j].subPurchaseOrderSnList.length; n++) {
|
||||||
return {
|
this.remove(waitCreateList[j].subPurchaseOrderSnList[n])
|
||||||
productSkuId: item.productSkuId,
|
}
|
||||||
deliverSkuNum: item.skuDeliveryQuantityMaxLimit
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return {
|
|
||||||
productSkuId: item.productSkuId,
|
|
||||||
deliverSkuNum: item.productSkuPurchaseQuantity
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
let packageInfos = []
|
|
||||||
data.orderDetailVOList.map(item => {
|
|
||||||
let packageDetailSaveInfos = []
|
|
||||||
if (this.robForm.isModifyMaxNum) {
|
|
||||||
packageDetailSaveInfos.push({
|
|
||||||
productSkuId: item.productSkuId,
|
|
||||||
skuNum: item.skuDeliveryQuantityMaxLimit
|
|
||||||
})
|
|
||||||
|
|
||||||
} else {
|
|
||||||
packageDetailSaveInfos.push({
|
|
||||||
productSkuId: item.productSkuId,
|
|
||||||
skuNum: item.productSkuPurchaseQuantity
|
|
||||||
})
|
|
||||||
}
|
|
||||||
packageInfos.push({packageDetailSaveInfos: packageDetailSaveInfos})
|
|
||||||
})
|
|
||||||
|
|
||||||
let addressInfo = this.addressList.filter(k => {
|
|
||||||
return k.mallId == data.mallId
|
|
||||||
})
|
|
||||||
|
|
||||||
let deliveryOrderCreateInfos = []
|
|
||||||
deliveryOrderCreateInfos.push({
|
|
||||||
deliverOrderDetailInfos: deliverOrderDetailInfos,
|
|
||||||
subPurchaseOrderSn: data.subPurchaseOrderSn,
|
|
||||||
deliveryAddressId: addressInfo[0].addressId,
|
|
||||||
packageInfos: packageInfos
|
|
||||||
})
|
|
||||||
|
|
||||||
let deliveryOrderCreateGroupList = []
|
|
||||||
deliveryOrderCreateGroupList.push({
|
|
||||||
deliveryOrderCreateInfos: deliveryOrderCreateInfos,
|
|
||||||
receiveAddressInfo: data.receiveAddressInfo,
|
|
||||||
subWarehouseId: data.subWarehouseId
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
let _this = this;
|
|
||||||
let tt = setInterval(function() {
|
|
||||||
if (_this.choosedList.length == 0) {
|
|
||||||
_this.isBegin = false;
|
|
||||||
clearInterval(tt);
|
|
||||||
}
|
|
||||||
}, 1000)
|
|
||||||
},
|
},
|
||||||
formatTime(time) {
|
formatTime(time) {
|
||||||
return timestampToTime(time)
|
return timestampToTime(time)
|
||||||
|
|||||||
97
yarn.lock
97
yarn.lock
@@ -2054,6 +2054,11 @@ address@^1.1.2:
|
|||||||
resolved "https://registry.npmmirror.com/address/-/address-1.2.2.tgz"
|
resolved "https://registry.npmmirror.com/address/-/address-1.2.2.tgz"
|
||||||
integrity sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==
|
integrity sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==
|
||||||
|
|
||||||
|
adler-32@~1.3.0:
|
||||||
|
version "1.3.1"
|
||||||
|
resolved "https://registry.npmmirror.com/adler-32/-/adler-32-1.3.1.tgz#1dbf0b36dda0012189a32b3679061932df1821e2"
|
||||||
|
integrity sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A==
|
||||||
|
|
||||||
aggregate-error@^3.0.0:
|
aggregate-error@^3.0.0:
|
||||||
version "3.1.0"
|
version "3.1.0"
|
||||||
resolved "https://registry.npmmirror.com/aggregate-error/-/aggregate-error-3.1.0.tgz"
|
resolved "https://registry.npmmirror.com/aggregate-error/-/aggregate-error-3.1.0.tgz"
|
||||||
@@ -2358,6 +2363,11 @@ balanced-match@^1.0.0:
|
|||||||
resolved "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz"
|
resolved "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz"
|
||||||
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
|
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
|
||||||
|
|
||||||
|
base64-arraybuffer@^1.0.2:
|
||||||
|
version "1.0.2"
|
||||||
|
resolved "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz"
|
||||||
|
integrity sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==
|
||||||
|
|
||||||
base64-js@^1.3.1:
|
base64-js@^1.3.1:
|
||||||
version "1.5.1"
|
version "1.5.1"
|
||||||
resolved "https://registry.npmmirror.com/base64-js/-/base64-js-1.5.1.tgz"
|
resolved "https://registry.npmmirror.com/base64-js/-/base64-js-1.5.1.tgz"
|
||||||
@@ -2568,6 +2578,14 @@ center-align@^0.1.1:
|
|||||||
align-text "^0.1.3"
|
align-text "^0.1.3"
|
||||||
lazy-cache "^1.0.3"
|
lazy-cache "^1.0.3"
|
||||||
|
|
||||||
|
cfb@~1.2.1:
|
||||||
|
version "1.2.2"
|
||||||
|
resolved "https://registry.npmmirror.com/cfb/-/cfb-1.2.2.tgz#94e687628c700e5155436dac05f74e08df23bc44"
|
||||||
|
integrity sha512-KfdUZsSOw19/ObEWasvBP/Ac4reZvAGauZhs6S/gqNhXhI7cKwvlH7ulj+dOEYnca4bm4SGo8C1bTAQvnTjgQA==
|
||||||
|
dependencies:
|
||||||
|
adler-32 "~1.3.0"
|
||||||
|
crc-32 "~1.2.0"
|
||||||
|
|
||||||
chalk@4.1.0:
|
chalk@4.1.0:
|
||||||
version "4.1.0"
|
version "4.1.0"
|
||||||
resolved "https://registry.npmmirror.com/chalk/-/chalk-4.1.0.tgz"
|
resolved "https://registry.npmmirror.com/chalk/-/chalk-4.1.0.tgz"
|
||||||
@@ -2751,6 +2769,11 @@ clone@^1.0.2:
|
|||||||
resolved "https://registry.npmmirror.com/clone/-/clone-1.0.4.tgz"
|
resolved "https://registry.npmmirror.com/clone/-/clone-1.0.4.tgz"
|
||||||
integrity sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==
|
integrity sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==
|
||||||
|
|
||||||
|
codepage@~1.15.0:
|
||||||
|
version "1.15.0"
|
||||||
|
resolved "https://registry.npmmirror.com/codepage/-/codepage-1.15.0.tgz#2e00519024b39424ec66eeb3ec07227e692618ab"
|
||||||
|
integrity sha512-3g6NUTPd/YtuuGrhMnOMRjFc+LJw/bnMp3+0r/Wcz3IXUuCosKRJvMphm5+Q+bvTVGcJJuRvVLuYba+WojaFaA==
|
||||||
|
|
||||||
color-convert@^1.9.0:
|
color-convert@^1.9.0:
|
||||||
version "1.9.3"
|
version "1.9.3"
|
||||||
resolved "https://registry.npmmirror.com/color-convert/-/color-convert-1.9.3.tgz"
|
resolved "https://registry.npmmirror.com/color-convert/-/color-convert-1.9.3.tgz"
|
||||||
@@ -2953,6 +2976,11 @@ cosmiconfig@^7.0.0:
|
|||||||
path-type "^4.0.0"
|
path-type "^4.0.0"
|
||||||
yaml "^1.10.0"
|
yaml "^1.10.0"
|
||||||
|
|
||||||
|
crc-32@~1.2.0, crc-32@~1.2.1:
|
||||||
|
version "1.2.2"
|
||||||
|
resolved "https://registry.npmmirror.com/crc-32/-/crc-32-1.2.2.tgz#3cad35a934b8bf71f25ca524b6da51fb7eace2ff"
|
||||||
|
integrity sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==
|
||||||
|
|
||||||
cross-spawn@^5.0.1:
|
cross-spawn@^5.0.1:
|
||||||
version "5.1.0"
|
version "5.1.0"
|
||||||
resolved "https://registry.npmmirror.com/cross-spawn/-/cross-spawn-5.1.0.tgz"
|
resolved "https://registry.npmmirror.com/cross-spawn/-/cross-spawn-5.1.0.tgz"
|
||||||
@@ -2997,6 +3025,13 @@ css-declaration-sorter@^6.3.1:
|
|||||||
resolved "https://registry.npmmirror.com/css-declaration-sorter/-/css-declaration-sorter-6.4.1.tgz"
|
resolved "https://registry.npmmirror.com/css-declaration-sorter/-/css-declaration-sorter-6.4.1.tgz"
|
||||||
integrity sha512-rtdthzxKuyq6IzqX6jEcIzQF/YqccluefyCYheovBOLhFT/drQA9zj/UbRAa9J7C0o6EG6u3E6g+vKkay7/k3g==
|
integrity sha512-rtdthzxKuyq6IzqX6jEcIzQF/YqccluefyCYheovBOLhFT/drQA9zj/UbRAa9J7C0o6EG6u3E6g+vKkay7/k3g==
|
||||||
|
|
||||||
|
css-line-break@^2.1.0:
|
||||||
|
version "2.1.0"
|
||||||
|
resolved "https://registry.npmjs.org/css-line-break/-/css-line-break-2.1.0.tgz"
|
||||||
|
integrity sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==
|
||||||
|
dependencies:
|
||||||
|
utrie "^1.0.2"
|
||||||
|
|
||||||
css-loader@^6.5.0:
|
css-loader@^6.5.0:
|
||||||
version "6.8.1"
|
version "6.8.1"
|
||||||
resolved "https://registry.npmmirror.com/css-loader/-/css-loader-6.8.1.tgz"
|
resolved "https://registry.npmmirror.com/css-loader/-/css-loader-6.8.1.tgz"
|
||||||
@@ -3897,6 +3932,11 @@ file-entry-cache@^6.0.1:
|
|||||||
dependencies:
|
dependencies:
|
||||||
flat-cache "^3.0.4"
|
flat-cache "^3.0.4"
|
||||||
|
|
||||||
|
file-saver@^2.0.5:
|
||||||
|
version "2.0.5"
|
||||||
|
resolved "https://registry.npmmirror.com/file-saver/-/file-saver-2.0.5.tgz#d61cfe2ce059f414d899e9dd6d4107ee25670c38"
|
||||||
|
integrity sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA==
|
||||||
|
|
||||||
fill-range@^7.0.1:
|
fill-range@^7.0.1:
|
||||||
version "7.0.1"
|
version "7.0.1"
|
||||||
resolved "https://registry.npmmirror.com/fill-range/-/fill-range-7.0.1.tgz"
|
resolved "https://registry.npmmirror.com/fill-range/-/fill-range-7.0.1.tgz"
|
||||||
@@ -3989,6 +4029,11 @@ forwarded@0.2.0:
|
|||||||
resolved "https://registry.npmmirror.com/forwarded/-/forwarded-0.2.0.tgz"
|
resolved "https://registry.npmmirror.com/forwarded/-/forwarded-0.2.0.tgz"
|
||||||
integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==
|
integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==
|
||||||
|
|
||||||
|
frac@~1.1.2:
|
||||||
|
version "1.1.2"
|
||||||
|
resolved "https://registry.npmmirror.com/frac/-/frac-1.1.2.tgz#3d74f7f6478c88a1b5020306d747dc6313c74d0b"
|
||||||
|
integrity sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA==
|
||||||
|
|
||||||
fraction.js@^4.2.0:
|
fraction.js@^4.2.0:
|
||||||
version "4.2.0"
|
version "4.2.0"
|
||||||
resolved "https://registry.npmmirror.com/fraction.js/-/fraction.js-4.2.0.tgz"
|
resolved "https://registry.npmmirror.com/fraction.js/-/fraction.js-4.2.0.tgz"
|
||||||
@@ -4335,6 +4380,14 @@ html-webpack-plugin@^5.1.0:
|
|||||||
pretty-error "^4.0.0"
|
pretty-error "^4.0.0"
|
||||||
tapable "^2.0.0"
|
tapable "^2.0.0"
|
||||||
|
|
||||||
|
html2canvas@^1.4.1:
|
||||||
|
version "1.4.1"
|
||||||
|
resolved "https://registry.npmjs.org/html2canvas/-/html2canvas-1.4.1.tgz"
|
||||||
|
integrity sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==
|
||||||
|
dependencies:
|
||||||
|
css-line-break "^2.1.0"
|
||||||
|
text-segmentation "^1.0.3"
|
||||||
|
|
||||||
htmlparser2@^6.1.0:
|
htmlparser2@^6.1.0:
|
||||||
version "6.1.0"
|
version "6.1.0"
|
||||||
resolved "https://registry.npmmirror.com/htmlparser2/-/htmlparser2-6.1.0.tgz"
|
resolved "https://registry.npmmirror.com/htmlparser2/-/htmlparser2-6.1.0.tgz"
|
||||||
@@ -6788,6 +6841,13 @@ sprintf-js@~1.0.2:
|
|||||||
resolved "https://registry.npmmirror.com/sprintf-js/-/sprintf-js-1.0.3.tgz"
|
resolved "https://registry.npmmirror.com/sprintf-js/-/sprintf-js-1.0.3.tgz"
|
||||||
integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==
|
integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==
|
||||||
|
|
||||||
|
ssf@~0.11.2:
|
||||||
|
version "0.11.2"
|
||||||
|
resolved "https://registry.npmmirror.com/ssf/-/ssf-0.11.2.tgz#0b99698b237548d088fc43cdf2b70c1a7512c06c"
|
||||||
|
integrity sha512-+idbmIXoYET47hH+d7dfm2epdOMUDjqcB4648sTZ+t2JwoyBFL/insLfB/racrDmsKB3diwsDA696pZMieAC5g==
|
||||||
|
dependencies:
|
||||||
|
frac "~1.1.2"
|
||||||
|
|
||||||
ssri@^8.0.1:
|
ssri@^8.0.1:
|
||||||
version "8.0.1"
|
version "8.0.1"
|
||||||
resolved "https://registry.npmmirror.com/ssri/-/ssri-8.0.1.tgz"
|
resolved "https://registry.npmmirror.com/ssri/-/ssri-8.0.1.tgz"
|
||||||
@@ -7060,6 +7120,13 @@ terser@^5.10.0, terser@^5.16.8:
|
|||||||
commander "^2.20.0"
|
commander "^2.20.0"
|
||||||
source-map-support "~0.5.20"
|
source-map-support "~0.5.20"
|
||||||
|
|
||||||
|
text-segmentation@^1.0.3:
|
||||||
|
version "1.0.3"
|
||||||
|
resolved "https://registry.npmjs.org/text-segmentation/-/text-segmentation-1.0.3.tgz"
|
||||||
|
integrity sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==
|
||||||
|
dependencies:
|
||||||
|
utrie "^1.0.2"
|
||||||
|
|
||||||
text-table@^0.2.0:
|
text-table@^0.2.0:
|
||||||
version "0.2.0"
|
version "0.2.0"
|
||||||
resolved "https://registry.npmmirror.com/text-table/-/text-table-0.2.0.tgz"
|
resolved "https://registry.npmmirror.com/text-table/-/text-table-0.2.0.tgz"
|
||||||
@@ -7341,6 +7408,13 @@ utils-merge@1.0.1:
|
|||||||
resolved "https://registry.npmmirror.com/utils-merge/-/utils-merge-1.0.1.tgz"
|
resolved "https://registry.npmmirror.com/utils-merge/-/utils-merge-1.0.1.tgz"
|
||||||
integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==
|
integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==
|
||||||
|
|
||||||
|
utrie@^1.0.2:
|
||||||
|
version "1.0.2"
|
||||||
|
resolved "https://registry.npmjs.org/utrie/-/utrie-1.0.2.tgz"
|
||||||
|
integrity sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==
|
||||||
|
dependencies:
|
||||||
|
base64-arraybuffer "^1.0.2"
|
||||||
|
|
||||||
uuid@^8.3.2:
|
uuid@^8.3.2:
|
||||||
version "8.3.2"
|
version "8.3.2"
|
||||||
resolved "https://registry.npmmirror.com/uuid/-/uuid-8.3.2.tgz"
|
resolved "https://registry.npmmirror.com/uuid/-/uuid-8.3.2.tgz"
|
||||||
@@ -7722,11 +7796,21 @@ window-size@0.1.0:
|
|||||||
resolved "https://registry.npmmirror.com/window-size/-/window-size-0.1.0.tgz"
|
resolved "https://registry.npmmirror.com/window-size/-/window-size-0.1.0.tgz"
|
||||||
integrity sha512-1pTPQDKTdd61ozlKGNCjhNRd+KPmgLSGa3mZTHoOliaGcESD8G1PXhh7c1fgiPjVbNVfgy2Faw4BI8/m0cC8Mg==
|
integrity sha512-1pTPQDKTdd61ozlKGNCjhNRd+KPmgLSGa3mZTHoOliaGcESD8G1PXhh7c1fgiPjVbNVfgy2Faw4BI8/m0cC8Mg==
|
||||||
|
|
||||||
|
wmf@~1.0.1:
|
||||||
|
version "1.0.2"
|
||||||
|
resolved "https://registry.npmmirror.com/wmf/-/wmf-1.0.2.tgz#7d19d621071a08c2bdc6b7e688a9c435298cc2da"
|
||||||
|
integrity sha512-/p9K7bEh0Dj6WbXg4JG0xvLQmIadrner1bi45VMJTfnbVHsc7yIajZyoSoK60/dtVBs12Fm6WkUI5/3WAVsNMw==
|
||||||
|
|
||||||
word-wrap@~1.2.3:
|
word-wrap@~1.2.3:
|
||||||
version "1.2.5"
|
version "1.2.5"
|
||||||
resolved "https://registry.npmmirror.com/word-wrap/-/word-wrap-1.2.5.tgz"
|
resolved "https://registry.npmmirror.com/word-wrap/-/word-wrap-1.2.5.tgz"
|
||||||
integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==
|
integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==
|
||||||
|
|
||||||
|
word@~0.3.0:
|
||||||
|
version "0.3.0"
|
||||||
|
resolved "https://registry.npmmirror.com/word/-/word-0.3.0.tgz#8542157e4f8e849f4a363a288992d47612db9961"
|
||||||
|
integrity sha512-OELeY0Q61OXpdUfTp+oweA/vtLVg5VDOXh+3he3PNzLGG/y0oylSOC1xRVj0+l4vQ3tj/bB1HVHv1ocXkQceFA==
|
||||||
|
|
||||||
wordwrap@0.0.2:
|
wordwrap@0.0.2:
|
||||||
version "0.0.2"
|
version "0.0.2"
|
||||||
resolved "https://registry.npmmirror.com/wordwrap/-/wordwrap-0.0.2.tgz"
|
resolved "https://registry.npmmirror.com/wordwrap/-/wordwrap-0.0.2.tgz"
|
||||||
@@ -7764,6 +7848,19 @@ ws@^8.13.0:
|
|||||||
resolved "https://registry.npmmirror.com/ws/-/ws-8.13.0.tgz"
|
resolved "https://registry.npmmirror.com/ws/-/ws-8.13.0.tgz"
|
||||||
integrity sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==
|
integrity sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==
|
||||||
|
|
||||||
|
xlsx@^0.18.5:
|
||||||
|
version "0.18.5"
|
||||||
|
resolved "https://registry.npmmirror.com/xlsx/-/xlsx-0.18.5.tgz#16711b9113c848076b8a177022799ad356eba7d0"
|
||||||
|
integrity sha512-dmg3LCjBPHZnQp5/F/+nnTa+miPJxUXB6vtk42YjBBKayDNagxGEeIdWApkYPOf3Z3pm3k62Knjzp7lMeTEtFQ==
|
||||||
|
dependencies:
|
||||||
|
adler-32 "~1.3.0"
|
||||||
|
cfb "~1.2.1"
|
||||||
|
codepage "~1.15.0"
|
||||||
|
crc-32 "~1.2.1"
|
||||||
|
ssf "~0.11.2"
|
||||||
|
wmf "~1.0.1"
|
||||||
|
word "~0.3.0"
|
||||||
|
|
||||||
y18n@^5.0.5:
|
y18n@^5.0.5:
|
||||||
version "5.0.8"
|
version "5.0.8"
|
||||||
resolved "https://registry.npmmirror.com/y18n/-/y18n-5.0.8.tgz"
|
resolved "https://registry.npmmirror.com/y18n/-/y18n-5.0.8.tgz"
|
||||||
|
|||||||
Reference in New Issue
Block a user