Преглед на файлове

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

Co-authored-by: Cursor <cursoragent@cursor.com>
zlwu преди 1 месец
родител
ревизия
f33b905f0d

+ 7 - 0
web-admin/src/composables/useClientColumnFilters.ts

@@ -17,6 +17,13 @@ export interface ColumnFilterDef {
   enumOptions?: ColumnFilterEnumOption[]
   /** 自定义取值(展示值 / 比较值) */
   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 */

+ 15 - 14
web-admin/src/composables/useServerColumnFilters.ts

@@ -10,8 +10,8 @@ import {
 
 /**
  * 服务端列条件:管理 state、toQueryParams、藏列清条件。
- * toQueryParams 本页(报销申请)YAGNI 写死映射 applyDateFrom / amountOp / statusIn 等;
- * 日后推广可在 ColumnFilterDef 增加可选 queryKey。
+ * toQueryParams 按 ColumnFilterDef 的 queryKey / queryKeyFrom|To / queryKeyPrefix 映射;
+ * 未配置时回退 prop(枚举 → `${key}In`,日期 → `${key}From|To`,数字 → `${prefix}Op` 等)。
  */
 export function useServerColumnFilters(
   columnDefs: ColumnFilterDef[],
@@ -90,35 +90,36 @@ export function useServerColumnFilters(
       const state = filters[prop]
       if (!def || !isColumnFilterActive(def.type, state)) continue
 
+      const key = def.queryKey || prop
+
       if (def.type === 'datetime') {
-        // 本页仅 applyTime → applyDateFrom / applyDateTo
         const s = state as DatetimeColumnFilterState
-        if (s.from) q.applyDateFrom = s.from
-        if (s.to) q.applyDateTo = s.to
+        const fromKey = def.queryKeyFrom || `${key}From`
+        const toKey = def.queryKeyTo || `${key}To`
+        if (s.from) q[fromKey] = s.from
+        if (s.to) q[toKey] = s.to
         continue
       }
       if (def.type === 'number') {
-        // 本页仅 amount → amountOp / amountMin|amountMax|amount
         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.min !== '' && s.min != null) q.amountMin = String(s.min)
-          if (s.max !== '' && s.max != null) q.amountMax = String(s.max)
+          if (s.min !== '' && s.min != null) q[`${prefix}Min`] = String(s.min)
+          if (s.max !== '' && s.max != null) q[`${prefix}Max`] = String(s.max)
         } else if (s.value !== '' && s.value != null) {
-          q.amount = String(s.value)
+          q[prefix] = String(s.value)
         }
         continue
       }
       if (def.type === 'enum') {
-        // 本页仅 status → statusIn
         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
       }
-      // text:prop 直接作为 query key(applyCode/title/expenseName/currentNode)
       const s = state as TextColumnFilterState
       const text = String(s.text || '').trim()
-      if (text) q[prop] = text
+      if (text) q[key] = text
     }
     return q
   }

+ 13 - 6
web-admin/src/views/bx/reimburse/apply/index.vue

@@ -858,15 +858,22 @@ const { rows, total, currentPage, pageSize, rangeText, loading, refresh, search,
 const quickSearchKeyword = ref('')
 
 const columnFilterDefs: ColumnFilterDef[] = [
-  { prop: 'applyTime', label: '申请时间', type: 'datetime' },
-  { prop: 'applyCode', label: '报销单号', type: 'text' },
-  { prop: 'title', label: '报销标题', type: 'text' },
-  { prop: 'expenseName', label: '费用项目', type: 'text' },
-  { prop: 'amount', label: '报销金额(元)', type: 'number' },
+  {
+    prop: 'applyTime',
+    label: '申请时间',
+    type: 'datetime',
+    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',
     label: '状态',
     type: 'enum',
+    queryKey: 'status',
     enumOptions: [
       { value: 'draft', label: '待提交' },
       { value: 'pending', label: '审批中' },
@@ -874,7 +881,7 @@ const columnFilterDefs: ColumnFilterDef[] = [
       { value: 'rejected', label: '审批驳回' }
     ]
   },
-  { prop: 'currentNode', label: '当前节点', type: 'text' }
+  { prop: 'currentNode', label: '当前节点', type: 'text', queryKey: 'currentNode' }
 ]
 
 const {