From 22838ee71a0aa3081222d48993f00740066b4af4 Mon Sep 17 00:00:00 2001 From: SunWuyuan Date: Fri, 29 Aug 2025 16:54:03 +0800 Subject: [PATCH] =?UTF-8?q?feat(kv):=20=E6=B7=BB=E5=8A=A0=E8=8E=B7?= =?UTF-8?q?=E5=8F=96=E9=94=AE=E5=90=8D=E5=88=97=E8=A1=A8=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增 listKeysOnly 方法用于获取指定命名空间下的键名列表,并添加对应的路由接口 /:namespace/_keys 支持分页和排序查询。返回结果包含键名数组、总数和分页信息,便于前端展示大量键名时使用。 --- routes/kv.js | 54 ++++++++++++++++++++++++++++++++++++++++++++++++ utils/kvStore.js | 30 +++++++++++++++++++++++++++ 2 files changed, 84 insertions(+) diff --git a/routes/kv.js b/routes/kv.js index 01e332c..a70e061 100644 --- a/routes/kv.js +++ b/routes/kv.js @@ -234,6 +234,60 @@ router.delete( }) ); +/** + * GET /:namespace/_keys + * 获取指定命名空间下的键名列表(分页,不包括内容) + */ +router.get( + "/:namespace/_keys", + checkRestrictedUUID, + readAuthMiddleware, + errors.catchAsync(async (req, res, next) => { + const { namespace } = req.params; + const { sortBy, sortDir, limit, skip } = req.query; + + // 构建选项 + const options = { + sortBy: sortBy || "key", + sortDir: sortDir || "asc", + limit: limit ? parseInt(limit) : 100, + skip: skip ? parseInt(skip) : 0, + }; + + const keys = await kvStore.listKeysOnly(namespace, options); + + // 获取总记录数 + const totalRows = await kvStore.count(namespace); + + // 构建响应对象 + const response = { + keys: keys, + total_rows: totalRows, + current_page: { + limit: options.limit, + skip: options.skip, + count: keys.length, + }, + }; + + // 如果还有更多数据,添加load_more字段 + const nextSkip = options.skip + options.limit; + if (nextSkip < totalRows) { + const baseUrl = `${req.baseUrl}/${namespace}/_keys`; + const queryParams = new URLSearchParams({ + sortBy: options.sortBy, + sortDir: options.sortDir, + limit: options.limit, + skip: nextSkip, + }).toString(); + + response.load_more = `${baseUrl}?${queryParams}`; + } + + return res.json(response); + }) +); + /** * GET /:namespace * 获取指定命名空间下的所有键名及元数据列表 diff --git a/utils/kvStore.js b/utils/kvStore.js index 4baf4a8..d0f3179 100644 --- a/utils/kvStore.js +++ b/utils/kvStore.js @@ -160,6 +160,36 @@ class KVStore { })); } + /** + * 获取指定命名空间下的键名列表(不包括内容) + * @param {string} namespace - 命名空间 + * @param {object} options - 查询选项 + * @returns {Array} 键名列表 + */ + async listKeysOnly(namespace, options = {}) { + const { sortBy = "key", sortDir = "asc", limit = 100, skip = 0 } = options; + + // 构建排序条件 + const orderBy = {}; + orderBy[sortBy] = sortDir.toLowerCase(); + + // 查询以命名空间开头的所有键,只选择键名 + const items = await prisma.kVStore.findMany({ + where: { + namespace: namespace, + }, + select: { + key: true, + }, + orderBy, + take: limit, + skip: skip, + }); + + // 只返回键名数组 + return items.map((item) => item.key); + } + /** * 统计指定命名空间下的键值对数量 * @param {string} namespace - 命名空间