244 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			HTML
		
	
	
	
		
			Vendored
		
	
	
	
			
		
		
	
	
			244 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			HTML
		
	
	
	
		
			Vendored
		
	
	
	
{{define "theme-server-status/service"}}
 | 
						||
{{template "theme-server-status/header" .}}
 | 
						||
<div id="app">
 | 
						||
    {{template "theme-server-status/content-nav" .}}
 | 
						||
    <!--  showGroup true -->
 | 
						||
    <template v-if="showGroup">
 | 
						||
        <section v-if="servicesTag.length === 0" class="container content" style="max-width: 95vw; min-height: .01%;overflow-x: auto;">
 | 
						||
            <p>No Valid Service Monitor Configuration Entries Found. Please Verify in the <a href="/monitor">Admin Panel</a>.</p>
 | 
						||
        </section>
 | 
						||
        <section v-else class="container content" style="max-width: 95vw; min-height: .01%;overflow-x: auto;" v-for="group in servicesTag">
 | 
						||
            {{template "theme-server-status/service-group-true" .}} 
 | 
						||
        </section>
 | 
						||
    </template>
 | 
						||
    <!--  showGroup false -->
 | 
						||
    <template v-else>
 | 
						||
        <section v-if="servicesNoTag.length === 0" class="container content" style="max-width: 95vw; min-height: .01%;overflow-x: auto;">
 | 
						||
            <p>No Valid Service Monitor Configuration Entries Found. Please Verify in the <a href="/monitor">Admin Panel</a>.</p>
 | 
						||
        </section>
 | 
						||
        <section v-else class="container content" style="max-width: 95vw; min-height: .01%;overflow-x: auto;">
 | 
						||
            {{template "theme-server-status/service-group-false" .}}
 | 
						||
        </section>
 | 
						||
    </template>
 | 
						||
    {{if .CycleTransferStats}}
 | 
						||
        <section class="container content table-responsive" style="max-width: 95vw">
 | 
						||
            <table class="table table-striped table-condensed table-hover">
 | 
						||
                <thead>
 | 
						||
                    <tr class="node-group-tag">
 | 
						||
                        <th colspan="16" style="border:none;">
 | 
						||
                            {{tr "CycleTransferStats"}}
 | 
						||
                        </th>
 | 
						||
                    </tr>
 | 
						||
                    <tr class="node-group-cell">
 | 
						||
                        <th class="node-cell center">ID</th>
 | 
						||
                        <th class="node-cell center">{{tr "Rules"}}</th>
 | 
						||
                        <th class="node-cell center">{{tr "Server"}}</th>
 | 
						||
                        <th class="node-cell center">{{tr "From"}}</th>
 | 
						||
                        <th class="node-cell center">{{tr "To"}}</th>
 | 
						||
                        <th class="node-cell center">MAX</th>
 | 
						||
                        <th class="node-cell center">MIN</th>
 | 
						||
                        <th class="node-cell center">{{tr "NextCheck"}}</th>
 | 
						||
                        <th class="node-cell center">{{tr "CurrentUsage"}}</th>
 | 
						||
                        <th class="node-cell center">{{tr "Transleft"}}</th>
 | 
						||
                    </tr>
 | 
						||
                </thead>
 | 
						||
                <tbody>
 | 
						||
                    {{range $id, $stats := .CycleTransferStats}}
 | 
						||
                        {{range $innerId, $transfer := $stats.Transfer}}
 | 
						||
                            {{$TransLeftPercent := TransLeftPercent (UintToFloat $transfer) (UintToFloat $stats.Max)}}
 | 
						||
                            <tr>
 | 
						||
                                <td class="node-cell center">{{$id}}</td>
 | 
						||
                                <td class="node-cell center">{{$stats.Name}}</td>
 | 
						||
                                <td class="node-cell center">{{index $stats.ServerName $innerId}}</td>
 | 
						||
                                <td class="node-cell center">{{$stats.From|tf}}</td>
 | 
						||
                                <td class="node-cell center">{{$stats.To|tf}}</td>
 | 
						||
                                <td class="node-cell center">{{$stats.Max|bf}}</td>
 | 
						||
                                <td class="node-cell center">{{$stats.Min|bf}}</td>
 | 
						||
                                <td class="node-cell center">{{(index $stats.NextUpdate $innerId)|sft}}</td>
 | 
						||
                                <td class="node-cell center">{{$transfer|bf}}</td>
 | 
						||
                                <td class="node-cell center">
 | 
						||
                                    <div class="progress">
 | 
						||
                                        <div style="width: {{$TransLeftPercent}}%" :class="'progress-bar progress-bar-' + toSSBar('{{TransClassName $TransLeftPercent}}')">
 | 
						||
                                            <small style="display: inline-block;width: max-content;">{{TransLeft $stats.Max $transfer}} / {{$TransLeftPercent}} %</small>
 | 
						||
                                        </div>
 | 
						||
                                    </div>
 | 
						||
                                </td>
 | 
						||
                            </tr>
 | 
						||
                        {{end}}
 | 
						||
                    {{end}}
 | 
						||
                </tbody>
 | 
						||
            </table>
 | 
						||
        </section>
 | 
						||
    {{end}}
 | 
						||
    {{template "theme-server-status/content-footer" .}}
 | 
						||
</div>
 | 
						||
<script>
 | 
						||
    new Vue({
 | 
						||
        el: '#app',
 | 
						||
        delimiters: ['@#', '#@'],
 | 
						||
        data: {
 | 
						||
            page: 'service',
 | 
						||
            defaultTemplate: {{.Conf.Site.Theme}},
 | 
						||
            templates: {{.Themes}},
 | 
						||
            services: {{.Services}},
 | 
						||
            servicesTag: [],
 | 
						||
            servicesNoTag: []
 | 
						||
        },
 | 
						||
        created() {
 | 
						||
            this.servicesTag = this.groupingData(this.initData(this.services),"type");
 | 
						||
            this.servicesNoTag = this.initData(this.services);
 | 
						||
        },
 | 
						||
        mounted() {
 | 
						||
            this.initTooltip();
 | 
						||
        },
 | 
						||
        mixins: [mixinsVue],
 | 
						||
        methods: {
 | 
						||
            toSSBar(n) {
 | 
						||
                switch (n) {
 | 
						||
                    case "fine":
 | 
						||
                        return "success"
 | 
						||
                    case "offline":
 | 
						||
                        return "danger"
 | 
						||
                    case "error":
 | 
						||
                        return "danger"
 | 
						||
                    case "warning":
 | 
						||
                        return "warning"
 | 
						||
                }
 | 
						||
                return n
 | 
						||
            },
 | 
						||
            initData(services) {
 | 
						||
                let nodes = [];
 | 
						||
                for (let key in services) {
 | 
						||
                    const service = services[key];
 | 
						||
                    let node = {
 | 
						||
                        type: service.Monitor.Type,
 | 
						||
                        name: service.Monitor.Name,
 | 
						||
                        currentUp: parseInt(service.CurrentUp),
 | 
						||
                        currentDown: parseInt(service.CurrentDown),
 | 
						||
                        totalUp: parseInt(service.TotalUp),
 | 
						||
                        totalDown: parseInt(service.TotalDown),
 | 
						||
                        up: service.Up,
 | 
						||
                        down: service.Down,
 | 
						||
                        delay: service.Delay,
 | 
						||
                        avgDelay: parseInt(this.getAvgDelay(service.Delay)) + "ms",
 | 
						||
                        health: this.getStateInfo(this.getPercent(service.CurrentUp, service.CurrentDown)),
 | 
						||
                        totalUpTime: this.getProgressInfo(this.getPercent(service.TotalUp, service.TotalDown))
 | 
						||
                    };
 | 
						||
                    nodes.push(node);
 | 
						||
                };
 | 
						||
                for (let i = 0; i < nodes.length; i++) {
 | 
						||
                    const node = nodes[i];
 | 
						||
                    node.dayDetail = this.getDayTails(node)
 | 
						||
                }
 | 
						||
                return nodes
 | 
						||
            },
 | 
						||
            initTooltip() {
 | 
						||
                $(document).ready(function(){
 | 
						||
                    $('[data-toggle="tooltip"]').tooltip();
 | 
						||
                });
 | 
						||
            },
 | 
						||
            getPercent(up, down) {
 | 
						||
                if (!up) {
 | 
						||
                    up = 0;
 | 
						||
                }
 | 
						||
                if (!down) {
 | 
						||
                    down = 0
 | 
						||
                }
 | 
						||
                const currentUp = parseInt(up)
 | 
						||
                const currentDown = parseInt(down)
 | 
						||
                const total = currentUp + currentDown
 | 
						||
                if (total === 0) {
 | 
						||
                    if (currentUp > 0) {
 | 
						||
                        return 100
 | 
						||
                    }
 | 
						||
                    return 0
 | 
						||
                } else if (currentUp === 0) {
 | 
						||
                    return 0.00001 / total * 100
 | 
						||
                }
 | 
						||
                return this.toFixed2(currentUp / total * 100)
 | 
						||
            },
 | 
						||
            getDayTails(service) {
 | 
						||
                const result = [];
 | 
						||
                for (let i = 0; i < service.up.length; i++) {
 | 
						||
                    const up = service.up[i];
 | 
						||
                    const down = service.down[i];
 | 
						||
                    let delay = Number(service.delay[i]);
 | 
						||
                    let percent = this.getPercent(up, down);
 | 
						||
                    if (percent <= 0) {
 | 
						||
                        percent = 0;
 | 
						||
                    }
 | 
						||
                    let className = this.getStateInfo(percent).className;
 | 
						||
                    let available = '{{tr "Availability"}}';
 | 
						||
                    let averageLatency = '{{tr "AverageLatency"}}';
 | 
						||
                    const text = `${this.beforeDay(service.up.length - i - 1)},${available}:${Number(percent).toFixed(3)}%,${averageLatency}:${Number(delay).toFixed(3)}ms`;
 | 
						||
                    result.push({
 | 
						||
                        text, className
 | 
						||
                    });
 | 
						||
                }
 | 
						||
                return result;
 | 
						||
            },
 | 
						||
            beforeDay(days) {
 | 
						||
                const today = new Date();
 | 
						||
                today.setDate(today.getDate() - days);
 | 
						||
                // 获取月份和日期并格式化
 | 
						||
                const month = (today.getMonth() + 1).toString().padStart(2, '0');
 | 
						||
                const day = today.getDate().toString().padStart(2, '0');
 | 
						||
                return `${month}-${day}`;
 | 
						||
            },
 | 
						||
            getStateInfo(percent) {
 | 
						||
                if (percent < 0) {
 | 
						||
                    percent = 0;
 | 
						||
                }
 | 
						||
                const result = {
 | 
						||
                    className: "good",
 | 
						||
                    text: "",
 | 
						||
                    percent
 | 
						||
                }
 | 
						||
                if (percent === 0) {
 | 
						||
                    result.className = ""
 | 
						||
                    result.text = '{{tr "StatusNoData"}}'
 | 
						||
                } else if (percent > 95) {
 | 
						||
                    result.className = "good"
 | 
						||
                    result.text = '{{tr "StatusGood"}}'
 | 
						||
                } else if (percent > 80) {
 | 
						||
                    result.className = "warning"
 | 
						||
                    result.text = '{{tr "StatusLowAvailability"}}'
 | 
						||
                } else {
 | 
						||
                    result.className = "danger"
 | 
						||
                    result.text = '{{tr "StatusDown"}}'
 | 
						||
                }
 | 
						||
                return result;
 | 
						||
            },
 | 
						||
            getProgressInfo(percent) {
 | 
						||
                const result = this.getStateInfo(percent);
 | 
						||
                result.style = `width: ${parseInt(percent)}%`;
 | 
						||
                result.percent = Number(percent).toFixed(2);
 | 
						||
                const className = result.className;
 | 
						||
                if (className === "good") {
 | 
						||
                    result.className = 'progress-bar progress-bar-success'
 | 
						||
                } else if (className === "warning") {
 | 
						||
                    result.className = 'progress-bar progress-bar-warning'
 | 
						||
                } else if (className === "danger") {
 | 
						||
                    result.className = 'progress-bar progress-bar-danger'
 | 
						||
                } else {
 | 
						||
                    result.className = ""
 | 
						||
                    result.style = "width: 100%"
 | 
						||
                }
 | 
						||
                return result
 | 
						||
            },
 | 
						||
            getAvgDelay(array) {
 | 
						||
                const { sum, count } = array.reduce((acc, value) => {
 | 
						||
                    if (value !== 0) {
 | 
						||
                        acc.sum += value;
 | 
						||
                        acc.count += 1;
 | 
						||
                    }
 | 
						||
                    return acc;
 | 
						||
                }, { sum: 0, count: 0 });
 | 
						||
 | 
						||
                return count > 0 ? sum / count : 0;
 | 
						||
            }
 | 
						||
        }
 | 
						||
    })
 | 
						||
</script>
 | 
						||
{{template "theme-server-status/footer" .}}
 | 
						||
{{end}} |