核心功能设计已完成,包含frpc热重启冷重启两种设计逻辑

This commit is contained in:
2026-07-23 20:17:03 +08:00
parent 4cfb684f86
commit 2afff129b9
8 changed files with 500 additions and 78 deletions
+21 -42
View File
@@ -17,7 +17,7 @@ const app = createApp({
const token = ref("");
// ===== Tab =====
const activeTab = ref("config");
const activeTab = ref("proxies");
// ===== 全局配置 =====
const globalConfig = reactive({
@@ -296,51 +296,30 @@ const app = createApp({
const handleImport = async (e) => {
const file = e.target.files[0];
if (!file) return;
try {
const text = await file.text();
const parsed = TOML.parse(text);
if (!parsed.proxies || !Array.isArray(parsed.proxies)) {
alert("无效的 TOML 文件:缺少 proxies 数组");
return;
}
// 过滤出有效的隧道条目
const list = parsed.proxies.filter(
(p) => p.name && p.localIP && p.localPort && p.remotePort,
);
if (list.length === 0) {
alert("未解析到有效的隧道条目");
return;
}
if (
!confirm(`解析到 ${list.length} 条隧道,将覆盖当前配置,确认导入?`)
)
return;
// 批量导入:先清空,再逐条插入(后端未提供批量接口,用循环)
// 简单做法:先删除所有,再逐个创建
for (const p of proxies.value) {
await apiFetch("/api/proxy/" + p.id, { method: "DELETE" });
const formData = new FormData();
formData.append('file', file);
try {
const res = await fetch('/api/import/toml', {
method: 'POST',
headers: {
'Authorization': 'Bearer ' + token.value,
// 不要设置 Content-Type,浏览器会自动加上 boundary
},
body: formData,
});
const data = await res.json();
if (data.code === 0) {
alert(data.msg);
await loadAllData();
} else {
alert('导入失败: ' + data.msg);
}
for (const p of list) {
await apiFetch("/api/proxy", {
method: "POST",
body: JSON.stringify({
name: p.name,
type: p.type || "tcp",
localIP: p.localIP,
localPort: p.localPort,
remotePort: p.remotePort,
enabled: p.enabled !== undefined ? p.enabled : true,
}),
});
}
await loadProxies();
await loadFrpcStatus();
alert("导入成功!");
} catch (err) {
alert("解析 TOML 失败: " + err.message);
alert('网络错误: ' + err.message);
}
e.target.value = "";
e.target.value = '';
};
// ===== 导出 TOML =====