feat: 支持自定义订阅节点并兼容现有数据库

This commit is contained in:
2026-09-29 11:52:41 +08:00
parent 3faf960f35
commit ab7d1c937a
27 changed files with 2203 additions and 449 deletions
+89
View File
@@ -0,0 +1,89 @@
import { ActionForm } from "@/components/action-form";
import { CopyButton } from "@/components/copy-button";
import { Input } from "@/components/ui/input";
import { SubmitButton } from "@/components/submit-button";
import type { Hy2NodeRow } from "@/lib/store";
import { createNodeAction, updateNodeAction } from "./actions";
const example = `- name: "HK AnyTLS"
type: anytls
server: hk.example.com
port: 443
password: "your-password"
sni: hk.example.com
udp: true`;
export function CustomNodeForm({ node }: { node?: Hy2NodeRow }) {
return (
<ActionForm
action={node ? updateNodeAction : createNodeAction}
className="dense-form-grid dense-form-grid--nodes"
>
{node && <input name="id" type="hidden" value={node.id} />}
<input name="node_type" type="hidden" value="custom" />
<label className="field">
<span>Slug</span>
<Input
name="slug"
defaultValue={node?.slug}
placeholder="hk-anytls"
required
/>
</label>
<label className="field">
<span>显示名</span>
<Input
name="name"
defaultValue={node?.name}
placeholder="香港 · AnyTLS"
required
/>
</label>
<label className="checkbox">
<input
name="enabled"
type="checkbox"
defaultChecked={node ? Boolean(node.enabled) : true}
/>
<span>启用节点</span>
</label>
<p className="muted full-span">
仅写入订阅,不使用 HY2 鉴权和流量统计。订阅中的节点名称以 YAML 的 name
为准。
</p>
<label className="field full-span">
<span>节点 YAML</span>
<textarea
className="mono-textarea"
name="custom_config_yaml"
defaultValue={node?.custom_config_yaml}
placeholder={example}
rows={9}
spellCheck={false}
autoCapitalize="off"
required
aria-describedby={node ? `yaml-help-${node.id}` : "yaml-help-new"}
/>
</label>
<div className="full-span stack-tight">
<p
className="muted text-xs"
id={node ? `yaml-help-${node.id}` : "yaml-help-new"}
>
支持单个 proxy 对象、单节点列表,或 proxies
包装;每条记录一个节点。保存后可在「订阅配置」中拖拽排序、加入分组。
</p>
<details className="config-collapse">
<summary>查看 AnyTLS 示例</summary>
<pre>{example}</pre>
<div className="p-2">
<CopyButton value={example} />
</div>
</details>
</div>
<SubmitButton variant={node ? "outline" : "default"}>
{node ? "保存自定义节点" : "创建自定义节点"}
</SubmitButton>
</ActionForm>
);
}