Repository navigation
fix: delete tip - #7801
fix: delete tip#7801
Conversation
| .catch(() => {}) | ||
| } | ||
| </script> | ||
|
|
There was a problem hiding this comment.
Review of the diff
1. Wrong entity in the confirmation message (likely a bug)
const resourceName = document.source_file_id && document.resource_type === 'image' ? '图片' : '文档'
return MsgConfirm(`是否删除${resourceName}:${document.name}?`)handleDeleteParagraph(index) deletes a paragraph, but the confirm text refers to document.name — the whole document. The user is warned "delete document X" while only one paragraph is removed. It should reference the paragraph being removed, e.g.:
const paragraph = document.content[index]
...
MsgConfirm(`是否删除${resourceName}:${paragraph.name ?? paragraph.text}?`)2. resourceName logic is suspicious
document.source_file_id && document.resource_type === 'image' — the source_file_id check is unrelated to whether the item is an image and will silently fall back to '文档' when the id is 0/empty. Use document.resource_type === 'image' (or an explicit map) only.
3. Index-based deletion + async confirm = stale index
Between opening the dialog and confirming, document.content may change (other deletions, refresh, reorder). splice(index, 1) could then delete the wrong paragraph. Safer:
const paragraph = document.content[index]
if (!paragraph) return
await MsgConfirm(...)
const currentIndex = document.content.indexOf(paragraph)
if (currentIndex !== -1) document.content.splice(currentIndex, 1)Also add bounds check (index < 0 || index >= content.length).
4. Captured document may no longer be selected
The .then callback mutates the document captured before the dialog. If the user switches/imports another document while the dialog is open, you silently mutate a document that is no longer selectedDocument. Guard:
if (selectedDocument.value !== document) return
document.content.splice(index, 1)5. .catch(() => {}) hides real errors
This swallows both "user cancelled" and genuine failures (e.g. splice/validation errors). Prefer an explicit cancel path:
try {
await MsgConfirm(...)
...
} catch (e) {
// cancelled — no-op
}and make sure empty catch is intentional (some ESLint configs flag no-empty).
6. Variable shadowing: document
Naming a local document shadows the DOM global. In a Vue SFC this is confusing and risks accidental DOM access bugs; rename to doc / currentDocument.
7. Return value / API consistency
handleDeleteParagraph now returns a Promise (resolved with void or rejected-swallowed). It's used as a click handler, so it's harmless, but if other handlers are sync or if callers await it, be consistent. Also consider showing a success toast to match other handlers, and disabling re-entry (double-click opens two dialogs).
8. Minor
- Missing spaces in the Chinese message punctuation is fine, but keep wording consistent with other dialogs in the codebase.
- If the last paragraph is deleted, verify the preview/validation state (
validate, empty-state UI, selected indices) is refreshed —splicealone may not update derived state or the emitted model. - Import ordering (
MsgConfirm, MsgWarning) is fine.
Suggested rewrite
async function handleDeleteParagraph(index: number) {
const doc = selectedDocument.value
if (!doc) return
const paragraph = doc.content[index]
if (!paragraph) return
const resourceName = doc.resource_type === 'image' ? '图片' : '文档'
try {
await MsgConfirm(`是否删除${resourceName}:${paragraph.name ?? ''}?`)
} catch {
return // user cancelled
}
if (selectedDocument.value !== doc) return
const currentIndex = doc.content.indexOf(paragraph)
if (currentIndex !== -1) doc.content.splice(currentIndex, 1)
}
fix: delete tip