新增门店订单与核销管理列表,对齐 Android 订单能力并完善账号级缓存。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-29 14:46:10 +08:00
parent c4de3d17d0
commit 08492df6ce
51 changed files with 3668 additions and 102 deletions

View File

@ -2,49 +2,89 @@
## 模块职责
Orders 模块负责登录后的订单 Tab。当前已覆盖订单管理、核销订单和押金订单相关入口,提供列表展示、筛选、分页、刷新、扫码核销、手动核销、押金核销、押金退款、历史拍摄、任务上传、尾片入口,以及 orderType 11/14 订单来源(带客单绑定)闭环。
Orders 模块负责登录后的订单 Tab 与订单相关二级页面。当前已对齐 Android `zhiflyfollow` 订单列表能力:主订单列表(摄影师/非店长)、店长押金订单 Tab、独立核销管理页以及押金订单独立入口、历史拍摄、任务上传、尾片入口 orderType 11/14 订单来源(带客单绑定)闭环。
订单 Tab 内的门店订单详情页与核销订单详情页暂未接入,列表卡片仅展示摘要信息
订单 Tab 内不再展示「订单管理 / 核销订单」分段核销管理通过首页菜单、TabBar 扫码或路由 push 进入独立页面
当前仍不迁移独立视频播放器增强、尾片审核进度、上传后自动关联订单尾片等后端未体现的能力;这些能力后续按明确接口再补
门店订单详情页与核销订单详情页暂未接入,列表卡片仅展示摘要信息与卡片内操作
当前仍不迁移独立视频播放器增强、尾片审核进度、上传后自动关联订单尾片等后端未体现的能力;多点位核销的定位 + 打卡点 Sheet 若 iOS 尚无完整能力,列表内仅预留扫码入口。
## 页面结构
| 场景 | 视图 | 说明 |
|------|------|------|
| 订单 Tab · 非店长 | `StoreOrderListView` | 对齐 Android `OrderListScreen` |
| 订单 Tab · 店长 | `StoreAdminOrderListView` | 对齐 Android `DepositOrderListScreen` |
| 核销管理 | `WriteOffListView` | 对齐 Android `WriteOffListScreen`,独立 push 页 |
| 押金订单入口 | `DepositOrderEntryView` | 首页 `deposit_order*` 仍保留独立入口 |
`OrdersRootView``AppRoleCode.storeAdmin` 分流店长 Tab 与主订单 Tab。
## 核心对象
- `OrdersView`:订单 Tab 根视图,读取 `AccountContext``PermissionContext``AppRouter` `OrdersAPI`
- `OrdersViewModel`:管理订单子入口、筛选条件、分页状态、加载状态和手动核销状态
- `DepositOrderListViewModel`:管理押金订单分页、核销、退款和操作后刷新
- `DepositOrderDetailViewModel`:管理押金订单详情加载,缺少门店时不发起请求
- `DepositOrderShootingInfoViewModel`:管理押金订单单个打卡点的底片、成片和评价
- `OrderRefundViewModel`:管理普通订单退款金额校验和提交保护(详情页接入前保留逻辑层)
- `HistoricalShootingInfoViewModel`:管理多点位订单历史拍摄媒体展示
- `MultiTravelTaskUploadViewModel`管理多点旅拍任务上传的订单号、已核销打卡点、云盘附件、本地附件、OSS 上传和提交
- `OrdersAPI`封装订单列表、核销订单列表和订单核销接口
- `OrdersEntry`:表示订单 Tab 内部入口,包含订单管理和核销订单
- `OrdersRoute`:表示订单模块二级页面路由,包含押金详情、历史拍摄、任务上传和尾片入口。
- `OrderNumberParser`:负责从扫码内容中解析订单号,支持 URL query、键值文本和纯订单号
- `StoreOrderListView`订单 Tab 根视图,组合 `OrderListHeaderView``OrderListCardView` `OrdersViewModel`
- `StoreAdminOrderListView`:店长订单 Tab组合共享头部与店长卡片使用 `StoreAdminOrderListViewModel`
- `WriteOffListView`:核销管理页,使用 `WriteOffListViewModel`,含横向状态 pill、日期筛选与扫码/手动核销
- `OrderListHeaderView`:白底状态/日期筛选头部;手机号搜索使用系统 `.searchable`
- `OrderListCardView`:主订单卡片,对齐 Android `OrderView` 展示顺序与操作区
- `OrderListComponents`:状态 Chip、信息行、操作按钮、精修单选等共享组件
- `OrderDialogViews`:退款、赠送修图/视频、店长退款、核销确认弹窗
- `OrdersViewModel`:主订单列表分页、筛选、卡片操作(退款/核销/精修/取消/赠送)与订单来源
- `StoreAdminOrderListViewModel`店长订单列表`storeOrderList` / `storeOrderRefund`
- `WriteOffListViewModel`:核销列表筛选、分页与核销提交
- `DepositOrderListViewModel`:押金订单分页、核销、退款(独立押金入口
- `OrderRefundViewModel`:普通订单退款金额校验与提交
- `OrdersAPI`:订单列表、核销列表、精修更新、取消、赠送、店长列表/退款等接口。
- `OrdersEntry`:订单 Tab 内部入口枚举,保留 `verificationOrders` 供测试/推送兼容。
- `OrdersRoute`:二级路由,含 `writeOffList`、押金详情、历史拍摄、任务上传、尾片入口。
- `OrderNumberParser`:从扫码内容解析订单号。
## 数据流程
订单页面从 `AccountContext.currentScenic` 读取当前景区 ID`PermissionContext.currentAppRole` 读取当前角色。景区管理员角色(`AppRoleCode.scenicAdmin`)使用景区管理员订单接口,其他角色使用摄影师订单接口。
### 主订单列表
订单管理支持状态筛选、手机号搜索、开始/结束日期筛选。筛选变更后从第一页重新加载,滚动到列表底部时加载下一页。列表卡片展示订单摘要,暂不支持点击进入详情页
`AccountContext.currentScenic` 读取景区 ID`PermissionContext.currentAppRole` 读取角色。景区管理员(`scenicAdmin`)使用景区管理员订单接口且卡片只读(隐藏退款/核销/拨号/精修/赠送/取消)
核销订单支持扫码和手动输入订单号。扫码使用 AVFoundation不缓存扫码结果扫码成功后先用 `OrderNumberParser` 提取订单号,命中当前核销列表时滚动定位并高亮卡片,未命中时填入订单号并允许继续核销。核销前统一弹确认框,确认后调用核销接口。核销成功后重新拉取第一页核销订单,并重置分页状态;核销失败只清理提交状态,不刷新列表
支持状态筛选(含精修筛选项)、手机号搜索、日期范围 Sheet 筛选。筛选变更后从第一页重新加载,滚动到底加载下一页
押金订单入口由首页 `deposit_order_detail``deposit_order``deposit_order_shooting_info` 进入。没有订单上下文时先展示押金订单页,用户可以手输订单号进入详情,也可以从列表进入详情。押金详情复用门店订单详情接口,按当前门店 ID 和订单号加载;拍摄点列表进入拍摄信息页,展示评价、底片和成片
卡片展示订单号、状态、创建时间、类型、订单来源、操作行、上传任务条orderType 19、精修单选、信息行、条件行、退款信息、备注、历史拍摄缩略图与取消订单按钮。操作受 `hideOrderWriteActions` 控制
普通订单退款逻辑已保留在 `OrderRefundViewModel`,待详情页接入后再开放入口。
### 店长订单 Tab
历史拍摄按订单号请求 `/api/yf-handset-app/photog/order/multi-travel/shoot-history`,仅展示项目、拍摄点和已有媒体,不做上传、下载、删除或编辑
`AccountContext.currentStore` 读取门店 ID调用 `GET /api/app/store/order/list`。筛选为全部/已支付/已完成/已退款。卡片展示项目、金额、时间、UID、手机号与退款/部分退款;线下产品订单额外展示核销按钮。仅 `orderType == 19` 可进详情
任务上传仅对 `orderType == 19` 的多点旅拍订单展示。页面先按订单号请求 `/api/yf-handset-app/photog/order/multi-travel/verified-scenic-spot-list` 获取已核销打卡点,再支持选择云盘素材和本地图片/视频;本地素材先通过 `OSSUploadService.uploadTaskFile` 上传,成功后和云盘文件一起提交到 `/api/yf-handset-app/photog/order/multi-travel/upload-material`
### 核销管理
视频预告和尾片上传按旧工程现状统一进入 `OrderTrailerView`,该页只做订单尾片流程引导,并打开已迁移的 `AlbumTrailerEntryView` 完成相册预览上传,不新增独立订单尾片接口
独立页面,调用 `writeOffList` 并支持 `order_status``order_verify_status``start_time``end_time``user_phone` 查询参数。横向 pill全部/已支付/已完成/已核销/未核销
订单来源(带客单绑定)仅对 `orderType == 11`(摄影师跟拍)或 `14`(线下扫码)展示,景区管理员只读不可操作。订单卡片嵌入 `OrderSourcePicker` Sheet选择合作获客员 → 加载其可绑定带客单 → 确认绑定。全页流程使用 `ReferralOrderSelectView`。绑定接口为 `POST .../sale-user/bind-referral-order`;普通订单退款成功后若存在 `referralOrder.id`,异步调用 `POST .../sale-user/referral-orders/{id}/status`status=3。获客员与带客单数据由 `CooperationOrderAPI` 提供
扫码使用 `OrderCodeScannerView`命中列表时滚动高亮核销前弹确认框成功后刷新第一页。TabBar 全局扫码通过 `pendingOrderScanCode` 交给核销页消费
### 押金订单(独立入口)
首页 `deposit_order_detail``deposit_order``deposit_order_shooting_info` 进入 `DepositOrderEntryView`,与 Tab 内店长列表 UI 分离但共用部分 API。
### 订单来源(带客单绑定)
仅对 `orderType == 11``14` 展示,景区管理员只读。绑定接口 `POST .../sale-user/bind-referral-order`;退款成功后若存在带客单则异步更新状态。
### 历史拍摄与任务上传
历史拍摄:`GET .../photog/order/multi-travel/shoot-history`。任务上传:仅 orderType 19先拉已核销打卡点再上传素材。
## 路由边界
首页 `photographer_orders``/scenic-order-manage` 会进入订单管理,`verification_order` 会进入核销订单,`deposit_order_detail``deposit_order``deposit_order_shooting_info` 会进入押金订单页。订单详情、核销订单详情、押金详情、押金拍摄信息、历史拍摄、任务上传和订单尾片已接入 `AppRoute.orders` 真实路由push 后继续隐藏 TabBar。
| 入口 | 目标 |
|------|------|
| `photographer_orders``/scenic-order-manage` | 订单 Tab · 主列表或店长列表 |
| `verification_order` | push `OrdersRoute.writeOffList`(核销管理) |
| `deposit_order*` | push 押金订单页 |
| TabBar 扫码 | 核销管理页消费扫码结果 |
未明确接口的订单后续能力继续进入占位页,避免入口崩溃
`AppRouter.routeToOrderVerification` 切换订单 Tab 并 push 核销页,不再设置 `selectedOrdersEntry`
未明确接口的订单能力继续占位,避免入口崩溃。
## 设计常量
订单列表专用色值与间距定义在 `AppDesign`(页面背景 `#F5F5F5`、输入背景 `#F4F4F4`、状态 Chip 色等与 Android 对齐)。