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.
9.2 KiB
9.2 KiB
模板元素显示条件说明文档
概述
在直接支付页面(/payment/direct-payment)中,模板元素的显示/隐藏受"合同总金额"和"本次支付金额"两个金额字段控制。本文档详细说明其作用机制。
核心函数
函数位置:czemc-budget-execution-frontend/src/views/payment/CreatePayment.vue
核心函数:checkFieldDisplayConditions(element) (第866-983行)
使用位置:模板中的动态字段渲染(第310行)
<el-form-item
v-if="(element.type !== 'approval_flow' || !element.is_main_approval_process) && checkFieldDisplayConditions(element)"
...
>
金额字段的定义和取值逻辑
1. 本次支付金额(current_payment_amount)
定义:用户在表单中输入的"支付金额"字段值
取值逻辑:
const currentPaymentAmount = formData.amount || 0
- 来源:直接使用表单数据
formData.amount - 说明:始终为用户当前输入的支付金额,不存在时默认为 0
2. 合同总金额(contract_total_amount)
定义:用于条件判断的合同总金额值
取值逻辑:
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 数组,格式如下:
{
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 |
判断流程
- 无显示条件:如果元素没有
display_conditions或为空数组,默认显示 - 有显示条件:遍历
display_conditions数组,所有条件必须同时满足(AND逻辑) - 条件匹配:
- 根据
condition.field确定要比较的值(contract_total_amount或current_payment_amount) - 根据
condition.op执行比较操作 - 将比较值与
condition.value进行比较
- 根据
- 返回结果:
- 所有条件都满足 → 显示字段
- 任一条件不满足 → 隐藏字段
实际应用示例
示例1:基于本次支付金额的条件
场景:当本次支付金额大于 50000 时,显示"大额支付说明"字段
配置:
{
id: 'field_001',
name: '大额支付说明',
display_conditions: [
{
field: 'current_payment_amount',
op: 'gt',
value: 50000
}
]
}
效果:
- 用户输入 60000 → 显示该字段
- 用户输入 30000 → 隐藏该字段
示例2:基于合同总金额的条件(已选择合同)
场景:当合同总金额小于等于 100000 时,显示"小额合同附件"字段
前提条件:
- 分类配置了
need_contract: true - 用户已选择合同,合同总金额为 80000
配置:
{
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 - 用户尚未选择合同
配置:
{
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 时,显示"中等金额说明"字段
配置:
{
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行):
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 |
注意事项
-
合同总金额的取值逻辑:
- 如果分类需要关联合同但用户未选择合同,
contract_total_amount会回退为本次支付金额 - 这可能导致某些基于合同总金额的条件判断不够准确,建议在配置条件时考虑这种情况
- 如果分类需要关联合同但用户未选择合同,
-
条件判断的默认行为:
- 无效条件、未知字段、无效数值等情况,函数会返回
true(默认显示) - 这保证了向后兼容性,但可能在某些异常情况下导致字段意外显示
- 无效条件、未知字段、无效数值等情况,函数会返回
-
验证规则的同步:
- 表单验证规则只在字段满足显示条件时才添加(第998行)
- 当字段被隐藏时,会自动清除其验证错误,避免用户看到隐藏字段的错误提示
-
性能考虑:
checkFieldDisplayConditions函数在每次字段渲染时都会被调用- 函数中包含大量
console.log,生产环境建议移除以提高性能
总结
- 本次支付金额(current_payment_amount):始终为用户输入的支付金额,用于判断当前支付规模
- 合同总金额(contract_total_amount):
- 优先使用已选择合同的真实总金额(如果分类需要关联合同且已选择)
- 否则回退为本次支付金额
- 用于判断合同规模
- 显示逻辑:所有条件必须同时满足(AND逻辑),条件不满足时字段自动隐藏并清除验证错误