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

325 lines
9.2 KiB

3 months ago
# 模板元素显示条件说明文档
## 概述
在直接支付页面(`/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逻辑条件不满足时字段自动隐藏并清除验证错误
3 months ago
3 months ago
3 months ago
3 months ago