From 03c5614170f0ceddc867795c8e574c98e327096f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B8=B8=E7=86=9F=E5=90=B4=E5=BD=A6=E7=A5=96?= Date: Tue, 21 Apr 2026 12:12:31 +0800 Subject: [PATCH] =?UTF-8?q?feat(order):=20=E6=96=B0=E5=A2=9EPO=E8=AE=A2?= =?UTF-8?q?=E5=8D=95=E7=AE=A1=E7=90=86=E9=A1=B5=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 实现PO订单查询功能,支持按客户、采购员、订单号、SKU、状态筛选 - 创建表格组件显示PO订单详细信息,包括供应商、商品类别、数量金额等字段 - 集成编辑模式功能,支持下拉选择、数值输入等不同类型的单元格编辑 - 添加分页功能支持,配置多种页面大小选项 - 实现列配置管理,支持动态显示隐藏表格列 - 集成模拟数据源,预设多个PO订单样本数据用于测试 - 添加响应式布局适配不同屏幕尺寸 --- src/api/quickQuery/quickQueryField.js | 12 + src/views/modules/order/poOrder.vue | 1193 +++++++++++++++++ .../components/QuickQueryFilter.vue | 254 ++++ .../quickQuery/utils/quickQueryMatch.js | 61 + 4 files changed, 1520 insertions(+) create mode 100644 src/api/quickQuery/quickQueryField.js create mode 100644 src/views/modules/order/poOrder.vue create mode 100644 src/views/modules/quickQuery/components/QuickQueryFilter.vue create mode 100644 src/views/modules/quickQuery/utils/quickQueryMatch.js diff --git a/src/api/quickQuery/quickQueryField.js b/src/api/quickQuery/quickQueryField.js new file mode 100644 index 0000000..06ef9cf --- /dev/null +++ b/src/api/quickQuery/quickQueryField.js @@ -0,0 +1,12 @@ +import { createAPI } from '@/utils/httpRequest.js' + +// 快捷查询字段配置 - rqrq + +export const listQuickQueryFieldsByTableId = data => + createAPI('/quickQuery/field/listByTableId', 'post', data) + +export const saveQuickQueryField = data => + createAPI('/quickQuery/field/save', 'post', data) + +export const deleteQuickQueryField = data => + createAPI('/quickQuery/field/delete', 'post', data) diff --git a/src/views/modules/order/poOrder.vue b/src/views/modules/order/poOrder.vue new file mode 100644 index 0000000..b92ae05 --- /dev/null +++ b/src/views/modules/order/poOrder.vue @@ -0,0 +1,1193 @@ + + + + + diff --git a/src/views/modules/quickQuery/components/QuickQueryFilter.vue b/src/views/modules/quickQuery/components/QuickQueryFilter.vue new file mode 100644 index 0000000..3f9ebac --- /dev/null +++ b/src/views/modules/quickQuery/components/QuickQueryFilter.vue @@ -0,0 +1,254 @@ + + + + + diff --git a/src/views/modules/quickQuery/utils/quickQueryMatch.js b/src/views/modules/quickQuery/utils/quickQueryMatch.js new file mode 100644 index 0000000..2cff4e4 --- /dev/null +++ b/src/views/modules/quickQuery/utils/quickQueryMatch.js @@ -0,0 +1,61 @@ +/** + * 快捷查询条件:解析 JSON + 单行数据是否满足(纯函数,供列表页与后端约定一致) - rqrq + * + * 条件项结构:{ fieldName, fieldLabel?, dataType, operator, value } + * operator: GT | LT | EQ | CONTAINS + * dataType: NUMBER | TEXT | DATETIME + */ + +/** + * @param {string} conditionJsonString - QuickQueryFilter 提交的 JSON 字符串 + * @returns {{ ok: true, conditions: Array } | { ok: false, error: string }} + */ +export function parseQuickQueryJson (conditionJsonString) { + if (conditionJsonString == null || conditionJsonString === '') { + return { ok: true, conditions: [] } + } + try { + const parsed = JSON.parse(conditionJsonString) + if (!Array.isArray(parsed)) { + return { ok: false, error: '条件必须是数组' } + } + return { ok: true, conditions: parsed } + } catch (e) { + return { ok: false, error: '条件格式错误' } + } +} + +/** + * 判断一行数据是否满足全部快捷条件(AND) + * @param {Object} row - 行数据 + * @param {Array|null|undefined} conditions - parseQuickQueryJson 得到的 conditions;null/空则恒为 true + * @returns {boolean} + */ +export function matchQuickQueryRow (row, conditions) { + if (!conditions || !conditions.length) return true + for (const c of conditions) { + const raw = row[c.fieldName] + const target = c.value + const op = c.operator + const dt = (c.dataType || '').toUpperCase() + if (dt === 'TEXT') { + const sv = String(raw == null ? '' : raw) + const tv = String(target == null ? '' : target) + if (op === 'EQ' && sv !== tv) return false + if (op === 'CONTAINS' && !sv.toLowerCase().includes(tv.toLowerCase())) return false + } else if (dt === 'NUMBER') { + const nv = parseFloat(raw) + const nt = parseFloat(target) + if (Number.isNaN(nv) || Number.isNaN(nt)) return false + if (op === 'GT' && !(nv > nt)) return false + if (op === 'LT' && !(nv < nt)) return false + if (op === 'EQ' && nv !== nt) return false + } else if (dt === 'DATETIME') { + const dv = String(raw == null ? '' : raw).slice(0, 10) + const dtarget = String(target == null ? '' : target).slice(0, 10) + if (op === 'GT' && !(dv > dtarget)) return false + if (op === 'LT' && !(dv < dtarget)) return false + } + } + return true +}