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