You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
cz-hjjc-budget/模板元素显示条件说明.md

326 lines
9.2 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 模板元素显示条件说明文档
## 概述
在直接支付页面(`/payment/direct-payment`)中,模板元素的显示/隐藏受"合同总金额"和"本次支付金额"两个金额字段控制。本文档详细说明其作用机制。
## 核心函数
**函数位置**`czemc-budget-execution-frontend/src/views/payment/CreatePayment.vue`
**核心函数**`checkFieldDisplayConditions(element)` 第866-983行
**使用位置**模板中的动态字段渲染第310行
```vue
<el-form-item
v-if="(element.type !== 'approval_flow' || !element.is_main_approval_process) && checkFieldDisplayConditions(element)"
...
>
```
## 金额字段的定义和取值逻辑
### 1. 本次支付金额current_payment_amount
**定义**:用户在表单中输入的"支付金额"字段值
**取值逻辑**
```javascript
const currentPaymentAmount = formData.amount || 0
```
- **来源**:直接使用表单数据 `formData.amount`
- **说明**:始终为用户当前输入的支付金额,不存在时默认为 0
---
### 2. 合同总金额contract_total_amount
**定义**:用于条件判断的合同总金额值
**取值逻辑**
```javascript
let contractTotalAmount
if (selectedCategory.value?.need_contract && selectedContract.value) {
// 情况1分类需要关联合同且已选择合同
contractTotalAmount = selectedContract.value.amount_total || 0
} else {
// 情况2分类不需要关联合同或未选择合同
contractTotalAmount = currentPaymentAmount // 使用本次支付金额
}
```
**两种取值情况**
#### 情况1分类需要关联合同且已选择合同
- **取值来源**`selectedContract.value.amount_total`
- **说明**:使用已选择合同的真实总金额
- **适用场景**:直接支付页面,分类配置了 `need_contract: true`,用户已选择合同
#### 情况2分类不需要关联合同或未选择合同
- **取值来源**`formData.amount`(本次支付金额)
- **说明**:将本次支付金额作为"合同总金额"用于条件判断
- **适用场景**
- 分类未配置需要关联合同(`need_contract: false`
- 分类需要关联合同,但用户尚未选择合同
- 非直接支付场景
---
## 显示条件的判断逻辑
### 条件配置格式
每个模板元素(`element`)可以配置 `display_conditions` 数组,格式如下:
```javascript
{
display_conditions: [
{
field: 'contract_total_amount' | 'current_payment_amount', // 要判断的字段
op: 'lt' | 'lte' | 'gt' | 'gte' | 'eq', // 操作符
value: 10000 // 比较值(数字)
},
// ... 可以有多个条件所有条件必须同时满足AND逻辑
]
}
```
### 支持的操作符
| 操作符 | 含义 | 示例 | 说明 |
|--------|------|------|------|
| `lt` | 小于 | `{ field: 'current_payment_amount', op: 'lt', value: 10000 }` | 本次支付金额 < 10000 |
| `lte` | 小于等于 | `{ field: 'contract_total_amount', op: 'lte', value: 50000 }` | 合同总金额 50000 |
| `gt` | 大于 | `{ field: 'current_payment_amount', op: 'gt', value: 5000 }` | 本次支付金额 > 5000 |
| `gte` | 大于等于 | `{ field: 'contract_total_amount', op: 'gte', value: 100000 }` | 合同总金额 ≥ 100000 |
| `eq` | 等于 | `{ field: 'current_payment_amount', op: 'eq', value: 8888 }` | 本次支付金额 = 8888 |
### 判断流程
1. **无显示条件**:如果元素没有 `display_conditions` 或为空数组,默认**显示**
2. **有显示条件**:遍历 `display_conditions` 数组,**所有条件必须同时满足**AND逻辑
3. **条件匹配**
- 根据 `condition.field` 确定要比较的值(`contract_total_amount` 或 `current_payment_amount`
- 根据 `condition.op` 执行比较操作
- 将比较值与 `condition.value` 进行比较
4. **返回结果**
- 所有条件都满足 → **显示**字段
- 任一条件不满足 → **隐藏**字段
---
## 实际应用示例
### 示例1基于本次支付金额的条件
**场景**:当本次支付金额大于 50000 时,显示"大额支付说明"字段
**配置**
```javascript
{
id: 'field_001',
name: '大额支付说明',
display_conditions: [
{
field: 'current_payment_amount',
op: 'gt',
value: 50000
}
]
}
```
**效果**
- 用户输入 60000 → 显示该字段
- 用户输入 30000 → 隐藏该字段
---
### 示例2基于合同总金额的条件已选择合同
**场景**:当合同总金额小于等于 100000 时,显示"小额合同附件"字段
**前提条件**
- 分类配置了 `need_contract: true`
- 用户已选择合同,合同总金额为 80000
**配置**
```javascript
{
id: 'field_002',
name: '小额合同附件',
display_conditions: [
{
field: 'contract_total_amount',
op: 'lte',
value: 100000
}
]
}
```
**效果**
- 合同总金额 = 80000使用 `selectedContract.amount_total`
- 80000 ≤ 100000 → **显示**该字段
---
### 示例3基于合同总金额的条件未选择合同
**场景**:当合同总金额大于 200000 时,显示"大额合同审批"字段
**前提条件**
- 分类配置了 `need_contract: true`
- 用户**尚未**选择合同
**配置**
```javascript
{
id: 'field_003',
name: '大额合同审批',
display_conditions: [
{
field: 'contract_total_amount',
op: 'gt',
value: 200000
}
]
}
```
**效果**
- 由于未选择合同,`contract_total_amount` = `formData.amount`(本次支付金额)
- 如果用户输入 250000 → 250000 > 200000 → **显示**该字段
- 如果用户输入 150000 → 150000 ≤ 200000 → **隐藏**该字段
---
### 示例4多条件组合AND逻辑
**场景**:当本次支付金额大于 10000 **且**合同总金额小于等于 500000 时,显示"中等金额说明"字段
**配置**
```javascript
{
id: 'field_004',
name: '中等金额说明',
display_conditions: [
{
field: 'current_payment_amount',
op: 'gt',
value: 10000
},
{
field: 'contract_total_amount',
op: 'lte',
value: 500000
}
]
}
```
**效果**
- 本次支付金额 = 20000合同总金额 = 400000 → 两个条件都满足 → **显示**
- 本次支付金额 = 5000合同总金额 = 400000 → 第一个条件不满足 → **隐藏**
- 本次支付金额 = 20000合同总金额 = 600000 → 第二个条件不满足 → **隐藏**
---
## 实时响应机制
当金额字段或合同选择发生变化时,会触发字段显示/隐藏的重新计算:
**监听逻辑**第2071-2095行
```javascript
watch(
() => [formData.amount, selectedContract.value],
() => {
// 当金额字段或合同选择变化时,清除隐藏字段的验证错误
if (formRef.value && templateElements.value) {
nextTick(() => {
templateElements.value.forEach(element => {
if (!checkFieldDisplayConditions(element)) {
// 字段不满足显示条件,清除验证错误
formRef.value?.clearValidate(`fields.${element.id}`)
}
})
})
}
},
{ deep: true }
)
```
**触发时机**
- 用户修改"支付金额"时
- 用户选择/清除合同时
- 合同信息变化时(通过 `deep: true` 深度监听)
**响应效果**
- 隐藏不满足条件的字段,并清除其验证错误
- 显示满足条件的字段
---
## 关键代码位置汇总
| 功能 | 文件位置 | 行号范围 |
|------|---------|----------|
| 显示条件判断核心函数 | `CreatePayment.vue` | 866-983 |
| 模板中使用显示条件 | `CreatePayment.vue` | 310 |
| 金额变化监听 | `CreatePayment.vue` | 2071-2095 |
| 表单验证规则生成(考虑显示条件) | `CreatePayment.vue` | 986-1024 |
---
## 注意事项
1. **合同总金额的取值逻辑**
- 如果分类需要关联合同但用户未选择合同,`contract_total_amount` 会回退为本次支付金额
- 这可能导致某些基于合同总金额的条件判断不够准确,建议在配置条件时考虑这种情况
2. **条件判断的默认行为**
- 无效条件、未知字段、无效数值等情况,函数会返回 `true`(默认显示)
- 这保证了向后兼容性,但可能在某些异常情况下导致字段意外显示
3. **验证规则的同步**
- 表单验证规则只在字段满足显示条件时才添加第998行
- 当字段被隐藏时,会自动清除其验证错误,避免用户看到隐藏字段的错误提示
4. **性能考虑**
- `checkFieldDisplayConditions` 函数在每次字段渲染时都会被调用
- 函数中包含大量 `console.log`,生产环境建议移除以提高性能
---
## 总结
- **本次支付金额current_payment_amount**:始终为用户输入的支付金额,用于判断当前支付规模
- **合同总金额contract_total_amount**
- 优先使用已选择合同的真实总金额(如果分类需要关联合同且已选择)
- 否则回退为本次支付金额
- 用于判断合同规模
- **显示逻辑**所有条件必须同时满足AND逻辑条件不满足时字段自动隐藏并清除验证错误