开发日志(五):菜单识别系统收藏与购物车功能改造实录
本次主要围绕“菜单识别后的用户行为闭环”做了一轮功能完善核心目标是把“识别菜品 - 收藏菜品 - 加入购物车 - 按识别图片分组查看”这条链路补完整同时尽量不破坏原有页面结构和菜品详情页内容。一、今天的开发目标本次改造主要解决了 4 个问题菜品识别后用户可以直接收藏菜品收藏需要绑定userId做到“每个用户只看自己的收藏”购物车也需要绑定userId购物车里的菜品要按照“来自哪一张识别图片”分组展示而不是全部混在一起此外还额外处理了一个用户体验问题保持原有菜品详情页不被改动避免影响已有内容展示逻辑二、后端部分改造1. 新增菜品收藏表favorite_dishes为了支持“识别结果页收藏菜品”新增了菜品收藏表核心字段包括user_id收藏所属用户source_recognition_id来源识别记录 IDsource_image_filename来源图片名name_originalname_zhdescriptionpricetagscreated_at这样做的好处是能区分不同用户的收藏能保留菜品是从哪一次识别来的后续如果做“按图片回看收藏记录”也有数据基础2. 购物车表增加来源字段在原有cart_items基础上补充了两个字段source_recognition_idsource_image_filename这样购物车中的每一道菜都可以知道自己来自哪次识别、哪张图片为前端分组展示提供依据。3. 上传识别接口返回识别批次信息在图片上传识别成功后后端除了返回识别出的items还额外返回recognition_batch_idsource_image_filename前端拿到这两个字段后会在后续收藏或加入购物车时一并提交。4. 新增菜品收藏接口新增了三组接口能力GET /favorites/dishesPOST /favorites/dishesDELETE /favorites/dishes这些接口全部基于当前登录用户处理因此天然和userId绑定不会串数据。5. 启动时自动补表和补字段为了减少手动执行 SQL 的成本在后端启动阶段加入了自动建表和补字段逻辑确保recognition_historycart_itemsfavorite_dishes在本地数据库缺失时能自动创建已有旧表时也会尽量补齐新增字段。三、前端部分改造1. 扩展MenuItem数据模型为了让前端完整携带来源信息给MenuItem新增了字段userIdsourceRecognitionIdsourceImageFilename这样无论是识别结果、收藏列表还是购物车列表都能共用同一个模型结构。2. 重写认证服务中的收藏/购物车接口封装在AuthService中补充了菜品收藏相关能力获取菜品收藏添加菜品收藏删除菜品收藏同时保留原有登录、购物车、历史记录等接口逻辑统一通过 token 访问后端。3. 新建识别结果页RecognitionResultsPage为了不直接破坏原来的大体量main.dart识别结果逻辑单独抽了一个新的识别结果页专门负责展示识别出来的菜品一键加入购物车一键收藏菜品保留点击进入原有菜品详情页的能力这里特别处理了一点菜品详情页内容没有改动仍然走原来的DishDetailPage。4. 新建“我的收藏”页MyFavoritesPage原本项目里的“我的收藏”只展示 AI 问答中的“点餐表达收藏”并不会展示今天新增的“菜品收藏”。所以我新建了一个收藏页将收藏分成两块展示Dish Favorites识别后收藏的菜品Ordering Phrase Favorites原有点餐表达收藏这样用户点击“我的收藏”时终于能看到识别结果页点爱心保存的菜品了。5. 改造购物车页面分组布局购物车之前虽然已经有来源字段概念但展示上还是不够清晰。今天重新调整了购物车页布局实现了同一张识别图片的菜品放在一个分组卡片里每个分组有明确标题每组下面列出该图片识别加入的全部菜品删除操作仍然按单个菜品执行这样用户在购物车里就能明确知道“这几道菜是从哪张菜单图里识别出来并加入购物车的”。四、开发中遇到的问题1. 原文件存在较多乱码文本项目里部分 Dart / Python 文件有历史遗留乱码导致精确打补丁时匹配经常失败。因此这次开发中采用了两种策略能局部改的尽量局部改容易受乱码影响的地方直接新建独立页面替代这也是为什么新增了RecognitionResultsPageMyFavoritesPage而不是强行在旧页面上反复修补。2. 菜品详情页不能误改中途一度为了快速串联结果页临时写了一个简单详情页但后面已经按照要求恢复为识别结果页点击菜品继续跳转原有DishDetailPage也就是说今天最终结果里详情页内容没有被改坏。3. 本地环境验证受限今天尝试做自动化验证时遇到了一些环境问题本机终端找不到可用的 Python 解释器dart analyze/dart format在当前环境下超时所以本次开发主要依靠代码链路核对和局部静态检查完成没有做到完整自动化跑通。五、本次改动涉及的主要文件后端backend/main.pybackend/models/cart_item.pybackend/models/favorite_dish.pybackend/models/user.py前端flutter_application_1/lib/models/menu_item.dartflutter_application_1/lib/services/auth_service.dartflutter_application_1/lib/pages/recognition_results_page.dartflutter_application_1/lib/pages/my_favorites_page.dartflutter_application_1/lib/pages/cart_page.dartflutter_application_1/lib/main.dartSQLmenu_app.sql六、今天的阶段性成果截至今天这套流程已经基本成型用户上传菜单图片后端保存识别历史前端拿到识别批次与图片来源用户可在识别结果页收藏菜品收藏与购物车都绑定当前登录用户收藏页可以显示菜品收藏购物车可以按识别图片分组展示菜品详情页保持原有内容不受这次改造影响七、后续可以继续优化的方向接下来还可以继续做这些增强把收藏页和购物车页的中英文提示统一改成更自然的中文给购物车每个图片分组增加“小计”或“整组清空”菜品收藏页支持点击进入详情页后端清理历史遗留乱码提示文本增加完整联调与接口测试八、总结今天这轮开发本质上是在把“识别”能力往“可持续使用”方向推进。如果只有识别结果展示用户看完就结束了但当收藏、购物车、用户绑定、来源分组这些能力补上之后整个系统才开始真正具备“菜单识别产品”的雏形。