|
@@ -33,8 +33,8 @@
|
|
|
type="date"
|
|
type="date"
|
|
|
placeholder="选择日期"
|
|
placeholder="选择日期"
|
|
|
size="mini"
|
|
size="mini"
|
|
|
- format="yyyy-MM-dd"
|
|
|
|
|
- value-format="yyyy-MM-dd"
|
|
|
|
|
|
|
+ :format="column.format || 'yyyy-MM-dd'"
|
|
|
|
|
+ :value-format="column.valueFormat || 'yyyy-MM-dd'"
|
|
|
style="width: 100%"
|
|
style="width: 100%"
|
|
|
:disabled="isViewMode"
|
|
:disabled="isViewMode"
|
|
|
/>
|
|
/>
|
|
@@ -44,8 +44,8 @@
|
|
|
type="datetime"
|
|
type="datetime"
|
|
|
placeholder="选择日期时间"
|
|
placeholder="选择日期时间"
|
|
|
size="mini"
|
|
size="mini"
|
|
|
- format="yyyy-MM-dd HH:mm:ss"
|
|
|
|
|
- value-format="yyyy-MM-dd HH:mm:ss"
|
|
|
|
|
|
|
+ :format="column.format || 'yyyy-MM-dd HH:mm:ss'"
|
|
|
|
|
+ :value-format="column.valueFormat || 'yyyy-MM-dd HH:mm:ss'"
|
|
|
style="width: 100%"
|
|
style="width: 100%"
|
|
|
:disabled="isViewMode"
|
|
:disabled="isViewMode"
|
|
|
/>
|
|
/>
|
|
@@ -55,11 +55,31 @@
|
|
|
type="year"
|
|
type="year"
|
|
|
placeholder="选择年份"
|
|
placeholder="选择年份"
|
|
|
size="mini"
|
|
size="mini"
|
|
|
- format="yyyy"
|
|
|
|
|
- value-format="yyyy"
|
|
|
|
|
|
|
+ :format="column.format || 'yyyy'"
|
|
|
|
|
+ :value-format="column.valueFormat || 'yyyy'"
|
|
|
style="width: 100%"
|
|
style="width: 100%"
|
|
|
:disabled="isViewMode"
|
|
:disabled="isViewMode"
|
|
|
/>
|
|
/>
|
|
|
|
|
+ <!-- 字典下拉,与 SurveyFormDialog 一致写法 -->
|
|
|
|
|
+ <el-select
|
|
|
|
|
+ v-else-if="
|
|
|
|
|
+ column.type === 'select' && (column.dictCode || column.dictType)
|
|
|
|
|
+ "
|
|
|
|
|
+ v-model="scope.row[column.prop]"
|
|
|
|
|
+ :placeholder="column.placeholder || '请选择' + column.label"
|
|
|
|
|
+ size="mini"
|
|
|
|
|
+ style="width: 100%"
|
|
|
|
|
+ :disabled="isViewMode"
|
|
|
|
|
+ :clearable="true"
|
|
|
|
|
+ >
|
|
|
|
|
+ <el-option
|
|
|
|
|
+ v-for="item in getDictOptions(column.dictCode || column.dictType)"
|
|
|
|
|
+ :key="item.key || item.value"
|
|
|
|
|
+ :label="item.name || item.label"
|
|
|
|
|
+ :value="item.key || item.value"
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ <!-- 自定义选项下拉 -->
|
|
|
<el-select
|
|
<el-select
|
|
|
v-else-if="
|
|
v-else-if="
|
|
|
column.type === 'select' && Array.isArray(column.options)
|
|
column.type === 'select' && Array.isArray(column.options)
|
|
@@ -69,19 +89,13 @@
|
|
|
size="mini"
|
|
size="mini"
|
|
|
style="width: 100%"
|
|
style="width: 100%"
|
|
|
:disabled="isViewMode"
|
|
:disabled="isViewMode"
|
|
|
- clearable
|
|
|
|
|
|
|
+ :clearable="true"
|
|
|
>
|
|
>
|
|
|
<el-option
|
|
<el-option
|
|
|
v-for="opt in column.options"
|
|
v-for="opt in column.options"
|
|
|
- :key="
|
|
|
|
|
- opt &&
|
|
|
|
|
- (opt.value != null ? String(opt.value) : String(opt.label))
|
|
|
|
|
- "
|
|
|
|
|
- :label="opt && (opt.label != null ? opt.label : opt.value)"
|
|
|
|
|
- :value="
|
|
|
|
|
- opt &&
|
|
|
|
|
- (opt.value != null ? String(opt.value) : String(opt.label))
|
|
|
|
|
- "
|
|
|
|
|
|
|
+ :key="opt.value || opt.key"
|
|
|
|
|
+ :label="opt.label || opt.name"
|
|
|
|
|
+ :value="opt.value || opt.key"
|
|
|
/>
|
|
/>
|
|
|
</el-select>
|
|
</el-select>
|
|
|
<el-switch
|
|
<el-switch
|
|
@@ -175,9 +189,11 @@
|
|
|
<script>
|
|
<script>
|
|
|
import { Message } from 'element-ui'
|
|
import { Message } from 'element-ui'
|
|
|
import { saveSingleRecordSurvey } from '@/api/audit/survey'
|
|
import { saveSingleRecordSurvey } from '@/api/audit/survey'
|
|
|
|
|
+ import { dictMixin } from '@/mixins/useDict'
|
|
|
|
|
|
|
|
export default {
|
|
export default {
|
|
|
name: 'FixedAssetsTable',
|
|
name: 'FixedAssetsTable',
|
|
|
|
|
+ mixins: [dictMixin],
|
|
|
props: {
|
|
props: {
|
|
|
// 表格数据配置(嵌套结构)
|
|
// 表格数据配置(嵌套结构)
|
|
|
tableItems: {
|
|
tableItems: {
|
|
@@ -250,6 +266,8 @@
|
|
|
autoIdSeed: 1,
|
|
autoIdSeed: 1,
|
|
|
// 原始保存的数据(用于回显)
|
|
// 原始保存的数据(用于回显)
|
|
|
rawSavedData: null,
|
|
rawSavedData: null,
|
|
|
|
|
+ // 字典数据容器(用于 dictMixin 拉取字典)
|
|
|
|
|
+ dictData: {},
|
|
|
}
|
|
}
|
|
|
},
|
|
},
|
|
|
computed: {
|
|
computed: {
|
|
@@ -298,11 +316,37 @@
|
|
|
const metas = Array.isArray(this.columnsMeta) ? this.columnsMeta : []
|
|
const metas = Array.isArray(this.columnsMeta) ? this.columnsMeta : []
|
|
|
const byLabel = new Map()
|
|
const byLabel = new Map()
|
|
|
const byId = new Map()
|
|
const byId = new Map()
|
|
|
|
|
+ const byFieldName = new Map()
|
|
|
|
|
+ const byName = new Map()
|
|
|
metas.forEach((m) => {
|
|
metas.forEach((m) => {
|
|
|
- if (m && m.label) byLabel.set(String(m.label), m)
|
|
|
|
|
- if (m && m.fieldId) byId.set(String(m.fieldId), m)
|
|
|
|
|
|
|
+ if (!m) return
|
|
|
|
|
+ if (m.label) byLabel.set(String(m.label).trim(), m)
|
|
|
|
|
+ if (m.fieldId) byId.set(String(m.fieldId).trim(), m)
|
|
|
|
|
+ if (m.fieldName) byFieldName.set(String(m.fieldName).trim(), m)
|
|
|
|
|
+ if (m.name) byName.set(String(m.name).trim(), m)
|
|
|
})
|
|
})
|
|
|
const normalizeType = (meta, fallback) => {
|
|
const normalizeType = (meta, fallback) => {
|
|
|
|
|
+ // 优先根据 format 判定日期类型
|
|
|
|
|
+ const formatStr =
|
|
|
|
|
+ meta && meta.format ? String(meta.format).trim() : ''
|
|
|
|
|
+ if (formatStr) {
|
|
|
|
|
+ const f = formatStr.toLowerCase()
|
|
|
|
|
+ if (/(hh|hh:mm|hh:mm:ss)/i.test(formatStr) || f.includes('hh')) {
|
|
|
|
|
+ return 'datetime'
|
|
|
|
|
+ }
|
|
|
|
|
+ if (/^y{4}$/i.test(formatStr)) {
|
|
|
|
|
+ return 'year'
|
|
|
|
|
+ }
|
|
|
|
|
+ if (
|
|
|
|
|
+ (/y{4}/i.test(formatStr) && /m{2}/i.test(formatStr)) ||
|
|
|
|
|
+ f.includes('yyyy-mm') ||
|
|
|
|
|
+ f.includes('yyyy-mm-dd')
|
|
|
|
|
+ ) {
|
|
|
|
|
+ return 'date'
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 其次根据后端类型字段判定
|
|
|
const t = (
|
|
const t = (
|
|
|
meta && (meta.type || meta.fieldType)
|
|
meta && (meta.type || meta.fieldType)
|
|
|
? String(meta.type || meta.fieldType)
|
|
? String(meta.type || meta.fieldType)
|
|
@@ -325,34 +369,159 @@
|
|
|
if (t.includes('select')) return 'select'
|
|
if (t.includes('select')) return 'select'
|
|
|
return fallback
|
|
return fallback
|
|
|
}
|
|
}
|
|
|
|
|
+ const deriveDateFormats = (meta, type) => {
|
|
|
|
|
+ const res = { format: undefined, valueFormat: undefined }
|
|
|
|
|
+ const fmt = meta && meta.format ? String(meta.format).trim() : ''
|
|
|
|
|
+ if (type === 'year') {
|
|
|
|
|
+ res.format = fmt && /^y{4}$/i.test(fmt) ? fmt : 'yyyy'
|
|
|
|
|
+ res.valueFormat = res.format
|
|
|
|
|
+ } else if (type === 'datetime') {
|
|
|
|
|
+ const def = 'yyyy-MM-dd HH:mm:ss'
|
|
|
|
|
+ res.format = fmt && /(H|h)/.test(fmt) ? fmt : def
|
|
|
|
|
+ res.valueFormat = res.format
|
|
|
|
|
+ } else if (type === 'date') {
|
|
|
|
|
+ const def = 'yyyy-MM-dd'
|
|
|
|
|
+ res.format = fmt && /y{2,}[-/ ]?m{2}/i.test(fmt) ? fmt : def
|
|
|
|
|
+ res.valueFormat = res.format
|
|
|
|
|
+ }
|
|
|
|
|
+ return res
|
|
|
|
|
+ }
|
|
|
|
|
+ const pickNumberLengths = (meta, tLower) => {
|
|
|
|
|
+ // 明确优先级:整数位用 fieldTypelen, 小数位用 fieldTypenointlen
|
|
|
|
|
+ const totalLen =
|
|
|
|
|
+ meta.fieldTypelen ??
|
|
|
|
|
+ meta.fieldTypeLen ??
|
|
|
|
|
+ meta.field_typelen ??
|
|
|
|
|
+ meta.totalLength ??
|
|
|
|
|
+ meta.length ??
|
|
|
|
|
+ meta.fieldLength
|
|
|
|
|
+ const decimalLen =
|
|
|
|
|
+ meta.fieldTypenointlen ??
|
|
|
|
|
+ meta.fieldTypeNointLen ??
|
|
|
|
|
+ meta.field_typenointlen ??
|
|
|
|
|
+ meta.decimalLength ??
|
|
|
|
|
+ meta.scale
|
|
|
|
|
+ // 若后端标明 integer 或整型,强制小数位为0
|
|
|
|
|
+ const t = String(tLower || '').toLowerCase()
|
|
|
|
|
+ const dec = t.includes('int') || t === 'integer' ? 0 : decimalLen
|
|
|
|
|
+ return {
|
|
|
|
|
+ totalLen: totalLen !== undefined ? Number(totalLen) : undefined,
|
|
|
|
|
+ decimalLen: dec !== undefined ? Number(dec) : undefined,
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
return cols.map((col) => {
|
|
return cols.map((col) => {
|
|
|
- const meta =
|
|
|
|
|
- (col.label && byLabel.get(String(col.label))) ||
|
|
|
|
|
- (col.fieldId && byId.get(String(col.fieldId))) ||
|
|
|
|
|
|
|
+ // 更宽松的 meta 匹配:label/fieldName/name/fieldId
|
|
|
|
|
+ const labelKey = col.label ? String(col.label).trim() : ''
|
|
|
|
|
+ const idKey = col.fieldId ? String(col.fieldId).trim() : ''
|
|
|
|
|
+ let meta =
|
|
|
|
|
+ (labelKey &&
|
|
|
|
|
+ (byLabel.get(labelKey) ||
|
|
|
|
|
+ byFieldName.get(labelKey) ||
|
|
|
|
|
+ byName.get(labelKey))) ||
|
|
|
|
|
+ (idKey && byId.get(idKey)) ||
|
|
|
null
|
|
null
|
|
|
if (meta) {
|
|
if (meta) {
|
|
|
- col.type = normalizeType(meta, col.type || 'input')
|
|
|
|
|
- if (Array.isArray(meta.options) && meta.options.length) {
|
|
|
|
|
|
|
+ // 仅按是否存在字典编码决定是否为下拉(忽略 fieldType)
|
|
|
|
|
+ const codeFromMeta =
|
|
|
|
|
+ (meta.dictCode && String(meta.dictCode).trim()) ||
|
|
|
|
|
+ (meta.dictType && String(meta.dictType).trim()) ||
|
|
|
|
|
+ (meta.typeKey && String(meta.typeKey).trim()) ||
|
|
|
|
|
+ (meta.dictId && String(meta.dictId).trim()) ||
|
|
|
|
|
+ (meta.dictid && String(meta.dictid).trim()) ||
|
|
|
|
|
+ ''
|
|
|
|
|
+
|
|
|
|
|
+ const codeFromCol =
|
|
|
|
|
+ (col.dictCode && String(col.dictCode).trim()) ||
|
|
|
|
|
+ (col.dictType && String(col.dictType).trim()) ||
|
|
|
|
|
+ ''
|
|
|
|
|
+
|
|
|
|
|
+ const dictCode = codeFromMeta || codeFromCol
|
|
|
|
|
+
|
|
|
|
|
+ if (dictCode) {
|
|
|
|
|
+ // 有字典编码:强制下拉
|
|
|
|
|
+ col.type = 'select'
|
|
|
|
|
+ col.dictCode = dictCode
|
|
|
|
|
+ col.dictType = dictCode
|
|
|
|
|
+ const dictOpts = this.getDictOptions(dictCode) || []
|
|
|
|
|
+ col.options = (dictOpts || []).map((d) => ({
|
|
|
|
|
+ key: d.key != null ? d.key : d.value,
|
|
|
|
|
+ name: d.name != null ? d.name : d.label,
|
|
|
|
|
+ value: d.value,
|
|
|
|
|
+ label: d.label,
|
|
|
|
|
+ }))
|
|
|
|
|
+ if (!Array.isArray(col.options)) col.options = []
|
|
|
|
|
+ } else if (Array.isArray(meta.options) && meta.options.length) {
|
|
|
|
|
+ // 无字典编码但给了 options:也下拉
|
|
|
|
|
+ col.type = 'select'
|
|
|
col.options = meta.options
|
|
col.options = meta.options
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // 非字典:按原规则回退(仅用于非字典字段)
|
|
|
|
|
+ col.type = normalizeType(meta, col.type || 'input')
|
|
|
|
|
+ }
|
|
|
|
|
+ // 若为日期类,按 meta.format 派生 format/valueFormat,供模板绑定
|
|
|
|
|
+ if (
|
|
|
|
|
+ col.type === 'date' ||
|
|
|
|
|
+ col.type === 'datetime' ||
|
|
|
|
|
+ col.type === 'year'
|
|
|
|
|
+ ) {
|
|
|
|
|
+ const f = deriveDateFormats(meta, col.type)
|
|
|
|
|
+ if (f.format) col.format = f.format
|
|
|
|
|
+ if (f.valueFormat) col.valueFormat = f.valueFormat
|
|
|
}
|
|
}
|
|
|
- col.totalLength = meta.totalLength
|
|
|
|
|
- // 若为整数类型,强制小数位为0
|
|
|
|
|
|
|
+ // 元数据上的长度规则(兼容多种命名)
|
|
|
const rawType = String(
|
|
const rawType = String(
|
|
|
meta.type || meta.fieldType || ''
|
|
meta.type || meta.fieldType || ''
|
|
|
).toLowerCase()
|
|
).toLowerCase()
|
|
|
- if (rawType.includes('int') || rawType === 'integer') {
|
|
|
|
|
- col.decimalLength = 0
|
|
|
|
|
- } else {
|
|
|
|
|
- col.decimalLength = meta.decimalLength
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ const lens = pickNumberLengths(meta, rawType)
|
|
|
|
|
+ col.totalLength = lens.totalLen
|
|
|
|
|
+ col.decimalLength = lens.decimalLen
|
|
|
|
|
+ } else if (
|
|
|
|
|
+ labelKey &&
|
|
|
|
|
+ (labelKey === '字典' || labelKey.includes('字典'))
|
|
|
|
|
+ ) {
|
|
|
|
|
+ // 兜底:标题包含“字典”的列一律渲染为下拉
|
|
|
|
|
+ col.type = 'select'
|
|
|
|
|
+ // 确保为数组,避免模板条件不触发
|
|
|
|
|
+ if (!Array.isArray(col.options)) col.options = []
|
|
|
}
|
|
}
|
|
|
return col
|
|
return col
|
|
|
})
|
|
})
|
|
|
},
|
|
},
|
|
|
},
|
|
},
|
|
|
watch: {
|
|
watch: {
|
|
|
|
|
+ // 当字段元数据到达/变化时,预置需要的字典键,让 dictMixin 能拉取对应的字典
|
|
|
|
|
+ columnsMeta: {
|
|
|
|
|
+ handler(newVal) {
|
|
|
|
|
+ console.log(newVal)
|
|
|
|
|
+ const metas = Array.isArray(newVal) ? newVal : []
|
|
|
|
|
+ const codes = new Set()
|
|
|
|
|
+ metas.forEach((m) => {
|
|
|
|
|
+ if (!m) return
|
|
|
|
|
+ const code =
|
|
|
|
|
+ (m.dictCode && String(m.dictCode).trim()) ||
|
|
|
|
|
+ (m.dictType && String(m.dictType).trim()) ||
|
|
|
|
|
+ (m.typeKey && String(m.typeKey).trim()) ||
|
|
|
|
|
+ (m.dictId && String(m.dictId).trim()) ||
|
|
|
|
|
+ (m.dictid && String(m.dictid).trim()) ||
|
|
|
|
|
+ ''
|
|
|
|
|
+ if (code) codes.add(code)
|
|
|
|
|
+ })
|
|
|
|
|
+ // 初始化 dictData 的键,供 mixin 的 getDictType 使用
|
|
|
|
|
+ if (!this.dictData) this.dictData = {}
|
|
|
|
|
+ codes.forEach((k) => {
|
|
|
|
|
+ if (!this.dictData[k]) this.$set(this.dictData, k, [])
|
|
|
|
|
+ })
|
|
|
|
|
+ // 触发批量获取
|
|
|
|
|
+ if (codes.size > 0 && typeof this.getDictType === 'function') {
|
|
|
|
|
+ this.getDictType()
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ immediate: true,
|
|
|
|
|
+ deep: true,
|
|
|
|
|
+ },
|
|
|
tableItems: {
|
|
tableItems: {
|
|
|
handler(newVal) {
|
|
handler(newVal) {
|
|
|
|
|
+ console.log('表头:', newVal)
|
|
|
// 仅根据列定义刷新视图,不修改数据来源(数据仅来自父组件传入的 savedData)
|
|
// 仅根据列定义刷新视图,不修改数据来源(数据仅来自父组件传入的 savedData)
|
|
|
if (
|
|
if (
|
|
|
Array.isArray(this.fixedAssetsData) &&
|
|
Array.isArray(this.fixedAssetsData) &&
|
|
@@ -419,6 +588,13 @@
|
|
|
},
|
|
},
|
|
|
},
|
|
},
|
|
|
methods: {
|
|
methods: {
|
|
|
|
|
+ // 获取字典选项(兼容本组件与 dictMixin)
|
|
|
|
|
+ getDictOptions(dictType) {
|
|
|
|
|
+ if (!dictType || !this.dictData) return []
|
|
|
|
|
+ const key = String(dictType)
|
|
|
|
|
+ const arr = this.dictData[key]
|
|
|
|
|
+ return Array.isArray(arr) ? arr : []
|
|
|
|
|
+ },
|
|
|
sanitizeNumberInput(row, column) {
|
|
sanitizeNumberInput(row, column) {
|
|
|
const prop = column && column.prop
|
|
const prop = column && column.prop
|
|
|
if (!prop) return
|
|
if (!prop) return
|
|
@@ -1601,6 +1777,7 @@
|
|
|
const isValidDate = (v) =>
|
|
const isValidDate = (v) =>
|
|
|
typeof v === 'string' &&
|
|
typeof v === 'string' &&
|
|
|
/^\d{4}-\d{2}-\d{2}(?:\s+\d{2}:\d{2}(:\d{2})?)?$/.test(v)
|
|
/^\d{4}-\d{2}-\d{2}(?:\s+\d{2}:\d{2}(:\d{2})?)?$/.test(v)
|
|
|
|
|
+ const isValidYear = (v) => typeof v === 'string' && /^\d{4}$/.test(v)
|
|
|
const isIntegerWithLen = (v, len) => {
|
|
const isIntegerWithLen = (v, len) => {
|
|
|
if (typeof v !== 'string') v = v == null ? '' : String(v)
|
|
if (typeof v !== 'string') v = v == null ? '' : String(v)
|
|
|
if (!/^[-+]?\d+$/.test(v)) return false
|
|
if (!/^[-+]?\d+$/.test(v)) return false
|
|
@@ -1643,9 +1820,47 @@
|
|
|
}
|
|
}
|
|
|
if (isEmpty(value)) return
|
|
if (isEmpty(value)) return
|
|
|
|
|
|
|
|
- const t = String(meta.type || meta.fieldType || '').toLowerCase()
|
|
|
|
|
- const intLen = meta.totalLength
|
|
|
|
|
- const decLen = meta.decimalLength
|
|
|
|
|
|
|
+ // 根据 format 优先推断类型
|
|
|
|
|
+ const fmt = (meta.format && String(meta.format).trim()) || ''
|
|
|
|
|
+ let inferred = ''
|
|
|
|
|
+ if (fmt) {
|
|
|
|
|
+ const fl = fmt.toLowerCase()
|
|
|
|
|
+ if (/(hh|hh:mm|hh:mm:ss)/i.test(fmt) || fl.includes('hh')) {
|
|
|
|
|
+ inferred = 'datetime'
|
|
|
|
|
+ } else if (/^y{4}$/i.test(fmt)) {
|
|
|
|
|
+ inferred = 'year'
|
|
|
|
|
+ } else if (
|
|
|
|
|
+ (/y{4}/i.test(fmt) && /m{2}/i.test(fmt)) ||
|
|
|
|
|
+ fl.includes('yyyy-mm') ||
|
|
|
|
|
+ fl.includes('yyyy-mm-dd')
|
|
|
|
|
+ ) {
|
|
|
|
|
+ inferred = 'date'
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ const tRaw = String(meta.type || meta.fieldType || '').toLowerCase()
|
|
|
|
|
+ const t = inferred || tRaw
|
|
|
|
|
+ const lens = ((m) => ({
|
|
|
|
|
+ totalLen:
|
|
|
|
|
+ m.totalLength ??
|
|
|
|
|
+ m.fieldTypeLen ??
|
|
|
|
|
+ m.fieldTypelen ??
|
|
|
|
|
+ m.field_typelen ??
|
|
|
|
|
+ m.length ??
|
|
|
|
|
+ m.fieldLength,
|
|
|
|
|
+ decimalLen:
|
|
|
|
|
+ m.decimalLength ??
|
|
|
|
|
+ m.fieldTypeNointLen ??
|
|
|
|
|
+ m.fieldTypenointlen ??
|
|
|
|
|
+ m.field_typenointlen ??
|
|
|
|
|
+ m.scale,
|
|
|
|
|
+ }))(meta || {})
|
|
|
|
|
+ const intLen =
|
|
|
|
|
+ lens.totalLen !== undefined ? Number(lens.totalLen) : undefined
|
|
|
|
|
+ const decLenRaw =
|
|
|
|
|
+ lens.decimalLen !== undefined
|
|
|
|
|
+ ? Number(lens.decimalLen)
|
|
|
|
|
+ : undefined
|
|
|
|
|
+ const decLen = t.includes('int') || t === 'integer' ? 0 : decLenRaw
|
|
|
if (
|
|
if (
|
|
|
t === 'number' ||
|
|
t === 'number' ||
|
|
|
t === 'int' ||
|
|
t === 'int' ||
|
|
@@ -1672,22 +1887,56 @@
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
} else if (t === 'date' || t === 'datetime' || t === 'year') {
|
|
} else if (t === 'date' || t === 'datetime' || t === 'year') {
|
|
|
- if (!isValidDate(value)) {
|
|
|
|
|
- errors.push(
|
|
|
|
|
- `第${rowIndex + 1}行【${
|
|
|
|
|
- col.label
|
|
|
|
|
- }】日期格式不正确,应为YYYY-MM-DD或YYYY-MM-DD HH:mm:ss`
|
|
|
|
|
- )
|
|
|
|
|
|
|
+ if (t === 'year') {
|
|
|
|
|
+ if (!isValidYear(value)) {
|
|
|
|
|
+ errors.push(
|
|
|
|
|
+ `第${rowIndex + 1}行【${col.label}】必须是四位年份`
|
|
|
|
|
+ )
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ if (!isValidDate(value)) {
|
|
|
|
|
+ errors.push(
|
|
|
|
|
+ `第${rowIndex + 1}行【${
|
|
|
|
|
+ col.label
|
|
|
|
|
+ }】日期格式不正确,应为YYYY-MM-DD或YYYY-MM-DD HH:mm:ss`
|
|
|
|
|
+ )
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // 字典/枚举
|
|
|
|
|
- if (Array.isArray(meta.options) && meta.options.length > 0) {
|
|
|
|
|
|
|
+ // 字典/枚举:优先使用 dictCode 的选项校验;否则退回 meta.options
|
|
|
|
|
+ const dictCode =
|
|
|
|
|
+ (meta.dictCode && String(meta.dictCode).trim()) ||
|
|
|
|
|
+ (meta.dictType && String(meta.dictType).trim()) ||
|
|
|
|
|
+ (meta.typeKey && String(meta.typeKey).trim()) ||
|
|
|
|
|
+ (meta.dictId && String(meta.dictId).trim()) ||
|
|
|
|
|
+ (meta.dictid && String(meta.dictid).trim()) ||
|
|
|
|
|
+ ''
|
|
|
|
|
+ let optionsToCheck = []
|
|
|
|
|
+ if (dictCode) {
|
|
|
|
|
+ const dictOpts = this.getDictOptions(dictCode) || []
|
|
|
|
|
+ optionsToCheck = Array.isArray(dictOpts) ? dictOpts : []
|
|
|
|
|
+ }
|
|
|
|
|
+ if (
|
|
|
|
|
+ (!optionsToCheck || optionsToCheck.length === 0) &&
|
|
|
|
|
+ Array.isArray(meta.options)
|
|
|
|
|
+ ) {
|
|
|
|
|
+ optionsToCheck = meta.options
|
|
|
|
|
+ }
|
|
|
|
|
+ if (Array.isArray(optionsToCheck) && optionsToCheck.length > 0) {
|
|
|
const allowed = new Set(
|
|
const allowed = new Set(
|
|
|
- meta.options.map(
|
|
|
|
|
- (o) =>
|
|
|
|
|
- o && (o.value != null ? String(o.value) : String(o.label))
|
|
|
|
|
- )
|
|
|
|
|
|
|
+ optionsToCheck
|
|
|
|
|
+ .map((o) => {
|
|
|
|
|
+ const v =
|
|
|
|
|
+ o &&
|
|
|
|
|
+ (o.key != null
|
|
|
|
|
+ ? o.key
|
|
|
|
|
+ : o.value != null
|
|
|
|
|
+ ? o.value
|
|
|
|
|
+ : o.label)
|
|
|
|
|
+ return v != null ? String(v) : undefined
|
|
|
|
|
+ })
|
|
|
|
|
+ .filter(Boolean)
|
|
|
)
|
|
)
|
|
|
const valStr = String(value)
|
|
const valStr = String(value)
|
|
|
if (!allowed.has(valStr)) {
|
|
if (!allowed.has(valStr)) {
|