feat: AI 周末行程规划 — DeepSeek 智能排期 + 高德 POI + 多日翻页

- 接入 DeepSeek API,提交想法时自动 AI 打标(品类/时段/时长/搜索策略)
- 新增行程规划 API:智能选取想法 → 高德 POI 搜索 → AI 生成最优行程
- 支持多日计划("整个周末"拆分周六/周日,并行 AI 调用)
- 行程展示逐日翻页,时间线可滚动,操作按钮固定底部
- 分享卡适配多日格式,支持图片保存与原生分享
- Prisma schema 新增 WeekendPlan 模型及 BlindBoxIdea AI 标签字段
- Jenkinsfile 集成 DEEPSEEK_API_KEY 环境变量
This commit is contained in:
2026-02-27 01:51:47 +08:00
parent 8c6da410ca
commit 9c680ec11e
16 changed files with 1721 additions and 70 deletions
+42 -1
View File
@@ -1,6 +1,6 @@
import { NextResponse } from "next/server";
import { prisma } from "@/lib/prisma";
import { getRoomByCode } from "@/lib/blindbox";
import { getRoomByCode, requireMembership } from "@/lib/blindbox";
import { apiHandler, ApiError, requireUserId } from "@/lib/api";
export const GET = apiHandler(async (_req, { params }) => {
@@ -14,6 +14,9 @@ export const GET = apiHandler(async (_req, { params }) => {
code: room.code,
name: room.name,
creatorId: room.creatorId,
city: room.city,
lat: room.lat,
lng: room.lng,
poolCount: room._count.ideas,
members: room.members.map((m) => ({
...m.user,
@@ -22,6 +25,44 @@ export const GET = apiHandler(async (_req, { params }) => {
});
});
export const PATCH = apiHandler(async (req, { params }) => {
const { code } = await params;
const { userId, city, lat, lng } = await req.json();
requireUserId(userId);
const room = await prisma.blindBoxRoom.findUnique({
where: { code: code.toUpperCase() },
});
if (!room) throw new ApiError("房间不存在", 404);
await requireMembership(room.id, userId);
const numLat = Number(lat);
const numLng = Number(lng);
if (
!Number.isFinite(numLat) || !Number.isFinite(numLng) ||
numLat < -90 || numLat > 90 || numLng < -180 || numLng > 180
) {
throw new ApiError("位置坐标无效");
}
const updated = await prisma.blindBoxRoom.update({
where: { id: room.id },
data: {
city: typeof city === "string" ? city.trim() : null,
lat: numLat,
lng: numLng,
},
});
return NextResponse.json({
city: updated.city,
lat: updated.lat,
lng: updated.lng,
});
});
export const DELETE = apiHandler(async (req, { params }) => {
const { code } = await params;
const { userId } = await req.json();