BANK_MAHA_WM

需要配合监控使用

// ==UserScript==
// @name         BANK_MAHA_WM
// @namespace    http://tampermonkey.net/
// @version      2025-04-12
// @description  需要配合监控使用
// @author       WebMonitor
// @match        https://www.mahaconnect.in/InternetBanking1/ib/*
// @icon         TODO
// @grant        GM_xmlhttpRequest
// @grant        GM_addElement
// @grant        GM_setValue
// @grant        GM_getValue
// @run-at       document-idle
// @license      MIT
// ==/UserScript==

(() => {
    "use strict";

    const initTxnJob = async () => {
        let timeFlag = new Date().getTime();
        let startFlag;
        const id = setInterval(async () => {
            if (!((startFlag = GM_getValue("mk_start_flag", false)))) {
                clearInterval(id);
                
                let intervalIdsInner = GM_getValue("mk_interval_id", []);
                if (intervalIdsInner) {
                    for (let i = 0; i < intervalIdsInner.length; i++) {
                        clearInterval(intervalIdsInner[i]);
                    }
                    intervalIdsInner = [];
                    GM_setValue("mk_interval_id", intervalIdsInner);
                }
                return;
            }
            const startButton = document.querySelector("#mk_start");
            startButton.value = startFlag ? "停止" : "开始";
            startButton.style.backgroundColor = startFlag ? "#f00" : "#fff";

            try {
                if (!document.querySelector("div[id='mainform:retailTabMenu'] > ul > li:nth-of-type(1) > a")) return;
                
                if (!document.querySelector("a[onclick*='mainform:MiniStatementView']")) {
                    document.querySelector("div[id='mainform:retailTabMenu'] > ul > li:nth-of-type(1) > a").click();
                    await delay(9000);
                }

                document.querySelector("a[onclick*='mainform:MiniStatementView']").click();
                await waitForEle("div[id='mainform:MiniStatementView']");
                document.querySelector("div[id='mainform:MiniStatementView'] a[aria-label='Close']").click();

                if (new Date().getTime() - timeFlag > 60000) {
                    document.querySelector("div[id='mainform:retailTabMenu'] > ul > li:nth-of-type(2) > a").click();
                    await delay(9000);
                    document.querySelector("div[id='mainform:retailTabMenu'] > ul > li:nth-of-type(1) > a").click();
                    await delay(9000);
                    timeFlag = new Date().getTime();
                }
            } catch (e) { }
            finally {
                await delay(9000);
            }
        }, 9000);
        let intervalIds = GM_getValue("mk_interval_id", []);
        intervalIds.push(id);
        GM_setValue("mk_interval_id", intervalIds);
    };

    const initDashBoard = () => {
        /* 面板容器 */
        GM_addElement(document.querySelector("body"), "div", {
            id: "mk_wrapper",
            style: "position: fixed; bottom: 10px; right: 10px; z-index: 9999; padding: 10px; background: #fff; border: 1px solid #ccc; border-radius: 5px; box-shadow: 0 0 10px rgba(0,0,0,0.5);"
        });

        /* 输入控件 */
        GM_addElement(document.querySelector("#mk_wrapper"), "input", {
            id: "mk_user_name",
            type: "text",
            style: "display: block; width: 200px; height: 30px; margin-bottom: 5px; border-radius: 5px; border: 1px solid #ccc; padding: 5px;",
            placeholder: "请输入用户"
        });
        document.querySelector("#mk_user_name").value = GM_getValue("mk_user_name", "");

        /* 按钮控件 */
        GM_addElement(document.querySelector("#mk_wrapper"), "input", {
            id: "mk_start",
            type: "button",
            value: "开始",
            style: "display: block; width: 200px; height: 30px; margin-bottom: 5px; border-radius: 5px; border: 1px solid #ccc; padding: 5px;"
        });
        const startButton = document.querySelector("#mk_start");
        startButton.onclick = () => {
            const userName = document.querySelector("#mk_user_name").value;
            if (!userName) {
                alert("请输入用户名");
                return;
            }

            GM_setValue("mk_user_name", userName);

            let startFlag = !GM_getValue("mk_start_flag", false);
            GM_setValue("mk_start_flag", startFlag);
            const startButton = document.querySelector("#mk_start");
            startButton.value = startFlag ? "停止" : "开始";
            startButton.style.backgroundColor = startFlag ? "#f00" : "#fff";
            if (startFlag) {
                initTxnJob();
            }
        };


        GM_addElement(document.querySelector("#mk_wrapper"), "input", {
            id: "mk_balance",
            type: "text",
            style: "display: block; width: 200px; height: 30px; margin-bottom: 5px; border-radius: 5px; border: 1px solid #ccc; padding: 5px;",
            readonly: true,
            placeholder: "余额"
        });
    };

    const initOverride = () => {
        const originOpen = XMLHttpRequest.prototype.open;
        const parser = new DOMParser();
        XMLHttpRequest.prototype.open = function (_, url) {
            if (GM_getValue("mk_start_flag", false)) {
                this.addEventListener("readystatechange", function () {
                    if (this.readyState === 4) {
                        const responseDoc = parser.parseFromString(this.responseText, "text/html");
                        parseTxnList(responseDoc);
                    }
                });
            }
            originOpen.apply(this, arguments);
        };
    };

    const parseTxnList = (responseDoc) => {
        if (!responseDoc) return;

        const txnList = responseDoc.querySelectorAll("tbody[id='mainform:StatementViewId_data'] tr[data-ri]");
        if (!txnList) return;
        for (let i = 0; i < txnList.length; i++) {
            const txn = txnList[i];

            const tds = txn.querySelectorAll("td");
            const deibit = tds[3].innerText.replace(",", "").replace(".", "").replace("INR", "").replace("\n", "").replace("\t", "").trim();
            const credit = tds[4].innerText.replace(",", "").replace(".", "").replace("INR", "").replace("\n", "").replace("\t", "").trim();
            const amount = deibit || credit;
            const balance = tds[5].innerText.replace(",", "").replace(".", "").replace("INR", "").replace("\n", "").replace("\t", "").trim();
            const type = credit ? 0 : 1;
            const remarks = tds[1].innerText.replace("\n", "").replace("\t", "").trim();

            if (i == 0) {
                const balanceEle = document.querySelector("#mk_balance");
                balanceEle.value = tds[5].innerText.replace("\n", "").replace("\t", "").trim();
            }

            const match = remarks.match(/\d{12}/);
            var transactionCode;
            if (match) {
                transactionCode = match[0];
            }

            var messageIdentifyCode;
            var split = remarks.split("/");
            messageIdentifyCode = split[split.length - 1];

            var userName = document.querySelector("#mk_user_name").value;

            const data = {
                key: `Maha_${userName}_`,
                value: {
                    amount: amount,
                    balance: balance,
                    detail: remarks,
                    transactionCode: transactionCode,
                    transactionType: type,
                    messageIdentifyCode: messageIdentifyCode
                }
            };

            GM_xmlhttpRequest({
                method: "POST",
                url: "http://localhost:34567",
                headers: {
                    "Content-Type": "application/json",
                },
                data: JSON.stringify(data),
                onload: function (response) {
                    console.log(response.responseText);
                }
            });
        }
    };

    const waitForEle = async (selector, timeout = 36000) => {
        let startTime = Date.now();
        while (Date.now() - startTime < timeout) {
            let targetEle = document.querySelector(selector);
            if (targetEle && targetEle.style.display !== "none") return targetEle;
            await delay(1000);
        }
    };

    const waitForEleNone = async (selector, timeout = 36000) => {
        let startTime = Date.now();
        while (Date.now() - startTime < timeout) {
            let targetEle = document.querySelector(selector);
            if (targetEle && targetEle.style.display === "none") return targetEle;
            await delay(1000);
        }
    };

    const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));

    initOverride();
    initDashBoard();
    initTxnJob();

})();