# 用户端 App 购物车操作日志 操作时间:2026-09-08。操作类型:扩展。影响模块:Flutter用户端、Go商城Client API、接口契约与视觉记录。 ## 操作前状态 已阅读最新13-购物车原图及03需求。既有ec_cart表没有用户端接口;商城/详情购物车按钮弹出未开放提示,详情没有加入购物车;结算页面只接收单一商品。工作区已有大量前序变更,本轮未重置、清理或提交。数据库和缓存继续使用原配置的远程服务,本机只运行API和Web。 ## 本次变更 | 文件(仓库相对路径) | 位置与职责 | 行数说明 | | --- | --- | --- | | backend/api/internal/logic/client/user/cart.go | 51行ListCart、80行GetCartItem、104行SetCartItem;本人条目和条件数量写入 | 新增186行 | | backend/api/internal/logic/client/user/shop.go | 65行CreateShopOrder;items校验、固定锁顺序、购物车版本消费 | 扩展既有函数,不替换支付和退款 | | backend/api/internal/routers/client.go、client_test.go | 用户鉴权组新增GET shop/cart、GET/PUT shop/cart/items/:identity | 3条路由和路由注册断言 | | apps/user_app/lib/domain/models/cart_item.dart | 强类型条目、整数金额、库存和版本 | 新增49行 | | apps/user_app/lib/data/repositories/client_repository.dart | 18行cart及条件写入;40行submitCartOrder | 追加接口,保留submitShopOrder签名 | | apps/user_app/lib/ui/features/shop/cart_page.dart | 购物车、失效提示、单选全选、管理删除、真实金额 | 新增350行 | | apps/user_app/lib/ui/features/shop/product_detail_page.dart | 37行_add;未知结果保留目标数量,重试不重新累加 | 扩展底部动作 | | apps/user_app/lib/ui/features/shop/checkout_page.dart | fromCart模式和103行_submit;多商品快照、地址和金额确认 | 文件现355行,单商品流程保留 | | apps/user_app/lib/ui/features/shop/shop_page.dart、lib/app/router.dart | 商城购物车按钮;/cart和/cart/checkout及登录守卫 | 扩展现有导航 | | backend/api/internal/logic/client/user/cart_test.go | 幂等、账户过滤、版本、数量、归档及多商品事务 | 新增178行 | | apps/user_app/test/ui/cart_page_test.dart、test/data/cart_test.dart | 交互、未知结果、选中地址、整数金额、HTTP鉴权 | 新增182和64行 | | apps/user_app/test/support/a1_fixture.dart、tool/a1_visual_test.dart | 独立购物车测试数据及图13视觉截图 | 不进入运行中的商品数据 | | scripts/compare-user-app-a1.ps1 | 图13并排图,现12组原图对照 | 输出仅用于检查差异 | ## 行为与数据边界 - 所有购物车读写按JWT账户过滤,商品使用公开identity。账户行锁串行保护创建、改量和归档;不新增远程表、字段或容器。 - PUT提交绝对quantity、selected和revision;相同目标无副作用,过期版本返回2403。版本采用购物车公开UUID和微秒精度时间,已通过真实PostgreSQL写后重读验证。 - quantity=0归档。数据库仍保留正数量以兼容旧CHECK,API把归档行解释为零并保留版本,避免旧请求复活已删除商品。新增/增加受库存和999上限限制;最多100条有效商品。 - 全选和批量删除逐项写入,部分失败后重新加载服务端状态;不能把局部成功描述为整体成功。 - 订单可提交多个不同商品,按identity排序锁库存,拒绝重复商品及非法数量。cart_revision必须与本人的有效勾选条目及数量一致;移除购物车、扣库存、创建订单在同一事务,任一步失败整体回滚。 - 原订单request_no优先恢复已有结果,原单商品客户端不传cart_revision仍兼容。用户点击提交前不创建订单,不支付、不触发真实配送。 ## 验证结果 - `go test ./...`、`go vet ./...`、`go build -o %TEMP%/heqi-cart-api.exe ./cmd/main/main.go`通过;之后补充首次加购false勾选和非法订单items两项测试,定向测试通过。 - `flutter analyze --no-pub`通过;用户端完整79项测试通过。视觉发现生产主题的FilledButton在Row内无限宽约束,修复为受约束宽度,并让新增交互测试使用真实AppTheme,3项交互回归再次通过。 - 图12、13各在320/360/390/430宽度、1.0/1.3文字缩放下共16项视觉检查通过,已打开390图13及320大字体图12核对。原图和截图并排生成成功;这仅证明无布局溢出,不代表原稿一致。 - Flutter Web Release重新构建通过,本地18571使用新产物;Go API本地12426连接既有远程PostgreSQL/Redis。`pnpm contract:sync`与`pnpm contract:check`通过,48个资源。 - 匿名GET shop/cart实测HTTP401。授权测试账户原有一条15kg配送服务购物车记录,数量1/勾选true,本次保留。 - 远程HTTP联调给商品9和10各加入2件,同一数量请求重试不累加。创建订单 **EC1788842040900189900**(identity `01a07f4b-5e44-72e5-893d-6b194089cf13`),两商品应付41800分;重复提交返回同一订单,已结算购物车条目被原子移除。 - 上述联调订单已取消,临时地址已归档,两种商品库存恢复29和30;没有支付或实际履约。 - 浏览器390×844实测游客加购跳登录并回商品详情,登录后加购成功;购物车将测试商品从1改为2,合计20800分变为31300分,多商品结算显示原有商品10300分×1和新增商品10500分×2。未在浏览器提交订单;完整创建/重试/取消已由上述HTTP真实联调覆盖。 - 重新打开最新Web构建并重新登录后,新增商品仍为2件,验证了远程持久化;手机截图已核对最新分组与底部按钮。随后通过管理、单选和删除确认归档本次测试商品,HTTP复核仅剩原有商品数量1/勾选true。 ## 视觉差异与未完成项 整体仍为failed/部分实现,不能写“图13已1:1完成”。原图有配送承诺、规格、押金提示、保障区和推荐区,当前后台模型及接口没有完整支持;本次未编造承诺、押金或优惠。原图128+169+100与展示合计425不一致,实际结算必须服从服务端整数金额。 远程示例商品9/10没有图片,原有15kg商品图片URL返回404,仍显示明确空/失败状态,没有把设计稿里的其他商品图当成真实商品照片。基础白色商品分组、分隔线、圆形勾选和底部金额已调整;图片、上下分区、规格及精确间距仍不一致。 详情收藏、客服、分享及购物车优惠/推荐/押金配置未完成;全量状态更新为12张部分实现、46张尚无完整页面、0张通过严格全功能1:1验收。订单未知结果在当前页面复用请求号,跨页面重建持久化恢复仍须继续完善;本轮没有将原生Android/iOS购物车交互标为验收通过。 ## 维护说明 后续增加SKU、促销、押金与推荐应扩展对应领域服务,金额和库存继续服务端确认。修改购物车必须复用条件版本契约,并覆盖失效条目、并发版本、所有权和事务回滚测试。批量动作若改为原子接口需同步契约和失败提示。继续沿用当前技术栈和环境;禁止通过全库迁移或重置数据修复展示差异。