Greasy Fork is available in English.

京东云无线宝积分查询

京东云无线宝路由器积分统计、积分兑换、积分查询脚本

// ==UserScript==
// @name         京东云无线宝积分查询
// @namespace    http://blog.gobyte.cn/
// @version      0.44
// @description  京东云无线宝路由器积分统计、积分兑换、积分查询脚本
// @author       misterchou@qq.com 山岚
// @match        *://router-app-api.jdcloud.com/*
// @grant        GM_xmlhttpRequest
// ==/UserScript==

(function() {
    'use strict';

    /**
使用教程:
1.安装油猴子,或者复制JS代码到浏览器控制台运行:
京东云无线宝积分查询
https://greasyfork.org/zh-CN/scripts/416281-%E4%BA%AC%E4%B8%9C%E4%BA%91%E6%97%A0%E7%BA%BF%E5%AE%9D%E7%A7%AF%E5%88%86%E6%9F%A5%E8%AF%A2

2.抓包获取Key
需要通过抓包“京东云无线宝”App获取。在header内,链接是:https://router-app-api.jdcloud.com/v1/开头的链接,具体请自行修改代码。

3.打开网址查看效果
https://router-app-api.jdcloud.com/v1

4.抓包工具
Android 系统 : HttpCanary
iOS 系统 :Stream
*/


    //↓↓↓↓↓↓↓↓↓↓必须填写!!!↓↓↓↓↓↓↓↓↓↓↓↓↓↓=============================

    let wskey = "";
    localStorage.setItem('wskey',wskey);

    //如下参数如不填写,将无法获取到路由器的备注名!!!

    //listAllUserDevicesUrl 这个请找到:https://gw.smart.jd.com/f/service/listAllUserDevices? 开头的链接并复制填入,每个人的账号不一样,请按照你抓包的结果填入此项。
    var listAllUserDevicesUrl = "https://gw.smart.jd.com/f/service/listAllUserDevices?plat_version=5.1.1&app_version=6.5.5&hard_platform=PCRT00&plat=Android",

        //以下参数需要也是在 https://gw.smart.jd.com/f/service/listAllUserDevices  开头的链接header内获取
        pin = "",
        tgt = "",
        accesskey = "",
        Authorization = "";

    //↑↑↑↑↑↑↑↑↑↑必须填写!!!↑↑↑↑↑↑↑↑↑↑↑↑↑↑=============================
    //读取本地数据
    if ( localStorage.getItem("wskey") != null ){
        wskey = localStorage.getItem("wskey");
    }else{
        localStorage.setItem('wskey',wskey);
    }

    //     localStorage.setItem('pin',pin);
    //     localStorage.setItem('appkey',appkey);
    //     localStorage.setItem('tgt',tgt);
    //     localStorage.setItem('accesskey',accesskey);
    //     localStorage.setItem('Authorization',Authorization);

    //start
    let mac_arr = [];
    let sum = 0 ,exchanged = 0,thisDevice = 0,bodyStr="",todayPoint = null;
    let todayPointCount = 0;
    let allPointnts = 0;
    //所有未兑换的积分统计
    let allAmount = 0;

    //今日所有设备总积分
    fetch(`https://router-app-api.jdcloud.com/v1/regions/cn-north-1/todayPointDetail?sortField=today_point&sortDirection=DESC&pageSize=15&currentPage=1&time=${new Date().getTime()}`, {
        "credentials": "omit",
        "headers": {
            "content-type": "application/json",
            "wskey": wskey,
            "User-Agent": "Mozilla/5.0 (Linux; Android 9; MI 6 Build/PKQ1.190118.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/74.0.3729.136 Mobile Safari/537.36 (JBOX-APP; Android/2.0.4/8)",
        },
        "referrerPolicy": "no-referrer-when-downgrade",
        "body": null,
        "method": "GET",
        "mode": "cors"
    })
        .then(res => {
        return res.json();
    })
        .then(data => {
        //                 console.log(`今日总积分:`,JSON.stringify(data));
        if(JSON.stringify(data).indexOf('权限') > -1){
            //             alert("抓包的Key值可能失效,请重新抓包!!!");
            window.localStorage.clear();
            console.error("抓包的Key值可能失效,请重新抓包!!!",data);
        }
        let pointInfos = data.result.pointInfos;

        //遍历所有设备
        for( let i = 0; i < pointInfos.length; i++ ){
            let mac = pointInfos[i].mac;
            //保存mac备用
            mac_arr.push(mac);
            //获取备注名;默认mac地址
            let name = localStorage.getItem(mac) ? localStorage.getItem(mac) : mac;
            todayPointCount += pointInfos[i].todayPointIncome;
            allPointnts += pointInfos[i].allPointIncome;
            // 所有的值以mac为id前缀,后面再添加不同值的名字。如:未兑换的积分id为:mac_amount,这样就会让id变得唯一且容易修改dom
            bodyStr += `<tr>
<td>${name}</td>
<td style="display:none" name="${mac}">MAC:${mac}</td>
<td style="color: #03A9F4;" >${data.result.todayDate} 日积分:${pointInfos[i].todayPointIncome}</td>
<td style="display:none">缓存:<span id=''></span></td>
<td>未兑换:<span id='${mac}_amount'></span></td>
<td>总积分:${pointInfos[i].allPointIncome}</td>
<td><button id='${mac}_exchangeButton' class="exchangeButton" onClick="exchangePoint(this,'${mac}',${mac})" style="display:none">兑换</button></td>
<td><button style="display:none" onClick="markName(this,'${mac}')">本地备注</button></td>`;
        };
        document.querySelector("body").innerHTML = `<table cellpadding="10"> <tr> ${bodyStr} <td><button onClick="allExchangePoint(this)" style="display:none">全部兑换</button></td> </tr>
<tr><td></td><td><b>统计:</b>今日总积分:<span style="color:red;">${todayPointCount}</span></td> <td class="所有未兑换总积分">总计:<span style="color:blue;" id="allAmountId">${allAmount}</span></td><td class="所有总积分">总计:<span style="color:blue;">${allPointnts}</span></td></tr>
</table>`;

        //显示未兑换的积分
        //查询所有账户信息和积分
        mac_arr.map(
            mac =>{
                let routerAccountInfo_url = `https://router-app-api.jdcloud.com/v1/regions/cn-north-1/routerAccountInfo?mac=${mac}`;
                fetch(routerAccountInfo_url, {
                    "headers": {
                        "content-type": "application/json",
                        "wskey": wskey,
                        "Referer": "http://guanli.luyou.360.cn/new_index.htm"
                    },
                    "referrerPolicy": "no-referrer-when-downgrade",
                    "body": null,
                    "method": "get",
                    "mode": "cors"
                })
                    .then(res => {
                    return res.json();
                }).then( data => {
                    //统计未兑换的设备积分
                    allAmountFun(data.result.accountInfo.amount);
                    document.getElementById(`${mac}_amount`).textContent = data.result.accountInfo.amount;
                    document.getElementById(`${mac}_exchangeButton`).attributes.onclick.value = `exchangePoint(this,'${mac}',${data.result.accountInfo.amount})`;
                });
            }
        );
    });

    //     ==========================
    //给所有未兑换积分统计dom赋值
    //统计未兑换总积分函数
    function allAmountFun(n){
        allAmount += n;
        document.getElementById('allAmountId').textContent = allAmount;
    }
    //兑换积分函数
    window.exchangePoint= function (obj,mac,point) {
        console.log("外部调用",mac,point);
        point = window.prompt("请输入需要兑换的积分",point);
        if(!point) return;
        //构造请求体
        const pointExchangeBody = {
            "pointExchangeReqVo": {
                "deviceId": mac,
                "pointAmount": point,
                "source": 3
            },
            "regionId": "cn-north-1"
        };

        fetch("https://router-app-api.jdcloud.com/v1/regions/cn-north-1/point:exchange", {
            "headers": {
                "content-type": "application/json",
                "wskey": wskey,
                "User-Agent": "",
            },
            "body": JSON.stringify(pointExchangeBody),
            "method": "POST",
            "mode": "cors"
        })
            .then(res => {
            return res.json();
        })
            .then(data => {
            if(data.code === 200){
                alert("兑换成功!");
            }else{
                alert("失败!请按下F12 - console (控制台)内截图给开发者");
                console.error(data);
            }
        });
    }

    //备注函数
    window.markName=(obj,mac)=>{
        let name = window.prompt("请输入备注名","")
        if(!name) return;
        localStorage.setItem(mac,name);
        window.location.reload();
    }

    //获取设备名称
    var hader = {
        "appkey" : "996",
        "pin": pin,
        "tgt": tgt,
        "accesskey": accesskey,
        "Authorization": Authorization,
    };
    runAsync(listAllUserDevicesUrl,"POST",hader,"")
        .then((result)=> {
        if( result.indexOf("errorInfo") > -1){
            alert("获取设备备注失败,请检查参数是否正确:\n pin、tgt、accesskey、Authorization");
            console.log(result);
        }
        return result;
    }).then(function(result){
        JSON.parse(result).result[0].list.forEach( r=>{
            console.log(r.device_id,r.device_name);
            localStorage.setItem(r.device_id,r.device_name);
        });
    });

    //跨域请求
    //send数据函数
    //参数1:url;参数2:请求类型get或post;参数3:请求头;参数4:post的body;
    function runAsync(url,send_type,header,data_ry) {
        var p = new Promise((resolve, reject)=> {
            GM_xmlhttpRequest({
                method: send_type,
                url: url,
                headers: header,
                data:data_ry,
                onload: function(response){
                    //console.log("请求成功");
                    //console.log(response.responseText);
                    resolve(response.responseText);
                },
                onerror: function(response){
                    //console.log("请求失败");
                    reject("请求失败");
                }
            });
        })
        return p;
    }
    //-1
})();