From 18a259a5d211153a4cb69d5636bfaf2777c4f6d9 Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 9 Jul 2025 19:39:07 +0300 Subject: [PATCH] =?UTF-8?q?=D0=B2=D0=B0=D1=88=D0=B5=20=D1=81=D0=BE=D0=BE?= =?UTF-8?q?=D0=B1=D1=89=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BA=D0=BE=D0=BC=D0=BC?= =?UTF-8?q?=D0=B8=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/routes/tables.js | 43 +++++++++ .../src/components/tables/UserTableView.vue | 92 ++++++++++++++++--- frontend/src/services/tablesService.js | 7 ++ frontend/vite.config.js | 5 + 4 files changed, 136 insertions(+), 11 deletions(-) diff --git a/backend/routes/tables.js b/backend/routes/tables.js index 3bb0cb1..33d5ad2 100644 --- a/backend/routes/tables.js +++ b/backend/routes/tables.js @@ -93,6 +93,49 @@ router.post('/:id/rows', async (req, res, next) => { } }); +// Получить строки таблицы с фильтрацией по продукту и тегам +router.get('/:id/rows', async (req, res, next) => { + try { + const tableId = req.params.id; + const { product, tags } = req.query; // tags = "B2B,VIP" + // Получаем все столбцы, строки и значения ячеек + const columns = (await db.getQuery()('SELECT * FROM user_columns WHERE table_id = $1', [tableId])).rows; + const rows = (await db.getQuery()('SELECT * FROM user_rows WHERE table_id = $1', [tableId])).rows; + const cellValues = (await db.getQuery()('SELECT * FROM user_cell_values WHERE row_id IN (SELECT id FROM user_rows WHERE table_id = $1)', [tableId])).rows; + + // Находим id нужных колонок + const productCol = columns.find(c => c.options && c.options.purpose === 'product'); + const tagsCol = columns.find(c => c.options && c.options.purpose === 'userTags'); + + // Собираем строки с нужными полями + const data = rows.map(row => { + const cells = cellValues.filter(cell => cell.row_id === row.id); + return { + id: row.id, + product: cells.find(c => c.column_id === productCol?.id)?.value, + userTags: cells.find(c => c.column_id === tagsCol?.id)?.value, + // ... другие поля при необходимости + }; + }); + + // Фильтрация на сервере + let filtered = data; + if (product) { + filtered = filtered.filter(r => r.product === product); + } + if (tags) { + const tagArr = tags.split(',').map(t => t.trim()); + filtered = filtered.filter(r => + tagArr.some(tag => (r.userTags || '').split(',').map(t => t.trim()).includes(tag)) + ); + } + + res.json(filtered); + } catch (err) { + next(err); + } +}); + // Изменить значение ячейки (доступно всем) router.patch('/cell/:cellId', async (req, res, next) => { try { diff --git a/frontend/src/components/tables/UserTableView.vue b/frontend/src/components/tables/UserTableView.vue index cf61f8a..061e5fb 100644 --- a/frontend/src/components/tables/UserTableView.vue +++ b/frontend/src/components/tables/UserTableView.vue @@ -9,6 +9,23 @@ {{ rebuildStatus.message }} + +
+ + + + + + + Сбросить фильтры +
@@ -30,7 +47,7 @@ - +