From 82ecb49292ef9a45b0a654cef8fe776e9a4dc2d7 Mon Sep 17 00:00:00 2001 From: kittentm Date: Mon, 3 Aug 2026 04:23:33 +0200 Subject: [PATCH] feat: /search --- app/components/header.vue | 4 + app/pages/search/index.vue | 207 +++++++++++++++++++++++++++ server/api/admin/users/search.get.ts | 70 +++++++++ 3 files changed, 281 insertions(+) create mode 100644 app/pages/search/index.vue create mode 100644 server/api/admin/users/search.get.ts diff --git a/app/components/header.vue b/app/components/header.vue index f18b80c..25535f7 100644 --- a/app/components/header.vue +++ b/app/components/header.vue @@ -38,6 +38,10 @@ const emit = defineEmits(['logout', 'navigate']) @click="emit('navigate', '/')"> Welcome + diff --git a/app/pages/search/index.vue b/app/pages/search/index.vue new file mode 100644 index 0000000..8ae04a5 --- /dev/null +++ b/app/pages/search/index.vue @@ -0,0 +1,207 @@ + + + \ No newline at end of file diff --git a/server/api/admin/users/search.get.ts b/server/api/admin/users/search.get.ts new file mode 100644 index 0000000..a9e5f52 --- /dev/null +++ b/server/api/admin/users/search.get.ts @@ -0,0 +1,70 @@ +import { queryNnas } from '../../../utils/nnasDb' + +export default defineEventHandler(async (event) => { + const queryParams = getQuery(event) + const searchTerm = String(queryParams.q || '').trim() + const page = Math.max(1, parseInt(String(queryParams.page || '1'), 10)) + const limit = Math.max(1, Math.min(50, parseInt(String(queryParams.limit || '10'), 10))) + const offset = (page - 1) * limit + + if (!searchTerm) { + return { + data: [], + pagination: { total: 0, page, limit, totalPages: 0 } + } + } + + try { + const wildPattern = `%${searchTerm}%` + const startsWithPattern = `${searchTerm}%` + + const countResult = await queryNnas( + `SELECT COUNT(*) AS total + FROM users + WHERE username ILIKE $1 + OR CAST(pid AS TEXT) ILIKE $1 + OR email ILIKE $1`, + [wildPattern] + ) + + const total = parseInt(countResult.rows[0]?.total || '0', 10) + const totalPages = Math.ceil(total / limit) + + const dataResult = await queryNnas( + `SELECT + pid AS id, + username AS sfid, + pid, + email + FROM users + WHERE username ILIKE $1 + OR CAST(pid AS TEXT) ILIKE $1 + OR email ILIKE $1 + ORDER BY + CASE + WHEN LOWER(username) = LOWER($2) OR CAST(pid AS TEXT) = $2 THEN 0 + WHEN username ILIKE $3 OR email ILIKE $3 OR CAST(pid AS TEXT) ILIKE $3 THEN 1 + ELSE 2 + END, + pid DESC + LIMIT $4 OFFSET $5`, + [wildPattern, searchTerm, startsWithPattern, limit, offset] + ) + + return { + data: dataResult.rows, + pagination: { + total, + page, + limit, + totalPages + } + } + } catch (error: any) { + console.error('[NNAS DB SEARCH ERROR]:', error) + throw createError({ + statusCode: 500, + statusMessage: `NNAS Database query failed` + }) + } +}) \ No newline at end of file