Greasy Fork

小米路由器PC端设备实时网速

小米路由器PC端后台管理界面设备实时网速

目前为 2022-10-11 提交的版本。查看 最新版本

// ==UserScript==
// @name         小米路由器PC端设备实时网速
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  小米路由器PC端后台管理界面设备实时网速
// @author       过去终究是个回忆
// @license      MIT
// @match        http://192.168.31.1/cgi-bin/luci/*/web/home*
// @require      https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/dayjs/1.10.8/dayjs.min.js
// @require      https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/vue/2.6.14/vue.min.js
// @require      https://unpkg.com/[email protected]/dist/ajaxhook.min.js
// @require      https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/element-ui/2.15.7/index.min.js
// @grant        GM_getResourceText
// @grant        GM_addStyle
// @grant        GM_addStyle
// @grant        unsafeWindow
// @resource     element-ui https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/element-ui/2.15.7/theme-chalk/index.min.css
// @run-at       document-start
// ==/UserScript==

(function () {
    'use strict';

    GM_addStyle(GM_getResourceText('element-ui'))
    GM_addStyle(`
        @font-face{font-family:element-icons;src:url(https://lf9-cdn-tos.bytecdntp.com/cdn/expire-1-M/element-ui/2.15.7/theme-chalk/fonts/element-icons.woff) format("woff"),url(https://lf9-cdn-tos.bytecdntp.com/cdn/expire-1-M/element-ui/2.15.7/theme-chalk/fonts/element-icons.ttf) format("truetype");font-weight:400;font-display:"auto";font-style:normal}
        #net-speed {
            float: left;
            margin-top: 40px;
            width: 100%;
            }
            .demo-table-expand {
            font-size: 0;
        }
        .speed-line {
            display: flex;
            justify-content: space-between;
            align-items: center;
        }
        .speed-line div[role="progressbar"] {
            width: 300px;
        }
    `)

    const maxEachDataStorage = 100
    const updateDevDataEvent = new Event('updateDevData')
    const initData = {
        history: {},
        tableData: []
    }

    window.ah.proxy({
        //请求成功后进入
        onResponse: (response, handler) => {
            if (response.config.url.includes('/api/misystem/status')) {
                const data = JSON.parse(response.response)
                initData.tableData = data.dev
                data.dev.forEach(item => {
                    if (!initData.history[item.mac]) {
                        initData.history[item.mac] = []
                    }
                    const each = {
                        ...item,
                        dateSecond: Date.now(),
                        combinedSpeed: item.upspeed + item.downspeed,
                    }
                    if (initData.history[item.mac].length === maxEachDataStorage) {
                        initData.history[item.mac][maxEachDataStorage] = each
                    } else if (initData.history[item.mac].length < maxEachDataStorage) {
                        initData.history[item.mac].push(each)
                    } else if (initData.history[item.mac].length > maxEachDataStorage) {
                        initData.history[item.mac].splice(maxEachDataStorage - 1, initData.history.length, each)
                    }
                })
                document.dispatchEvent(updateDevDataEvent)
            }
            handler.next(response)
        }
    }, unsafeWindow)

    window.onload = function () {
        const container = document.createElement('div')
        container.id = 'net-speed'
        console.log('net-speed starting...')

        const target = document.querySelector('#bd>.mod-routerstatus.nav-tab-content')
        target.appendChild(container)

        new Vue({
            el: container,
            data() {
                return {
                    dialogTableTitle: 'dialogTableTitle',
                    dialogTableVisible: false,
                    currentRow: {},
                    history: {},
                    tableData: [],
                }
            },
            created() {
                this.history = initData.history
                this.tableData = initData.tableData
                document.addEventListener("updateDevData", () => {
                    this.history = initData.history
                    this.tableData = initData.tableData
                })
            },
            methods: {
                byteFormat: byteFormat,
                secondToDate: secondToDate,
                speedFormat(number, precision, isarray) {
                    return this.byteFormat(number, precision, isarray) + '/S'
                },
                speedFormatter(row, column, cellValue) {
                    return this.speedFormat(cellValue, 100)
                },
                dataFormatter(row, column, cellValue) {
                    return this.byteFormat(cellValue, 100)
                },
                secondFormatter(row, column, cellValue) {
                    return this.secondToDate(cellValue)
                },
                dateTimeFormatter(row, column, cellValue) {
                    return dayjs(cellValue).format('YYYY-MM-DD HH:mm:ss')
                },
                showHistoryData(row) {
                    this.dialogTableVisible = true
                    this.dialogTableTitle = `${row.devname}(${row.mac}) 历史数据`
                    this.currentRow = row
                    console.log(this.history)
                }
            },
            template: `
            <div id="net-speed">
                <el-table
                    v-loading="!tableData.length"
                    :data="tableData"
                    :default-sort="{prop: 'combinedSpeed', order: 'ascending'}"
                    border
                    fit
                    max-height="500px"
                    style="width: 100%;"
                >
                    <el-table-column
                        prop="devname"
                        label="设备"
                        sortable
                        width="200"
                    />
                    <el-table-column
                        prop="mac"
                        label="MAC"
                        sortable
                        width="148"
                    />
                    <el-table-column
                        prop="combinedSpeed"
                        label="网速"
                        width="540"
                        sortable
                        sort-by="combinedSpeed"
                    >
                        <template slot-scope="scope">
                            <p class="speed-line">上传速度: <el-progress :percentage="scope.row.upspeed / scope.row.maxuploadspeed * 100" :show-text="false" color="#2673bf"></el-progress>{{speedFormat(scope.row.upspeed, 100)}}</p>
                            <p class="speed-line">下载速度: <el-progress :percentage="scope.row.downspeed / scope.row.maxdownloadspeed * 100" :show-text="false" color="#33cc33"></el-progress>{{speedFormat(scope.row.downspeed, 100)}}</p>
                        </template>
                    </el-table-column>
                    <el-table-column
                        prop="maxuploadspeed"
                        label="历史最大上传速度"
                        width="158"
                        sortable
                        :formatter="speedFormatter"
                    />
                    <el-table-column
                        prop="maxdownloadspeed"
                        label="历史最大下载速度"
                        width="158"
                        sortable
                        :formatter="speedFormatter"
                    />
                    <el-table-column
                        prop="upload"
                        label="上传流量"
                        width="102"
                        sortable
                        :formatter="dataFormatter"
                    />
                    <el-table-column
                        prop="download"
                        label="下载流量"
                        width="102"
                        sortable
                        :formatter="dataFormatter"
                    />
                    <el-table-column
                        prop="online"
                        label="在线时间"
                        width="140"
                        sortable
                        :formatter="secondFormatter"
                    />
                    <el-table-column
                        prop="devname"
                        label="操作"
                        fixed="right"
                    >
                        <template slot-scope="scope">
                            <el-button type="text" size="small" @click="showHistoryData(scope.row)">历史数据</el-button>
                        </template>
                    </el-table-column>
                </el-table>
                <el-dialog :title="dialogTableTitle" :visible.sync="dialogTableVisible">
                    <el-table
                        :data="this.history[this.currentRow.mac]"
                        :default-sort="{prop: 'dateSecond', order: 'descending'}"
                        border
                        fit
                        max-height="500px"
                        style="width: 100%;"
                    >
                        <el-table-column
                            property="dateSecond"
                            sortable
                            label="时间"
                            width="164"
                            :formatter="dateTimeFormatter"
                        />
                        <el-table-column
                            label="网速"
                            sortable
                            min-width="540"
                            sort-by="combinedSpeed"
                        >
                            <template slot-scope="scope">
                                <p class="speed-line">上传速度: <el-progress :percentage="scope.row.upspeed / scope.row.maxuploadspeed * 100" :show-text="false" color="#2673bf"></el-progress>{{speedFormat(scope.row.upspeed, 100)}}</p>
                                <p class="speed-line">下载速度: <el-progress :percentage="scope.row.downspeed / scope.row.maxdownloadspeed * 100" :show-text="false" color="#33cc33"></el-progress>{{speedFormat(scope.row.downspeed, 100)}}</p>
                            </template>
                        </el-table-column>
                    </el-table>
                </el-dialog>
            </div>
        `
        })
    }
})();