feat: 行程活动拖拽排序 + 编辑表单(含高德 POI 搜索)

- 安装 @dnd-kit/core/sortable/utilities/modifiers
- BlindboxPlan: 同天内拖拽排序(PointerSensor + TouchSensor,限垂直轴)
- BlindboxPlan: 点击编辑弹出 sheet modal,支持改时间(type=time)、时长、活动名
- BlindboxPlan: POI 字段改为高德 inputtips 搜索下拉,选中自动填入名称/地址/坐标
- BlindboxPlan: 搜索传入房间坐标 location 参数,结果按距离排序
- BlindboxPlan: 跨天移动通过 select 立即生效
- plan route: 新增 update_plan action,支持 PATCH 保存修改后的 days
- page.tsx: 新增 handlePlanDaysChange,乐观更新本地 state + 失败时回滚
This commit is contained in:
2026-03-02 12:06:50 +08:00
parent df2e373beb
commit 4e6a3e007c
5 changed files with 502 additions and 55 deletions
+21 -1
View File
@@ -75,7 +75,7 @@ function computeEndTime(planData: string, now: Date): Date | null {
}
export const PATCH = apiHandler(async (req) => {
const { planId, userId, action } = await req.json();
const { planId, userId, action, days } = await req.json();
requireUserId(userId);
if (!planId) throw new ApiError("planId 不能为空");
@@ -105,6 +105,26 @@ export const PATCH = apiHandler(async (req) => {
return NextResponse.json({ ok: true });
}
if (act === "update_plan") {
if (plan.status !== "active" && plan.status !== "accepted") {
throw new ApiError("只能编辑进行中的计划", 400);
}
if (!Array.isArray(days) || days.length === 0) {
throw new ApiError("days 数据无效", 400);
}
const newPlanData = JSON.stringify({ days });
await prisma.weekendPlan.update({
where: { id: planId },
data: {
planData: newPlanData,
...(plan.status === "accepted"
? { endTime: computeEndTime(newPlanData, new Date()) }
: {}),
},
});
return NextResponse.json({ ok: true });
}
throw new ApiError("无效的操作", 400);
});