feat: 添加分类的行内编辑和更新功能

This commit is contained in:
seahi committed 2026-08-15 14:35:33 +08:00
1 parent c9ca199fa5
commit 5affda0889
2 files changed
+127 -26

No files matched your search

@@ -139,5 +139,33 @@ export const actions: Actions = {
console.error('Error deleting category:', err); console.error('Error deleting category:', err);
return { success: false, error: '删除分类失败' }; return { success: false, error: '删除分类失败' };
} }
},
update: async ({ request, platform }) => {
const db = platform?.env?.DB as any;
if (!db) return fail(500, { error: '数据库未连接' });
const formData = await request.formData();
const id = formData.get('id');
const name = formData.get('name')?.toString().trim();
const slug = formData.get('slug')?.toString().trim();
if (!id || !name || !slug) {
return fail(400, { error: '分类 ID、名称和 URL 别名为必填项' });
}
try {
await db
.prepare('UPDATE categories SET name = ?, slug = ? WHERE id = ?')
.bind(name, slug, id)
.run();
return { success: true };
} catch (err: unknown) {
console.error('Error updating category:', err);
if ((err as any)?.message?.includes('UNIQUE constraint failed')) {
return fail(400, { error: '分类名称或 URL 别名已存在' });
}
return fail(500, { error: '更新分类失败' });
}
} }
}; };
+99 -26
View File
@@ -11,6 +11,8 @@
let isSlugUserModified = $state(false); let isSlugUserModified = $state(false);
let isGenerating = $state(false); let isGenerating = $state(false);
let editingId = $state<number | null>(null);
const slugHandler = createSlugAutoHandler({ const slugHandler = createSlugAutoHandler({
getSlug: () => slug, getSlug: () => slug,
setSlug: (val) => (slug = val), setSlug: (val) => (slug = val),
@@ -104,34 +106,88 @@
{#each data.categories as category (category.id || category)} {#each data.categories as category (category.id || category)}
<tr> <tr>
<td>{category.id}</td> <td>{category.id}</td>
<td><strong>{category.name}</strong></td> <td>
<td><span class="badge">{category.slug}</span></td> {#if editingId === category.id}
<input
type="text"
name="name"
value={category.name}
form="edit-form-{category.id}"
required
class="edit-input"
/>
{:else}
<strong>{category.name}</strong>
{/if}
</td>
<td>
{#if editingId === category.id}
<input
type="text"
name="slug"
value={category.slug}
form="edit-form-{category.id}"
required
class="edit-input"
/>
{:else}
<span class="badge">{category.slug}</span>
{/if}
</td>
<td><span class="badge">{category.post_count} 篇文章</span></td> <td><span class="badge">{category.post_count} 篇文章</span></td>
<td> <td>
<form {#if editingId === category.id}
action="?/delete" <form
method="POST" id="edit-form-{category.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; // will submit naturally, just reset editingId
} setTimeout(() => {
e.preventDefault(); editingId = null;
const form = e.target as HTMLFormElement; }, 0);
const submitter = e.submitter; }}
const confirmed = await confirmState.show( >
`确定要删除${$page.data.aliases?.category || '分类'} "${category.name}" 吗?删除后相关文章将归为未${$page.data.aliases?.category || '分类'}。` <input type="hidden" name="id" value={category.id} />
); <button type="submit" class="action-btn">保存</button>
if (confirmed) { </form>
form.dataset.confirmed = 'true'; <button type="button" class="action-btn" onclick={() => (editingId = null)}>
form.requestSubmit(submitter); 取消
} </button>
}} {:else}
> <button
<input type="hidden" name="id" value={category.id} /> type="button"
<button type="submit" class="action-btn delete">删除</button> class="action-btn"
</form> onclick={() => (editingId = category.id)}
>
编辑
</button>
<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?.category || '分类'} "${category.name}" 吗?删除后相关文章将归为未${$page.data.aliases?.category || '分类'}。`
);
if (confirmed) {
form.dataset.confirmed = 'true';
form.requestSubmit(submitter);
}
}}
>
<input type="hidden" name="id" value={category.id} />
<button type="submit" class="action-btn delete">删除</button>
</form>
{/if}
</td> </td>
</tr> </tr>
{/each} {/each}
@@ -322,4 +378,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>