20260904173136
This commit is contained in:
1 parent
0928437c67
commit
4e167df0f0
40 files changed
+3471
-2314
No files matched your search
@@ -0,0 +1,133 @@
|
||||
// 模块数据驱动列表的「查询条件」工具:构建查询 SQL 片段、解析查询输入/默认值。
|
||||
// 供 fms-module-list / fms-module-edit 等按模块元数据渲染的组件共用;
|
||||
// 展示格式化(parseOptions / formatDateValue)见 fieldUtils.js。
|
||||
|
||||
export const identifierRe = /^[A-Za-z_][A-Za-z0-9_]*$/
|
||||
|
||||
export function escapeSqlText(value) {
|
||||
return String(value).replaceAll("'", "''")
|
||||
}
|
||||
|
||||
export function requireModuleId(value) {
|
||||
const id = String(value ?? '')
|
||||
if (!/^\d+$/.test(id)) throw new Error('模块 ID 格式不正确')
|
||||
return id
|
||||
}
|
||||
|
||||
export function isEmptyValue(value) {
|
||||
return value === undefined || value === null || value === ''
|
||||
}
|
||||
|
||||
export function isRangeQuery(item) {
|
||||
return (
|
||||
item.config.b_operator === 'between' ||
|
||||
item.config.b_component === 'number-range' ||
|
||||
item.field.b_type === 'datetime'
|
||||
)
|
||||
}
|
||||
|
||||
export function isNumericField(item) {
|
||||
return item.field.b_type === 'number' || item.field.b_type === 'money'
|
||||
}
|
||||
|
||||
export function isDateQuery(item) {
|
||||
return (
|
||||
item.config.b_component === 'date-picker' ||
|
||||
item.field.b_type === 'date' ||
|
||||
item.field.b_type === 'datetime'
|
||||
)
|
||||
}
|
||||
|
||||
export function emptyQueryValue(item) {
|
||||
if (item.field.b_type === 'checkbox') return ''
|
||||
if (isRangeQuery(item) || item.config.b_operator === 'in') return []
|
||||
return undefined
|
||||
}
|
||||
|
||||
export function defaultQueryValue(item) {
|
||||
const value = item.config.b_default_value
|
||||
if (value === null || value === undefined || value === '') return emptyQueryValue(item)
|
||||
if (isRangeQuery(item) || item.config.b_operator === 'in') {
|
||||
try {
|
||||
const parsed = JSON.parse(value)
|
||||
if (Array.isArray(parsed)) return parsed
|
||||
} catch {
|
||||
// 非 JSON 默认值继续按逗号分隔处理。
|
||||
}
|
||||
return String(value)
|
||||
.split(',')
|
||||
.map((part) => part.trim())
|
||||
.filter(Boolean)
|
||||
}
|
||||
if (isNumericField(item)) {
|
||||
const number = Number(value)
|
||||
return Number.isFinite(number) ? number : undefined
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
export function sqlLiteral(value, field, endOfRange = false) {
|
||||
if (isEmptyValue(value)) return null
|
||||
|
||||
if (field.b_type === 'number' || field.b_type === 'money') {
|
||||
const number = Number(value)
|
||||
return Number.isFinite(number) ? String(number) : null
|
||||
}
|
||||
|
||||
if (field.b_type === 'checkbox') {
|
||||
return value === true || Number(value) === 1 ? '1' : '0'
|
||||
}
|
||||
|
||||
let normalized = String(value)
|
||||
const isDate = field.b_type === 'date' || field.b_type === 'datetime'
|
||||
if (isDate && value && typeof value.format === 'function') {
|
||||
normalized = value.format('YYYY-MM-DD')
|
||||
} else if (isDate) {
|
||||
normalized = String(value).slice(0, 10)
|
||||
}
|
||||
|
||||
if (field.b_type === 'datetime') {
|
||||
normalized += endOfRange ? ' 23:59:59' : ' 00:00:00'
|
||||
}
|
||||
|
||||
return `N'${escapeSqlText(normalized)}'`
|
||||
}
|
||||
|
||||
export function buildQueryCondition(item, value) {
|
||||
const fieldName = item.field.b_field
|
||||
if (!identifierRe.test(fieldName)) return ''
|
||||
|
||||
const field = `[${fieldName}]`
|
||||
if (isRangeQuery(item)) {
|
||||
const values = Array.isArray(value) ? value : []
|
||||
const start = sqlLiteral(values[0], item.field)
|
||||
const end = sqlLiteral(values[1], item.field, true)
|
||||
if (start && end) return `${field} BETWEEN ${start} AND ${end}`
|
||||
if (start) return `${field} >= ${start}`
|
||||
if (end) return `${field} <= ${end}`
|
||||
return ''
|
||||
}
|
||||
|
||||
if (item.config.b_operator === 'in') {
|
||||
let values = value
|
||||
if (!Array.isArray(values)) {
|
||||
values = String(value ?? '')
|
||||
.split(',')
|
||||
.map((part) => part.trim())
|
||||
.filter(Boolean)
|
||||
}
|
||||
const literals = []
|
||||
for (const entry of values) {
|
||||
const literal = sqlLiteral(entry, item.field)
|
||||
if (literal) literals.push(literal)
|
||||
}
|
||||
return literals.length ? `${field} IN (${literals.join(', ')})` : ''
|
||||
}
|
||||
|
||||
const literal = sqlLiteral(value, item.field)
|
||||
if (!literal) return ''
|
||||
if (item.config.b_operator === 'like') {
|
||||
return `${field} LIKE N'%${escapeSqlText(String(value))}%'`
|
||||
}
|
||||
return `${field} = ${literal}`
|
||||
}
|
||||
Reference in new issue
Block a user