import type { ReactNode, MouseEvent } from 'react'; import type { FloorMapDataSources, FloorMapMergedItem, RecordBoardBodyView, RecordBoardProps, RecordBoardToolBarProps, ReservationScheduleBandValue, TimeNavigatorPassthroughProps, PisellReservationScheduleProps } from '@pisell/materials'; /** 只读平面图点击预约后的行为 */ export declare type FloorMapBookingClickMode = 'hostDrawer' | 'detailModal'; export declare type FloorMapBookingClickArgs = { event: MouseEvent; raw: Record | undefined; row: PisellReservationTableRow; dataSources: FloorMapDataSources; mode: 'read' | 'edit'; }; export interface SelectFloorMapResourcePayload { row: PisellReservationTableRow; item: FloorMapMergedItem; resource: { id: string | number; form_id?: string | number; code?: string; main_field?: string; relation_id?: string | number; raw?: PisellReservationTableRow; }; } export interface ResourceSelectModeConfig { enabled: boolean; onSelectResource: (payload: SelectFloorMapResourcePayload) => void; } /** 长条桌多段的进度(0–1),与 slots 按下标对应 */ export declare type ReservationSlotEntry = { name: string; time: string; /** 可选:该段底部细进度条 */ progress?: number; }; /** * 预约平面图行数据(桌位 mock / 业务台位) */ export declare type PisellReservationTableRow = { id: string; code: string; /** 资源接口 `main_field` 原值,供平面图侧栏「选择数据行」等展示 */ main_field?: string; /** 资源所属 form 的 id(来自 /shop/form/resource/page 的 form_id,保留原始类型) */ form_id?: string | number; area?: string; /** * occupied 使用中 | booked 已订 | maintenance 维护 | barBusy 吧台占用高亮环 | * available 空台(仅台号) */ cardStatus: 'occupied' | 'booked' | 'maintenance' | 'barBusy' | 'available'; guestName?: string; /** 平面图卡片展示用手机号(已脱敏可由业务传入,如 135****6789) */ guestPhone?: string; time?: string; /** 占用态结束时间等展示,如与 `time` 组合为「02:00 End」 */ timeEnd?: string; partySize?: number; /** 预订单「约 N 分钟后开始」展示(分钟) */ startsInMinutes?: number; /** 金额展示文案,如「$ 1288」 */ priceDisplay?: string; /** 是否已付(平面图右下角印章) */ isPaid?: boolean; /** 占用台:延误提示 +N 分(三角标) */ delayMinutes?: number; /** 预订单:迟到提示 late N 分 */ lateMinutes?: number; /** 已进行时长文案,如 1h45m、55m */ elapsedLabel?: string; progress?: number; /** 进度条语义:warning 黄色粗条(入座过久等)、success 绿色细条 */ progressTone?: 'warning' | 'success'; /** 顶栏强调:occupied 时橙色顶边(入座提醒) */ topAccentOrange?: boolean; nextGuest?: string; nextTime?: string; /** 方桌多订一段展示(如 T-6 两行预订) */ slots?: ReservationSlotEntry[]; moreCount?: number; /** 维护态右上角容量等,如 6p */ capacityLabel?: string; /** 吧台圆卡:第二组客人(如 B-4 两行) */ barSlots?: Array<{ name: string; time: string; }>; /** 吧台圆卡:剩余/进行时长,如 1h10m、55m */ barRemainingLabel?: string; /** * 平面图当前画布用的原始预约列表(如内置模式下时间轴选中时刻下 `sales.getResourceBookingList` 返回行内的 `bookings`), * 与卡片展示、占用/预留大类判定一致;按开始时间排序。 */ floorMapSourceBookings?: Record[]; /** 预约时段锚定日期 `YYYY-MM-DD`(来自接口 `start_at` / `start_date`),供仅含 `HH:mm` 的合成展示 */ floorMapReferenceDay?: string; /** * 宿主 `reserved_status`:`reserved` 时 `late` / `not_arrived` 驱动图元预留细分态;`undefined` 由 lateMinutes 兜底。 */ hostReservedStatus?: 'not_arrived' | 'late'; /** 宿主 `isTimeout`:`occupied` 为 true 时图元走超时占用样式 */ hostIsTimeout?: boolean; /** 合成行:下一档预约(与接口 isNext 语义一致时由映射写入 booking) */ isNext?: boolean; /** Story / 本地演示:映射到大屏资源墙卡片的灯控态(接灯控接口前预览)。 */ resourceWallLightState?: 'off' | 'off_soon_on' | 'on_soon_off'; resourceWallLightOnInMin?: number; resourceWallLightOffInMin?: number; /** * 接口直出的「当前资源订单总数」:来自 `sales.getResourceBookingList`(资源行顶层) * / `sales.getResourceBookingItem` 顶层返回的 `bookingCount`。 * 用于平面图资源卡标题 `资源名 (N/M)` 的**分母 M**;仅透传,不参与 * 占用 / 预约态判定与 floorMapSourceBookings 合并逻辑。 */ bookingCount?: number; /** * 接口直出的「已完成订单数」:与 `bookingCount` 同源,来自 `sales` 资源行顶层的 * `compeleteBookingCount`(映射层读入后存为 `completeBookingCount`)。用于平面图 * 资源卡标题 `资源名 (N/M)` 的**分子 N**; * 缺失时(旧数据 / 非 sales 路径)按 0 展示,仅在 `bookingCount > 0` 时与分母 * 联动渲染,避免空态卡多出 `(0/0)` 噪音。 */ completeBookingCount?: number; }; /** * 页面级预约看板:内置 Sales Management 预约列表(列、筛选、排序、GET booking)+ 时间轴 + 平面图。 * 默认不向父级要求 data/grid/searchParams;可选传入 `data` 以受控模式接管列表(Story / 特例)。 */ export interface PisellReservationProps extends Omit { /** * 受控列表数据。不传、`null`、或仅空数组且未受控分页/总数时,走内置 booking 列表请求(见组件内 `shouldUseBuiltinReservationList`)。 */ data?: unknown[] | null; total?: number; pagination?: RecordBoardProps['pagination']; onPageChange?: RecordBoardProps['onPageChange']; searchParams?: Record; onSearch?: RecordBoardProps['onSearch']; onReset?: RecordBoardProps['onReset']; loading?: boolean; /** * 平面图用桌位等数据源;未传 `tables` 时由当前预约列表接口数据映射(与列表同页) */ dataSources?: Record; gridDataSourceKey?: string; /** 顶栏时间轴受控值 */ scheduleValue?: ReservationScheduleBandValue; onScheduleChange?: (next: ReservationScheduleBandValue) => void; /** 覆盖路由里的 business_code,用于宿主 action 弹窗等无路由场景 */ reservationBiz?: string; /** 覆盖 Pico 关联餐牌 ID,用于宿主 action 弹窗等无路由场景 */ associatedMenuListIds?: number[]; /** 透传 PisellTimeNavigator;「跟随当前」时默认隐藏 Now,仍可改时间轴(改动后自动退出跟随) */ timeNavigatorProps?: TimeNavigatorPassthroughProps; /** * 透传 PisellReservationSchedule(如 minDate / maxDate); * 「跟随当前」时仍可改日期(改动后自动退出跟随) */ scheduleProps?: Omit; /** 合并到 RecordBoard.toolBar(与预约列工具栏合并,tabs 并列在时间轴后) */ toolBar?: Omit & { tabs?: ReactNode; }; scheduleStartSlot?: ReactNode; scheduleEndSlot?: ReactNode; onNewReservation?: () => void; fab?: ReactNode; floorMap?: RecordBoardProps['floorMap']; floorPlanId?: number | null; floorPlanCanvasWidth?: number; floorPlanCanvasHeight?: number; /** GET `?code=` 与保存 body;默认 `pisell_reservation` */ floorPlanCode?: string; floorPlanName?: Record; floorPlanSort?: number; floorPlanStatus?: number; onFloorPlanPersisted?: () => void; putFloorPlan?: (id: number, body: Record) => Promise; /** * 已废弃:内置点击不再读取该字段。未在 `onFloorMapBookingClick` 吞掉时,按引擎店铺 id 分流—— * **仅 `shop_id === 2155`(`getData('shop_id')` 或 `store.global.globalConfig.id`)走宿主结账抽屉**,否则走内置预约详情弹窗。 * 仍保留类型便于旧页面传参不报错;传入值无效果。 */ floorMapBookingClickMode?: FloorMapBookingClickMode; /** * 完全自定义点击逻辑;返回 `true` 时表示已处理,不再执行内置抽屉 / 详情弹窗。 */ onFloorMapBookingClick?: (args: FloorMapBookingClickArgs) => boolean | void; /** * 资源选择模式:点击平面图资源时只返回资源信息,不触发预约详情/新建/宿主抽屉。 */ resourceSelectMode?: ResourceSelectModeConfig; /** * 是否展示表格/平面图切换并允许切换;为 false 时配合 {@link lockedBodyView} 由 RecordBoard 锁定子视图。 * @default true */ bodyViewSwitchable?: boolean; /** * `bodyViewSwitchable === false` 时强制子视图;未传时 RecordBoard 默认为 `floorMap`。 * 表格专用页 {@link PisellReservationTablePage} 使用 `grid`。 */ lockedBodyView?: RecordBoardBodyView; /** * 与 RecordBoard 一致;不传则不写入 localStorage(场控页应不传)。 */ bodyViewStorageKey?: string; /** 点击平面图左上角 HUD 打开窄屏表格抽屉(画布已绑定资源行) */ floorMapHudTableDrawer?: boolean; /** * 布局变体。传 `'phone'` 时启用手机优化布局(根节点 `pisell-reservation-page--phone`,紧凑工具栏与顶栏折行等)。 * 其它字符串保留扩展,当前无额外语义。 */ variant?: string; /** * 强制「跟随当前时间」不可关闭(定时对齐墙钟、`getResourceBookingList` 与游标时间一致)。 * - **默认**:{@link lockedBodyView} 为 `resourceWall`,或用户在 RecordBoard 内**切换到「大屏 / resourceWall」子视图**时自动启用。 * - 设为 `true` 可在其它场景也强制跟随。 */ forceFollowWallClock?: boolean; }