refactor(web-admin): generalize server column filter queryKey mapping.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
zlwuandCursor committed 2026-09-06 08:15:49 +08:00
1 parent 3ab447b735
commit f33b905f0d
3 files changed
+35 -20

No files matched your search

@@ -17,6 +17,13 @@ export interface ColumnFilterDef {
enumOptions?: ColumnFilterEnumOption[] enumOptions?: ColumnFilterEnumOption[]
/** 自定义取值(展示值 / 比较值) */ /** 自定义取值(展示值 / 比较值) */
getValue?: (row: any) => unknown getValue?: (row: any) => unknown
/** 文本主查询键;默认 prop。枚举多选默认 `${queryKey}In` */
queryKey?: string
/** datetime 起止;默认 `${queryKey||prop}From` / `${queryKey||prop}To` */
queryKeyFrom?: string
queryKeyTo?: string
/** number 键前缀;默认 queryKey||prop → `${prefix}Op` / Min / Max / 单值键=prefix */
queryKeyPrefix?: string
} }
/** 文本列:服务端模糊 / 客户端也可只用 text */ /** 文本列:服务端模糊 / 客户端也可只用 text */
@@ -10,8 +10,8 @@ import {
/** /**
* 服务端列条件:管理 state、toQueryParams、藏列清条件。 * 服务端列条件:管理 state、toQueryParams、藏列清条件。
* toQueryParams 本页(报销申请)YAGNI 写死映射 applyDateFrom / amountOp / statusIn 等; * toQueryParams 按 ColumnFilterDef 的 queryKey / queryKeyFrom|To / queryKeyPrefix 映射;
* 日后推广可在 ColumnFilterDef 增加可选 queryKey。 * 未配置时回退 prop(枚举 → `${key}In`,日期 → `${key}From|To`,数字 → `${prefix}Op` 等)。
*/ */
export function useServerColumnFilters( export function useServerColumnFilters(
columnDefs: ColumnFilterDef[], columnDefs: ColumnFilterDef[],
@@ -90,35 +90,36 @@ export function useServerColumnFilters(
const state = filters[prop] const state = filters[prop]
if (!def || !isColumnFilterActive(def.type, state)) continue if (!def || !isColumnFilterActive(def.type, state)) continue
const key = def.queryKey || prop
if (def.type === 'datetime') { if (def.type === 'datetime') {
// 本页仅 applyTime → applyDateFrom / applyDateTo
const s = state as DatetimeColumnFilterState const s = state as DatetimeColumnFilterState
if (s.from) q.applyDateFrom = s.from const fromKey = def.queryKeyFrom || `${key}From`
if (s.to) q.applyDateTo = s.to const toKey = def.queryKeyTo || `${key}To`
if (s.from) q[fromKey] = s.from
if (s.to) q[toKey] = s.to
continue continue
} }
if (def.type === 'number') { if (def.type === 'number') {
// 本页仅 amount → amountOp / amountMin|amountMax|amount
const s = state as NumberColumnFilterState const s = state as NumberColumnFilterState
q.amountOp = s.op || 'between' const prefix = def.queryKeyPrefix || key
q[`${prefix}Op`] = s.op || 'between'
if (s.op === 'between') { if (s.op === 'between') {
if (s.min !== '' && s.min != null) q.amountMin = String(s.min) if (s.min !== '' && s.min != null) q[`${prefix}Min`] = String(s.min)
if (s.max !== '' && s.max != null) q.amountMax = String(s.max) if (s.max !== '' && s.max != null) q[`${prefix}Max`] = String(s.max)
} else if (s.value !== '' && s.value != null) { } else if (s.value !== '' && s.value != null) {
q.amount = String(s.value) q[prefix] = String(s.value)
} }
continue continue
} }
if (def.type === 'enum') { if (def.type === 'enum') {
// 本页仅 status → statusIn
const s = state as TextColumnFilterState const s = state as TextColumnFilterState
if (s.selected?.length) q.statusIn = s.selected.join(',') if (s.selected?.length) q[`${key}In`] = s.selected.join(',')
continue continue
} }
// text:prop 直接作为 query key(applyCode/title/expenseName/currentNode)
const s = state as TextColumnFilterState const s = state as TextColumnFilterState
const text = String(s.text || '').trim() const text = String(s.text || '').trim()
if (text) q[prop] = text if (text) q[key] = text
} }
return q return q
} }
@@ -858,15 +858,22 @@ const { rows, total, currentPage, pageSize, rangeText, loading, refresh, search,
const quickSearchKeyword = ref('') const quickSearchKeyword = ref('')
const columnFilterDefs: ColumnFilterDef[] = [ const columnFilterDefs: ColumnFilterDef[] = [
{ prop: 'applyTime', label: '申请时间', type: 'datetime' }, {
{ prop: 'applyCode', label: '报销单号', type: 'text' }, prop: 'applyTime',
{ prop: 'title', label: '报销标题', type: 'text' }, label: '申请时间',
{ prop: 'expenseName', label: '费用项目', type: 'text' }, type: 'datetime',
{ prop: 'amount', label: '报销金额(元)', type: 'number' }, queryKeyFrom: 'applyDateFrom',
queryKeyTo: 'applyDateTo'
},
{ prop: 'applyCode', label: '报销单号', type: 'text', queryKey: 'applyCode' },
{ prop: 'title', label: '报销标题', type: 'text', queryKey: 'title' },
{ prop: 'expenseName', label: '费用项目', type: 'text', queryKey: 'expenseName' },
{ prop: 'amount', label: '报销金额(元)', type: 'number', queryKeyPrefix: 'amount' },
{ {
prop: 'status', prop: 'status',
label: '状态', label: '状态',
type: 'enum', type: 'enum',
queryKey: 'status',
enumOptions: [ enumOptions: [
{ value: 'draft', label: '待提交' }, { value: 'draft', label: '待提交' },
{ value: 'pending', label: '审批中' }, { value: 'pending', label: '审批中' },
@@ -874,7 +881,7 @@ const columnFilterDefs: ColumnFilterDef[] = [
{ value: 'rejected', label: '审批驳回' } { value: 'rejected', label: '审批驳回' }
] ]
}, },
{ prop: 'currentNode', label: '当前节点', type: 'text' } { prop: 'currentNode', label: '当前节点', type: 'text', queryKey: 'currentNode' }
] ]
const { const {