尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Onyx 移动端输入栏工具控制(ActionsPopover + 深度研究开关)PR 路线图全解析

Onyx 移动端输入栏工具控制(ActionsPopover + 深度研究开关)PR 路线图全解析 Onyx 移动端输入栏工具控制ActionsPopover 深度研究开关PR 路线图全解析【免费下载链接】danswerOpen Source AI Platform - AI Chat with advanced features that works with every LLM项目地址: https://gitcode.com/GitHub_Trending/da/danswer本指南完整剖析 OnyxDanswer开源仓库中 移动端输入栏工具控制Mobile Input-Bar ControlsPR 路线图如何把 Web 端聊天输入栏的 ActionsPopover工具菜单与深度研究开关以 Web 对齐优先Approach B的方式移植到 React Native 移动端并按 4 个可独立评审、可随时发布的 PR 落地。读完你将掌握整个功能的 PR 拆分逻辑、每个 PR 的精确范围与文件清单、走查骨架walking skeleton策略、测试与漂移检查点drift checkpoint实践以及当前仓库中该方案的真实落地状态。背景移动端输入栏缺了什么Onyx 的 Web 端聊天输入栏工具栏早已具备完整的工具控制能力ActionsPopover工具/操作菜单和深度研究开关deep-research toggle。而移动端mobile/React Native Expo的聊天输入栏composer目前只能输入文本、附带文件、发送消息——用户无法控制agent 使用哪些工具强制指定某一个工具force a tool选择要搜索哪些知识源knowledge sources开启深度研究。路线图的目标是在Tier-2Standard范围内把这些控制移植到移动端做到与 Web 行为对齐web parity。范围界定来自 01-research.md 与 00-index.md范围内In scope范围外Out of scope深度研究开关deep-research toggleMCP 服务器 / 按 MCP 工具的开关点击即强制工具的操作列表forced_tool_idOAuth 重新认证单个工具的启用/禁用allowed_tool_ids管理端 More Actions 链接来源/连接器选择子视图internal_search_filters操作搜索框方案选择在 2026-07-16 的 GATE 1 确定为Approach B — Web-Parity-First构建真实的锚定Popover原语 移植三个 UI 原语SelectButton/Switch/Popover实现与服务端持久化的disabled_tool_ids完全对齐的行为。关键前提后端零改动能力已就绪路线图所依赖的承重事实load-bearing facts全部经过源码验证不需要任何后端改动和数据库迁移详见 00-index.md 与 03-detailed-design.md发送请求已接受全部四个字段SendMessageRequest已包含allowed_tool_ids、forced_tool_id、internal_search_filters一个BaseFilters和deep_research见 backend/onyx/server/query_and_chat/models.py。工具与知识源目录已经在传输线上GET /persona返回的MinimalPersonaSnapshot已携带tools: list[ToolSnapshot]与knowledge_sources: list[DocumentSource]见 backend/onyx/server/features/persona/models.py。移动端useAgents()已经在请求该端点只是MinimalAgent类型没有声明这两个字段——加宽类型即可零新增网络请求。deep_research_enabled管理端开关已存在Settings.deep_research_enabled: bool | None见 backend/onyx/server/settings/models.py通过GET /settings暴露。按 agent 的disabled_tool_ids已有表与端点表assistant__user_specific_config见 backend/onyx/db/models.py数据库层 upsert见 backend/onyx/db/user_preferences.py端点GET /user/assistant/preferences与PATCH /user/assistant/{id}/preferences见 backend/onyx/server/manage/users.py均BASIC_ACCESS权限。移动端当前的真实状态来自仓库扫描SendMessageBody只发送{message, chat_session_id, parent_message_id, file_descriptors, deep_research, origin}且deep_research被硬编码为false原 mobile/src/hooks/useChatController.ts 中allowed_tool_ids、forced_tool_id、internal_search_filters三个字段在类型中缺失。移动端也没有通用的 popover/菜单/动作面板原语——最接近的现成模式是 mobile/src/components/chat/FilePickerSheet.tsx一个基于 RNModal的底部面板以及rn-primitives/portalreact-native-reanimatedreact-native-gesture-handler技术栈PortalHost/挂载于 mobile/src/app/_layout.tsx。PR 总览与依赖序列路线图将整个功能拆成4 个评审友好review-sized的 PR核心策略是PR 2 就让深度研究端到端跑通即走查骨架工具菜单与来源选择在其后叠加每个 PR 合入后main依然可发布新控件只有在各自门槛gates通过时才可见因此部分合入在没有 feature flag 的情况下也是惰性的inert。PR标题预估 LOC依赖关键交付物1feat(mobile): tool-options foundation — send-body, contracts, primitives, icons~950–1,150—发送体/类型加宽 纯逻辑tools.ts/sources.tsSelectButton/Switch 8 个图标无聊天接线2feat(mobile): deep-research toggle~450–550PR 1走查骨架——深度研究经输入栏 pill 端到端可用3feat(mobile): actions popover — tools, force enable/disable~650–750PR 2锚定PopoverActionsPopover工具列表forced_tool_id 服务端持久化allowed_tool_ids4feat(mobile): actions popover — source selection search coupling~550–650PR 3来源子视图 搜索↔来源耦合internal_search_filters依赖序列走查骨架优先PR1 foundation (send-body pure contracts SelectButton/Switch icons) │ ▼ PR2 deep-research toggle (walking skeleton) ─► PR3 ActionsPopover (tools) ─► PR4 sources couplingPR 1是共享地基无运行时表面纯类型/逻辑/原语/图标PR 2是最细的端到端切片验证 composer→provider→submit 的整体形状PR 3引入锚定 popover设备端门槛及其第一个真实消费者PR 4完成 Tier-2 的全部能力。一个值得注意的决策PR 1 把原计划中的 plumbing管道与 primitives原语两个 PR 合并为一个基础 PRGATE 3 时 owner 的决定2026-07-16。它是无运行时表面的 PR类型、纯逻辑、原语、图标——都没有接进聊天因此仍然自洽但 LOC 会超过常见的 ~500–700 区间落在 ~950–1,150。如果评审时觉得过大自然的回退拆分是拆回plumbing/contracts与primitives/icons两部分。PR 1地基 —— send-body、契约、原语与图标目标一次性落地整个无运行时表面的地基——传输类型、纯逻辑、可复用原语与图标让 PR 2–4 只需要加状态与接线。应用里什么都还不可见。范围内内容发送体与类型加宽SendMessageBody新增allowed_tool_ids?/forced_tool_id?/internal_search_filters?及InternalSearchFilters类型mobile/src/api/chat/stream.ts加宽MinimalAgent新增tools/knowledge_sourcesmobile/src/chat/agents.ts给WorkspaceSettings增加deep_research_enabled?mobile/src/api/settings.ts。提交线程化submit(text, files?, onAccepted?, toolOptions?)替换硬编码的deep_research: false并在toolOptions缺失时无操作地填充三个新字段mobile/src/hooks/useChatController.ts。纯逻辑模块chat/tools.tsToolSnapshot、工具 ID 常量、谓词、computeAllowedToolIds、getIconForToolIdchat/sources.tsDocumentSource、SOURCE_META、buildInternalSearchFilters。原语select-button.tsxselect-button.styles.tsSELECT_COLORS字面量矩阵 resolveSelectStateselect-light变体foldable通过条件渲染标签实现——移动端没有 hoverswitch.tsxreanimated 轨道/滑块。图标8 个 SVGhourglass、globe、cpu、link、server、plug、unplug、slash路径数据取自04-implementation-plan.md附录。范围外锚定Popover留给 PR 3 及其消费者任何 hooks、provider 或聊天接线除既有发送路径外的任何网络调用。文件清单文件新增/修改本 PR 切片mobile/src/api/chat/stream.ts修改发送体字段 InternalSearchFiltersmobile/src/chat/agents.ts修改加宽MinimalAgentmobile/src/api/settings.ts修改deep_research_enabledmobile/src/hooks/useChatController.ts修改submit的toolOptions参数 请求体构建mobile/src/chat/tools.ts新增工具契约 谓词mobile/src/chat/sources.ts新增来源契约 过滤器构建mobile/src/components/ui/select-button.tsx.styles.ts新增pill 原语mobile/src/components/ui/switch.tsx新增开关原语mobile/src/icons/{hourglass,globe,cpu,link,server,plug,unplug,slash}.tsx新增8 个图标mobile/src/chat/__tests__/tools.test.ts新增纯逻辑测试mobile/src/components/ui/__tests__/select-button.test.tsx新增状态/矩阵渲染合入时的测试jest 单元测试computeAllowedToolIdsnull vs 列表绝不返回[]、hasSearchToolsAvailable、displayableTools过滤、buildInternalSearchFilters一个断言submit正确线程化toolOptions的 controller 测试SelectButton的 empty/selected/disabled 单元格解析Switch切换图标按默认尺寸渲染。漂移检查点重新确认后端SendMessageRequest字段名/类型models.py中确认/persona仍返回toolsknowledge_sources确认button.styles.ts的矩阵形状由SELECT_COLORS镜像未变。SelectButton/Switch使用port-web-component-to-mobile移植。当前仓库印证这一 PR 的成果在仓库中已经落地。例如 mobile/src/api/chat/stream.ts 的SendMessageBodyL18–33已含allowed_tool_ids?、forced_tool_id?、internal_search_filters?三个可选字段且ChatToolOptionsL35–41已定义mobile/src/chat/agents.ts 的MinimalAgentL20–35已声明tools: ToolSnapshot[]与knowledge_sources: DocumentSource[]mobile/src/chat/tools.ts 已完整实现ToolSnapshot、SEARCH_TOOL_ID等工具 ID 常量、isSearchTool/hasSearchToolsAvailable/displayableTools谓词与computeAllowedToolIds。纯逻辑契约速览来自 03-detailed-design.mdtools.ts的核心契约与 Web 端 web/src/lib/tools/interfaces.ts 的 Tier-2 子集对齐export interface ToolSnapshot { id: number; name: string; display_name: string; description: string; in_code_tool_id: string | null; // 匹配 SEARCH_TOOL_ID 等 mcp_server_id: number | null; // Tier-2 范围从列表排除 MCP 工具 chat_selectable: boolean; // 可见性过滤器 } export const SEARCH_TOOL_ID SearchTool; export const WEB_SEARCH_TOOL_ID WebSearchTool; export const IMAGE_GENERATION_TOOL_ID ImageGenerationTool; export const FILE_READER_TOOL_ID FileReaderTool; // 永远从列表隐藏 export function isSearchTool(t: ToolSnapshot): boolean; export function hasSearchToolsAvailable(tools: ToolSnapshot[]): boolean; // Search 或 WebSearch 存在即可 export function displayableTools(tools: ToolSnapshot[]): ToolSnapshot[]; // chat_selectable、无 MCP、无 FileReader export function computeAllowedToolIds(tools, disabled): number[] | null; // null 后端放行全部一个容易被忽略的陷阱computeAllowedToolIds在没有工具被禁用时必须返回null而不是[]——后端把null视为允许全部而发送[]会禁用一切。这正是仓库 mobile/src/chat/tools.ts 中实现的行为disabledToolIds.length 0时直接返回null。sources.ts的核心契约export type DocumentSource string; // snake_case 线上值web,google_drive,… export interface SourceMeta { icon: IconFunctionComponent; displayName: string; } export const SOURCE_META: RecordDocumentSource, SourceMeta; export function buildInternalSearchFilters(selectedSources): InternalSearchFilters | null; // stream.ts 中的新线上类型 export interface InternalSearchFilters { source_type: DocumentSource[] | null; }ChatToolOptions是线程化进submit()的最终打包对象export interface ChatToolOptions { deepResearch: boolean; allowedToolIds: number[] | null; forcedToolId: number | null; internalSearchFilters: InternalSearchFilters | null; }PR 2深度研究开关走查骨架目标用最简单的控件把 composer→provider→submit 路径端到端跑通。范围内内容useDeepResearchToggle移植 Web 的 ref 守卫逻辑——null→新会话过渡时保留开关状态真实会话切换与 agent 切换时重置Web 源见 web/src/hooks/useDeepResearchToggle.ts。ComposerToolsProvider暂时只含深度研究切片resolveToolOptions()返回deep_research其余字段为 null。ToolbarControls只渲染深度研究SelectButton由deep_research_enabled hasSearchToolsAvailable门槛控制。把ComposerToolsProvider接进ChatSurface在InputBar左侧簇渲染ToolbarControls把resolveToolOptions()线程化进sendWithAttachments→submit。文件清单文件新增/修改本 PR 切片mobile/src/hooks/useDeepResearchToggle.ts新增临时开关 重置mobile/src/state/ComposerToolsProvider.tsx新增provider深度研究切片mobile/src/components/chat/ToolbarControls.tsx新增仅深度研究 pillmobile/src/components/chat/InputBar.tsx修改渲染ToolbarControlsmobile/src/components/chat/ChatSurface.tsx修改provider 线程化选项mobile/src/hooks/__tests__/useDeepResearchToggle.test.ts新增重置矩阵门槛与测试无独立 feature flag——由deep_research_enabled管理端设置门槛关闭时不可见。合入测试jest 重置矩阵null→新会话时保留、真实切换 agent 变化时重置ToolbarControls门槛无设置或无搜索工具时隐藏 pill。手动验证开启 → 发送 → 请求携带deep_research: true。当前仓库印证mobile/src/hooks/useDeepResearchToggle.ts 已实现且完全遵循文档描述的语义——通过previousChatSessionIdref 实现仅当previousId ! null previousId ! chatSessionId才重置并在 agent 变化时重置L25–42mobile/src/components/chat/InputBar.tsx 左侧簇L124–135已经在 paperclip 按钮之后渲染ToolbarControls /。PR 3ActionsPopover —— 工具、强制与启用/禁用目标锚定 Actions 菜单支持工具强制与服务端持久化的启用/禁用。范围内内容popover.tsx锚定原语measureInWindow测量锚点、Portal 渲染、向上展开 屏幕内钳制 maxHeight/滚动、打开时Keyboard.dismiss()、键盘/旋转时重新测量。ActionsPopover.tsx组合Popover持有open/subViewActionLineItem.tsx点击强制带禁用即清除强制守卫尾部Switch启用/禁用搜索深入箭头。useForcedToolsuseAgentPreferencesapi/chat/agentPreferences.ts乐观onMutate/onError/onSettled 防抖。扩展ComposerToolsProviderToolbarControlsActions 触发器 强制工具 pills接线forced_tool_idallowed_tool_ids。为什么这个 PR 无法再拆分锚定Popover没有其他消费者——如果把它与ActionsPopover分开构建会留下一个不可测试的 PR且强制与启用/禁用共享同一行与同一个 provider拆分会产生重复状态。文件清单文件新增/修改本 PR 切片mobile/src/components/ui/popover.tsx新增锚定 popover 原语mobile/src/components/chat/ActionsPopover.tsx新增菜单外壳 主列表mobile/src/components/chat/ActionLineItem.tsx新增工具行强制 启用/禁用mobile/src/hooks/useForcedTools.ts新增单强制状态mobile/src/hooks/useAgentPreferences.ts新增GET 乐观 PATCHmobile/src/api/chat/agentPreferences.ts新增偏好 API 封装mobile/src/api/query-keys.ts修改agentPreferenceskeymobile/src/state/ComposerToolsProvider.tsx修改强制 禁用切片mobile/src/components/chat/ToolbarControls.tsx修改Actions 触发器 强制 pills设备端门槛owner 运行非自动化锚定 popover 在 iOS Android 上经expo prebuild后必须向上打开且不与键盘碰撞、不裁切出屏回退方案 把 popover 容器换成FilePickerSheet底部面板外壳。PR 4来源选择与搜索耦合目标以来源子视图和与 Web 完全一致的搜索↔来源耦合完成 Tier-2。范围内内容SourceSwitchList.tsx返回 全部启用/全部禁用 Switch行SourceIcon.tsx在ActionsPopover内原地替换主体。useConnectorSourcesapi/chat/connectors.tsGET/manage/connector-statususeSourceSelection临时状态自初始化为全部。接线internal_search_filters然后以独立提交添加搜索工具↔来源耦合移植sourcesInitialized守卫 单强制 previouslyEnabledSourcesRef幂等性。填充SOURCE_META默认 agentid 0使用连接器列表。文件清单文件新增/修改本 PR 切片mobile/src/components/chat/SourceSwitchList.tsx新增来源子视图mobile/src/components/chat/SourceIcon.tsx新增来源字形mobile/src/hooks/useConnectorSources.ts新增connector-status 查询mobile/src/api/chat/connectors.ts新增connector-status 包装mobile/src/hooks/useSourceSelection.ts新增选择 耦合mobile/src/api/query-keys.ts修改connectorSourceskeymobile/src/chat/sources.ts修改填充SOURCE_METAmobile/src/components/chat/ActionsPopover.tsx修改挂载子视图 箭头mobile/src/state/ComposerToolsProvider.tsx修改来源切片 过滤器mobile/src/hooks/__tests__/useSourceSelection.test.ts新增耦合 reducer测试与已知缺口jest 测试buildInternalSearchFilters{source_type}vs null耦合 reducer启用来源→固定搜索、禁用最后一个→解除固定、enable-all/disable-all、初始化后无振荡。手动选来源 → 发送 → 请求携带internal_search_filters.source_type。已知缺口联邦连接器EE/federated被推迟——这是文档明确的 Tier-2 缺口。三个 UI 原语的设计要点PR 1 与 PR 3 共同引入的SelectButton、Switch、Popover三个原语是整个功能的外观根基详细设计见 03-detailed-design.mdSelectButton——状态化 pillSelectState empty | selected唯一变体select-light。SELECT_COLORS必须是与BUTTON_COLORSmobile/src/components/ui/button.styles.ts同型的全类型字面量矩阵只用 NativeWind 语义 token 类bg-*、text-*icon与fg分开设置。移动端没有 hover因此 web 的 hover 单元格被折叠resolveSelectState(disabled, pressed)是状态/按压驱动的。foldable也是状态驱动的仅在展开时如深度研究的stateselected渲染标签不做 hover 展开。Switch——roleswitch的Pressable轨道32×18rounded-full reanimated 滑块14×14在2px↔17px间平移选中背景action-link-05。受控组件checked/onCheckedChange。Popover——打开时对锚点measureInWindow记录矩形通过Portal nameactions-popover渲染全屏透明外层点击外部关闭 定位面板bottom windowHeight - anchorY GAP、left clamp(anchorX, GUTTER, screenW - width - GUTTER)、maxHeight anchorY - insets.top - GAP内容放入ScrollView。打开时Keyboard.dismiss()reanimatedFadeIn 从底部原点轻微translateY/scale。这镜像了 Web 端 OpalPopover.Content sidebottom alignstart widthlg约 240px但向上翻转——这是文档明示的、由平台驱动的唯一分歧点底部停靠栏 键盘所致。高风险点与缓解措施plan-challenge 结论04-implementation-plan.md 附带的 plan-challenge 对方案做了六项检查全部通过其中有三处已被识别并缓解的脆弱点值得所有实施者注意搜索工具↔来源耦合可能渲染死循环render-loop——Web 端web/src/lib/searchFilters相关逻辑用sourcesInitialized守卫 仅在不一致时切换的幂等性来防止。缓解先以独立、经过 jest 测试的步骤交付纯来源选择再加耦合。锚定 popover 的键盘/出屏数学——缓解设备端门槛 底部面板外壳回退ActionsPopover内容是渲染器无关的换容器即可。useDeepResearchToggle的 null→新会话保留——缓解逐字移植 ref 守卫 对重置矩阵做单元测试见 mobile/src/hooks/useDeepResearchToggle.ts 的实际实现。其余检查结论可扩展性 PASS工具/来源列表有界三个原语是未来所有菜单的可复用基础设施行业标准 VERIFIED锚定 popover测量触发器→经 Portal 渲染→自动定位不出屏→键盘感知是 2026 年 RN 的标准做法乐观更新使用 TanStack Query 规范的onMutate(cancelsnapshotsetQueryData)/onError(rollback)/onSettled(invalidate) 防抖可维护性 PASS遵循mobile/CLAUDE.md约定原语放components/ui/、聊天组件放components/chat/、纯逻辑放chat/、hooks 放hooks/TanStack Query 以serverUrl为 key结论为PROPER FIX而非补丁——deep_research从硬编码false变为真实开关值三个字段从真实 UI 状态填充disabled_tool_ids持久化到与 Web 相同的服务端记录。测试策略总览移动端使用jest-expo没有 Onyx 容器的移动端 E2E因此测试集中在纯逻辑与两个易死循环的 reducer上锚定 popover 的渲染在设备端验证不在 jest 中纯逻辑mobile/src/chat/tests/computeAllowedToolIds无禁用时 null、部分禁用时列表、绝不[]、hasSearchToolsAvailable、displayableTools剔除 MCP / 非chat_selectable/ FileReader、buildInternalSearchFilters{source_type}vs null。useDeepResearchToggle重置矩阵——null→新会话保留、真实会话切换重置、agent 变化总是重置、切换正确。来源耦合 reducer启用来源固定搜索、禁用最后一个来源解除固定、enable-all/disable-all、initialized后无振荡。useAgentPreferences乐观设置 → PATCH → 失效发送完整disabled_tool_ids数组失败回滚。ToolbarControls门槛deep_research_enabled为 false 或无搜索工具时深度研究 pill 隐藏agent 无可显示工具时 Actions 触发器隐藏。设备端门槛owner 运行expo prebuild后 iOS Android 上锚定 popover 向上打开且不与键盘碰撞/不裁切出屏不稳定则回退到底部面板外壳。测试实现注意jest 中要直接导入叶子组件reanimated barrels 会崩溃 jest runner——这是 mobile/CLAUDE.md 明确的移动端标准。端到端场景验收标尺来自 02-high-level-design.md 的完整验收场景可作为 PR 全部合入后的行为判据用户打开一个 agent 的聊天该 agent 拥有 Search、Web Search、Image Generation 工具且工作区已启用深度研究。输入栏显示 paperclip、sliders Actions 按钮与一个折叠的 hourglass深度研究pill。用户点Actions→ 面板在按钮上方弹出键盘收起以免裁切。用户点Image Generation行 → 高亮强制。用户在Web Search上点启用/禁用开关 → Web Search 被禁用。用户点Search上的箭头 → 面板滑到sources视图。用户关掉两个连接器保留三个点返回。用户点 hourglass pill → 展开为 Deep Research 并高亮。用户输入问题并点发送。请求现在携带deep_research: true、forced_tool_id: image-gen id、allowed_tool_ids: [除 Web Search 外的所有工具]、internal_search_filters: { source_type: [保留的三个连接器] }。启用/禁用选择Web Search 关闭为该 agent 保存到服务器下次打开该 agent 时 Web Search 仍被禁用而强制工具、来源与深度研究 pill 全部重置。当前仓库落地现状值得注意的是本仓库的当前状态显示该路线图的成果已经大面积落地PR 1 中规划的所有核心文件stream.ts的ChatToolOptions/SendMessageBody扩展、mobile/src/chat/agents.ts 的类型加宽、mobile/src/chat/tools.ts 与 mobile/src/chat/sources.ts 的纯逻辑模块以及 PR 2–4 规划的实现文件ComposerToolsProvider、ToolbarControls、ActionsPopover、ActionLineItem、SourceSwitchList、SourceIcon、popover、select-button、switch、useDeepResearchToggle、useForcedTools、useAgentPreferences、useConnectorSources、useSourceSelection均存在于mobile/src/下且行为与文档描述一致如useDeepResearchToggle的 ref 守卫、InputBar左侧簇的ToolbarControls /渲染、computeAllowedToolIds的 null 语义。阅读本路线图时可以把这些源码文件作为每个 PR 的最终形态参照物用文档中的 drift checkpoint 逐一对照验证。结语这份路线图的工程价值这份 PR 路线图的精髓不在于功能本身而在于工程化拆解先铺无运行时表面的地基PR 1再用最薄的端到端切片验证整体形状PR 2 走查骨架随后逐个叠加有状态的功能层PR 3 锚定 popover、PR 4 来源耦合每个 PR 自带范围边界、文件清单、合入测试、设备端门槛与漂移检查点。它同时示范了一套可复用的实践以承重事实锁定零后端改动的前提、以类型加宽代替新增请求、以逐字移植 ref 守卫避免微妙的状态 bug、以乐观更新 防抖处理服务端持久化、以及用on-device gate 渲染器无关回退驯服键盘相邻锚定面板这一 RN 领域的高风险模式。对于任何要在现有架构上增量移植复杂 Web 交互到移动端的团队这份文档都是一个值得对照的范本。【免费下载链接】danswerOpen Source AI Platform - AI Chat with advanced features that works with every LLM项目地址: https://gitcode.com/GitHub_Trending/da/danswer创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表