# TicketBookingDialog Action 调用文档

`TicketBookingDialog` 通过 `pisell1.handleOpenEditBooking` action 唤起，支持**编辑模式**和**新建模式**两种调用方式，通过 `data` 中传递的字段自动区分。

---

## 编辑模式

传入 `order_id`，弹窗拉取订单详情后进入编辑流程。

```typescript
action({
  type: 'pisell1.handleOpenEditBooking',
  data: {
    order_id: 12345,
  },
  callback: (res: any) => {
    // 编辑完成后的回调
    (window as any)?.shopApi?.booking?.refreshBookingDetail();
  },
});
```

### 参数


| 字段              | 类型                   | 必填  | 说明                      |
| --------------- | -------------------- | --- | ----------------------- |
| `data.order_id` | `number`             | 是   | 订单 ID，弹窗内部通过此 ID 拉取订单详情 |
| `callback`      | `(res: any) => void` | 否   | 弹窗关闭/保存/支付完成时的回调        |


---

## 新建模式

不传 `order_id`，改传 `createModeConfig`，可预填客户、商品、日期等数据，直接进入新建流程。

```typescript
action({
  type: 'pisell1.handleOpenEditBooking',
  data: {
    createModeConfig: {
      bookingConfigParams: {
        item_type: 'appointment_booking',
        sub_type: 'ticket',
      },
      initialModalState: {
        client: {
          value: {
            id: 100,
            nickname: 'John Doe',
            phone: '13800138000',
            email: 'john@example.com',
            cover: '',
          },
          edit: false,
        },
        date: {
          value: dayjs('2026-04-20 10:00'),
          edit: false,
        },
        service: {
          value: [
            {
              _id: 'pre_001',
              id: 42,
              title: 'Yoga Class',
              quantity: 1,
              price: 50,
              cover: 'https://example.com/yoga.jpg',
              _extend: {
                price: 50,
                total: 50,
                origin_total: 50,
                quantity: 1,
                product_name: 'Yoga Class',
                startDate: dayjs('2026-04-20 10:00'),
                endDate: dayjs('2026-04-20 11:00'),
              },
            },
          ],
          edit: true,
        },
        notes: {
          orderNote: 'VIP 客户，优先安排',
          edit: false,
        },
      },
      productDisplayConfig: 'sku-list-a2',
      businessCode: 'TICKET_BIZ',
    },
  },
  callback: (res: any) => {
    if (res.type === 'save') {
      // 新建保存成功，res.data 包含提交的订单数据
    }
    if (res.type === 'checkout') {
      // 结账流程完成
    }
    if (res.type === 'paymentClose') {
      // 支付弹窗关闭，res.reset 表示是否重置
    }
    if (res.type === 'close') {
      // 用户手动关闭弹窗
    }
  },
});
```

### `data.createModeConfig` 参数


| 字段                     | 类型                    | 必填  | 说明                          |
| ---------------------- | --------------------- | --- | --------------------------- |
| `bookingConfigParams`  | `Record<string, any>` | 是   | 商品配置参数，决定拉取什么类型的商品列表        |
| `initialModalState`    | `Record<string, any>` | 否   | 预填充的 modalState 片段，浅合并到默认值上 |
| `productDisplayConfig` | `string`              | 否   | 商品列表展示风格，默认 `'sku-list-a2'` |
| `businessCode`         | `string`              | 否   | 业务编码；新建下单会写入 TicketBooking 状态 |
| `associated_menu_list_ids` | `number[]`        | 否   | 餐牌 ID 列表；非空时覆盖 `getProducts` 的 `menu_list_ids`（否则用 board `menu_list_tab.menu_list`） |


### `bookingConfigParams` 常见配置

Ticket 模式（门票/预约类）：

```typescript
bookingConfigParams: {
  item_type: 'appointment_booking',
  sub_type: 'ticket',
}
```

Food 模式（餐饮类）：

```typescript
bookingConfigParams: {
  item_type: 'appointment_booking',
  sub_type: 'food',
  source_type: 'pos',
}
```

### `initialModalState` 可用字段

所有字段均为可选，只传需要预填的部分，未传的字段使用默认空值。

#### `client` — 客户

```typescript
client: {
  value: {
    id: number,           // 客户 ID
    nickname: string,     // 显示名称
    phone?: string,       // 手机号
    email?: string,       // 邮箱
    country_calling_code?: string, // 国际区号
    cover?: string,       // 头像
  },
  edit: boolean,          // 是否标记为已编辑
}
```

#### `date` — 日期时间

```typescript
date: {
  value: Dayjs,           // dayjs 实例
  edit: boolean,
}
```

#### `service` — 商品/服务列表（购物车）

```typescript
service: {
  value: Array<{
    _id: string,          // 前端唯一标识
    id: number,           // 商品 ID
    title: string,        // 商品名称
    quantity: number,     // 数量
    price: number,        // 单价
    cover?: string,       // 商品图片
    duration?: number,    // 服务时长（分钟）
    _extend: {
      price: number,
      total: number,      // 总价（含折扣）
      origin_total: number, // 原总价（不含折扣）
      quantity: number,
      product_name: string,
      startDate: Dayjs,
      endDate: Dayjs,
      holder_id?: number | number[], // 预约主体 ID
      resource?: any,     // 资源
      other?: {           // 规格/套餐还原数据
        rowKey: string,
        product_id: number,
        option: any[],
        bundle: any[],
        product_variant_id: number,
        quantity: number,
      },
    },
  }>,
  edit: boolean,
}
```

#### `pet` — 宠物/预约主体

```typescript
pet: {
  value: object,          // 宠物信息
  edit: boolean,
}
```

#### `addons` — 附加商品

```typescript
addons: {
  value: any[],           // 附加商品列表
  edit: boolean,
}
```

#### `form` — 表单

```typescript
form: {
  value: object,          // 表单数据
  forms: any[],           // 表单配置
  edit: boolean,
}
```

#### `notes` — 备注

```typescript
notes: {
  orderNote: string,      // 订单备注
  internalNotes?: any[],  // 内部备注
  edit: boolean,
}
```

---

## callback 回调类型

两种模式的 `callback` 返回格式一致：


| `res.type`              | 触发时机           | 附带数据                 |
| ----------------------- | -------------- | -------------------- |
| `'save'`                | 保存/新建成功        | `res.data` — 提交的订单数据 |
| `'checkout'`            | 结账流程完成         | `res.data` — 提交的订单数据 |
| `'paymentClose'`        | 支付弹窗关闭         | `res.reset` — 是否需要重置 |
| `'close'`               | 用户手动关闭弹窗       | 无                    |
| `'no-support-business'` | 业务类型不支持（仅编辑模式） | 无                    |


---

## 模式判断规则

`order_id` 和 `createModeConfig` 互斥，`order_id` 优先：

- `data.order_id` 存在 → 编辑模式
- `data.order_id` 不存在且 `data.createModeConfig` 存在 → 新建模式
- 两者都不存在 → 不打开

---

## 两种模式行为差异


| 行为              | 编辑模式                         | 新建模式                   |
| --------------- | ---------------------------- | ---------------------- |
| API 调用          | `getBookingDetail(order_id)` | 无，直接渲染                 |
| `bookingDetail` | 后端返回的订单详情对象                  | `null`                 |
| `bookingId`     | 订单 ID                        | `0`                    |
| 保存按钮            | 调用 `editBooking` API         | 调用 `createBooking` API |
| 已付金额            | 从订单中还原                       | 无（全新支付）                |
| 支付弹窗            | 还原已有支付记录                     | 全新支付流程                 |
| 弹窗标题            | 订单的 booking_id               | 新建预约                   |


