diff --git a/packages/cli/src/addons/index.ts b/packages/cli/src/addons/index.ts index 44d3a76acf..57a1d49eed 100644 --- a/packages/cli/src/addons/index.ts +++ b/packages/cli/src/addons/index.ts @@ -23,7 +23,7 @@ declare module 'koishi' { Object.assign(App.Config.Advanced.dict, { autoRestart: Schema.boolean().description('应用在运行时崩溃自动重启。').default(true).hidden(), timezoneOffset: Schema.number().description('时区偏移量 (分钟)。').default(new Date().getTimezoneOffset()), - stackTraceLimit: Schema.number().description('报错的调用堆栈深度。').default(10), + stackTraceLimit: Schema.natural().description('报错的调用堆栈深度。').default(10), plugins: Schema.object({}).hidden(), }) diff --git a/packages/cli/src/addons/watcher.ts b/packages/cli/src/addons/watcher.ts index b81eafcbdb..3c6e512ed6 100644 --- a/packages/cli/src/addons/watcher.ts +++ b/packages/cli/src/addons/watcher.ts @@ -315,7 +315,7 @@ namespace Watcher { export const Config = Schema.object({ root: Schema.string().description('要监听的根目录,相对于当前工作路径。'), - debounce: Schema.number().default(100).description('延迟触发更新的等待时间。'), + debounce: Schema.natural().role('ms').default(100).description('延迟触发更新的等待时间。'), ignored: Schema.union([ Schema.array(Schema.string()), Schema.transform(Schema.string(), (value) => [value]), diff --git a/packages/core/src/app.ts b/packages/core/src/app.ts index 3c0e3baa44..fb6ae15cd0 100644 --- a/packages/core/src/app.ts +++ b/packages/core/src/app.ts @@ -277,24 +277,30 @@ export namespace App { Schema.array(Schema.string()), Schema.transform(Schema.string(), (nickname) => [nickname]), ] as const).description('机器人的昵称,可以是字符串或字符串数组。将用于指令前缀的匹配。'), - autoAssign: Schema.boolean().default(true).description('当获取不到频道数据时,是否使用接受者作为代理者。'), - autoAuthorize: Schema.number().default(1).description('当获取不到用户数据时默认使用的权限等级。'), - minSimilarity: Schema.number().default(0.4).description('用于模糊匹配的相似系数,应该是一个 0 到 1 之间的数值。数值越高,模糊匹配越严格。设置为 1 可以完全禁用模糊匹配。'), + autoAssign: Schema.union([ + Schema.boolean(), + Schema.function(), + ] as const).default(true).description('当获取不到频道数据时,是否使用接受者作为代理者。'), + autoAuthorize: Schema.union([ + Schema.natural(), + Schema.function(), + ] as const).default(1).description('当获取不到用户数据时默认使用的权限等级。'), + minSimilarity: Schema.percent().default(0.4).description('用于模糊匹配的相似系数,应该是一个 0 到 1 之间的数值。数值越高,模糊匹配越严格。设置为 1 可以完全禁用模糊匹配。'), }).description('基础设置')) defineProperty(Config, 'Features', Schema.object({ delay: Schema.object({ - character: Schema.number().default(0).description('调用 `session.sendQueued()` 时消息间发送的最小延迟,按前一条消息的字数计算。'), - message: Schema.number().default(0.1 * Time.second).description('调用 `session.sendQueued()` 时消息间发送的最小延迟,按固定值计算。'), - cancel: Schema.number().default(0).description('调用 `session.cancelQueued()` 时默认的延迟。'), - broadcast: Schema.number().default(0.5 * Time.second).description('调用 `bot.broadcast()` 时默认的延迟。'), - prompt: Schema.number().default(Time.minute).description('调用 `session.prompt()` 是默认的等待时间。'), + character: Schema.natural().role('ms').default(0).description('调用 `session.sendQueued()` 时消息间发送的最小延迟,按前一条消息的字数计算。'), + message: Schema.natural().role('ms').default(0.1 * Time.second).description('调用 `session.sendQueued()` 时消息间发送的最小延迟,按固定值计算。'), + cancel: Schema.natural().role('ms').default(0).description('调用 `session.cancelQueued()` 时默认的延迟。'), + broadcast: Schema.natural().role('ms').default(0.5 * Time.second).description('调用 `bot.broadcast()` 时默认的延迟。'), + prompt: Schema.natural().role('ms').default(Time.minute).description('调用 `session.prompt()` 是默认的等待时间。'), }), }).description('消息设置')) defineProperty(Config, 'Advanced', Schema.object({ prettyErrors: Schema.boolean().default(true).description('启用报错优化模式。在此模式下 Koishi 会对程序抛出的异常进行整理,过滤掉框架内部的调用记录,输出更易读的提示信息。'), - maxListeners: Schema.number().default(64).description('每种监听器的最大数量。如果超过这个数量,Koishi 会认定为发生了内存泄漏,将产生一个警告。'), + maxListeners: Schema.natural().default(64).description('每种监听器的最大数量。如果超过这个数量,Koishi 会认定为发生了内存泄漏,将产生一个警告。'), }).description('高级设置')) Config.list.push(Config.Basic, Config.Features, Config.Advanced) diff --git a/packages/core/src/command.ts b/packages/core/src/command.ts index f72263fd04..e410de156f 100644 --- a/packages/core/src/command.ts +++ b/packages/core/src/command.ts @@ -282,7 +282,7 @@ export class Command = Schema.object({ - authority: Schema.number(), + authority: Schema.natural(), hidden: Schema.boolean(), checkArgCount: Schema.boolean(), checkUnknown: Schema.boolean(), diff --git a/packages/koishi/src/adapter.ts b/packages/koishi/src/adapter.ts index f76d38326e..bde3159743 100644 --- a/packages/koishi/src/adapter.ts +++ b/packages/koishi/src/adapter.ts @@ -27,9 +27,9 @@ export namespace InjectedAdapter { public isListening = false static Config: Schema = Schema.object({ - retryTimes: Schema.number().description('初次连接时的最大重试次数,仅用于 ws 协议。').default(6), - retryInterval: Schema.number().description('初次连接时的重试时间间隔,仅用于 ws 协议。').default(5 * Time.second), - retryLazy: Schema.number().description('连接关闭后的重试时间间隔,仅用于 ws 协议。').default(Time.minute), + retryTimes: Schema.natural().description('初次连接时的最大重试次数,仅用于 ws 协议。').default(6), + retryInterval: Schema.natural().role('ms').description('初次连接时的重试时间间隔,仅用于 ws 协议。').default(5 * Time.second), + retryLazy: Schema.natural().role('ms').description('连接关闭后的重试时间间隔,仅用于 ws 协议。').default(Time.minute), }).description('连接设置') constructor(ctx: Context, config: T) { diff --git a/packages/koishi/src/quester.ts b/packages/koishi/src/quester.ts index 9cb9ed5d73..84bb2cfa55 100644 --- a/packages/koishi/src/quester.ts +++ b/packages/koishi/src/quester.ts @@ -52,7 +52,7 @@ export namespace Quester { endpoint: Schema.string().role('url').description('要连接的端点。').default(config.endpoint), proxyAgent: Schema.string().role('url').description('使用的代理服务器地址。').default(config.proxyAgent), headers: Schema.dict(Schema.string()).description('要附加的额外请求头。').default(config.headers), - timeout: Schema.number().description('等待连接建立的最长时间。').default(config.timeout), + timeout: Schema.natural().role('ms').description('等待连接建立的最长时间。').default(config.timeout), }).description('请求设置') } diff --git a/packages/koishi/src/router.ts b/packages/koishi/src/router.ts index a392706cf3..8f7ffd1e44 100644 --- a/packages/koishi/src/router.ts +++ b/packages/koishi/src/router.ts @@ -40,7 +40,7 @@ declare module '@koishijs/core' { defineProperty(App.Config, 'Network', Schema.object({ host: Schema.string().default('localhost').description('要监听的 IP 地址。如果将此设置为 `0.0.0.0` 将监听所有地址,包括局域网和公网地址。'), - port: Schema.number().description('要监听的端口。'), + port: Schema.natural().max(65535).description('要监听的端口。'), selfUrl: Schema.string().role('url').description('应用暴露在公网的地址。部分插件 (例如 github 和 telegram) 需要用到。'), }).description('网络设置')) diff --git a/plugins/a11y/schedule/src/index.ts b/plugins/a11y/schedule/src/index.ts index 729265c2b9..9133e9a70c 100644 --- a/plugins/a11y/schedule/src/index.ts +++ b/plugins/a11y/schedule/src/index.ts @@ -34,7 +34,7 @@ export interface Config { } export const Config = Schema.object({ - minInterval: Schema.number().description('允许的最小时间间隔。').default(Time.minute), + minInterval: Schema.natural().role('ms').description('允许的最小时间间隔。').default(Time.minute), }) export function apply(ctx: Context, { minInterval }: Config) { diff --git a/plugins/adapter/telegram/src/http.ts b/plugins/adapter/telegram/src/http.ts index 335ebc0b36..2fc05bccf5 100644 --- a/plugins/adapter/telegram/src/http.ts +++ b/plugins/adapter/telegram/src/http.ts @@ -187,7 +187,7 @@ export class HttpPolling extends TelegramAdapter { BotConfig, Schema.object({ pollingTimeout: Schema.union([ - Schema.number(), + Schema.natural(), Schema.transform(Schema.const(true as const), () => 60), ]).default(60).description('通过长轮询获取更新时请求的超时 (单位为秒)。'), }), diff --git a/plugins/assets/git/src/index.ts b/plugins/assets/git/src/index.ts index 0a3f7e64bd..3f07a3675b 100644 --- a/plugins/assets/git/src/index.ts +++ b/plugins/assets/git/src/index.ts @@ -231,8 +231,8 @@ namespace JsdelivrAssets { baseDir: Schema.string().required(), }), tempDir: Schema.string().default(resolve(__dirname, '../.temp')), - flushInterval: Schema.number().default(Time.second * 3), - maxBranchSize: Schema.number().default(50 * 1024 * 1024), + flushInterval: Schema.natural().role('ms').default(Time.second * 3), + maxBranchSize: Schema.natural().role('byte').default(50 * 1024 * 1024), }) } diff --git a/plugins/common/forward/src/index.ts b/plugins/common/forward/src/index.ts index 330698e988..adf6c474b3 100644 --- a/plugins/common/forward/src/index.ts +++ b/plugins/common/forward/src/index.ts @@ -31,7 +31,7 @@ export interface Config { export const schema = Schema.union([ Schema.object({ rules: Schema.array(Rule), - interval: Schema.number().default(Time.hour), + interval: Schema.natural().role('ms').default(Time.hour), }), Schema.transform(Schema.array(Rule), (rules) => ({ rules })), ]) diff --git a/plugins/common/recall/src/index.ts b/plugins/common/recall/src/index.ts index 056d261ac1..1335a1cd5e 100644 --- a/plugins/common/recall/src/index.ts +++ b/plugins/common/recall/src/index.ts @@ -5,7 +5,7 @@ export interface Config { } export const Config = Schema.object({ - timeout: Schema.number().default(Time.hour).description('消息保留的时间。'), + timeout: Schema.natural().role('ms').default(Time.hour).description('消息保留的时间。'), }) export const name = 'recall' diff --git a/plugins/database/mongo/src/index.ts b/plugins/database/mongo/src/index.ts index f49cf4b3c5..f33ca5abf6 100644 --- a/plugins/database/mongo/src/index.ts +++ b/plugins/database/mongo/src/index.ts @@ -277,7 +277,7 @@ namespace MongoDatabase { export const Config = Schema.object({ protocol: Schema.string().description('要使用的协议名。').default('mongodb'), host: Schema.string().description('要连接到的主机名。').default('localhost'), - port: Schema.number().description('要连接到的端口号。'), + port: Schema.natural().max(65535).description('要连接到的端口号。'), username: Schema.string().description('要使用的用户名。'), password: Schema.string().description('要使用的密码。').role('secret'), database: Schema.string().description('要访问的数据库名。').default('koishi'), diff --git a/plugins/database/mysql/src/index.ts b/plugins/database/mysql/src/index.ts index 03756769fa..b1291fa1f3 100644 --- a/plugins/database/mysql/src/index.ts +++ b/plugins/database/mysql/src/index.ts @@ -436,7 +436,7 @@ namespace MysqlDatabase { export const Config = Schema.object({ host: Schema.string().description('要连接到的主机名。').default('localhost'), - port: Schema.number().description('要连接到的端口号。').default(3306), + port: Schema.natural().max(65535).description('要连接到的端口号。').default(3306), user: Schema.string().description('要使用的用户名。').default('root'), password: Schema.string().description('要使用的密码。').role('secret'), database: Schema.string().description('要访问的数据库名。').default('koishi'), diff --git a/plugins/frontend/chat/src/index.ts b/plugins/frontend/chat/src/index.ts index 16943b532f..78b16427b3 100644 --- a/plugins/frontend/chat/src/index.ts +++ b/plugins/frontend/chat/src/index.ts @@ -61,8 +61,8 @@ export interface Config extends ClientExtension { export const Config = Schema.object({ refresh: RefreshConfig, whitelist: Schema.array(Schema.string()), - maxMessages: Schema.number(), - logLevel: Schema.number(), + maxMessages: Schema.natural(), + logLevel: Schema.natural().max(3), }) const logger = new Logger('message') diff --git a/plugins/frontend/chat/src/receiver.ts b/plugins/frontend/chat/src/receiver.ts index 2795e8b8a4..b96e39962a 100644 --- a/plugins/frontend/chat/src/receiver.ts +++ b/plugins/frontend/chat/src/receiver.ts @@ -7,9 +7,9 @@ export interface RefreshConfig { } export const RefreshConfig = Schema.object({ - user: Schema.number().description('刷新用户数据的时间间隔。').default(Time.hour), - guild: Schema.number().description('刷新群组数据的时间间隔。').default(Time.hour), - channel: Schema.number().description('刷新频道数据的时间间隔。').default(Time.hour), + user: Schema.natural().role('ms').description('刷新用户数据的时间间隔。').default(Time.hour), + guild: Schema.natural().role('ms').description('刷新群组数据的时间间隔。').default(Time.hour), + channel: Schema.natural().role('ms').description('刷新频道数据的时间间隔。').default(Time.hour), }).description('刷新选项') const textSegmentTypes = ['text', 'header', 'section'] diff --git a/plugins/frontend/components/client/form/union.vue b/plugins/frontend/components/client/form/union.vue index 21d320adf1..9967410a73 100644 --- a/plugins/frontend/components/client/form/union.vue +++ b/plugins/frontend/components/client/form/union.vue @@ -52,7 +52,7 @@ const config = computed({ }) const choices = computed(() => { - return props.schema.list.filter(item => item.type !== 'transform') + return props.schema.list.filter(item => !['function', 'transform'].includes(item.type)) }) const isSelect = computed(() => { diff --git a/plugins/frontend/components/client/layout/index.ts b/plugins/frontend/components/client/layout/index.ts index 6d111ac901..daf4f7f6bd 100644 --- a/plugins/frontend/components/client/layout/index.ts +++ b/plugins/frontend/components/client/layout/index.ts @@ -8,7 +8,7 @@ import TabItem from './tab-item.vue' export default function (app: App) { app.component('k-card-aside', CardAside) - app.component('k-card-numeric', CardNumeric) + app.component('k-numeric', CardNumeric) app.component('k-card', Card) app.component('k-content', Content) app.component('k-tab-group', TabGroup) diff --git a/plugins/frontend/logger/src/index.ts b/plugins/frontend/logger/src/index.ts index 70c72c732b..afb18e4c41 100644 --- a/plugins/frontend/logger/src/index.ts +++ b/plugins/frontend/logger/src/index.ts @@ -112,7 +112,7 @@ namespace LogProvider { export const Config = Schema.object({ root: Schema.string().default('logs').description('存放输出日志的本地目录。'), - maxAge: Schema.number().default(30).description('日志文件保存的最大天数。'), + maxAge: Schema.natural().default(30).description('日志文件保存的最大天数。'), }) } diff --git a/plugins/frontend/status/src/meta.ts b/plugins/frontend/status/src/meta.ts index a3e8f6a21d..d8b0e5803b 100644 --- a/plugins/frontend/status/src/meta.ts +++ b/plugins/frontend/status/src/meta.ts @@ -66,7 +66,7 @@ namespace MetaProvider { } export const Config = Schema.object({ - metaInternal: Schema.number().description('元数据推送的时间间隔。').default(Time.hour), + metaInternal: Schema.natural().role('ms').description('元数据推送的时间间隔。').default(Time.hour), }) export interface Payload extends Assets.Stats { diff --git a/plugins/frontend/status/src/profile.ts b/plugins/frontend/status/src/profile.ts index 86515dc48a..926a4ca5f6 100644 --- a/plugins/frontend/status/src/profile.ts +++ b/plugins/frontend/status/src/profile.ts @@ -71,7 +71,7 @@ namespace ProfileProvider { } export const Config = Schema.object({ - tickInterval: Schema.number().description('性能数据推送的时间间隔。').default(Time.second * 5), + tickInterval: Schema.natural().role('ms').description('性能数据推送的时间间隔。').default(Time.second * 5), }) export interface Payload { diff --git a/plugins/frontend/status/src/stats.ts b/plugins/frontend/status/src/stats.ts index 65c2d72b94..7eb297701f 100644 --- a/plugins/frontend/status/src/stats.ts +++ b/plugins/frontend/status/src/stats.ts @@ -343,7 +343,7 @@ namespace StatisticsProvider { } export const Config = Schema.object({ - statsInternal: Schema.number().description('统计数据推送的时间间隔。').default(Time.minute * 10), + statsInternal: Schema.natural().role('ms').description('统计数据推送的时间间隔。').default(Time.minute * 10), }) export type Extension = (payload: Payload, data: StatisticsProvider.Data) => Promise diff --git a/plugins/github/src/server.ts b/plugins/github/src/server.ts index 99ae30a56e..f4dfe57b3c 100644 --- a/plugins/github/src/server.ts +++ b/plugins/github/src/server.ts @@ -53,9 +53,9 @@ export const Config = Schema.object({ appSecret: Schema.string().description('GitHub OAuth App Secret.'), redirect: Schema.string().description('授权成功后的跳转链接。'), messagePrefix: Schema.string().description('推送消息的前缀。').default('[GitHub] '), - replyTimeout: Schema.number().description('等待用户回复消息进行快捷操作的时间。').default(Time.hour), - promptTimeout: Schema.number().description('等待用户键入用户名的时间。缺省时会使用全局设置。'), - requestTimeout: Schema.number().description('等待请求 GitHub 的时间,超时将提示操作失败。缺省时会使用全局设置。'), + replyTimeout: Schema.natural().role('ms').description('等待用户回复消息进行快捷操作的时间。').default(Time.hour), + promptTimeout: Schema.natural().role('ms').description('等待用户键入用户名的时间。缺省时会使用全局设置。'), + requestTimeout: Schema.natural().role('ms').description('等待请求 GitHub 的时间,超时将提示操作失败。缺省时会使用全局设置。'), }) export interface OAuth { diff --git a/plugins/puppeteer/src/index.ts b/plugins/puppeteer/src/index.ts index 8fffa5800a..d588297e41 100644 --- a/plugins/puppeteer/src/index.ts +++ b/plugins/puppeteer/src/index.ts @@ -22,9 +22,9 @@ type LaunchOptions = Parameters[0] const LaunchOptions = Schema.object({ executablePath: Schema.string().description('Chromium 可执行文件的路径。缺省时将自动从系统中寻找。'), viewPort: Schema.object({ - width: Schema.number().description('默认的视图宽度。').default(800), - height: Schema.number().description('默认的视图高度。').default(600), - deviceScaleFactor: Schema.number().description('默认的设备缩放比率。').default(2), + width: Schema.natural().description('默认的视图宽度。').default(800), + height: Schema.natural().description('默认的视图高度。').default(600), + deviceScaleFactor: Schema.number().min(0).description('默认的设备缩放比率。').default(2), }), }).description('浏览器设置') diff --git a/plugins/puppeteer/src/screenshot.ts b/plugins/puppeteer/src/screenshot.ts index 6579de0b3d..c719b7787f 100644 --- a/plugins/puppeteer/src/screenshot.ts +++ b/plugins/puppeteer/src/screenshot.ts @@ -42,9 +42,9 @@ export interface Config { export const Config: Schema = Schema.object({ protocols: Schema.array(Schema.string()).description('允许的协议列表。').default(['http', 'https']), - maxSize: Schema.number().description('单张图片的最大尺寸,单位为字节。当截图尺寸超过这个值时会自动截取图片顶部的一段进行发送。').default(1000000), - loadTimeout: Schema.number().description('加载页面的最长时间。当一个页面等待时间超过这个值时,如果此页面主体已经加载完成,则会发送一条提示消息“正在加载中,请稍等片刻”并继续等待加载;否则会直接提示“无法打开页面”并终止加载。').default(Time.second * 5), - idleTimeout: Schema.number().description('等待页面空闲的最长时间。当一个页面等待时间超过这个值时,将停止进一步的加载并立即发送截图。').default(Time.second * 30), + maxSize: Schema.natural().role('byte').description('单张图片的最大尺寸,单位为字节。当截图尺寸超过这个值时会自动截取图片顶部的一段进行发送。').default(1024 * 1024), + loadTimeout: Schema.natural().role('ms').description('加载页面的最长时间。当一个页面等待时间超过这个值时,如果此页面主体已经加载完成,则会发送一条提示消息“正在加载中,请稍等片刻”并继续等待加载;否则会直接提示“无法打开页面”并终止加载。').default(Time.second * 5), + idleTimeout: Schema.natural().role('ms').description('等待页面空闲的最长时间。当一个页面等待时间超过这个值时,将停止进一步的加载并立即发送截图。').default(Time.second * 30), }).description('截图设置') export function apply(ctx: Context, config: Config) { diff --git a/plugins/teach/src/index.ts b/plugins/teach/src/index.ts index b6924ce2b9..9c2ec17f38 100644 --- a/plugins/teach/src/index.ts +++ b/plugins/teach/src/index.ts @@ -47,32 +47,32 @@ export type Config = Dialogue.Config export const schema: Schema = Schema.intersect([ Schema.object({ prefix: Schema.string().description('教学指令的前缀。').default('#'), - historyTimeout: Schema.number().description('教学操作在内存中的保存时间。').default(Time.minute * 10), + historyTimeout: Schema.natural().role('ms').description('教学操作在内存中的保存时间。').default(Time.minute * 10), }).description('通用设置'), Schema.object({ authority: Schema.object({ - base: Schema.number().description('可访问教学系统的权限等级。').default(2), - admin: Schema.number().description('可修改非自己创建的问答的权限等级。').default(3), - context: Schema.number().description('可修改上下文设置的权限等级。').default(3), - frozen: Schema.number().description('可修改锁定的问答的权限等级。').default(4), - regExp: Schema.number().description('可使用正则表达式的权限等级。').default(3), - writer: Schema.number().description('可设置作者或匿名的权限等级。').default(2), + base: Schema.natural().description('可访问教学系统的权限等级。').default(2), + admin: Schema.natural().description('可修改非自己创建的问答的权限等级。').default(3), + context: Schema.natural().description('可修改上下文设置的权限等级。').default(3), + frozen: Schema.natural().description('可修改锁定的问答的权限等级。').default(4), + regExp: Schema.natural().description('可使用正则表达式的权限等级。').default(3), + writer: Schema.natural().description('可设置作者或匿名的权限等级。').default(2), }), }).description('权限设置'), Schema.object({ - maxRedirections: Schema.number().description('问题重定向的次数上限。').default(3), - successorTimeout: Schema.number().description('问答触发后继问答的持续时间。').default(Time.second * 20), - appellationTimeout: Schema.number().description('称呼作为问题触发的后续效果持续时间。').default(Time.minute * 10), + maxRedirections: Schema.natural().description('问题重定向的次数上限。').default(3), + successorTimeout: Schema.natural().role('ms').description('问答触发后继问答的持续时间。').default(Time.second * 20), + appellationTimeout: Schema.natural().role('ms').description('称呼作为问题触发的后续效果持续时间。').default(Time.minute * 10), }).description('触发设置'), Schema.object({ - maxPreviews: Schema.number().description('同时查看的最大问答数量。').default(10), - previewDelay: Schema.number().description('显示两个问答之间的时间间隔。').default(Time.second * 0.5), - itemsPerPage: Schema.number().description('搜索结果每一页显示的最大数量。').default(30), - maxAnswerLength: Schema.number().description('搜索结果中回答显示的长度限制。').default(100), - mergeThreshold: Schema.number().description('合并搜索模式中,相同的问题和回答被合并的最小数量。').default(5), + maxPreviews: Schema.natural().description('同时查看的最大问答数量。').default(10), + previewDelay: Schema.natural().role('ms').description('显示两个问答之间的时间间隔。').default(Time.second * 0.5), + itemsPerPage: Schema.natural().description('搜索结果每一页显示的最大数量。').default(30), + maxAnswerLength: Schema.natural().description('搜索结果中回答显示的长度限制。').default(100), + mergeThreshold: Schema.natural().description('合并搜索模式中,相同的问题和回答被合并的最小数量。').default(5), }).description('显示设置'), ])