import { and, eq } from "drizzle-orm"; import { getDb } from "../../../db"; import { progress } from "../../../db/schema"; const user = (r: Request) => r.headers.get("oai-authenticated-user-id"); const todayInChina = () => new Intl.DateTimeFormat("en-CA", { timeZone: "Asia/Shanghai" }).format(new Date()); const parseTasks = (value: string) => { try { return JSON.parse(value) as string[]; } catch { return []; } }; export async function GET(r: Request) { const id = user(r); if (!id) return Response.json({ error: "请登录后再使用打卡功能。" }, { status: 401 }); try { return Response.json({ progress: await getDb().select().from(progress).where(eq(progress.userId, id)) }); } catch { return Response.json({ error: "暂时无法读取云端进度。" }, { status: 500 }); } } export async function PUT(r: Request) { const id = user(r); if (!id) return Response.json({ error: "请登录后再保存打卡。" }, { status: 401 }); const b = await r.json() as { date?: string; doneTasks?: string[]; mood?: string; note?: string }; if (!/^2026-(09|10|11|12)-\d{2}$/.test(b.date || "") || !Array.isArray(b.doneTasks)) return Response.json({ error: "提交的数据格式不正确。" }, { status: 400 }); const today = todayInChina(); if (b.date! > today) return Response.json({ error: "未来日期暂不能打卡。" }, { status: 400 }); try { const db = getDb(), now = new Date().toISOString(), checkinType = b.date! < today ? "makeup" : "normal"; const existing = await db.select().from(progress).where(and(eq(progress.userId, id), eq(progress.planDate, b.date!))); if (b.date! < today && existing[0] && parseTasks(existing[0].doneTasks).some(task => !b.doneTasks!.includes(task))) return Response.json({ error: "过去日期已完成的项目不能取消,只能补打未完成项目。" }, { status: 400 }); const values = { userId: id, planDate: b.date!, doneTasks: JSON.stringify(b.doneTasks), mood: (b.mood || "").slice(0, 20), note: (b.note || "").slice(0, 1000), checkinType, checkedAt: now, updatedAt: now }; await db.insert(progress).values(values).onConflictDoUpdate({ target: [progress.userId, progress.planDate], set: values }); const row = await db.select().from(progress).where(and(eq(progress.userId, id), eq(progress.planDate, b.date!))); return Response.json({ progress: row[0] }); } catch { return Response.json({ error: "暂时无法保存到云端,请稍后重试。" }, { status: 500 }); } }