|
|
@@ -28,25 +28,64 @@
|
|
|
:prop="field.prop"
|
|
|
:required="isFieldMarkedRequired(field)"
|
|
|
>
|
|
|
+ <!-- 数字型文本输入(字段类型为input但后端定义为数字:与固定表一致) -->
|
|
|
+ <el-input
|
|
|
+ v-if="
|
|
|
+ (field.type === 'input' || !field.type) &&
|
|
|
+ _detectNumericKind(field)
|
|
|
+ "
|
|
|
+ v-model="form[field.prop]"
|
|
|
+ :placeholder="field.placeholder || `请输入${field.label}`"
|
|
|
+ :disabled="field.disabled || isViewMode"
|
|
|
+ :maxlength="
|
|
|
+ computeNumberMaxlength({
|
|
|
+ totalLength:
|
|
|
+ field.totalLength ||
|
|
|
+ field.fieldTypeLen ||
|
|
|
+ field.fieldTypelen ||
|
|
|
+ field.field_typelen,
|
|
|
+ decimalLength:
|
|
|
+ field.decimalLength ||
|
|
|
+ field.fieldTypeNointLen ||
|
|
|
+ field.fieldTypenointlen ||
|
|
|
+ field.field_typenointlen,
|
|
|
+ })
|
|
|
+ "
|
|
|
+ style="width: 100%"
|
|
|
+ @input="onNumberInput($event, field)"
|
|
|
+ />
|
|
|
+
|
|
|
<!-- 文本输入框 -->
|
|
|
<el-input
|
|
|
- v-if="field.type === 'input' || !field.type"
|
|
|
+ v-else-if="field.type === 'input' || !field.type"
|
|
|
v-model="form[field.prop]"
|
|
|
:placeholder="field.placeholder || `请输入${field.label}`"
|
|
|
:disabled="field.disabled || isViewMode"
|
|
|
:maxlength="field.formatLength || field.totalLength"
|
|
|
/>
|
|
|
|
|
|
- <!-- 数字输入框 -->
|
|
|
- <el-input-number
|
|
|
+ <!-- 数字输入框(与固定表一致的长度与小数位控制) -->
|
|
|
+ <el-input
|
|
|
v-else-if="field.type === 'number'"
|
|
|
v-model="form[field.prop]"
|
|
|
:placeholder="field.placeholder || `请输入${field.label}`"
|
|
|
:disabled="field.disabled || isViewMode"
|
|
|
- :min="field.min"
|
|
|
- :max="field.max"
|
|
|
- :precision="field.precision"
|
|
|
+ :maxlength="
|
|
|
+ computeNumberMaxlength({
|
|
|
+ totalLength:
|
|
|
+ field.totalLength ||
|
|
|
+ field.fieldTypeLen ||
|
|
|
+ field.fieldTypelen ||
|
|
|
+ field.field_typelen,
|
|
|
+ decimalLength:
|
|
|
+ field.decimalLength ||
|
|
|
+ field.fieldTypeNointLen ||
|
|
|
+ field.fieldTypenointlen ||
|
|
|
+ field.field_typenointlen,
|
|
|
+ })
|
|
|
+ "
|
|
|
style="width: 100%"
|
|
|
+ @input="onNumberInput($event, field)"
|
|
|
/>
|
|
|
|
|
|
<!-- 下拉选择框(字典类型) -->
|
|
|
@@ -344,6 +383,55 @@
|
|
|
this.initDictData()
|
|
|
},
|
|
|
methods: {
|
|
|
+ computeNumberMaxlength({ totalLength, decimalLength }) {
|
|
|
+ const t = Number(totalLength)
|
|
|
+ const d = Number(decimalLength)
|
|
|
+ if (!t || Number.isNaN(t)) return null
|
|
|
+ if (d && !Number.isNaN(d) && d > 0) return t + 1
|
|
|
+ return t
|
|
|
+ },
|
|
|
+ onNumberInput(val, field) {
|
|
|
+ const totalLength =
|
|
|
+ field.totalLength ||
|
|
|
+ field.fieldTypeLen ||
|
|
|
+ field.fieldTypelen ||
|
|
|
+ field.field_typelen
|
|
|
+ const decimalLength =
|
|
|
+ field.decimalLength ||
|
|
|
+ field.fieldTypeNointLen ||
|
|
|
+ field.fieldTypenointlen ||
|
|
|
+ field.field_typenointlen
|
|
|
+ const raw = String(val == null ? '' : val)
|
|
|
+ let s = raw
|
|
|
+ const isNeg = s.startsWith('-')
|
|
|
+ s = s.replace(/[^\d.]/g, '')
|
|
|
+ const parts = s.split('.')
|
|
|
+ let intPart = parts[0] || ''
|
|
|
+ let decPart = parts[1] || ''
|
|
|
+ if (decimalLength == null || Number(decimalLength) === 0) {
|
|
|
+ if (totalLength) intPart = intPart.substring(0, Number(totalLength))
|
|
|
+ this.$set(this.form, field.prop, (isNeg ? '-' : '') + intPart)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if (totalLength) {
|
|
|
+ const t = Number(totalLength)
|
|
|
+ intPart = intPart.substring(0, Math.max(0, t))
|
|
|
+ }
|
|
|
+ if (decimalLength) {
|
|
|
+ decPart = decPart.substring(0, Number(decimalLength))
|
|
|
+ }
|
|
|
+ // 允许输入以 '.' 结尾的中间态,例如 '0.'
|
|
|
+ const typedTrailingDot = raw.endsWith('.')
|
|
|
+ if (!intPart) intPart = '0'
|
|
|
+ const clipped =
|
|
|
+ intPart +
|
|
|
+ (typedTrailingDot && decPart === ''
|
|
|
+ ? '.'
|
|
|
+ : decPart
|
|
|
+ ? '.' + decPart
|
|
|
+ : '')
|
|
|
+ this.$set(this.form, field.prop, (isNeg ? '-' : '') + clipped)
|
|
|
+ },
|
|
|
// 用于控制红色必填星标:对必填或包含数值规则的字段都加红色标记
|
|
|
isFieldMarkedRequired(field) {
|
|
|
if (!field) return false
|