# 助教服务流水（GetOrderAssistantDetails） → assistant_service_records 字段映射

> 生成时间：2026-02-14

## 端点信息

| 属性 | 值 |
|------|-----|
| 接口路径 | `AssistantPerformance/GetOrderAssistantDetails` |
| 请求方法 | POST |
| ODS 对应表 | `ods.assistant_service_records` |
| JSON 数据路径 | `data.orderAssistantDetails` |

## 字段映射

| JSON 字段 | ODS 列名 | 类型转换 | 说明 |
|-----------|----------|----------|------|
| id | id | int→BIGINT（`parse_int`） | 本条助教流水记录的主键 ID（流水唯一标识） |
| tenant_id | tenant_id | int→BIGINT（`parse_int`） | 租户/品牌 ID |
| site_id | site_id | int→BIGINT（`parse_int`） | 门店 ID，本数据中指“朗朗桌球”这一家门店 |
| siteProfile | siteProfile | object→JSONB（原样存储） | 门店信息快照，包括 id、shop_name、address 等，和其他 JSON 里的 siteProfile 一致 |
| site_table_id | site_table_id | int→BIGINT（`parse_int`） | 球台 ID |
| order_settle_id | order_settle_id | int→BIGINT（`parse_int`） | 订单结算 ID，相当于“结账单号”的内部主键 |
| order_trade_no | order_trade_no | string→TEXT（原样） | 订单交易号，整个订单层面的编号 |
| order_pay_id | order_pay_id | int→BIGINT（`parse_int`） | 关联到“支付记录”的主键 ID |
| order_assistant_id | order_assistant_id | int→BIGINT（`parse_int`） | 订单中“助教项目明细”的内部 ID |
| order_assistant_type | order_assistant_type | int→INT（`parse_int`） | 来自 JSON 导出的原始字段，用于保留业务取值 |
| assistantName | assistantName | string→TEXT（原样） | 助教姓名，如“何海婷”“胡敏”等 |
| assistantNo | assistantNo | string→TEXT（原样） | 助教编号，例如 "27" |
| assistant_level | assistant_level | string→TEXT（原样） | 助教等级名称，与 assistant_level 一一对应（初级/中级/高级/助教管理） |
| levelName | levelname | string→TEXT（原样） | 名称字段，用于展示与辅助识别 |
| site_assistant_id | site_assistant_id | int→BIGINT（`parse_int`） | 门店维度的助教 ID |
| skill_id | skill_id | int→BIGINT（`parse_int`） | 助教服务“课程/技能”ID |
| skillName | skillname | string→TEXT（原样） | 名称字段，用于展示与辅助识别 |
| system_member_id | system_member_id | int→BIGINT（`parse_int`） | 系统级会员 ID（全集团统一 ID） |
| tableName | tablename | string→TEXT（原样） | 名称字段，用于展示与辅助识别 |
| tenant_member_id | tenant_member_id | int→BIGINT（`parse_int`） | 商户维度会员 ID（门店/品牌内的会员主键） |
| user_id | user_id | int→BIGINT（`parse_int`） | 助教对应的“用户账号 ID”（系统级用户） |
| assistant_team_id | assistant_team_id | int→BIGINT（`parse_int`） | 助教所属团队 ID |
| nickname | nickname | string→TEXT（原样） | 助教对外昵称，如“佳怡”“周周”“球球”等 |
| ledger_name | ledger_name | string→TEXT（原样） | 名称字段，用于展示与辅助识别 |
| ledger_group_name | ledger_group_name | string→TEXT（原样） | 助教项目所属的“计费分组/套餐分组名称”，例如某种助教套餐或业务组名称 |
| ledger_amount | ledger_amount | float→NUMERIC(18,2)（`parse_decimal`） | 按标准单价计算出来的应收金额（近似 = ledger_unit_price × income_seconds / 3600） |
| ledger_count | ledger_count | float→NUMERIC(18,4)（`parse_decimal(scale=4)`） | 台账记录的计时总秒数 |
| ledger_unit_price | ledger_unit_price | float→NUMERIC(18,4)（`parse_decimal(scale=4)`） | 助教服务 标准单价（通常是标价：每小时、每节课的单价） |
| ledger_status | ledger_status | int→INT（`parse_int`） | 来自 JSON 导出的原始字段，用于保留业务取值 |
| ledger_start_time | ledger_start_time | string→TIMESTAMP（`parse_timestamp`） | 台账层面记录的开始时间 |
| ledger_end_time | ledger_end_time | string→TIMESTAMP（`parse_timestamp`） | 台账层面的结束时间 |
| manual_discount_amount | manual_discount_amount | float→NUMERIC(18,2)（`parse_decimal`） | 收银员手动给予的减免金额（人工改价） |
| member_discount_amount | member_discount_amount | float→NUMERIC(18,2)（`parse_decimal`） | 由会员卡折扣产生的优惠金额 |
| coupon_deduct_money | coupon_deduct_money | float→NUMERIC(18,2)（`parse_decimal`） | 由“优惠券/代金券/团购券”等 直接抵扣到这条助教服务上的金额 |
| service_money | service_money | float→NUMERIC(18,2)（`parse_decimal`） | 用于记录与助教结算的金额（平台预留的“成本/分成”字段） |
| projected_income | projected_income | float→NUMERIC(18,2)（`parse_decimal`） | 实际结算计入门店的金额（已经考虑折扣、卡权益、券等后的结果） |
| real_use_seconds | real_use_seconds | int→INT（`parse_int`） | 实际使用时长（秒） |
| income_seconds | income_seconds | int→INT（`parse_int`） | 计费秒数 / 应计收入对应的时间 |
| start_use_time | start_use_time | string→TIMESTAMP（`parse_timestamp`） | 助教实际开始服务时间 |
| last_use_time | last_use_time | string→TIMESTAMP（`parse_timestamp`） | 最后一次使用（实际服务）时间 |
| create_time | create_time | string→TIMESTAMP（`parse_timestamp`） | 这条助教流水记录创建时间（一般接近结算/下单时间） |
| is_single_order | is_single_order | int→INT（`parse_int`） | 布尔/开关字段，用于表示权限、可用性或状态开关 |
| is_delete | is_delete | int→INT（`parse_int`） | 逻辑删除标志 |
| is_trash | is_trash | int→INT（`parse_int`） | 布尔/开关字段，用于表示权限、可用性或状态开关 |
| trash_reason | trash_reason | string→TEXT（原样） | 废除原因（文本说明），例如“顾客取消”“录入错误”等 |
| trash_applicant_id | trash_applicant_id | int→BIGINT（`parse_int`） | 提出废除申请的员工 ID（通常是操作员/管理员） |
| trash_applicant_name | trash_applicant_name | string→TEXT（原样） | 废除申请人姓名 |
| operator_id | operator_id | int→BIGINT（`parse_int`） | 操作员 ID（录入/结算这条助教服务的员工） |
| operator_name | operator_name | string→TEXT（原样） | 操作员姓名，与 operator_id 一起使用，便于直接阅读 |
| salesman_name | salesman_name | string→TEXT（原样） | 关联的“营业员/销售员姓名”，用于提成归属 |
| salesman_org_id | salesman_org_id | int→BIGINT（`parse_int`） | 营业员所属组织/部门 ID |
| salesman_user_id | salesman_user_id | int→BIGINT（`parse_int`） | 营业员用户 ID |
| person_org_id | person_org_id | int→BIGINT（`parse_int`） | 助教所属“人事组织/部门 ID” |
| add_clock | add_clock | int→INT（`parse_int`） | 加钟秒数，即在原有预约/服务基础上临时追加的时长 |
| returns_clock | returns_clock | int→INT（`parse_int`） | 退钟秒数（取消加钟或提前结束退回的时间） |
| composite_grade | composite_grade | →NUMERIC(10,2) | 综合评分（例如技能+服务加权后的平均分），当前数据没有实际评分 |
| composite_grade_time | composite_grade_time | string→TIMESTAMP（`parse_timestamp`） | 助教服务所在的球台名称（如 "A17"、"S1"） |
| skill_grade | skill_grade | →NUMERIC(10,2) | 顾客对“技能表现”的评分（整数或打分等级） |
| service_grade | service_grade | →NUMERIC(10,2) | 顾客对“服务态度”的评分 |
| sum_grade | sum_grade | →NUMERIC(10,2) | 累计评分总和（可能用于计算平均分），当前为 0 |
| grade_status | grade_status | int→INT（`parse_int`） | 1 = 未评价/正常 |
| get_grade_times | get_grade_times | int→INT（`parse_int`） | 该条记录对应的评价次数（或该助教被评价次数快照） |
| is_not_responding | is_not_responding | int→INT（`parse_int`） | 布尔/开关字段，用于表示权限、可用性或状态开关 |
| is_confirm | is_confirm | int→INT（`parse_int`） | 布尔/开关字段，用于表示权限、可用性或状态开关 |
| assistantteamname | assistantteamname | string→TEXT（原样） | 助教团队名称（新增字段） |
| real_service_money | real_service_money | float→NUMERIC(18,2)（`parse_decimal`） | 实际服务费金额（新增字段） |

## ETL 补充字段

| ODS 列名 | 生成逻辑 |
|-----------|----------|
| content_hash | 对业务字段（排除 ETL 元数据列）计算 SHA-256，用于变更检测与去重 |
| source_file | 固定值：`assistant_service_records.json`，标识原始导出文件 |
| source_endpoint | API 端点路径，如 `AssistantPerformance/GetOrderAssistantDetails` |
| fetched_at | ETL 入库时间戳（`TIMESTAMPTZ DEFAULT now()`） |
| payload | 完整原始 JSON 记录快照（`JSONB NOT NULL`），用于回溯与二次解析 |

## 类型转换规则

- **时间戳**：通过 `TypeParser.parse_timestamp()` 转换，支持 ISO 字符串和 Unix 毫秒时间戳，自动处理时区
- **金额**：通过 `TypeParser.parse_decimal(value, scale=2)` 转换，`ROUND_HALF_UP` 四舍五入
- **整数**：通过 `TypeParser.parse_int()` 转换，`None` 保持为 `NULL`
- **字符串**：原样保留，`None` / 空字符串均存为 `NULL` 或空文本
- **布尔值**：API 返回 `true/false`，ODS 存为 `BOOLEAN` 或 `INT`（0/1）
- **JSONB**：`siteProfile`、`payload` 等复合对象直接以 `JSONB` 类型存储
