# 模板元素显示条件说明文档 ## 概述 在直接支付页面(`/payment/direct-payment`)中,模板元素的显示/隐藏受"合同总金额"和"本次支付金额"两个金额字段控制。本文档详细说明其作用机制。 ## 核心函数 **函数位置**:`czemc-budget-execution-frontend/src/views/payment/CreatePayment.vue` **核心函数**:`checkFieldDisplayConditions(element)` (第866-983行) **使用位置**:模板中的动态字段渲染(第310行) ```vue ``` ## 金额字段的定义和取值逻辑 ### 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逻辑),条件不满足时字段自动隐藏并清除验证错误