Add image upload to cases with cleanup

This commit is contained in:
2026-09-12 10:06:16 +08:00
parent 6e550c0d5b
commit 370ec568aa
+22 -10
View File
@@ -1,15 +1,18 @@
---
import { and, asc, desc, eq, gt, lt, max } from "drizzle-orm";
import AdminLayout from "../../layouts/AdminLayout.astro";
import ImageField from "../../components/admin/ImageField.astro";
import { cases } from "../../db/schema";
import { getDb } from "../../lib/db";
import { getEnv } from "../../lib/env";
import { parseForm } from "../../lib/form";
import { deleteMedia } from "../../lib/media";
import { caseInput } from "../../schemas";
export const prerender = false;
const db = getDb(getEnv().DB);
const env = getEnv();
const db = getDb(env.DB);
let errors: Record<string, string> = {};
let failedId = "";
@@ -44,6 +47,11 @@ if (Astro.request.method === "POST") {
});
} else {
const id = str(form, "id");
const newImage = parsed.data.imageUrl || null;
const [current] = await db.select().from(cases).where(eq(cases.id, id)).limit(1);
if (current && current.imageUrl !== newImage) {
await deleteMedia(env, current.imageUrl);
}
await db
.update(cases)
.set({
@@ -51,14 +59,17 @@ if (Astro.request.method === "POST") {
location: parsed.data.location || null,
completedAt: parsed.data.completedAt || null,
description: parsed.data.description || null,
imageUrl: parsed.data.imageUrl || null,
imageUrl: newImage,
status: parsed.data.status,
updatedAt: new Date(),
})
.where(eq(cases.id, id));
}
} else if (action === "delete") {
await db.delete(cases).where(eq(cases.id, str(form, "id")));
const id = str(form, "id");
const [current] = await db.select().from(cases).where(eq(cases.id, id)).limit(1);
await deleteMedia(env, current?.imageUrl);
await db.delete(cases).where(eq(cases.id, id));
} else if (action === "up" || action === "down") {
const id = str(form, "id");
const [current] = await db.select().from(cases).where(eq(cases.id, id)).limit(1);
@@ -109,8 +120,7 @@ const list = await db.select().from(cases).orderBy(asc(cases.sortOrder));
<input id="a-date" name="completedAt" type="text" placeholder="例:2026年2月" />
</div>
<div>
<label for="a-img">圖片 URL</label>
<input id="a-img" name="imageUrl" type="text" placeholder="https://..." />
<ImageField name="imageUrl" label="圖片" scope="cases" id="a-img" />
</div>
<div style="grid-column:1/-1">
<label for="a-desc">描述</label>
@@ -144,8 +154,13 @@ const list = await db.select().from(cases).orderBy(asc(cases.sortOrder));
<input name="completedAt" type="text" value={item.completedAt ?? ""} />
</div>
<div>
<label>圖片 URL</label>
<input name="imageUrl" type="text" value={item.imageUrl ?? ""} />
<ImageField
name="imageUrl"
label="圖片"
scope="cases"
value={item.imageUrl}
id={`img-${item.id}`}
/>
</div>
<div style="grid-column:1/-1">
<label>描述</label>
@@ -159,9 +174,6 @@ const list = await db.select().from(cases).orderBy(asc(cases.sortOrder));
</select>
</div>
</div>
{item.imageUrl && (
<img src={item.imageUrl} alt={item.title} style="margin-top:14px;max-width:220px;border-radius:10px;" />
)}
<div class="actions">
<button type="submit" name="action" value="save">儲存</button>
<button type="submit" name="action" value="up" class="secondary mini" disabled={i === 0}>↑ 上移</button>