规则列表标出不可达行,「分流规则」改名「全局规则」

MATCH 的实现是无条件返回 true(rules/common/final.go:16-18),第一条
MATCH 之后的行永远轮不到。全局规则和附加规则的列表都把这类行标红、
拦路的 MATCH 标黄,hover 给原因;表底作兜底的 MATCH 不标黄,那是正常
用法。附加规则里用户自己的 MATCH 总会架空表底的自动兜底,兜底行跟着
标红。

规则页的「分流规则」改名「全局规则」,和「附加规则」对仗;术语表里
「分流规则」退为两者的统称。

顺手修 ini 导入的兜底判断:firstMatchIndex 没有 MATCH 时返回 -1,
之前误写成 === null,条件恒假,配方的兜底规则从来没被导入过。
This commit is contained in:
2026-08-12 13:43:38 +08:00
parent f57eb55328
commit 57690a159c
3 changed files with 85 additions and 21 deletions
+39 -5
View File
@@ -20,7 +20,7 @@ import {
proxyGroupName,
subRuleName,
} from '@shared/inbound-groups.ts'
import { missingLanRules } from '@shared/rules.ts'
import { firstMatchIndex, missingLanRules } from '@shared/rules.ts'
import type { GroupSpec, OutboundSetup, PanelGroup } from '@shared/inbound-groups.ts'
import { resolveChain } from '@shared/outbound-chain.ts'
import { latestDelay } from '../api'
@@ -84,6 +84,12 @@ const foreignRuleSet = computed(
/** 内网直连还缺几条。全齐了按钮就不出现 */
const lanMissing = computed(() => missingLanRules(props.subRules).length)
/**
* 用户自己写的第一条 MATCH 的下标,没有时是 -1。它之后的行——包括表底的
* 自动兜底——永远轮不到,标红;它自己标黄,hover 说明原因。
*/
const subMatchAt = computed(() => firstMatchIndex(props.subRules))
/** 默认入站由配置顶层的端口字段声明,没有 proxy 字段可写,也不能删。 */
const locked = computed(() => props.inbound.isDefault)
@@ -717,8 +723,22 @@ const complete = computed(
</h3>
<ul class="srules">
<li v-for="(rule, i) in subRules" :key="i" class="srule">
<span class="mono s-text" :title="rule">{{ rule }}</span>
<li
v-for="(rule, i) in subRules"
:key="i"
:class="['srule', subMatchAt >= 0 && i > subMatchAt && 'is-dead', i === subMatchAt && 'is-culprit']"
>
<span
class="mono s-text"
:title="
i === subMatchAt
? 'MATCH 命中所有流量,它之后的规则永远不会被检查'
: subMatchAt >= 0 && i > subMatchAt
? '排在 MATCH 之后,永远不会被检查'
: rule
"
>{{ rule }}</span
>
<span class="s-acts">
<button
type="button"
@@ -751,8 +771,12 @@ const complete = computed(
</span>
</li>
<li
class="srule is-final"
title="兜底:没被上面的规则分走的流量走这一路自己的出站。这一条由 Patchbay 自动维护"
:class="['srule is-final', subMatchAt >= 0 && 'is-dead']"
:title="
subMatchAt >= 0
? '上面的 MATCH 已拦下所有流量,这条自动兜底不会再被使用'
: '兜底:没被上面的规则分走的流量走这一路自己的出站。这一条由 Patchbay 自动维护'
"
>
<span class="mono s-text">MATCH,{{ proxyGroupName(inbound.name) }}</span>
</li>
@@ -949,6 +973,16 @@ const complete = computed(
color: var(--c-text-faint);
}
/* 不可达:在用户自己的 MATCH 之后(含自动兜底),永远轮不到 */
.srule.is-dead .s-text {
color: var(--c-danger);
}
/* 拦路的那条 MATCH:它后面的行全是死行 */
.srule.is-culprit .s-text {
color: var(--c-warn);
}
/* 操作按钮悬停到行上才现身,规则文本是主角 */
.s-acts {
flex: none;