订阅健康检查默认开启,编辑支持改名

内核没有默认的健康检查地址,url 为空时检查根本不会运行
(adapter/provider/healthcheck.go:196-199),所以默认值必须写全;
开关只翻 enable,手写的 url/interval 留着下次开启时还用。
改名和策略组 use: 的引用同步收在同一次变换里,链式副本由保存
链路的 syncGenerated 按新名字重建,缓存路径刻意不动——file 类型
的数据本体和副本认亲都靠它。
This commit is contained in:
2026-08-12 17:30:07 +08:00
parent b28fc572f7
commit d6942c5702
6 changed files with 237 additions and 49 deletions
+28 -4
View File
@@ -15,6 +15,8 @@ import {
listSubscriptions,
providerNames,
removeSubscription,
renameSubscription,
setSubscriptionHealthCheck,
subscriptionPathConflict,
subscriptionReferences,
updateSubscription,
@@ -103,7 +105,6 @@ const rows = computed(() =>
name: s.name,
lines: info ? info.proxies.length : null,
updated: parseUpdated(info?.updatedAt),
healthCheck: s.healthCheck !== null,
}
}),
)
@@ -149,7 +150,8 @@ async function submitForm(draft: {
}) {
const editing = formEditing.value
// 名字查重放行了、但净化后的缓存路径和别人相同的,在这里拦(编辑不改名,只查新增)
// 名字查重放行了、但净化后的缓存路径和别人相同的,在这里拦
// (只查新增:改名不动缓存路径,不会制造新的撞车)
if (!editing) {
const path = providerCachePath(draft.name)
const clash = subscriptionPathConflict(props.data, draft.name, path)
@@ -173,8 +175,17 @@ async function submitForm(draft: {
}
}
// 编辑时先改名再改字段。名字没动时 renameSubscription 原样返回;
// file 类型只有名称可改,不能走 updateSubscription——它会写进 url
const next = editing
? updateSubscription(clone(), editing.name, draft.url, draft.interval)
? editing.type === 'file'
? renameSubscription(clone(), editing.name, draft.name)
: updateSubscription(
renameSubscription(clone(), editing.name, draft.name),
draft.name,
draft.url,
draft.interval,
)
: draft.file
? addFileSubscription(clone(), draft.name)
: addSubscription(clone(), draft.name, draft.url, draft.interval)
@@ -182,7 +193,8 @@ async function submitForm(draft: {
// 失败时不能关对话框——关了再打开就是空表单,填的名称、地址、间隔全没了
if (!ok) return
formOpen.value = false
if (!editing) selectedName.value = draft.name
// 新增和改名都要把选中跟过去,否则选中名失效会被重置到第一行
selectedName.value = draft.name
}
function askRemove() {
@@ -205,6 +217,17 @@ async function removeConfirmed() {
await commit(removeSubscription(clone(), target.name), `已删除 ${target.name}`)
}
/** 开关选中订阅的健康检查。写配置文件,走 commit()。 */
async function toggleHealthCheck() {
const target = selected.value
if (!target || saving.value) return
const enable = target.healthCheck === null
await commit(
setSubscriptionHealthCheck(clone(), target.name, enable),
enable ? `已开启 ${target.name} 的健康检查` : `已关闭 ${target.name} 的健康检查`,
)
}
/** 让内核立刻重新拉取。运行时动作,不写配置文件,所以不走 commit()。 */
async function refresh() {
const target = selected.value
@@ -290,6 +313,7 @@ async function refreshAll() {
@edit="openEdit"
@remove="askRemove"
@refresh="refresh"
@toggle-health-check="toggleHealthCheck"
/>
</div>