update at 2026-03-05 19:48:59
This commit is contained in:
4
pxterm/public/icons/copy.svg
Normal file
4
pxterm/public/icons/copy.svg
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="currentColor">
|
||||||
|
<path d="M4 2a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V2z"/>
|
||||||
|
<path d="M2 6a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2v-1H6a3 3 0 0 1-3-3V6H2z"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 284 B |
@@ -198,6 +198,41 @@ export const useServerStore = defineStore("server", () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function copyServer(serverId: string): Promise<void> {
|
||||||
|
const sourceServer = servers.value.find((item) => item.id === serverId);
|
||||||
|
if (!sourceServer) {
|
||||||
|
throw new Error("源服务器不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建新服务器,复制所有信息
|
||||||
|
const copiedServer: ServerProfile = {
|
||||||
|
...sourceServer,
|
||||||
|
id: `srv-${crypto.randomUUID()}`,
|
||||||
|
name: `${sourceServer.name}-copy`,
|
||||||
|
projectPresets: [...sourceServer.projectPresets],
|
||||||
|
tags: [...sourceServer.tags],
|
||||||
|
lastConnectedAt: ""
|
||||||
|
};
|
||||||
|
|
||||||
|
// 复制凭据
|
||||||
|
try {
|
||||||
|
const sourceCredential = await getCredentialInput(serverId);
|
||||||
|
if (sourceCredential) {
|
||||||
|
await saveCredential(copiedServer.id, sourceCredential);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
// 如果凭据复制失败,仍然创建服务器,但不复制凭据
|
||||||
|
console.warn("复制凭据失败:", error);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 保存新服务器(插入到源服务器后面)
|
||||||
|
const sourceIndex = servers.value.findIndex((item) => item.id === serverId);
|
||||||
|
const nextServers = [...servers.value];
|
||||||
|
nextServers.splice(sourceIndex + 1, 0, copiedServer);
|
||||||
|
await persistServerOrder(nextServers);
|
||||||
|
selectedServerId.value = copiedServer.id;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 将指定服务器上移一位。
|
* 将指定服务器上移一位。
|
||||||
* 返回:
|
* 返回:
|
||||||
@@ -371,6 +406,7 @@ export const useServerStore = defineStore("server", () => {
|
|||||||
createServer,
|
createServer,
|
||||||
saveServer,
|
saveServer,
|
||||||
deleteServer,
|
deleteServer,
|
||||||
|
copyServer,
|
||||||
moveServerUp,
|
moveServerUp,
|
||||||
moveServerDown,
|
moveServerDown,
|
||||||
applyServerOrder,
|
applyServerOrder,
|
||||||
|
|||||||
@@ -637,6 +637,7 @@ select.input {
|
|||||||
margin-left: 3px;
|
margin-left: 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.server-copy-btn,
|
||||||
.server-ai-btn,
|
.server-ai-btn,
|
||||||
.server-move-btn,
|
.server-move-btn,
|
||||||
.connect-icon-btn {
|
.connect-icon-btn {
|
||||||
@@ -652,12 +653,18 @@ select.input {
|
|||||||
transition: background-color 0.16s ease, box-shadow 0.16s ease, opacity 0.16s ease;
|
transition: background-color 0.16s ease, box-shadow 0.16s ease, opacity 0.16s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.server-copy-icon,
|
||||||
.server-ai-icon {
|
.server-ai-icon {
|
||||||
width: 22px;
|
width: 22px;
|
||||||
height: 22px;
|
height: 22px;
|
||||||
background-color: var(--btn);
|
background-color: var(--btn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.server-copy-btn:hover:not(:disabled) {
|
||||||
|
background: color-mix(in srgb, var(--accent) 16%, transparent);
|
||||||
|
border-radius: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
.server-move-btn {
|
.server-move-btn {
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
cursor: grab;
|
cursor: grab;
|
||||||
|
|||||||
@@ -68,6 +68,15 @@
|
|||||||
<div class="server-info-top">
|
<div class="server-info-top">
|
||||||
<p class="server-name">{{ item.name }}</p>
|
<p class="server-name">{{ item.name }}</p>
|
||||||
<div class="server-row-actions" @click.stop>
|
<div class="server-row-actions" @click.stop>
|
||||||
|
<button
|
||||||
|
class="server-copy-btn"
|
||||||
|
type="button"
|
||||||
|
title="复制服务器"
|
||||||
|
aria-label="复制服务器"
|
||||||
|
@click.stop="copyServer(item)"
|
||||||
|
>
|
||||||
|
<span class="icon-mask server-copy-icon" style="--icon: url('/icons/copy.svg')" aria-hidden="true"></span>
|
||||||
|
</button>
|
||||||
<button
|
<button
|
||||||
class="server-ai-btn"
|
class="server-ai-btn"
|
||||||
type="button"
|
type="button"
|
||||||
@@ -283,6 +292,15 @@ async function openCodexForServer(server: ServerProfile): Promise<void> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function copyServer(server: ServerProfile): Promise<void> {
|
||||||
|
try {
|
||||||
|
await serverStore.copyServer(server.id);
|
||||||
|
appStore.notify("info", `已复制服务器: ${server.name}-copy`);
|
||||||
|
} catch (error) {
|
||||||
|
appStore.notify("error", formatActionError("复制服务器失败", error));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function canDragReorder(serverId: string): boolean {
|
function canDragReorder(serverId: string): boolean {
|
||||||
return serverStore.servers.some((item) => item.id === serverId);
|
return serverStore.servers.some((item) => item.id === serverId);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user