# XCharge 支付组件使用文档

## 概述

`XCharge` 用于门诊/收费等场景的支付方式选择与金额录入：
- 支持单选支付与混合支付（多选）。
- 支付详情仅展示“金额”输入框；每种方式的字段名可通过配置映射。
- 自动汇总总支付金额并通过事件抛出。

## 组件引入

```vue
<x-charge
  :queryParamsName="'chargeConfig'"
  :parameter="{ registerId: 'xxx' }"
  @method="onMethod"
  @methods="onMethods"
  @totalPaymentAmount="onTotal"
  @action="onAction"
/>
```

### Props
- `queryParamsName: string`：后端/配置平台上的配置名。
- `parameter: object`：拉取数据源逻辑时传入的参数（可选）。

## 配置结构（Schema）

```ts
interface ChargeConfig {
  amountFields: Array<{ field: string; label: string; disabled?: boolean }>
  paymentMethods: Array<{ key: string; label: string; amountLabel?: string }>
  bottomFields: Array<{ field: string; label: string; disabled?: boolean }>
  actionButtons: Array<{ key: string; label: string; icon?: string }>
  enableMixedPayment: boolean
  // 新增：金额字段名称映射（优先级最高）
  paymentAmountLabels?: Record<string, string> // e.g. { '现金': '现金金额' }
  // 可选：事件名覆写
  eventNames?: {
    method?: string
    methods?: string
    totalPaymentAmount?: string
    action?: string
  }
  // 可选：数据源逻辑名（通过 runLogic 拉取初始数据）
  dataSourceConfig?: string
}
```

### 字段含义
- `amountFields`：顶部金额信息区（展示型/输入型混合，按配置 `disabled` 控制）。
- `paymentMethods`：支付方式列表，展示在方式选择区。可为每项配置 `amountLabel` 作为金额输入框的名称。
- 金额字段名称：优先使用 `paymentMethods[].amountLabel`；未配置时回退为“{支付方式}金额”。（已移除 `paymentAmountLabels` 配置）
- `bottomFields`：底部金额与辅助字段区（如账户余额、实收、找零）。
- `actionButtons`：底部操作按钮（收费/退费/打印等）。
- `enableMixedPayment`：是否启用混合支付（true=多选；false=单选）。
- `eventNames`：对外抛出事件名的自定义（默认见下）。
- `dataSourceConfig`：用于通过 `runLogic` 拉取初始数据的逻辑名。

### 最小配置示例
```js
{
  enableMixedPayment: true,
  paymentMethods: [
    { key: '医保卡', label: '医保卡' },
    { key: '微信/支付宝', label: '微信/支付宝' },
    { key: '银行卡', label: '银行卡' },
    { key: '现金', label: '现金' }
  ],
  paymentAmountLabels: {
    '现金': '现金金额',
    '医保卡': '医保支付金额'
  },
  amountFields: [
    { field: 'f_amount', label: '费用总额' }
  ],
  bottomFields: [
    { field: 'received', label: '实收' },
    { field: 'change', label: '找零' }
  ],
  actionButtons: [
    { key: 'charge', label: '收费', icon: 'check' }
  ]
}
```

## 关键事件

- `@method(value: string)`：单选/主方式变更（向后兼容）。
- `@methods(values: string[])`：混合支付方式列表变更。
- `@totalPaymentAmount(total: number)`：支付金额合计变更。
- `@paymentAmountChange(payload: { method: string; amount: number })`：任意单个支付方式金额变更。
- `@action(payload: ActionPayload)`：点击底部操作按钮时触发。

```ts
interface ActionPayload {
  key: string                    // 按钮 key
  data: Record<string, any>      // 页面顶部/底部的数据对象
  method: string                 // 当前主方式（兼容字段）
  mixedPayment: {
    selectedMethods: string[]
    paymentAmounts: Record<string, number>
    totalPaymentAmount: number
  }
}
```

## 交互与展示规则

- 支付详情区只显示金额输入框；每种方式的标签来自：
  1) `paymentMethods[].amountLabel`
  2) 回退为“{支付方式}金额”。
- 混合支付：已选方式的金额输入框横向同一行展示，超出可横向滚动。
- 单一支付：同一行展示一个金额输入。
- 边框与卡片背景均已移除，样式与底部区域保持一致、简洁。

## 使用代码示例

```vue
<template>
  <x-charge
    :queryParamsName="'testChargeConfig'"
    :parameter="{ visitId: '123' }"
    @method="onMethod"
    @methods="onMethods"
    @totalPaymentAmount="onTotal"
    @action="onAction"
  />
</template>

<script>
export default {
  methods: {
    onMethod(value) { console.log('主方式:', value) },
    onMethods(values) { console.log('已选方式:', values) },
    onTotal(total) { console.log('合计金额:', total) },
    onAction(payload) { console.log('动作数据:', payload) }
  }
}
</script>
```

## 内置数据/计算

- `paymentAmounts: Record<string, number>`：各支付方式金额，输入变更自动更新。
- 自动计算 `data.totalPaymentAmount` 并通过事件抛出。

## 注意事项

- 若使用混合支付，请确保 `paymentMethods` 的 `key` 唯一且与 `paymentAmountLabels` 中的键一致。
- 仅金额字段参与总额计算；备注、状态等已从 UI 中移除（如需扩展，可在底部区域或外层表单自行补充）。
- 配置缺失或数据源异常时组件会启用默认数据以保障可用性。
# XCharge 混合支付组件

## 功能特性

### 1. 配置控制混合支付
- 通过 `enableMixedPayment` 配置项控制是否启用混合支付
- 支持单选模式（传统）和混合支付模式（多选）

### 2. 混合支付模式
- 支持多种支付方式同时选择
- 每种支付方式可单独设置金额、备注、状态
- 自动计算总支付金额
- 支持动态添加/移除支付方式

### 3. 单选模式（向后兼容）
- 保持原有的单选支付方式
- 完全兼容现有配置和代码

## 配置示例

### 启用混合支付
```javascript
{
  enableMixedPayment: true,
  paymentMethods: [
    { key: "医保卡", label: "医保卡" },
    { key: "微信/支付宝", label: "微信/支付宝" },
    { key: "银行卡", label: "银行卡" },
    { key: "现金", label: "现金" }
  ],
  // ... 其他配置
}
```

### 禁用混合支付（单选模式）
```javascript
{
  enableMixedPayment: false,
  paymentMethods: [
    { key: "医保卡", label: "医保卡" },
    { key: "现金", label: "现金" }
  ],
  // ... 其他配置
}
```

## 事件

### 单选模式事件
- `@method`: 支付方式选择事件
- `@action`: 操作按钮点击事件

### 混合支付模式事件
- `@method`: 主要支付方式选择事件（向后兼容）
- `@methods`: 多选支付方式变化事件
- `@totalPaymentAmount`: 总支付金额变化事件
- `@action`: 操作按钮点击事件（包含混合支付数据）

## 数据结构

### 混合支付数据结构
```javascript
{
  selectedMethods: ['医保卡', '微信/支付宝'],
  paymentAmounts: { '医保卡': 50, '微信/支付宝': 30 },
  paymentNotes: { '医保卡': '医保支付', '微信/支付宝': '扫码支付' },
  paymentStatus: { '医保卡': 'paid', '微信/支付宝': 'pending' },
  totalPaymentAmount: 80
}
```

## 使用示例

```vue
<template>
  <x-charge 
    :queryParamsName="'chargeConfig'"
    :data="chargeData"
    @method="handleMethod"
    @methods="handleMethods"
    @totalPaymentAmount="handleTotalAmount"
    @action="handleAction"
  />
</template>

<script>
export default {
  methods: {
    handleMethod(value) {
      console.log('单选支付方式:', value)
    },
    handleMethods(methods) {
      console.log('多选支付方式:', methods)
    },
    handleTotalAmount(amount) {
      console.log('总支付金额:', amount)
    },
    handleAction(actionData) {
      if (actionData.mixedPayment) {
        console.log('混合支付数据:', actionData.mixedPayment)
      } else {
        console.log('单选支付数据:', actionData.method)
      }
    }
  }
}
</script>
```

## 修复的问题

1. **方法名冲突**: 修复了XChargeDemo中`totalPaymentAmount`方法名与数据属性冲突
2. **配置访问安全**: 添加了计算属性`isMixedPaymentEnabled`来安全访问配置
3. **空值检查**: 所有配置访问都添加了空值检查，避免运行时错误
4. **事件处理**: 改进了事件处理逻辑，支持单选和混合支付两种模式
5. **向后兼容**: 确保所有原有功能完全兼容

## 测试建议

1. 测试单选模式下的正常功能
2. 测试混合支付模式下的多选功能
3. 测试配置切换时的状态清理
4. 测试各种边界情况（空配置、无效数据等）
