mirror of
https://github.com/bolucat/Archive.git
synced 2026-04-23 00:17:16 +08:00
Update On Mon Feb 16 19:58:17 CET 2026
This commit is contained in:
@@ -7,38 +7,63 @@
|
||||
</p>
|
||||
</header>
|
||||
<section ref="section" :class="{ 'modal-card-body': true }">
|
||||
<b-field :label="$tc('log.refreshInterval')">
|
||||
<b-select v-model="intervalTime" @input="changeInterval">
|
||||
<option
|
||||
v-for="candidate in intervalCandidate"
|
||||
:key="candidate"
|
||||
:value="candidate"
|
||||
>
|
||||
{{ `${candidate} ${$tc("log.seconds")}` }}
|
||||
</option>
|
||||
</b-select>
|
||||
</b-field>
|
||||
<b-field label="Logs" style="margin-bottom: 2rem">
|
||||
<div class="log-title">{{ $t("log.logsLabel") }}</div>
|
||||
<div class="log-content" tabindex="0" @keydown="handleLogKeydown">
|
||||
<RecycleScroller
|
||||
ref="logScroller"
|
||||
v-slot="{ item }"
|
||||
v-slot="{ item, index }"
|
||||
class="log-scroller"
|
||||
:items="items"
|
||||
:items="filteredItems"
|
||||
:item-size="itemSize"
|
||||
:grid-items="1"
|
||||
:buffer="1000"
|
||||
>
|
||||
<hightlight-log class="text" :text="item.text"></hightlight-log>
|
||||
<div class="log-row">
|
||||
<span class="log-line-number">{{ index + 1 }}</span>
|
||||
<hightlight-log class="text" :text="item.text"></hightlight-log>
|
||||
</div>
|
||||
</RecycleScroller>
|
||||
</b-field>
|
||||
<b-field>
|
||||
<b-switch v-model="autoScoll" @input="changeScoll">
|
||||
{{ $tc("log.autoScoll") }}
|
||||
</b-switch>
|
||||
</b-field>
|
||||
</div>
|
||||
<div class="log-footer">
|
||||
<div class="log-footer-item">
|
||||
<div class="log-footer-label">{{ $tc("log.refreshInterval") }}</div>
|
||||
<div class="log-footer-control">
|
||||
<b-select v-model="intervalTime" @input="changeInterval">
|
||||
<option
|
||||
v-for="candidate in intervalCandidate"
|
||||
:key="candidate"
|
||||
:value="candidate"
|
||||
>
|
||||
{{ `${candidate} ${$tc("log.seconds")}` }}
|
||||
</option>
|
||||
</b-select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="log-footer-item">
|
||||
<div class="log-footer-label">{{ $tc("log.category") }}</div>
|
||||
<div class="log-footer-control">
|
||||
<b-select v-model="levelFilter">
|
||||
<option
|
||||
v-for="option in levelOptions"
|
||||
:key="option.value"
|
||||
:value="option.value"
|
||||
>
|
||||
{{ $t(option.label) }}
|
||||
</option>
|
||||
</b-select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="log-footer-item">
|
||||
<div class="log-footer-label">{{ $tc("log.autoScoll") }}</div>
|
||||
<div class="log-footer-control">
|
||||
<b-switch v-model="autoScoll" @input="changeScoll" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import HightlightLog from "@/components/highlightLog";
|
||||
export default {
|
||||
@@ -53,8 +78,26 @@ export default {
|
||||
intervalCandidate: [2, 5, 10, 15],
|
||||
itemSize: 28,
|
||||
autoScoll: true,
|
||||
levelFilter: "all",
|
||||
levelOptions: [
|
||||
{ value: "all", label: "log.categories.all" },
|
||||
{ value: "error", label: "log.categories.error" },
|
||||
{ value: "warn", label: "log.categories.warn" },
|
||||
{ value: "info", label: "log.categories.info" },
|
||||
{ value: "debug", label: "log.categories.debug" },
|
||||
{ value: "trace", label: "log.categories.trace" },
|
||||
{ value: "other", label: "log.categories.other" },
|
||||
],
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
filteredItems() {
|
||||
if (this.levelFilter === "all") {
|
||||
return this.items;
|
||||
}
|
||||
return this.items.filter((item) => item.level === this.levelFilter);
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.autoScoll = !(localStorage.getItem("log.autoScoll") === "false");
|
||||
|
||||
@@ -74,12 +117,63 @@ export default {
|
||||
clearInterval(this.intervalId);
|
||||
},
|
||||
methods: {
|
||||
handleLogKeydown(event) {
|
||||
const scroller = this.$refs.logScroller;
|
||||
const el = scroller && scroller.$el ? scroller.$el : null;
|
||||
if (!el) {
|
||||
return;
|
||||
}
|
||||
const pageStep = Math.max(1, Math.floor(el.clientHeight * 0.9));
|
||||
switch (event.key) {
|
||||
case "Home":
|
||||
el.scrollTop = 0;
|
||||
event.preventDefault();
|
||||
break;
|
||||
case "End":
|
||||
el.scrollTop = el.scrollHeight;
|
||||
event.preventDefault();
|
||||
break;
|
||||
case "PageUp":
|
||||
el.scrollTop = Math.max(0, el.scrollTop - pageStep);
|
||||
event.preventDefault();
|
||||
break;
|
||||
case "PageDown":
|
||||
el.scrollTop = Math.min(el.scrollHeight, el.scrollTop + pageStep);
|
||||
event.preventDefault();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
},
|
||||
detectLevel(text) {
|
||||
const lower = text.toLowerCase();
|
||||
if (lower.includes("[e]") || lower.includes(" error ")) {
|
||||
return "error";
|
||||
}
|
||||
if (lower.includes("[w]") || lower.includes(" warn")) {
|
||||
return "warn";
|
||||
}
|
||||
if (lower.includes("[d]") || lower.includes(" debug")) {
|
||||
return "debug";
|
||||
}
|
||||
if (lower.includes("[t]") || lower.includes(" trace")) {
|
||||
return "trace";
|
||||
}
|
||||
if (lower.includes("[i]") || lower.includes(" info")) {
|
||||
return "info";
|
||||
}
|
||||
return "other";
|
||||
},
|
||||
updateLog(logs) {
|
||||
if (logs.data.length && logs.data.length !== 0) {
|
||||
const baseIndex = this.items.length;
|
||||
const items = logs.data
|
||||
.split("\n")
|
||||
.map((x, i) => ({ text: x, id: baseIndex + i }));
|
||||
.map((x, i) => ({
|
||||
text: x,
|
||||
id: baseIndex + i,
|
||||
level: this.detectLevel(x),
|
||||
}));
|
||||
if (this.endOfLine) {
|
||||
this.items = this.items.concat(items);
|
||||
} else {
|
||||
@@ -88,8 +182,8 @@ export default {
|
||||
}
|
||||
this.endOfLine = items[items.length - 1].text.endsWith("\n");
|
||||
this.currentSkip += new Blob([logs.data]).size;
|
||||
if (this.autoScoll) {
|
||||
this.$refs.logScroller.scrollToItem(this.items.length - 1);
|
||||
if (this.autoScoll && this.filteredItems.length > 0) {
|
||||
this.$refs.logScroller.scrollToItem(this.filteredItems.length - 1);
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -109,13 +203,70 @@ export default {
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.text {
|
||||
font-size: 16px;
|
||||
line-height: 30px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.log-title {
|
||||
font-weight: 600;
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
|
||||
.log-content {
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.log-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.log-line-number {
|
||||
min-width: 3.5rem;
|
||||
text-align: right;
|
||||
color: #9aa4b2;
|
||||
font-size: 14px;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.log-footer {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: flex-start;
|
||||
gap: 1.5rem;
|
||||
}
|
||||
|
||||
.log-footer-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 0.5rem;
|
||||
min-width: 160px;
|
||||
}
|
||||
|
||||
.log-footer-label {
|
||||
font-weight: 600;
|
||||
min-height: 1.5rem;
|
||||
}
|
||||
|
||||
.log-footer-control ::v-deep .control,
|
||||
.log-footer-control ::v-deep .select,
|
||||
.log-footer-control ::v-deep select {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.log-footer-control ::v-deep .control {
|
||||
min-height: 40px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss">
|
||||
.log-scroller {
|
||||
height: 50vh;
|
||||
|
||||
@@ -79,7 +79,7 @@
|
||||
</template>
|
||||
</b-field>
|
||||
|
||||
<b-field v-show="transparentType == 'gvisor_tun' || transparentType == 'system_tun'" label-position="on-border">
|
||||
<b-field v-show="tunEnabled" label-position="on-border">
|
||||
<template slot="label">
|
||||
{{ $t("setting.tunMode") }}
|
||||
<b-tooltip type="is-dark" multilined :label="$t('setting.messages.tunMode')" position="is-right">
|
||||
@@ -93,7 +93,7 @@
|
||||
</b-select>
|
||||
</b-field>
|
||||
|
||||
<b-field v-show="transparentType == 'gvisor_tun' || transparentType == 'system_tun'" label-position="on-border">
|
||||
<b-field v-show="tunEnabled" label-position="on-border">
|
||||
<template slot="label">
|
||||
{{ $t("setting.tunIPv6") }}
|
||||
<b-tooltip type="is-dark" multilined :label="$t('setting.messages.tunIPv6')" position="is-right">
|
||||
@@ -107,6 +107,22 @@
|
||||
</b-select>
|
||||
</b-field>
|
||||
|
||||
<b-field v-show="tunEnabled" label-position="on-border">
|
||||
<template slot="label">StrictRoute</template>
|
||||
<b-select v-model="tunStrictRoute" expanded>
|
||||
<option :value="true">{{ $t("setting.options.enabled") }}</option>
|
||||
<option :value="false">{{ $t("setting.options.disabled") }}</option>
|
||||
</b-select>
|
||||
</b-field>
|
||||
|
||||
<b-field v-show="tunEnabled" label-position="on-border">
|
||||
<template slot="label">AutoRoute</template>
|
||||
<b-select v-model="tunAutoRoute" expanded>
|
||||
<option :value="true">{{ $t("setting.options.enabled") }}</option>
|
||||
<option :value="false">{{ $t("setting.options.disabled") }}</option>
|
||||
</b-select>
|
||||
</b-field>
|
||||
|
||||
<b-field label-position="on-border">
|
||||
<template slot="label">
|
||||
{{ $t("setting.pacMode") }}
|
||||
@@ -201,6 +217,19 @@
|
||||
</b-select>
|
||||
</b-field>
|
||||
|
||||
<b-field label-position="on-border">
|
||||
<template slot="label">
|
||||
{{ $t("setting.logLevel") }}
|
||||
</template>
|
||||
<b-select v-model="logLevel" expanded>
|
||||
<option value="trace">{{ $t("setting.options.trace") }}</option>
|
||||
<option value="debug">{{ $t("setting.options.debug") }}</option>
|
||||
<option value="info">{{ $t("setting.options.info") }}</option>
|
||||
<option value="warn">{{ $t("setting.options.warn") }}</option>
|
||||
<option value="error">{{ $t("setting.options.error") }}</option>
|
||||
</b-select>
|
||||
</b-field>
|
||||
|
||||
<b-field label-position="on-border">
|
||||
<template slot="label">
|
||||
{{ $t("setting.inboundSniffing") }}
|
||||
@@ -323,12 +352,15 @@ export default {
|
||||
data: () => ({
|
||||
proxyModeWhenSubscribe: "direct",
|
||||
tcpFastOpen: "default",
|
||||
logLevel: "info",
|
||||
muxOn: "no",
|
||||
mux: "8",
|
||||
transparent: "close",
|
||||
transparentType: "tproxy",
|
||||
tunFakeIP: true,
|
||||
tunIPv6: false,
|
||||
tunStrictRoute: false,
|
||||
tunAutoRoute: true,
|
||||
ipforward: false,
|
||||
portSharing: false,
|
||||
dnsForceMode: false,
|
||||
@@ -366,6 +398,11 @@ export default {
|
||||
}
|
||||
return toInt(port);
|
||||
},
|
||||
tunEnabled() {
|
||||
const isTunType =
|
||||
this.transparentType === "gvisor_tun" || this.transparentType === "system_tun";
|
||||
return this.transparent !== "close" && isTunType;
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
antipollution(val) {
|
||||
@@ -431,6 +468,7 @@ export default {
|
||||
),
|
||||
pacMode: this.pacMode,
|
||||
tcpFastOpen: this.tcpFastOpen,
|
||||
logLevel: this.logLevel,
|
||||
inboundSniffing: this.inboundSniffing,
|
||||
muxOn: this.muxOn,
|
||||
mux: parseInt(this.mux),
|
||||
@@ -438,6 +476,8 @@ export default {
|
||||
transparentType: this.transparentType,
|
||||
tunFakeIP: this.tunFakeIP,
|
||||
tunIPv6: this.tunIPv6,
|
||||
tunStrictRoute: this.tunStrictRoute,
|
||||
tunAutoRoute: this.tunAutoRoute,
|
||||
ipforward: this.ipforward,
|
||||
portSharing: this.portSharing,
|
||||
routeOnly: this.routeOnly,
|
||||
|
||||
@@ -112,6 +112,7 @@ export default {
|
||||
transparentType: "Transparent Proxy/System Proxy Implementation",
|
||||
tunMode: "TUN Mode",
|
||||
tunIPv6: "TUN IPv6",
|
||||
logLevel: "Log Level",
|
||||
pacMode: "Traffic Splitting Mode of Rule Port",
|
||||
preventDnsSpoofing: "Prevent DNS Spoofing",
|
||||
specialMode: "Special Mode",
|
||||
@@ -124,6 +125,11 @@ export default {
|
||||
concurrency: "Concurrency",
|
||||
inboundSniffing: "Sniffing",
|
||||
options: {
|
||||
trace: "Trace",
|
||||
debug: "Debug",
|
||||
info: "Info",
|
||||
warn: "Warn",
|
||||
error: "Error",
|
||||
global: "Do not Split Traffic",
|
||||
direct: "Direct",
|
||||
pac: "Depend on Rule Port",
|
||||
@@ -331,9 +337,20 @@ export default {
|
||||
},
|
||||
log: {
|
||||
logModalTitle: "View logs",
|
||||
logsLabel: "Logs",
|
||||
refreshInterval: "Refresh Interval",
|
||||
seconds: "seconds",
|
||||
autoScoll: "Auto Scroll",
|
||||
category: "Category",
|
||||
categories: {
|
||||
all: "All",
|
||||
error: "Error",
|
||||
warn: "Warn",
|
||||
info: "Info",
|
||||
debug: "Debug",
|
||||
trace: "Trace",
|
||||
other: "Other",
|
||||
},
|
||||
},
|
||||
tproxyWhiteIpGroups: {
|
||||
title: "White IP Groups",
|
||||
|
||||
@@ -104,6 +104,7 @@ export default {
|
||||
setting: {
|
||||
transparentProxy: "Transparent Proxy/System Proxy",
|
||||
transparentType: "Transparent Proxy/System Proxy Implementation",
|
||||
logLevel: "Log Level",
|
||||
pacMode: "Traffic Splitting Mode of Rule Port",
|
||||
preventDnsSpoofing: "جلوگیری از هک DNS",
|
||||
specialMode: "حالت ویژه",
|
||||
@@ -115,6 +116,11 @@ export default {
|
||||
portSharingOn: "به اشتراک گذاری پورت",
|
||||
concurrency: "همزمانی",
|
||||
options: {
|
||||
trace: "Trace",
|
||||
debug: "Debug",
|
||||
info: "Info",
|
||||
warn: "Warn",
|
||||
error: "Error",
|
||||
global: "عدم تقسیم ترافیک",
|
||||
direct: "Direct",
|
||||
pac: "بسته به پورت تصمیم گیری شود.",
|
||||
@@ -313,7 +319,19 @@ export default {
|
||||
},
|
||||
log: {
|
||||
logModalTitle: "دیدن لاگ ها",
|
||||
logsLabel: "لاگ ها",
|
||||
refreshInterval: "Refresh Interval",
|
||||
seconds: "ثانیه",
|
||||
autoScoll: "Auto Scroll",
|
||||
category: "Category",
|
||||
categories: {
|
||||
all: "All",
|
||||
error: "Error",
|
||||
warn: "Warn",
|
||||
info: "Info",
|
||||
debug: "Debug",
|
||||
trace: "Trace",
|
||||
other: "Other",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -104,6 +104,7 @@ export default {
|
||||
setting: {
|
||||
transparentProxy: "Proxy Transparente/Proxy do Sistema",
|
||||
transparentType: "Implementação do Proxy Transparente/Proxy do Sistema",
|
||||
logLevel: "Nível de Log",
|
||||
pacMode: "Modo de Divisão de Tráfego da Porta de Regra",
|
||||
preventDnsSpoofing: "Prevenir Falsificação de DNS",
|
||||
specialMode: "Modo Especial",
|
||||
@@ -115,6 +116,11 @@ export default {
|
||||
portSharingOn: "Compartilhamento de Porta",
|
||||
concurrency: "Concorrência",
|
||||
options: {
|
||||
trace: "Trace",
|
||||
debug: "Debug",
|
||||
info: "Info",
|
||||
warn: "Aviso",
|
||||
error: "Erro",
|
||||
global: "Não Dividir Tráfego",
|
||||
direct: "Direto",
|
||||
pac: "Depende da Porta de Regra",
|
||||
@@ -319,8 +325,19 @@ export default {
|
||||
},
|
||||
log: {
|
||||
logModalTitle: "Visualizar logs",
|
||||
logsLabel: "Logs",
|
||||
refreshInterval: "Intervalo de atualização",
|
||||
seconds: "segundos",
|
||||
autoScoll: "Rolagem Automática",
|
||||
category: "Categoria",
|
||||
categories: {
|
||||
all: "Todos",
|
||||
error: "Erro",
|
||||
warn: "Aviso",
|
||||
info: "Info",
|
||||
debug: "Debug",
|
||||
trace: "Trace",
|
||||
other: "Outros",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -107,6 +107,7 @@ export default {
|
||||
setting: {
|
||||
transparentProxy: "Прозрачный прокси/Системный прокси",
|
||||
transparentType: "Реализация прозрачного прокси/Системного прокси",
|
||||
logLevel: "Уровень журнала",
|
||||
pacMode: "Режим разделения трафика на порте с правилами",
|
||||
preventDnsSpoofing: "Предотвратить DNS-спуфинг",
|
||||
specialMode: "Специальный режим",
|
||||
@@ -119,6 +120,11 @@ export default {
|
||||
concurrency: "Параллелизм",
|
||||
inboundSniffing: "Сниффер",
|
||||
options: {
|
||||
trace: "Trace",
|
||||
debug: "Debug",
|
||||
info: "Info",
|
||||
warn: "Warn",
|
||||
error: "Error",
|
||||
global: "Не разделять трафик",
|
||||
direct: "Напрямую",
|
||||
pac: "Зависит от порта правил",
|
||||
@@ -321,9 +327,20 @@ export default {
|
||||
},
|
||||
log: {
|
||||
logModalTitle: "Просмотр журнала",
|
||||
logsLabel: "Журнал",
|
||||
refreshInterval: "Интервал обновления",
|
||||
seconds: "секунд",
|
||||
autoScoll: "Авто-пролистывание",
|
||||
category: "Категория",
|
||||
categories: {
|
||||
all: "Все",
|
||||
error: "Ошибка",
|
||||
warn: "Предупреждение",
|
||||
info: "Инфо",
|
||||
debug: "Debug",
|
||||
trace: "Trace",
|
||||
other: "Другое",
|
||||
},
|
||||
},
|
||||
domainsExcluded: {
|
||||
title: "Исключённые домены",
|
||||
|
||||
@@ -112,6 +112,7 @@ export default {
|
||||
transparentType: "透明代理/系统代理实现方式",
|
||||
tunMode: "TUN模式",
|
||||
tunIPv6: "TUN IPv6",
|
||||
logLevel: "日志等级",
|
||||
pacMode: "规则端口的分流模式",
|
||||
preventDnsSpoofing: "防止DNS污染",
|
||||
specialMode: "特殊模式",
|
||||
@@ -123,6 +124,11 @@ export default {
|
||||
portSharingOn: "开启端口分享",
|
||||
concurrency: "最大并发数",
|
||||
options: {
|
||||
trace: "跟踪",
|
||||
debug: "调试",
|
||||
info: "信息",
|
||||
warn: "警告",
|
||||
error: "错误",
|
||||
global: "不进行分流",
|
||||
direct: "直连模式",
|
||||
pac: "跟随规则端口",
|
||||
@@ -333,9 +339,20 @@ export default {
|
||||
},
|
||||
log: {
|
||||
logModalTitle: "查看日志",
|
||||
logsLabel: "日志",
|
||||
refreshInterval: "刷新间隔",
|
||||
seconds: "秒",
|
||||
autoScoll: "自动滚动",
|
||||
category: "分类",
|
||||
categories: {
|
||||
all: "全部",
|
||||
error: "错误",
|
||||
warn: "警告",
|
||||
info: "信息",
|
||||
debug: "调试",
|
||||
trace: "跟踪",
|
||||
other: "其他",
|
||||
},
|
||||
},
|
||||
|
||||
tproxyWhiteIpGroups: {
|
||||
|
||||
Reference in New Issue
Block a user