From 3c115a761036b7ee87b888fc43e2089aff57b599 Mon Sep 17 00:00:00 2001 From: lion <120344285@qq.com> Date: Mon, 18 May 2026 10:54:57 +0800 Subject: [PATCH] =?UTF-8?q?=E5=85=B3=E8=81=94=E5=A4=A7=E5=86=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/businessConfig/EditPayForm.vue | 59 +++++++-- .../components/paymentRegistration.vue | 115 ++++++++++++++++++ 2 files changed, 165 insertions(+), 9 deletions(-) diff --git a/src/views/businessConfig/EditPayForm.vue b/src/views/businessConfig/EditPayForm.vue index 0eaf3cd..7dc827c 100644 --- a/src/views/businessConfig/EditPayForm.vue +++ b/src/views/businessConfig/EditPayForm.vue @@ -130,6 +130,24 @@ /> + + + + +
+ 仅对本字段生效:源字段为空或无法解析为数字时,本字段清空;否则自动填中文大写金额。 +
+
f.field && f.field !== this.editForm.field) } }, watch: { @@ -1529,7 +1551,9 @@ export default { field: varName, name: this.formatVariableName(varName), type: 'text', - options: '' + options: '', + link_field: '', + uppercase_source: null } } }) @@ -1595,12 +1619,14 @@ export default { }, handleEditField(field) { // 保证link_field响应式 + const src = field.uppercase_source && field.uppercase_source.source_field this.editForm = { field: field.field || '', name: field.name || '', type: field.type || 'text', options: field.options || '', - link_field: field.link_field || '' + link_field: field.link_field || '', + uppercase_source_field: src || '' } this.showEditDrawer = true @@ -1612,13 +1638,22 @@ export default { return } + let uppercase_source = null + if (this.editForm.uppercase_source_field) { + uppercase_source = { + mode: 'field', + source_field: this.editForm.uppercase_source_field + } + } + // 更新字段元数据,保留所有必要的属性 this.fieldMetadata[this.editForm.field] = { field: this.editForm.field, // 确保保留字段名 name: this.editForm.name, type: this.editForm.type, options: this.editForm.options, - link_field: this.editForm.link_field || '' + link_field: this.editForm.link_field || '', + uppercase_source } // 更新代码预览区 @@ -1699,7 +1734,8 @@ export default { name: metadata.name, type: metadata.type, options: metadata.options, - link_field: metadata.link_field || '' + link_field: metadata.link_field || '', + uppercase_source: metadata.uppercase_source || null })) this.showEditDrawer = false @@ -1732,7 +1768,8 @@ export default { name: metadata.name, // Chinese name type: metadata.type, options: metadata.options, - link_field: metadata.link_field || '' + link_field: metadata.link_field || '', + uppercase_source: metadata.uppercase_source || null })) const params = { @@ -1777,7 +1814,9 @@ export default { field: varName, // Field name name: this.formatVariableName(varName), // Generate Chinese name type: 'text', - options: '' + options: '', + link_field: '', + uppercase_source: null // Removed placeholder and required } } @@ -1796,7 +1835,8 @@ export default { name: metadata.name, type: metadata.type, options: metadata.options, - link_field: metadata.link_field || '' + link_field: metadata.link_field || '', + uppercase_source: metadata.uppercase_source || null })) }, formatVariableName(name) { @@ -1858,7 +1898,8 @@ export default { name: serverField.name || this.formatVariableName(serverField.field), // Chinese name from server type: serverField.type || 'text', options: serverField.options || '', - link_field: serverField.link_field || '' // Add link_field + link_field: serverField.link_field || '', // Add link_field + uppercase_source: serverField.uppercase_source || null // Removed placeholder and required } }) diff --git a/src/views/contract/components/paymentRegistration.vue b/src/views/contract/components/paymentRegistration.vue index d26a5be..0778946 100644 --- a/src/views/contract/components/paymentRegistration.vue +++ b/src/views/contract/components/paymentRegistration.vue @@ -521,6 +521,7 @@ export default { forms1: null, // 事后支付表格1的HTML forms2: null, // 事后支付表格2的HTML activePostPaymentTab: 'form1', // 当前激活的tab + _uppercaseDomCleanups: null, // Map 用于移除大写联动委托监听 payTable: [ { label: '款项类型', @@ -1398,6 +1399,7 @@ export default { } if (currentDom && templateFields) { + this.applyConfigurableUppercase(currentDom, templateFields) // 获取所有输入控件 const inputs = currentDom.querySelectorAll('input, select, textarea') @@ -1724,6 +1726,7 @@ export default { // 使用setTimeout确保DOM完全加载 setTimeout(() => { + this.detachConfigurableUppercase(dom) const sdateAmountInputs = dom.querySelectorAll('input[data-field^="sdate"]') // 移除旧的监听器 @@ -1912,8 +1915,115 @@ export default { amount: dom.querySelectorAll('input[data-field^="amount"]').length, total: dom.querySelectorAll('input[data-field="total"]').length }) + + const templateFields = this.getTemplateFieldsForDom(dom) + this.attachConfigurableUppercase(dom, templateFields) }, 100) }, + getTemplateFieldsForDom(dom) { + if (!dom) return null + const r = this.$refs + if (r.mainTable1 && dom === r.mainTable1) { + return (this.contract && this.contract.contract_template && this.contract.contract_template.contract_template_fields) || null + } + if (r.mainTable2 && dom === r.mainTable2) { + return (this.contract && this.contract.contract_template2 && this.contract.contract_template2.contract_template_fields) || null + } + if (r.zoomedTable && dom === r.zoomedTable) { + if (this.activePostPaymentTab === 'form1') { + return (this.contract && this.contract.contract_template && this.contract.contract_template.contract_template_fields) || null + } + if (this.activePostPaymentTab === 'form2') { + return (this.contract && this.contract.contract_template2 && this.contract.contract_template2.contract_template_fields) || null + } + } + return null + }, + detachConfigurableUppercase(dom) { + if (!this._uppercaseDomCleanups || !dom) return + const cleanup = this._uppercaseDomCleanups.get(dom) + if (cleanup) { + cleanup() + this._uppercaseDomCleanups.delete(dom) + } + }, + attachConfigurableUppercase(dom, templateFields) { + if (!dom) return + if (!this._uppercaseDomCleanups) { + this._uppercaseDomCleanups = new Map() + } + const sourceFields = new Set() + if (templateFields && templateFields.length) { + templateFields.forEach(m => { + const cfg = m.uppercase_source + const s = cfg && cfg.mode === 'field' && cfg.source_field + if (s) sourceFields.add(s) + }) + } + if (sourceFields.size > 0) { + const handler = (e) => { + const t = e.target + if (!t || !t.getAttribute) return + const df = t.getAttribute('data-field') + if (df && sourceFields.has(df)) { + this.applyConfigurableUppercase(dom, templateFields) + } + } + const types = ['input', 'change', 'blur'] + types.forEach(type => dom.addEventListener(type, handler, true)) + const cleanup = () => { + types.forEach(type => dom.removeEventListener(type, handler, true)) + } + this._uppercaseDomCleanups.set(dom, cleanup) + } + this.applyConfigurableUppercase(dom, templateFields) + }, + parseMoneyForUppercase(raw) { + if (raw == null) return { kind: 'empty' } + const s = String(raw).trim() + if (s === '') return { kind: 'empty' } + const cleaned = s.replace(/[¥¥\s,,]/g, '') + if (cleaned === '') return { kind: 'empty' } + const n = parseFloat(cleaned) + if (!Number.isFinite(n)) return { kind: 'invalid' } + return { kind: 'ok', value: n } + }, + getSourceFieldRawValue(dom, fieldName) { + if (!dom || !fieldName) return '' + const radios = dom.querySelectorAll(`input[type="radio"][data-field="${fieldName}"]`) + if (radios.length) { + const c = dom.querySelector(`input[type="radio"][data-field="${fieldName}"]:checked`) + return c ? String(c.value) : '' + } + const el = dom.querySelector(`input[data-field="${fieldName}"],select[data-field="${fieldName}"],textarea[data-field="${fieldName}"]`) + if (!el) return '' + if (el.type === 'checkbox') { + const c = dom.querySelector(`input[type="checkbox"][data-field="${fieldName}"]:checked`) + return c ? String(c.value) : '' + } + return el.value != null ? String(el.value) : '' + }, + setConfigurableTargetFieldValue(dom, fieldName, text) { + if (!dom || !fieldName) return + const els = dom.querySelectorAll(`input[data-field="${fieldName}"],textarea[data-field="${fieldName}"],select[data-field="${fieldName}"]`) + els.forEach((el) => { + if (el.type === 'radio' || el.type === 'checkbox') return + el.value = text + }) + }, + applyConfigurableUppercase(dom, templateFields) { + if (!dom || !templateFields || !templateFields.length) return + templateFields.forEach((meta) => { + const conf = meta.uppercase_source + if (!conf || conf.mode !== 'field' || !conf.source_field) return + const src = conf.source_field + if (src === meta.field) return + const raw = this.getSourceFieldRawValue(dom, src) + const parsed = this.parseMoneyForUppercase(raw) + const val = parsed.kind === 'ok' ? numberToChinese(parsed.value) : '' + this.setConfigurableTargetFieldValue(dom, meta.field, val) + }) + }, caculateRoadDay() { // 计算当前激活的表格 let currentDom = null @@ -2166,6 +2276,9 @@ export default { upperCaseInput.value = numberToChinese(this.otherTotal) console.log('更新大写金额2:', upperCaseInput.value, this.otherTotal) } + + const tf = this.getTemplateFieldsForDom(dom) + if (tf) this.applyConfigurableUppercase(dom, tf) }, updateUpperCaseFromTotal(event, dom) { @@ -2178,6 +2291,8 @@ export default { this.total = parseFloat(totalInput.value.replace(/¥/g, '')) || 0 upperCaseInput.value = numberToChinese(this.total) } + const tf = this.getTemplateFieldsForDom(dom) + if (tf) this.applyConfigurableUppercase(dom, tf) }, // 显示历史记录弹窗