kurihada
|
3335f7f872
|
refactor: 移除 Service Worker 离线缓存 + 统一注册引导文案
- 删除 sw.js、ServiceWorkerRegistrar、offline 页面
- 保留 manifest 和 PWA 图标(添加到主屏幕仍可用)
- 注册引导文案统一为"10 秒注册,无需手机号"
|
2026-02-27 10:38:33 +08:00 |
|
kurihada
|
4cc9d66403
|
fix: SW 缓存导致页面不更新 — fetch 绕过 HTTP 缓存 + hydration 闪屏修复
- sw.js: HTML fetch 加 cache:"no-cache",避免从浏览器缓存拿旧页面
- ServiceWorkerRegistrar: 注册时 updateViaCache:"none",确保 SW 自身及时更新
- blindbox/page: 增加 hydrated 状态,防止 SSR/CSR 内容不一致导致闪屏
|
2026-02-27 10:28:23 +08:00 |
|
kurihada
|
beb2c632bb
|
refactor: 移除个人页面决策记录,统一由成就墙展示
决策记录已完整迁移至 /achievements 成就墙页面,
个人中心不再重复展示,减少冗余数据请求。
|
2026-02-27 10:05:22 +08:00 |
|
kurihada
|
c17b13b6a8
|
feat: 契约生命周期 + 到期通知 + 成就墙
- 扩展 WeekendPlan schema: 新增 endTime 字段与 userId 索引
- PATCH /api/blindbox/plan 支持 accept/complete/expire 操作,
接受时自动计算契约结束时间
- GET /api/blindbox/plan 支持 mode 参数 (latest/pending/history)
- 房间页接受契约后自动返回想法池,顶部显示"契约进行中"指示器
- 契约到期时触发浏览器通知 + 页面加载时弹出完成确认弹窗
- 新增 /achievements 成就墙页面:统计数据 + 决策记录/契约记录双标签
- 首页和个人中心新增成就墙入口
|
2026-02-27 02:12:18 +08:00 |
|
kurihada
|
d8e42b860f
|
feat: 已接受契约持久化 — 保存/加载/自动展示
- PATCH /api/blindbox/plan: 接受契约时更新状态为 accepted
- GET /api/blindbox/plan: 查询房间内最近一次已接受的计划
- 进入房间时自动加载已接受计划并展示行程视图
- 修复整个周末想法不足时重复活动的问题(不足则只生成一天)
|
2026-02-27 01:57:42 +08:00 |
|
kurihada
|
9c680ec11e
|
feat: AI 周末行程规划 — DeepSeek 智能排期 + 高德 POI + 多日翻页
- 接入 DeepSeek API,提交想法时自动 AI 打标(品类/时段/时长/搜索策略)
- 新增行程规划 API:智能选取想法 → 高德 POI 搜索 → AI 生成最优行程
- 支持多日计划("整个周末"拆分周六/周日,并行 AI 调用)
- 行程展示逐日翻页,时间线可滚动,操作按钮固定底部
- 分享卡适配多日格式,支持图片保存与原生分享
- Prisma schema 新增 WeekendPlan 模型及 BlindBoxIdea AI 标签字段
- Jenkinsfile 集成 DEEPSEEK_API_KEY 环境变量
|
2026-02-27 01:51:47 +08:00 |
|
kurihada
|
8c6da410ca
|
style: 周末契约顶部对齐极速救场 + 首页卡片样式统一
- blindbox/page: 加 justify-center 让标题垂直位置与 panic 页保持一致,移除 flex-1 子容器
- page: 周末契约卡片色值统一用 white/* 透明度,去掉紫色 drop-shadow,简化 hover 光晕
|
2026-02-27 00:12:58 +08:00 |
|
kurihada
|
fbb2c22964
|
feat: 场景细分为餐厅/咖啡奶茶/甜品 + 附近搜索优先 + 美食多选标签
|
2026-02-26 23:04:25 +08:00 |
|
kurihada
|
c0662de3dd
|
feat: 美食多选 + 自定义输入标签
|
2026-02-26 21:40:14 +08:00 |
|
kurihada
|
ab55f0981e
|
feat: 地点搜索附近优先 — 透传用户坐标给高德 inputtips
|
2026-02-26 21:00:48 +08:00 |
|
kurihada
|
838f98b48b
|
docs: 更新 BUGFIX.md 标记 Low 优先级 #27-#31 为已完成,BUGFIX.md 全部清零
|
2026-02-26 20:26:13 +08:00 |
|
kurihada
|
deba7ab2bb
|
fix: AudioContext 复用 + 盲盒加载错误提示 + icon 按钮 aria-label
- #27: panic/blindbox/ShareCardModal/AuthModal 中 icon-only 按钮补 aria-label
- #28: playChime 缓存复用单个 AudioContext,避免超出浏览器 ~6 个上限
- #29: 已完成(上一批次 ApiError.name = "ApiError")
- #30: blindbox lobby fetchRooms 失败时显示"加载失败/点击重试"
- #31: 已完成(theme.ts VALID_THEMES 校验)
|
2026-02-26 20:25:56 +08:00 |
|
kurihada
|
f4a8fd7fee
|
docs: 更新 BUGFIX.md 标记 Medium 优先级 #15-#26 为已完成
|
2026-02-26 20:22:30 +08:00 |
|
kurihada
|
5adfe8d3f1
|
fix: 客户端资源清理 — ShareCard 依赖 + 定时器 + 死代码
- #20: ShareCardModal useEffect 依赖改为 imageSrc 字符串,避免对象引用变化重复加载
- #21: BlindboxRoomPage 所有 setTimeout/rAF 统一收集,unmount 时清理
- #25: 删除未使用的 confettiCanvasRef 和 canvas 元素
|
2026-02-26 20:21:59 +08:00 |
|
kurihada
|
cf88d3a1d2
|
fix: 外部 API 错误处理 + 导航 URL 校验 + reset/narrow 错误反馈
- #22: 高德 API fetch 加 try/catch,失败返回 503 而非泛化 500
- #23: buildNavUrl 校验 location.split(",") 结果长度和非空
- #24: handleReset/handleNarrow 检查 res.ok,失败时 toast 提示
|
2026-02-26 20:20:59 +08:00 |
|
kurihada
|
dfb3cfa136
|
fix: 服务端验证强化 — 房间ID/坐标/swipe/盲盒竞态/空格
- #15: 房间 ID 扩展为 6 位字母数字,createRoom 用 P2002 重试替代 find-then-create
- #16: 盲盒编辑/删除改用 updateMany/deleteMany 原子操作,防止 TOCTOU
- #17: lat/lng 用 Number.isFinite + 范围校验 (-90~90, -180~180)
- #18: swipe action 必须为 'like' 或 'pass'
- #19: user PUT 的 JSON.parse(preferences) 加 try/catch
- #26: requireString 拒绝纯空格字符串
|
2026-02-26 20:19:56 +08:00 |
|
kurihada
|
93f20747e4
|
docs: 更新 BUGFIX.md 标记 High 优先级 #6-#14 为已完成
|
2026-02-26 20:16:54 +08:00 |
|
kurihada
|
50ae46fe15
|
fix: AuthModal 重开时重置表单 + 邀请页加入失败显示错误
- #13: useEffect 监听 open 变化时重置所有表单状态(用户名、密码、错误等)
- #14: handleJoin catch 中捕获错误消息并渲染到页面
|
2026-02-26 20:16:25 +08:00 |
|
kurihada
|
508903b67d
|
fix: SSE 认证 + 收藏去重 + 数据库索引和级联删除
- #7: SSE events 接口校验 userId 房间成员身份,start() 加 try/catch
- #9: Favorite 新增 restaurantId 字段做精确去重,不再用 JSON contains
- #10: 补齐 Decision/Favorite/Room/BlindBoxIdea 缺失索引
- #11: Decision/Favorite/BlindBoxMember/BlindBoxIdea 加 onDelete Cascade
|
2026-02-26 20:15:45 +08:00 |
|
kurihada
|
9c7f18e0fa
|
fix: 用户名唯一性竞态处理 + 密码长度上限 + JSON.parse 安全
- #6: register/user PUT 捕获 P2002 返回 409,apiHandler 全局兜底
- #8: GET /api/user 的 JSON.parse(preferences) 加 try/catch 防崩溃
- #12: 密码校验加 128 字符上限防 DoS
- #29: ApiError.name 设为 "ApiError" 便于调试
|
2026-02-26 20:14:02 +08:00 |
|
kurihada
|
6488c19172
|
fix: theme.ts 所有函数添加 SSR 守卫,校验 localStorage 合法值
- setStoredTheme/applyTheme/initTheme 添加 typeof window 检查
- getStoredTheme 校验存储值是否在白名单中,防止非法 theme 值
|
2026-02-26 20:11:21 +08:00 |
|
kurihada
|
c4d1a122b2
|
fix: fetch 后检查 res.ok 并校验数组类型,防止错误响应导致崩溃
- panic/page.tsx: suggestions fetch 检查 res.ok + Array.isArray
- profile/page.tsx: history/favorites fetch 检查 res.ok + Array.isArray
|
2026-02-26 20:10:59 +08:00 |
|
kurihada
|
5783d522b7
|
fix: SwipeDeck 检测他人重置后自动清空本地状态
当 server 端 swipeCount 归零而本地 currentIndex > 0 时
说明其他用户执行了重置,自动调用 clearLocalState()
|
2026-02-26 20:10:29 +08:00 |
|
kurihada
|
b9a07f84c0
|
fix: 盲盒抽取使用事务 + 乐观锁防止并发抽到同一想法
- 将 findMany + update 包裹在 prisma.$transaction 中
- 使用 updateMany({ where: { id, status: "in_pool" } }) 保证原子性
- count=0 时返回 409 提示用户重试
|
2026-02-26 20:10:04 +08:00 |
|
kurihada
|
90d3b35069
|
fix: 房间 swipe/undo/reset 接口添加成员身份校验
- swipe/undo:校验 userId 在 data.users 中,非成员返回 403
- reset:要求传 userId,校验为房间成员或创建者
- 客户端 handleReset/handleNarrow 传入 userId
|
2026-02-26 20:09:40 +08:00 |
|
kurihada
|
2a3cef890c
|
refactor: 拆分 MatchResult、ProfilePage、BlindboxRoomPage 大组件
- MatchResult: 提取 NoMatchResult、RunnerUpCard(635 → 513 行)
- ProfilePage: 提取 ProfileHistoryCard、ProfileFavoritesCard(692 → 526 行)
- BlindboxRoomPage: 提取 BlindboxMyIdeas、BlindboxDrawnHistory(855 → 668 行)
|
2026-02-26 19:59:35 +08:00 |
|
kurihada
|
423b94440d
|
refactor: 拆分 ShareCardModal(951 行 → 4 个模块)
- ShareCardModal.tsx (199 行): 模态框编排逻辑(图片生成、保存、分享)
- RestaurantShareCard.tsx: 餐厅分享卡片纯展示组件
- BlindboxShareCard.tsx: 盲盒分享卡片纯展示组件
- shareImage.ts: 图片工具函数(toPng 封装、dataUrl 转换、下载)
|
2026-02-26 19:54:12 +08:00 |
|
kurihada
|
07541ed686
|
refactor: 提取 useGeolocation hook 和 joinRoom 工具函数
- useGeolocation: 将 PanicPage 中 ~50 行 GPS 定位逻辑(requestGps + reverseGeocode + 状态管理)提取为独立 hook
- joinRoom: 统一 3 处重复的 POST /api/room/:id/join 调用(room、invite、panic 页面)
|
2026-02-26 19:49:05 +08:00 |
|
kurihada
|
0c5676493e
|
refactor: 提取 UserAvatar、Input、Card 三个可复用 UI 组件
- UserAvatar: 统一头像渲染(5 种尺寸),新增 resolveAvatar 工具函数,替换 SwipeDeck 和 RoomManageModal 中的重复逻辑
- Input: 统一表单输入样式(4 种尺寸 + default/purple 变体),替换 AuthModal、ProfilePage、BlindboxPage 共 12 处
- Card: 统一卡片容器样式 + 可选淡入动画和延迟,替换 ProfilePage 中 7 处重复的 motion.div
|
2026-02-26 19:43:07 +08:00 |
|
kurihada
|
9641acbcbd
|
refactor: 提取 buildNavUrl 工具函数,统一 room API 错误处理
- 将 MatchResult.tsx 和 profile/page.tsx 中重复的导航 URL 构建逻辑提取到 src/lib/navigation.ts
- 7 个 room API 路由从 return NextResponse.json({ error }, { status }) 统一改为 throw ApiError,由 apiHandler 统一捕获
|
2026-02-26 19:31:00 +08:00 |
|
kurihada
|
c9e20d4c95
|
refactor: 提取 useShare hook,统一分享和剪贴板逻辑
新增 useShare(Web Share API + clipboard fallback),
消除 QrInviteModal、BlindboxRoomPage、ShareCardModal 三处重复的分享代码。
|
2026-02-26 19:25:44 +08:00 |
|
kurihada
|
1229bb849b
|
refactor: 提取 validation.ts 和 amap.ts,统一 API 路由校验逻辑
新增 validation.ts(用户名/密码/邮箱/内容/房间名/必填字段校验)
和 amap.ts(AMAP API key 校验),消除 7 个路由中的重复验证代码。
|
2026-02-26 19:22:17 +08:00 |
|
kurihada
|
455b9e04d8
|
refactor: 提取 Button 组件,统一按钮变体、尺寸和加载状态
新增 Button.tsx 支持 5 种变体(primary/secondary/danger/ghost/purple)、
3 种尺寸(sm/md/lg)、pill/rounded 形状及内置 loading 状态,
替换 8 个文件中 16 处重复的按钮样板代码。
|
2026-02-26 18:39:14 +08:00 |
|
kurihada
|
19edcaeeb5
|
refactor: 提取 requireUserId/requireUser/requireMembership 校验工具
- 新增 requireUserId:统一 14 处 userId 非空校验,返回 401
- 新增 requireUser:统一 4 处用户存在性检查,返回 404
- validateMembership 升级为 requireMembership,直接抛 403
- 混合校验拆分为 auth(401) + 字段(400),状态码更准确
|
2026-02-26 18:17:17 +08:00 |
|
kurihada
|
0595887480
|
refactor: 引入 apiHandler + ApiError,消除 20 个路由的 try/catch 样板
- 新增 src/lib/api.ts:ApiError 错误类 + apiHandler 统一包装器
- 20 个 API 路由统一使用 apiHandler,删除重复的 try/catch 块
- 验证错误改用 throw new ApiError(),减少嵌套层级
- join/manage 路由的错误码映射改为直接抛出 ApiError
- 删除已无引用的 errorResponse 辅助函数
- 净减 273 行代码
|
2026-02-26 18:08:47 +08:00 |
|
kurihada
|
d4c6da57a1
|
refactor: Toast 升级为全局 Context,消除 onToast prop 透传
将 useToast 从独立 state hook 改为 Context-based,在 layout 中
挂载 ToastProvider 全局渲染 Toast。QrInviteModal、RoomManageModal、
ShareCardModal 不再需要 onToast prop,直接 useToast() 调用即可。
父组件 TopNav、MatchResult、profile、blindbox 移除了本地 Toast
渲染和 onToast 传递逻辑。
|
2026-02-26 17:57:34 +08:00 |
|
kurihada
|
b98920858c
|
refactor: 提取 useToast hook + Toast 组件,消除 4 处重复的通知逻辑
将 state + setTimeout 自动消失逻辑封装为 useToast hook,
Toast UI 统一为组件支持 top/bottom 两种位置,净减约 12 行。
|
2026-02-26 17:50:28 +08:00 |
|
kurihada
|
948274bcb9
|
refactor: 提取 Modal 基础组件,消除 4 个弹窗的重复样板代码
将 backdrop 遮罩、点击关闭、AnimatePresence 动画封装为 Modal 组件,
支持 sheet(底部弹出)和 dialog(居中缩放)两种变体,净减约 110 行。
|
2026-02-26 17:45:52 +08:00 |
|
kurihada
|
ac8cb8c635
|
feat: 盲盒想法支持编辑和删除,展示用户已投入的想法列表
|
2026-02-26 16:55:58 +08:00 |
|
kurihada
|
b1cbf0d589
|
fix: 修复页面过渡动画导致 fixed 定位失效和全局徽章被遮挡
|
2026-02-26 16:49:06 +08:00 |
|
kurihada
|
add9733bc9
|
ui: 页面切换过渡动画 — AnimatePresence 淡入滑出效果
|
2026-02-26 16:41:39 +08:00 |
|
kurihada
|
20f63c67cb
|
feat: 添加 PWA 支持 — 可安装到主屏幕、离线缓存、刘海屏适配
|
2026-02-26 16:37:40 +08:00 |
|
kurihada
|
31003110e1
|
fix: 滑卡退出距离自适应屏幕宽度,小屏设备体验更顺滑
|
2026-02-26 16:33:41 +08:00 |
|
kurihada
|
37eb7f07d7
|
ui: 滑卡互动增强 — like 徽章动画、分类标签可读性、进度数字区分
- RestaurantCard: like 徽章实时弹跳动画,首次出现滑入效果
- RestaurantCard: 分类标签改为白底黑字,图片上始终清晰
- SwipeDeck: 进度数字加背景色块包裹,与用户名视觉分离
|
2026-02-26 16:32:00 +08:00 |
|
kurihada
|
9759db54ca
|
fix: 修复浅色模式下 text-white 文字不可见,新增主题安全色规范
极速救场标题、个人中心导航和输入框改用语义色
|
2026-02-26 16:18:38 +08:00 |
|
kurihada
|
b2b18327cc
|
ui: 骨架屏替代全部页面级加载 spinner
- 新增 Skeleton 组件库:Skeleton、SkeletonCircle 基础元素 + 5 个业务骨架
(SwipeDeck、ProfileCard、RecordItem、BlindboxRoom、BlindboxList、RoomCard)
- 替换 room、profile、blindbox 列表、blindbox 房间、invite 5 个页面的加载态
- 替换 profile 历史记录 / 收藏列表的内联加载 spinner
- 更新 project-conventions.mdc:新增 Loading States 规范,
要求页面级和列表级加载必须使用骨架屏
|
2026-02-26 16:11:01 +08:00 |
|
kurihada
|
798b883250
|
ui: 房间页布局优化 — TopNav 重排、进度贴近卡片、按钮间距收紧
- TopNav: 退出按钮移到最左侧,房间号合并到邀请按钮,移除右侧内容避免与全局徽章重叠
- SwipeDeck: 移除绿色进度条,UserProgressBar 始终显示并贴在卡片正上方
- ActionButtons: 缩小与卡片的垂直间距
|
2026-02-26 15:50:51 +08:00 |
|
kurihada
|
4ce6ea469c
|
feat: 添加全局 Error Boundary 和餐厅图片加载失败 fallback
- error.tsx: 路由级错误边界,提供重试和返回首页操作
- global-error.tsx: 根布局级兜底,纯内联样式避免依赖加载
- RestaurantImage: 可复用图片组件,加载失败显示餐具占位图标
- 替换 RestaurantCard、MatchResult、profile 中所有餐厅图片
|
2026-02-26 15:22:29 +08:00 |
|
kurihada
|
e86f643c26
|
ui: 个人中心空状态插图优化,替换纯文字为图标动画 + CTA 按钮
提取可复用 EmptyState 组件,决策记录和收藏餐厅空状态
增加浮动图标、光晕动画和"去创建第一个房间"引导按钮
|
2026-02-26 15:18:22 +08:00 |
|
kurihada
|
12279117f3
|
feat: 全局主题切换(浅色/深色/跟随系统)
- CSS 变量驱动的主题系统,所有颜色响应 data-theme 属性
- 新增语义化色彩 heading/secondary/tertiary,替换硬编码 text-white/text-gray-*
- 右上角三态主题按钮(自动/浅色/深色),全局可用无需登录
- layout.tsx 内联脚本防闪烁
- 修复个人中心页面溢出无法滚动
|
2026-02-26 15:15:32 +08:00 |
|