condition-builder.js 1.78 KB
// 条件构建器 - 前后端共享
// 从 ConditionPanel.jsx 抽取的核心逻辑,供服务端定时任务使用
import dayjs from 'dayjs'

function buildReplacement(cond) {
  const { type, value, valueStart, valueEnd, importedValues, dictOptions } = cond

  switch (type) {
    case 'exact':
      return value ? `'${value}'` : "''"
    case 'fuzzy':
      return value ? `'%${value}%'` : "'%%'"
    case 'daterange':
      return valueStart ? `'${dayjs(valueStart).format('YYYY-MM-DD')}'` : "'2024-01-01'"
    case 'datemonth':
      return value ? `'${dayjs(value).format('YYYY-MM')}'` : "'2024-01'"
    case 'dateyear':
      return value ? `'${dayjs(value).format('YYYY')}'` : "'2024'"
    case 'dateday':
      return value ? `'${dayjs(value).format('YYYY-MM-DD')}'` : "'2024-01-01'"
    case 'dictionary':
      return value ? `'${value}'` : "''"
    case 'excel_import':
      if (importedValues && importedValues.length > 0) {
        const quoted = importedValues.map(v => `'${v}'`).join(',')
        return quoted
      }
      return "''"
    default:
      return value ? `'${value}'` : "''"
  }
}

/**
 * 处理日期区间中的结束日期占位符
 * 约定:{{end_xxx}} 对应 xxx 的日期区间结束值
 */
export function buildSqlWithDateRange(sql, conditions) {
  let result = sql
  for (const cond of conditions) {
    const placeholder = `{{${cond.name}}}`
    const replacement = buildReplacement(cond)
    result = result.replaceAll(placeholder, replacement)

    // 处理日期区间结束占位符 {{end_xxx}}
    if (cond.type === 'daterange' && cond.valueEnd) {
      const endPlaceholder = `{{end_${cond.name}}}`
      const endReplacement = `'${dayjs(cond.valueEnd).format('YYYY-MM-DD')}'`
      result = result.replaceAll(endPlaceholder, endReplacement)
    }
  }
  return result
}