feat: 添加标签的行内编辑和更新功能
continuous-integration/drone/push Build is passing

This commit is contained in:
seahi committed 2026-08-15 14:35:33 +08:00
1 parent c84c9cb4e8
commit 89d4279507
2 files changed
+103 -25

No files matched your search

+24
View File
@@ -76,5 +76,29 @@ export const actions: Actions = {
console.error('Error deleting tag:', err); console.error('Error deleting tag:', err);
return { success: false, error: '删除标签失败' }; return { success: false, error: '删除标签失败' };
} }
},
update: async ({ request, platform }) => {
const db = platform?.env?.DB;
if (!db) return fail(500, { error: '数据库未连接' });
const formData = await request.formData();
const id = formData.get('id');
const name = formData.get('name')?.toString().trim();
if (!id || !name) {
return fail(400, { error: '标签 ID 和名称为必填项' });
}
try {
await db.prepare('UPDATE tags SET name = ? WHERE id = ?').bind(name, id).run();
return { success: true };
} catch (err: unknown) {
console.error('Error updating tag:', err);
if ((err as any)?.message?.includes('UNIQUE constraint failed')) {
return fail(400, { error: '标签名称已存在' });
}
return fail(500, { error: '更新标签失败' });
}
} }
}; };
+79 -25
View File
@@ -6,6 +6,7 @@
let { data, form }: { data: PageData; form: ActionData } = $props(); let { data, form }: { data: PageData; form: ActionData } = $props();
let newTagName = $state(''); let newTagName = $state('');
let editingId = $state<number | null>(null);
</script> </script>
<div class="admin-page-header"> <div class="admin-page-header">
@@ -58,33 +59,69 @@
{#each data.tags as tag (tag.id || tag)} {#each data.tags as tag (tag.id || tag)}
<tr> <tr>
<td>{tag.id}</td> <td>{tag.id}</td>
<td><strong>{tag.name}</strong></td> <td>
{#if editingId === tag.id}
<input
type="text"
name="name"
value={tag.name}
form="edit-form-{tag.id}"
required
class="edit-input"
/>
{:else}
<strong>{tag.name}</strong>
{/if}
</td>
<td><span class="badge">{tag.post_count} 篇文章</span></td> <td><span class="badge">{tag.post_count} 篇文章</span></td>
<td> <td>
<form {#if editingId === tag.id}
action="?/delete" <form
method="POST" id="edit-form-{tag.id}"
class="inline-form" action="?/update"
onsubmit={async (e) => { method="POST"
if ((e.target as HTMLFormElement).dataset.confirmed === 'true') { class="inline-form"
(e.target as HTMLFormElement).removeAttribute('data-confirmed'); onsubmit={() => {
return; setTimeout(() => {
} editingId = null;
e.preventDefault(); }, 0);
const form = e.target as HTMLFormElement; }}
const submitter = e.submitter; >
const confirmed = await confirmState.show( <input type="hidden" name="id" value={tag.id} />
`确定要删除${$page.data.aliases?.tag || '标签'} "${tag.name}" 吗?` <button type="submit" class="action-btn">保存</button>
); </form>
if (confirmed) { <button type="button" class="action-btn" onclick={() => (editingId = null)}>
form.dataset.confirmed = 'true'; 取消
form.requestSubmit(submitter); </button>
} {:else}
}} <button type="button" class="action-btn" onclick={() => (editingId = tag.id)}>
> 编辑
<input type="hidden" name="id" value={tag.id} /> </button>
<button type="submit" class="action-btn delete">删除</button> <form
</form> action="?/delete"
method="POST"
class="inline-form"
onsubmit={async (e) => {
if ((e.target as HTMLFormElement).dataset.confirmed === 'true') {
(e.target as HTMLFormElement).removeAttribute('data-confirmed');
return;
}
e.preventDefault();
const form = e.target as HTMLFormElement;
const submitter = e.submitter;
const confirmed = await confirmState.show(
`确定要删除${$page.data.aliases?.tag || '标签'} "${tag.name}" 吗?`
);
if (confirmed) {
form.dataset.confirmed = 'true';
form.requestSubmit(submitter);
}
}}
>
<input type="hidden" name="id" value={tag.id} />
<button type="submit" class="action-btn delete">删除</button>
</form>
{/if}
</td> </td>
</tr> </tr>
{/each} {/each}
@@ -275,4 +312,21 @@
text-align: center; text-align: center;
color: var(--text-muted, rgba(0, 0, 0, 0.6)); color: var(--text-muted, rgba(0, 0, 0, 0.6));
} }
.edit-input {
width: 100%;
padding: 6px 8px;
border: 1px solid rgba(0, 0, 0, 0.2);
background: transparent;
font-family: inherit;
font-size: 0.95rem;
color: var(--text-color);
box-sizing: border-box;
border-radius: 4px;
}
.edit-input:focus {
outline: none;
border-color: var(--accent-color, #419b38);
}
</style> </style>