Skip to content

Commit e369079

Browse files
committed
feat: 调整部分页面 && 数据库字段变动
1 parent 0860507 commit e369079

11 files changed

Lines changed: 209 additions & 46 deletions

File tree

app/endpoints/details/page.tsx

Lines changed: 29 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -208,20 +208,7 @@ export default function EndpointDetailPage() {
208208
)}
209209
</div>
210210
<div className="flex items-center gap-2">
211-
<Button
212-
variant="light"
213-
isDisabled={refreshLoading}
214-
className="bg-default-100 hover:bg-default-200 dark:bg-default-100/10 dark:hover:bg-default-100/20"
215-
startContent={
216-
<FontAwesomeIcon
217-
icon={faRotateRight}
218-
className={refreshLoading ? "animate-spin" : ""}
219-
/>
220-
}
221-
onPress={handleRefresh}
222-
>
223-
{refreshLoading ? "刷新中..." : "刷新"}
224-
</Button>
211+
225212
{/* 回收站按钮 */}
226213
<Button
227214
isIconOnly
@@ -235,14 +222,7 @@ export default function EndpointDetailPage() {
235222
</Badge>
236223
</Button>
237224

238-
{/* 日志查询按钮 */}
239-
<Button
240-
isIconOnly
241-
color="primary"
242-
onPress={()=>router.push(`/endpoints/log?id=${endpointId}`)}
243-
>
244-
<FontAwesomeIcon icon={faMagnifyingGlass} />
245-
</Button>
225+
246226
</div>
247227
</div>
248228

@@ -387,8 +367,34 @@ export default function EndpointDetailPage() {
387367

388368
{/* 日志区域 */}
389369
<Card className="p-2">
390-
<CardHeader>
370+
<CardHeader className="flex items-center justify-between">
391371
<h3 className="text-lg font-semibold">日志输出</h3>
372+
<div className="flex items-center gap-2">
373+
<Button
374+
variant="light"
375+
size="sm"
376+
isDisabled={refreshLoading}
377+
className="bg-default-100 hover:bg-default-200 dark:bg-default-100/10 dark:hover:bg-default-100/20"
378+
startContent={
379+
<FontAwesomeIcon
380+
icon={faRotateRight}
381+
className={refreshLoading ? "animate-spin" : ""}
382+
/>
383+
}
384+
onPress={handleRefresh}
385+
>
386+
{refreshLoading ? "刷新中..." : "刷新"}
387+
</Button>
388+
{/* 日志查询按钮 */}
389+
<Button
390+
size="sm"
391+
isIconOnly
392+
color="primary"
393+
onPress={()=>router.push(`/endpoints/log?id=${endpointId}`)}
394+
>
395+
<FontAwesomeIcon icon={faMagnifyingGlass} />
396+
</Button>
397+
</div>
392398
</CardHeader>
393399
<CardBody>
394400
<LogViewer logs={logs} loading={loading} heightClass="h-[550px] md:h-[900px]" containerRef={logContainerRef} />

app/endpoints/page.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -981,8 +981,8 @@ export default function EndpointsPage() {
981981
</TableCell>
982982
<TableCell className="w-52">
983983
<div className="flex items-center gap-1 justify-start">
984-
{/* 查看日志 */}
985-
<Tooltip content="查看日志">
984+
{/* 查看详情 */}
985+
<Tooltip content="查看详情">
986986
<Button isIconOnly size="sm" variant="light" color="primary" onPress={()=>router.push(`/endpoints/details?id=${ep.id}`)}>
987987
<FontAwesomeIcon icon={faFileLines} />
988988
</Button>

app/tunnels/components/quick-create-tunnel-modal.tsx

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,6 @@ export default function QuickCreateTunnelModal({ isOpen, onOpenChange, onSaved,
164164
try {
165165
setSubmitting(true);
166166
const url = modalMode==='edit' ? buildApiUrl(`/api/tunnels/${editData?.id}`) : buildApiUrl("/api/tunnels");
167-
console.log("url",url);
168167
const method = modalMode==='edit' ? 'PUT' : 'POST';
169168
const res = await fetch(url, {
170169
method: method,
@@ -295,28 +294,18 @@ export default function QuickCreateTunnelModal({ isOpen, onOpenChange, onSaved,
295294
{/* 密码配置(可选) - 仅在选中主控版本不为空时显示 */}
296295
{(() => {
297296
// 更详细的调试信息
298-
console.log('=== 密码显示调试开始 ===');
299-
console.log('formData.apiEndpoint:', formData.apiEndpoint, typeof formData.apiEndpoint);
300-
console.log('endpoints:', endpoints);
301-
297+
302298
// 尝试不同的匹配方式
303299
const selectedEndpoint1 = endpoints.find(ep => ep.id === formData.apiEndpoint);
304300
const selectedEndpoint2 = endpoints.find(ep => String(ep.id) === String(formData.apiEndpoint));
305301
const selectedEndpoint3 = endpoints.find(ep => Number(ep.id) === Number(formData.apiEndpoint));
306302

307-
console.log('匹配方式1 (直接相等):', selectedEndpoint1);
308-
console.log('匹配方式2 (String转换):', selectedEndpoint2);
309-
console.log('匹配方式3 (Number转换):', selectedEndpoint3);
310-
303+
311304
// 使用最安全的匹配方式
312305
const selectedEndpoint = selectedEndpoint2 || selectedEndpoint1 || selectedEndpoint3;
313306
const hasVersion = selectedEndpoint && selectedEndpoint.version && selectedEndpoint.version.trim() !== '';
314307

315-
console.log('最终选中的endpoint:', selectedEndpoint);
316-
console.log('version:', selectedEndpoint?.version);
317-
console.log('hasVersion:', hasVersion);
318-
console.log('=== 密码显示调试结束 ===');
319-
308+
320309
if (!hasVersion) return null;
321310

322311
return (

app/tunnels/recycle/page.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ interface RecycleItem {
2626
logLevel: string;
2727
commandLine: string;
2828
instanceId?: string | null;
29+
password?: string | null;
2930
tcpRx: number;
3031
tcpTx: number;
3132
udpRx: number;
@@ -323,6 +324,13 @@ export default function RecyclePage(){
323324
{(item.mode === "server" || item.mode === "client") && (
324325
<div className="pt-2 border-t border-default-200/50">
325326
<div className="grid gap-3 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4">
327+
{/* 隧道密码显示 - 优先显示 */}
328+
<div>
329+
<span className="font-medium mr-1">隧道密码:</span>
330+
<span className="font-mono text-sm">
331+
{formatVal(item.password) !== "-" && item.password ? item.password : "-"}
332+
</span>
333+
</div>
326334
{/* 服务端模式才显示 TLS 相关信息 */}
327335
{item.mode === "server" && (
328336
<>

cmd/server/main.go

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,14 @@ func initDatabase(db *sql.DB) error {
323323
lastCheck DATETIME DEFAULT CURRENT_TIMESTAMP,
324324
createdAt DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
325325
updatedAt DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
326-
tunnelCount INTEGER DEFAULT 0
326+
tunnelCount INTEGER DEFAULT 0,
327+
os TEXT DEFAULT '',
328+
arch TEXT DEFAULT '',
329+
ver TEXT DEFAULT '',
330+
log TEXT DEFAULT '',
331+
tls TEXT DEFAULT '',
332+
crt TEXT DEFAULT '',
333+
key_path TEXT DEFAULT ''
327334
);`
328335

329336
createTunnelTable := `
@@ -343,6 +350,7 @@ func initDatabase(db *sql.DB) error {
343350
logLevel TEXT NOT NULL DEFAULT 'info',
344351
commandLine TEXT NOT NULL,
345352
instanceId TEXT,
353+
password TEXT DEFAULT '',
346354
tcpRx INTEGER DEFAULT 0,
347355
tcpTx INTEGER DEFAULT 0,
348356
udpRx INTEGER DEFAULT 0,
@@ -371,6 +379,7 @@ func initDatabase(db *sql.DB) error {
371379
logLevel TEXT NOT NULL DEFAULT 'info',
372380
commandLine TEXT NOT NULL,
373381
instanceId TEXT,
382+
password TEXT DEFAULT '',
374383
tcpRx INTEGER DEFAULT 0,
375384
tcpTx INTEGER DEFAULT 0,
376385
udpRx INTEGER DEFAULT 0,
@@ -462,6 +471,39 @@ func initDatabase(db *sql.DB) error {
462471
return err
463472
}
464473

474+
// ---- 为 Tunnel 表添加密码字段 ----
475+
if err := ensureColumn(db, "Tunnel", "password", "TEXT DEFAULT ''"); err != nil {
476+
return err
477+
}
478+
479+
// ---- 为 TunnelRecycle 表添加密码字段 ----
480+
if err := ensureColumn(db, "TunnelRecycle", "password", "TEXT DEFAULT ''"); err != nil {
481+
return err
482+
}
483+
484+
// ---- 为 Endpoint 表添加系统信息字段 ----
485+
if err := ensureColumn(db, "Endpoint", "os", "TEXT DEFAULT ''"); err != nil {
486+
return err
487+
}
488+
if err := ensureColumn(db, "Endpoint", "arch", "TEXT DEFAULT ''"); err != nil {
489+
return err
490+
}
491+
if err := ensureColumn(db, "Endpoint", "ver", "TEXT DEFAULT ''"); err != nil {
492+
return err
493+
}
494+
if err := ensureColumn(db, "Endpoint", "log", "TEXT DEFAULT ''"); err != nil {
495+
return err
496+
}
497+
if err := ensureColumn(db, "Endpoint", "tls", "TEXT DEFAULT ''"); err != nil {
498+
return err
499+
}
500+
if err := ensureColumn(db, "Endpoint", "crt", "TEXT DEFAULT ''"); err != nil {
501+
return err
502+
}
503+
if err := ensureColumn(db, "Endpoint", "key_path", "TEXT DEFAULT ''"); err != nil {
504+
return err
505+
}
506+
465507
return nil
466508
}
467509

components/ui/os-icon.tsx

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
import React from 'react';
2+
3+
interface OSIconProps {
4+
os?: string;
5+
arch?: string;
6+
type?: 'os' | 'arch';
7+
className?: string;
8+
}
9+
10+
export const OSIcon: React.FC<OSIconProps> = ({ os, arch, type = 'os', className = "w-4 h-4" }) => {
11+
const getOSIcon = (osName: string) => {
12+
const osLower = osName.toLowerCase();
13+
14+
if (osLower.includes('windows')) {
15+
return (
16+
<svg className={className} viewBox="0 0 24 24" fill="currentColor">
17+
<path d="M0 3.449L9.75 2.1v9.451H0m10.949-9.602L24 0v11.4H10.949M0 12.6h9.75v9.451L0 20.699M10.949 12.6H24V24l-13.051-1.351"/>
18+
</svg>
19+
);
20+
}
21+
22+
if (osLower.includes('linux') || osLower.includes('ubuntu') || osLower.includes('debian') || osLower.includes('centos') || osLower.includes('redhat') || osLower.includes('fedora')) {
23+
return (
24+
<svg className={className} viewBox="0 0 24 24" fill="currentColor">
25+
<path d="M12.504 0c-.155 0-.315.008-.480.021-4.226.333-3.105 4.807-3.17 6.298-.076 1.092-.3 1.953-1.05 3.02-.885 1.051-2.127 2.75-2.716 4.521-.278.832-.41 1.684-.287 2.489a.424.424 0 00-.11.135c-.26.268-.45.6-.663.839-.199.199-.485.267-.797.4-.313.136-.658.269-.864.68-.09.189-.136.394-.132.602 0 .199.027.4.055.536.058.399.116.728.04.97-.249.68-.28 1.145-.106 1.484.174.334.535.47.94.601.81.2 1.91.135 2.774.6.926.466 1.866.67 2.616.47.526-.116.97-.464 1.208-.946.587-.003 1.23-.269 2.26-.334.699-.058 1.574.267 2.577.2.025.134.063.198.114.333l.003.003c.391.778 1.113 1.132 1.884 1.071.771-.06 1.592-.536 2.257-1.306.631-.765 1.683-1.084 2.378-1.503.348-.199.629-.469.649-.853.023-.4-.2-.811-.714-1.376v-.097l-.003-.003c-.17-.2-.25-.535-.338-.926-.085-.401-.182-.786-.492-1.046h-.003c-.059-.054-.123-.067-.188-.135a.357.357 0 00-.19-.064c.431-1.278.264-2.55-.173-3.694-.533-1.41-1.465-2.638-2.175-3.483-.796-1.005-1.576-1.957-1.56-3.368.026-2.152.236-6.133-3.544-6.139zm.529 3.405h.013c.213 0 .396.062.584.198.19.135.33.332.438.533.105.259.158.459.166.724 0-.02.006-.04.006-.06v.105a.086.086 0 01-.004-.021l-.004-.024a1.807 1.807 0 01-.15.706c-.1.146-.247.273-.398.392a1.249 1.249 0 01-.543.2 1.301 1.301 0 01-.485-.06c-.207-.08-.347-.222-.472-.368a1.679 1.679 0 01-.305-.668c-.044-.239-.003-.457.046-.672.040-.168.095-.284.168-.403.145-.238.343-.356.539-.398a.706.706 0 01.402-.042zm4.505 1.036a.143.143 0 00-.031.009l.036-.004-.005-.005zm-.549.104c-.831.02-1.066.756-1.098 1.02-.037.31-.17.542-.334.828-.163.286-.351.543-.421.999-.051.334.010.696.154.98.144.283.397.509.658.678.522.338 1.372.347 1.975.075.603-.272 1.178-.781 1.157-1.307-.02-.525-.396-.989-.922-1.266-.526-.276-1.169-.401-1.169-.007zm-2.027 2.507c-.403.005-.416.5-.416.5s.013.495.416.5c.402-.005.415-.5.415-.5s-.013-.495-.415-.5z"/>
26+
</svg>
27+
);
28+
}
29+
30+
if (osLower.includes('mac') || osLower.includes('darwin') || osLower.includes('macos')) {
31+
return (
32+
<svg className={className} viewBox="0 0 24 24" fill="currentColor">
33+
<path d="M18.71 19.5c-.83 1.24-1.71 2.45-3.05 2.47-1.34.03-1.77-.79-3.29-.79-1.53 0-2 .77-3.27.82-1.31.05-2.3-1.32-3.14-2.53C4.25 17 2.94 12.45 4.7 9.39c.87-1.52 2.43-2.48 4.12-2.51 1.28-.02 2.5.87 3.29.87.78 0 2.26-1.07 3.81-.91.65.03 2.47.26 3.64 1.98-.09.06-2.17 1.28-2.15 3.81.03 3.02 2.65 4.03 2.68 4.04-.03.07-.42 1.44-1.38 2.83M13 3.5c.73-.83 1.94-1.46 2.94-1.5.13 1.17-.34 2.35-1.04 3.19-.69.85-1.83 1.51-2.95 1.42-.15-1.15.41-2.35 1.05-3.11z"/>
34+
</svg>
35+
);
36+
}
37+
38+
if (osLower.includes('android')) {
39+
return (
40+
<svg className={className} viewBox="0 0 24 24" fill="currentColor">
41+
<path d="M17.523 15.3414c-.5511 0-.9993-.4486-.9993-.9997s.4482-.9993.9993-.9993c.5511 0 .9993.4482.9993.9993.0001.5511-.4482.9997-.9993.9997m-11.046 0c-.5511 0-.9993-.4486-.9993-.9997s.4482-.9993.9993-.9993c.5511 0 .9993.4482.9993.9993 0 .5511-.4482.9997-.9993.9997m11.4045-6.02l1.9973-3.4592a.416.416 0 00-.1521-.5676.416.416 0 00-.5676.1521l-2.0223 3.503C15.5902 8.2439 13.8533 7.8508 12 7.8508s-3.5902.3931-5.1367 1.0989L4.841 5.4467a.4161.4161 0 00-.5677-.1521.4157.4157 0 00-.1521.5676l1.9973 3.4592C2.6889 11.1867.3432 14.6589 0 18.761h24c-.3435-4.1021-2.6892-7.5743-6.1185-9.4396"/>
42+
</svg>
43+
);
44+
}
45+
46+
// 默认显示通用操作系统图标
47+
return (
48+
<svg className={className} viewBox="0 0 24 24" fill="currentColor">
49+
<path d="M4 6h16v2H4zm0 5h16v2H4zm0 5h16v2H4z"/>
50+
</svg>
51+
);
52+
};
53+
54+
const getArchIcon = (archName: string) => {
55+
const archLower = archName.toLowerCase();
56+
57+
if (archLower.includes('x64') || archLower.includes('amd64') || archLower.includes('x86_64')) {
58+
return (
59+
<svg className={className} viewBox="0 0 24 24" fill="currentColor">
60+
<path d="M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5"/>
61+
</svg>
62+
);
63+
}
64+
65+
if (archLower.includes('arm') || archLower.includes('aarch64')) {
66+
return (
67+
<svg className={className} viewBox="0 0 24 24" fill="currentColor">
68+
<path d="M9.5 2A1.5 1.5 0 008 3.5v1A1.5 1.5 0 009.5 6h5A1.5 1.5 0 0016 4.5v-1A1.5 1.5 0 0014.5 2h-5zM12 8a4 4 0 00-4 4v6a2 2 0 002 2h4a2 2 0 002-2v-6a4 4 0 00-4-4z"/>
69+
</svg>
70+
);
71+
}
72+
73+
if (archLower.includes('x86') || archLower.includes('i386') || archLower.includes('i686')) {
74+
return (
75+
<svg className={className} viewBox="0 0 24 24" fill="currentColor">
76+
<path d="M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5"/>
77+
</svg>
78+
);
79+
}
80+
81+
// 默认CPU图标
82+
return (
83+
<svg className={className} viewBox="0 0 24 24" fill="currentColor">
84+
<path d="M6 18h12V8H6v10zM8 4h8v2H8V4zM8 20v-2h8v2H8z"/>
85+
</svg>
86+
);
87+
};
88+
89+
if (type === 'arch' && arch) {
90+
return getArchIcon(arch);
91+
}
92+
93+
if (type === 'os' && os) {
94+
return getOSIcon(os);
95+
}
96+
97+
return null;
98+
};

internal/api/endpoint.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -720,7 +720,7 @@ func (h *EndpointHandler) HandleRecycleList(w http.ResponseWriter, r *http.Reque
720720

721721
// 查询 TunnelRecycle 表所有字段
722722
rows, err := db.Query(`SELECT id, name, mode, tunnelAddress, tunnelPort, targetAddress, targetPort, tlsMode,
723-
certPath, keyPath, logLevel, commandLine, instanceId, tcpRx, tcpTx, udpRx, udpTx, min, max
723+
certPath, keyPath, logLevel, commandLine, instanceId, password, tcpRx, tcpTx, udpRx, udpTx, min, max
724724
FROM "TunnelRecycle" WHERE endpointId = ? ORDER BY id DESC`, endpointID)
725725
if err != nil {
726726
w.WriteHeader(http.StatusInternalServerError)
@@ -743,6 +743,7 @@ func (h *EndpointHandler) HandleRecycleList(w http.ResponseWriter, r *http.Reque
743743
LogLevel string `json:"logLevel"`
744744
CommandLine string `json:"commandLine"`
745745
InstanceID sql.NullString `json:"instanceId"`
746+
Password string `json:"password"`
746747
TCPRx int64 `json:"tcpRx"`
747748
TCPTx int64 `json:"tcpTx"`
748749
UDPRx int64 `json:"udpRx"`
@@ -756,7 +757,7 @@ func (h *EndpointHandler) HandleRecycleList(w http.ResponseWriter, r *http.Reque
756757
var item recycleItem
757758
if err := rows.Scan(
758759
&item.ID, &item.Name, &item.Mode, &item.TunnelAddress, &item.TunnelPort, &item.TargetAddress, &item.TargetPort, &item.TLSMode,
759-
&item.CertPath, &item.KeyPath, &item.LogLevel, &item.CommandLine, &item.InstanceID, &item.TCPRx, &item.TCPTx, &item.UDPRx, &item.UDPTx, &item.Min, &item.Max,
760+
&item.CertPath, &item.KeyPath, &item.LogLevel, &item.CommandLine, &item.InstanceID, &item.Password, &item.TCPRx, &item.TCPTx, &item.UDPRx, &item.UDPTx, &item.Min, &item.Max,
760761
); err == nil {
761762
list = append(list, item)
762763
}
@@ -870,7 +871,7 @@ func (h *EndpointHandler) HandleRecycleListAll(w http.ResponseWriter, r *http.Re
870871
db := h.endpointService.DB()
871872

872873
rows, err := db.Query(`SELECT tr.id, tr.name, tr.mode, tr.tunnelAddress, tr.tunnelPort, tr.targetAddress, tr.targetPort, tr.tlsMode,
873-
tr.certPath, tr.keyPath, tr.logLevel, tr.commandLine, tr.instanceId, tr.tcpRx, tr.tcpTx, tr.udpRx, tr.udpTx, tr.min, tr.max,
874+
tr.certPath, tr.keyPath, tr.logLevel, tr.commandLine, tr.instanceId, tr.password, tr.tcpRx, tr.tcpTx, tr.udpRx, tr.udpTx, tr.min, tr.max,
874875
tr.endpointId, ep.name as endpointName
875876
FROM "TunnelRecycle" tr
876877
JOIN "Endpoint" ep ON tr.endpointId = ep.id
@@ -898,6 +899,7 @@ func (h *EndpointHandler) HandleRecycleListAll(w http.ResponseWriter, r *http.Re
898899
LogLevel string `json:"logLevel"`
899900
CommandLine string `json:"commandLine"`
900901
InstanceID sql.NullString `json:"instanceId"`
902+
Password string `json:"password"`
901903
TCPRx int64 `json:"tcpRx"`
902904
TCPTx int64 `json:"tcpTx"`
903905
UDPRx int64 `json:"udpRx"`
@@ -911,7 +913,7 @@ func (h *EndpointHandler) HandleRecycleListAll(w http.ResponseWriter, r *http.Re
911913
var item recycleItemAll
912914
if err := rows.Scan(
913915
&item.ID, &item.Name, &item.Mode, &item.TunnelAddress, &item.TunnelPort, &item.TargetAddress, &item.TargetPort, &item.TLSMode,
914-
&item.CertPath, &item.KeyPath, &item.LogLevel, &item.CommandLine, &item.InstanceID, &item.TCPRx, &item.TCPTx, &item.UDPRx, &item.UDPTx, &item.Min, &item.Max,
916+
&item.CertPath, &item.KeyPath, &item.LogLevel, &item.CommandLine, &item.InstanceID, &item.Password, &item.TCPRx, &item.TCPTx, &item.UDPRx, &item.UDPTx, &item.Min, &item.Max,
915917
&item.EndpointID, &item.EndpointName,
916918
); err == nil {
917919
list = append(list, item)

internal/db/db.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,11 @@ func initSchema(db *sql.DB) error {
152152
return err
153153
}
154154

155+
// -------- 为 TunnelRecycle 表添加密码字段 --------
156+
if err := ensureColumn(db, "TunnelRecycle", "password", "TEXT DEFAULT ''"); err != nil {
157+
return err
158+
}
159+
155160
// -------- 为 Endpoint 表添加系统信息字段 --------
156161
if err := ensureColumn(db, "Endpoint", "os", "TEXT DEFAULT ''"); err != nil {
157162
return err
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
-- 为端点表添加系统信息字段
2+
ALTER TABLE "Endpoint" ADD COLUMN os TEXT DEFAULT '';
3+
ALTER TABLE "Endpoint" ADD COLUMN arch TEXT DEFAULT '';
4+
ALTER TABLE "Endpoint" ADD COLUMN ver TEXT DEFAULT '';
5+
ALTER TABLE "Endpoint" ADD COLUMN log TEXT DEFAULT '';
6+
ALTER TABLE "Endpoint" ADD COLUMN tls TEXT DEFAULT '';
7+
ALTER TABLE "Endpoint" ADD COLUMN crt TEXT DEFAULT '';
8+
ALTER TABLE "Endpoint" ADD COLUMN key_path TEXT DEFAULT '';
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
-- 为隧道表添加密码字段
2+
ALTER TABLE "Tunnel" ADD COLUMN password TEXT DEFAULT '';
3+
4+
-- 为隧道回收站表也添加密码字段以保持一致性
5+
ALTER TABLE "TunnelRecycle" ADD COLUMN password TEXT DEFAULT '';

0 commit comments

Comments
 (0)