Greasy Fork

来自缓存

Greasy Fork is available in English.

管理端脱敏

管理端页面敏感数据脱敏(MutationObserver )

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         管理端脱敏
// @namespace    http://tampermonkey.net/
// @version      2.0
// @description  管理端页面敏感数据脱敏(MutationObserver )
// @author       Huo-zai-feng-lang-li
// @license      MIT
// @match        *://*/*
// @grant        none
// @run-at       document-end
// ==/UserScript==

(function () {
    'use strict';

    const dp = s => {
        if (!s) return s;
        const str = String(s).trim();
        return /^1[3-9]\d{9}$/.test(str) ? str.substr(0, 3) + '****' + str.substr(7) : str;
    };

    const dc = s => {
        if (!s) return s;
        const str = String(s).trim();
        return /^[0-9A-Z]{18}$/i.test(str) ? str.substr(0, 6) + '********' + str.substr(14) : str;
    };

    const da = s => {
        if (!s) return s;
        const str = String(s).trim();
        return str.length >= 6 ? str.substr(0, 2) + '****' + str.substr(-2) : str;
    };

    const RULES = [
        { match: t => t.includes('统一社会信用代码'), fn: dc },
        { match: t => t.includes('联系人手机号') || t.includes('手机号'), fn: dp },
        { match: t => t.includes('账号') || t.includes('用户名'), fn: da },
    ];

    function buildColMap(ths) {
        const map = new Map();
        ths.forEach((th, idx) => {
            const t = (th.innerText || '').trim();
            for (const r of RULES) {
                if (r.match(t)) { map.set(idx, r.fn); break; }
            }
        });
        return map;
    }

    function maskRows(rows, colMap) {
        if (!colMap.size) return;
        rows.forEach(tr => {
            const tds = tr.querySelectorAll('td');
            colMap.forEach((fn, idx) => {
                if (!tds[idx]) return;
                const el = tds[idx].querySelector('.cell') || tds[idx];
                el.innerText = fn(el.innerText);
            });
        });
    }

    function processElTable(wrapper) {
        const hw = wrapper.querySelector(':scope > .el-table__header-wrapper');
        if (!hw) return;
        const colMap = buildColMap(hw.querySelectorAll('th'));
        if (!colMap.size) return;

        const bw = wrapper.querySelector(':scope > .el-table__body-wrapper');
        if (bw) maskRows(bw.querySelectorAll('tr'), colMap);

        wrapper.querySelectorAll(':scope > .el-table__fixed .el-table__fixed-body-wrapper, :scope > .el-table__fixed-right .el-table__fixed-body-wrapper')
            .forEach(fb => maskRows(fb.querySelectorAll('tr'), colMap));
    }

    function processNativeTable(table) {
        if (table.closest('.el-table')) return;
        maskRows(table.querySelectorAll('tr'), buildColMap(table.querySelectorAll('th')));
    }

    function processForm() {
        document.querySelectorAll('[class*=form-item], [class*=form-group], .el-form-item').forEach(el => {
            const label = el.querySelector('label, .el-form-item__label, .label');
            const input = el.querySelector('input, .el-input__inner');
            if (!label || !input) return;
            const txt = label.innerText.trim();
            for (const r of RULES) {
                if (r.match(txt)) { input.value = r.fn(input.value); break; }
            }
        });
    }

    function runAll() {
        document.querySelectorAll('.el-table').forEach(processElTable);
        document.querySelectorAll('table').forEach(processNativeTable);
        processForm();
    }

    // MutationObserver + rAF 合并,即时响应 DOM 变化
    let pending = false;
    const observer = new MutationObserver(() => {
        if (pending) return;
        pending = true;
        requestAnimationFrame(() => { pending = false; runAll(); });
    });

    runAll();
    observer.observe(document.body, { childList: true, subtree: true });
})();