// ==UserScript==
// @name 上架助手2024-油猴插件
// @namespace http://tampermonkey.net/
// @version 2024-12-12_01
// @description 上架助手2024
// @license MIT
// @author Beerspume
// @match https://*.soluxemall.com/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=benefits.soluxemall.com
// @grant GM_addElement
// @grant GM_log
// @grant GM_setClipboard
// @grant GM_download
// @grant GM_xmlhttpRequest
// @connect *
// ==/UserScript==
(function() {
'use strict';
//取得易采网站后台请求的授权信息
function getAuthorization(){
//从localStorage中取得授权信息
const json_jdcloud=localStorage.getItem("jdcloud");
let Authorization=undefined;
if(json_jdcloud){
try{
const jdcloud=JSON.parse(json_jdcloud);
Authorization=jdcloud.token;
//console.log(`Authorization: ${Authorization}`);
}catch(e){
console.log("jdcloud解析失败,请查看localStorage中的jdcloud是否正确");
}
}
return Authorization;
}
//复制内容到剪贴板
function copyToClipboard(text) {
navigator.clipboard.writeText(text)
.then(function() {
console.log('Text copied to clipboard');
})
.catch(function(err) {
console.error('Failed to copy text: ', err);
});
}
//将秒转化为小时
const fn_formatSeconds=(seconds)=>{
if(seconds===Infinity){
return "";
}else{
return `${Math.floor(seconds/3600)}小时${Math.floor(seconds%3600/60)}分钟${Math.floor(seconds%3600%60)}秒`;
}
};
function sleep(seconds){
return new Promise((resolve,reject)=>{
window.setTimeout(()=>{
resolve();
},seconds*1000);
});
}
const TimeSample=[];
const fn_timeSample=()=>{
TimeSample.push(new Date().getTime());
while(TimeSample.lenth>11){
TimeSample.shift();
}
let average=Infinity;
if(TimeSample.length>0){
average=(Math.max(...TimeSample)-Math.min(...TimeSample))/TimeSample.length/1000;
}
return average;
};
// 访问后台服务的统一接口
const api=(api_name,data)=>{
return new Promise((resolve,reject)=>{
GM_xmlhttpRequest({
url:"http://43.143.136.44/hysm/api/api.asp",
method:'POST',
responseType:"json",
headers:{i:api_name,"Content-Type":"application/x-www-form-urlencoded"},
data:ObjToParams(data),
onload:(event)=>{
if(event.status==200){
if(event.response.success){
resolve(event.response.data);
}else{
reject(event.response);
}
}else{
reject(event);
}
},
onerror:(event)=>{
reject(event);
}
});
});
}
//转换请求参数格式
function ObjToParams(obj){
let ret="";
Object.keys(obj).forEach((k)=>{
let v=obj[k];
if(typeof(v)==="object"){
v=JSON.stringify(v);
}
ret+=`${k}=${encodeURIComponent(v)}&`;
});
if(ret.length>1){
ret=ret.substring(0,ret.length-1)
}
return ret;
}
//下载图片存放到Blob
const fn_download_photo=function(photo_url){
return new Promise((resolve,reject)=>{
const re_photo_filename=/\/([^\/]+)$/;
const m_photo_filename=photo_url.match(re_photo_filename);
let photo_filename='noname.jpg';
if(m_photo_filename){
photo_filename=m_photo_filename[1];
}
GM_xmlhttpRequest({
url:photo_url,
method:'GET',
responseType:'blob',
onload:(event)=>{
const phpto_data=event.response;
resolve(phpto_data);
},
onerror:(event)=>{
reject(event);
}
});
});
};
//-------------------------------------------- 石油易采->供应商中心->商品管理->能源一号网 ----------------------------------------------------------------------------
//初始化添加商品页面
const fn_initNumberOne=()=>{
let el_menubar=document.querySelector(".hy_menubar");
if(!el_menubar){
// 插件功能区
el_menubar=document.createElement("div");
el_menubar.classList.add("hy_menubar");
el_menubar.style="z-index:999;width:10em;background-color:lightblue;position:fixed;top:10px;right:5px;border-radius:5px;font-size:larger; box-shadow: 0px 0px 10px;";
//主功能区
const el_mainContainer=document.createElement("div");
el_menubar.append(el_mainContainer);
el_mainContainer.style="height:100%;display:flex;flex-direction: column;justify-content:center;align-items:center;padding:5px 5px 5px 5px;";
//主功能区标题
const el_title=document.createElement("div");
el_mainContainer.append(el_title);
el_title.innerText="上架助手";
el_title.style="width:100%;text-align: center;margin-bottom:5px;font-weight: bolder;";
//商品sku输入框
const el_input=document.createElement("input");
el_mainContainer.append(el_input);
el_input.style="width:100%;margin-bottom:5px;";
el_input.setAttribute("placeholder","填入商品9开头sku");
el_input.classList.add("hy_input_shopskucodes");
//导入输入商品按钮
const el_b3=document.createElement("button");
el_mainContainer.append(el_b3);
el_b3.style="width:90%;margin-bottom:5px;";
el_b3.textContent="上传商品";
el_b3.addEventListener("click",(event)=>{doUploadGoodsListBySKU()});
el_b3.classList.add("hy_btn_import_goodsbysku");
//导入全部商品按钮
const el_b1=document.createElement("button");
el_mainContainer.append(el_b1);
el_b1.style="width:90%;margin-bottom:5px;";
el_b1.textContent="上传全部商品";
el_b1.addEventListener("click",(event)=>{doUploadGoodsListByPage(1,200)});
el_b1.classList.add("hy_btn_importALL_goods");
//上传响应商品按钮
const el_b2=document.createElement("button");
el_mainContainer.append(el_b2);
el_b2.style="width:90%;margin-bottom:5px;";
el_b2.textContent="上传响应商品";
el_b2.addEventListener("click",(event)=>{doUploadApplyGoodsListByPage(1,200)});
el_b2.classList.add("hy_btn_importapply_goods");
//查询消息显示区
const el_msg1=document.createElement("div");
el_mainContainer.append(el_msg1);
el_msg1.style="width:100%;color:red;display:none;margin-bottom:5px;";
el_msg1.innerText="";
el_msg1.classList.add("hy_msg1");
//完成信息显示区
const el_msg2=document.createElement("div");
el_mainContainer.append(el_msg2);
el_msg2.style="width:100%;color:red;display:none;margin-bottom:5px;color:green";
el_msg2.innerText="完成!可点击保存提交产品";
el_msg2.classList.add("hy_msg2");
//将助手工具添加到页面
document.body.insertAdjacentElement("afterBegin",el_menubar);
};
//取得商品列表
const getGoodsListByPage=(pageNum,pageSize,status)=>{
return new Promise((resolve,reject)=>{
let post_data={pageNum: pageNum, pageSize: pageSize}
if(status>0 ){
post_data.status=status;
};
//console.log(post_data);
const post_headers={
"Content-Type":"application/json;charset=UTF-8",
"Authorization":getAuthorization(),
};
GM_xmlhttpRequest({
url:"https://benefits.soluxemall.com/proxy/item-center/energynet/platform/shopDataFilling/selectPageListByStatus",
method:'POST',
data:JSON.stringify(post_data),
headers:post_headers,
onload:(event)=>{
try{
if(event.status==200){
const response=JSON.parse(event.responseText);
if(response.code=="0"){
resolve(response.data);
}else{
reject(response.msg);
}
}else{
reject(event);
}
}catch(e){
reject(e);
}
},
onerror:(event)=>{
reject(event);
}
});
});
};
//取得商品详情
const getGoodsDetail=(shopSkuId)=>{
return new Promise((resolve,reject)=>{
const post_data={shopSkuId: shopSkuId};
const post_headers={
"Content-Type":"application/json;charset=UTF-8",
"Authorization":getAuthorization(),
};
GM_xmlhttpRequest({
url:"https://benefits.soluxemall.com/proxy/item-center/energynet/platform/shopDataFilling/seachSupplierEnergyDataDetail",
method:'POST',
data:JSON.stringify(post_data),
headers:post_headers,
onload:(event)=>{
try{
if(event.status==200){
const response=JSON.parse(event.responseText);
if(response.code=="0"){
resolve(response.data);
}else{
reject(response.msg);
}
}else{
reject(event);
}
}catch(e){
reject(e);
}
},
onerror:(event)=>{
reject(event);
}
});
});
};
//两次请求的最小间隔时间
const minReuestInterval=2000;
//输入的sku商品上传
const doUploadGoodsListBySKU=()=>{
(async()=>{
const el_btn=document.querySelector(".hy_btn_import_goodsbysku");
if(el_btn){
el_btn.setAttribute("disabled",true);
}
const shopSkuId=document.querySelector(".hy_input_shopskucodes").value;
try{
const goods=await getGoodsDetail(shopSkuId);
await postGoodsToHYMS(goods);
console.log(`已上传商品${shopSkuId}`)
}catch(e){
console.error(`提交商品出现错误${shopSkuId}`);
console.error(e);
}
if(el_btn){
el_btn.removeAttribute("disabled");
}
})();
};
//遍历响应的商品并上传响应信息,采用递归方式遍历所有页
const doUploadApplyGoodsListByPage=(pn,ps)=>{
(async()=>{
const el_btn=document.querySelector(".hy_btn_importapply_goods");
if(el_btn){
el_btn.setAttribute("disabled",true);
}
const response=await getGoodsListByPage(pn,ps,3);
//console.log(response);
const pageNum=response.pageNum;
const pageSize=response.pageSize;
const totalPageCount=response.totalPageCount;
const totalCount=response.totalCount;
const result=response.result;
for(let i=0;i<result.length;i++){
const t0=(new Date()).getTime();
const currentNum=(pageNum-1)*pageSize+i+1;
const shopSkuId=result[i].shopSkuId;
try{
await postApplyGoodsToHYMS(result[i]);
console.log(`已上传响应商品${shopSkuId}(${currentNum}/${totalCount} at page:${pageNum})`)
}catch(e){
console.error(`提交响应商品出现错误${shopSkuId}(${currentNum}/${totalCount} at page:${pageNum})`);
console.error(result[i]);
console.error(e);
}
const t1=(new Date()).getTime();
if(t1-t0<minReuestInterval){
const sleepSeconds=(minReuestInterval-(t1-t0))/1000;
//console.log(`sleep ${sleepSeconds}秒`);
//await sleep(sleepSeconds);
}
}
if(pageNum<totalPageCount){
doUploadApplyGoodsListByPage(pageNum+1,pageSize);
}
console.log("上传结束");
if(el_btn){
el_btn.removeAttribute("disabled");
}
})();
};
//遍历商品并上传,采用递归方式遍历所有页
const doUploadGoodsListByPage=(pn,ps)=>{
(async()=>{
const el_btn_sync_import_goods=document.querySelector(".hy_btn_importALL_goods");
if(el_btn_sync_import_goods){
el_btn_sync_import_goods.setAttribute("disabled",true);
}
const response=await getGoodsListByPage(pn,ps,0);
const pageNum=response.pageNum;
const pageSize=response.pageSize;
const totalPageCount=response.totalPageCount;
const totalCount=response.totalCount;
const result=response.result;
for(let i=0;i<result.length;i++){
const t0=(new Date()).getTime();
const currentNum=(pageNum-1)*pageSize+i+1;
const shopSkuId=result[i].shopSkuId;
try{
const goods=await getGoodsDetail(shopSkuId);
await postGoodsToHYMS(goods);
console.log(`已上传商品${shopSkuId}(${currentNum}/${totalCount} at page:${pageNum})`)
}catch(e){
console.error(`提交商品出现错误${shopSkuId}(${currentNum}/${totalCount} at page:${pageNum})`);
console.error(result[i]);
console.error(e);
}
const t1=(new Date()).getTime();
if(t1-t0<minReuestInterval){
const sleepSeconds=(minReuestInterval-(t1-t0))/1000;
//console.log(`sleep ${sleepSeconds}秒`);
await sleep(sleepSeconds);
}
}
if(pageNum<totalPageCount){
doUploadGoodsListByPage(pageNum+1,pageSize);
}
console.log("上传结束");
if(el_btn_sync_import_goods){
el_btn_sync_import_goods.removeAttribute("disabled");
}
})();
};
//上传商品响应到HYMS
const postApplyGoodsToHYMS=(goods)=>{
return new Promise((resolve,reject)=>{
//console.log(goods);
const post_data={
"isagree":1,
"sellarea":goods.areaNames||[],
"agreeprice":goods.supplierSupplyPrice,
"shopSkuId":goods.shopSkuId
};
//console.log("post_data="+JSON.stringify(post_data));
const post_headers={
"Content-Type":"application/x-www-form-urlencoded",
};
GM_xmlhttpRequest({
url:"http://43.143.136.44/hysm/importapplygoods.asp",
method:'POST',
data:"param="+JSON.stringify(post_data),
headers:post_headers,
onload:(event)=>{
try{
const response=JSON.parse(event.responseText);
if(response.returncode==0){
resolve();
}else{
reject(response);
}
}catch(e){
reject(e);
}
},
onerror:(event)=>{
reject(event);
}
});
});
}
//上传商品到HYMS
const postGoodsToHYMS=(goods)=>{
return new Promise((resolve,reject)=>{
let goodsimgs = new Array();
let dataapplyItemAnnexRequestVoList = goods.applyItemAnnexRequestVoList||[];
for(let i=0;i<dataapplyItemAnnexRequestVoList;i++){
goodsimgs.push(dataapplyItemAnnexRequestVoList.annexUrl);
}
const post_data={
"brandCnName":goods.brandCnName,
"brandEnName":goods.brandEnName,
"detail":goods.detail,
"energySellPrice":goods.energySellPrice,
"goodsCode":goods.goodsCode,
"goodsName":goods.goodsName,
"itemCode":goods.itemCode,
"marketPrice":goods.marketPrice,
"param":goods.param,
"paramJson":goods.paramJson,
"shopSkuId":goods.shopSkuId,
"shopBaseSkuName":goods.shopBaseSkuName,
"sourceSkuUnit":goods.sourceSkuUnit,
"taxCode":goods.taxCode,
"taxRate":goods.taxRate,
"sellPrice":goods.sellPrice,
"goodsimgs":goodsimgs||[],
};
//console.log(JSON.stringify(post_data));
const post_headers={
"Content-Type":"application/x-www-form-urlencoded",
};
GM_xmlhttpRequest({
url:"http://43.143.136.44/hysm/importenergynetgoods.asp",
method:'POST',
data:"param="+JSON.stringify(post_data),
headers:post_headers,
onload:(event)=>{
try{
const response=JSON.parse(event.responseText);
if(response.returncode==0){
resolve();
}else{
reject(response);
}
}catch(e){
reject(e);
}
},
onerror:(event)=>{
reject(event);
}
});
});
}
};
/*----------------------------------访问页面到功能入口的路由---------------------------------------------*/
const href=document.location.href;
const match=[
{
"re":/shop-view\//,
"fn":fn_initNumberOne,
},
];
const param={};
(href.match(/(?<=[\?\&])([^\?\&]+)/g)||[]).forEach((s)=>{
let p=s.indexOf("=");
p=p>=0?p:s.length;
const key=s.substring(0,p);
const value=s.substring(p+1);
if(key){
param[key]=value;
}
});
for(let i=0;i<match.length;i++){
const m=match[i];
if(m.re.test(href)){
m.fn({param:param});
break;
}
}
})();