fix(desktop): require in-app confirmation before deleting shares

This commit is contained in:
2026-02-18 22:53:53 +08:00
parent bb8a4ea386
commit 9d600a2d5c

View File

@@ -151,6 +151,11 @@ const contextMenu = reactive({
y: 0,
item: null as FileItem | null,
});
const shareDeleteDialog = reactive({
visible: false,
loading: false,
share: null as ShareItem | null,
});
const dropState = reactive({
active: false,
uploading: false,
@@ -1073,9 +1078,20 @@ async function createDirectLinkForItem(current: FileItem, silent = false) {
throw new Error(String(response.data?.message || "创建直链失败"));
}
function requestDeleteShare(share: ShareItem) {
if (shareDeleteDialog.loading) return;
shareDeleteDialog.share = share;
shareDeleteDialog.visible = true;
}
function closeDeleteShareDialog(force = false) {
if (shareDeleteDialog.loading && !force) return;
shareDeleteDialog.visible = false;
shareDeleteDialog.loading = false;
shareDeleteDialog.share = null;
}
async function deleteShare(share: ShareItem) {
const confirmed = window.confirm(`确认删除分享 ${share.share_code} 吗?`);
if (!confirmed) return;
const response = await invokeBridge("api_delete_share", {
baseUrl: appConfig.baseUrl,
shareId: share.id,
@@ -1083,9 +1099,27 @@ async function deleteShare(share: ShareItem) {
if (response.ok && response.data?.success) {
showToast("分享已删除", "success");
await loadShares(true);
return;
return true;
}
showToast(response.data?.message || "删除分享失败", "error");
return false;
}
async function confirmDeleteShare() {
const share = shareDeleteDialog.share;
if (!share || shareDeleteDialog.loading) return;
shareDeleteDialog.loading = true;
try {
const ok = await deleteShare(share);
if (ok) {
closeDeleteShareDialog(true);
return;
}
shareDeleteDialog.loading = false;
} catch {
shareDeleteDialog.loading = false;
}
}
async function copyShareLink(share: ShareItem) {
@@ -1955,7 +1989,7 @@ onBeforeUnmount(() => {
<div class="share-actions">
<button class="action-btn" @click="openShareLink(share)">打开</button>
<button class="action-btn" @click="copyShareLink(share)">复制</button>
<button class="action-btn danger" @click="deleteShare(share)">删除</button>
<button class="action-btn danger" @click="requestDeleteShare(share)">删除</button>
</div>
</div>
</div>
@@ -2197,6 +2231,22 @@ onBeforeUnmount(() => {
<button v-if="!contextMenu.item.isDirectory" class="context-item" @click="executeContextAction('direct')">生成直链</button>
</div>
<div v-if="shareDeleteDialog.visible" class="confirm-mask" @click="closeDeleteShareDialog()">
<div class="confirm-card" @click.stop>
<h4>确认删除分享</h4>
<p>
确认删除分享码 <strong>{{ shareDeleteDialog.share?.share_code || "-" }}</strong>
删除后外链将立即失效
</p>
<div class="confirm-actions">
<button class="action-btn" :disabled="shareDeleteDialog.loading" @click="closeDeleteShareDialog()">取消</button>
<button class="action-btn danger" :disabled="shareDeleteDialog.loading" @click="confirmDeleteShare()">
{{ shareDeleteDialog.loading ? "删除中..." : "确定删除" }}
</button>
</div>
</div>
</div>
<div v-if="toast.visible" class="toast" :class="toast.type">{{ toast.message }}</div>
</div>
</template>
@@ -3163,6 +3213,46 @@ select:focus {
margin: 6px 4px;
}
.confirm-mask {
position: fixed;
inset: 0;
z-index: 1200;
background: rgba(20, 33, 54, 0.42);
display: grid;
place-items: center;
padding: 20px;
}
.confirm-card {
width: min(460px, 100%);
border-radius: 14px;
background: #fff;
border: 1px solid #d7e2f0;
box-shadow: 0 16px 36px rgba(30, 52, 88, 0.2);
padding: 18px;
display: grid;
gap: 10px;
}
.confirm-card h4 {
margin: 0;
font-size: 16px;
color: #203043;
}
.confirm-card p {
margin: 0;
color: #4f6784;
line-height: 1.6;
font-size: 13px;
}
.confirm-actions {
display: flex;
justify-content: flex-end;
gap: 8px;
}
.detail-panel h3 {
margin: 0;
font-size: 16px;