开源项目WPS AI插件察元AI文档助手:从 Ribbon 加载到 AI 对话框 URL 拼装 摘要OnAddinLoad 在加载项生命周期早期注册 ApiEvent、恢复模型索引并异步 loadModelList。openAIAssistantDialog 使用 Util.GetUrlPath 与 GetRouterHash 拼接 SPA 地址是与 WPS ShowDialog 强耦合的关键路径。关键词OnAddinLoad;ShowDialog;ribbon扩展阅读与维护提示本篇围绕「从 Ribbon 加载到 AI 对话框 URL 拼装」组织材料。仓库内与主题最直接相关的检索词包括OnAddinLoad、ShowDialog、ribbon。建议在阅读正文所列片段后用 IDE 全局搜索这些符号沿 import 与调用栈向上追问「谁在什么时机调用」而不是只记住单文件路径。摘要所概括的要点为OnAddinLoad 在加载项生命周期早期注册 ApiEvent、恢复模型索引并异步 loadModelList。openAIAssistantDialog 使用 Util.GetUrlPath 与 GetRouterHash 拼接 SPA 地址是与 WPS ShowDialog 强耦合的关键路径。落地到排障时可把现象粗分为三类交叉验证配置是否按预期写入持久化介质WPS COM 上下文是否可用例如是否缺少 ActiveDocument以及网络与证书策略是否拦截了 fetch。本篇涉及的模块通常只覆盖其中一两类需要与相邻篇目拼成完整拼图。教程文件名「12-yuanma-fenceng-yu-AI-bianma-zai-ben-xiangmu.md」仅用于导航与排序不等价于源码模块名。若正文中的行号与本地分支不一致多半因合并导致行偏移此时应以函数名、导出名为锚重新检索团队若维护了生成脚本可在变更大段源码后重新运行以保持摘录大致对齐。本文刻意避免对产品能力做营销式承诺所述行为均以当前仓库可见实现为准。若组织策略要求离线或内网模型应在网关、证书与代理层收口而不是假设加载项能绕过浏览器安全模型。若你同时阅读 docs/chayuan-llm-chain-series可先对照其中的总体链路图理解「请求从 UI 到 chatApi」的次序再回到本教程看数据结构、默认值与修改风险面两者互补不重复堆砌功能列表。正文1. 启动钩子枚举注入、PluginStorage 标记位、文档事件监听均在此处完成。阅读源码摘录时请把它当作「定位入口」而非完整实现同一函数可能在其他分支还有早退条件或 try/catch。修改默认行为前建议用最小文档手工走一遍相关助手或对话框并观察任务清单与日志中的字段是否与预期一致再决定是否做数据迁移或配置重置。// src/components/ribbon.js 第51-93行//这个函数在整个wps加载项中是第一个执行的functionOnAddinLoad(ribbonUI){if(typeofwindow.Application.ribbonUI!object){window.Application.ribbonUIribbonUI}if(typeofwindow.Application.Enum!object){// 如果没有内置枚举值window.Application.EnumUtil.WPS_Enum}//这几个导出函数是给外部业务系统调用的window.openOfficeFileFromSystemDemoSystemDemo.openOfficeFileFromSystemDemo window.InvokeFromSystemDemoSystemDemo.InvokeFromSystemDemo window.Application.PluginStorage.setItem(EnableFlag,false)//往PluginStorage中设置一个标记用于控制两个按钮的置灰window.Application.PluginStorage.setItem(ApiEventFlag,false)//往PluginStorage中设置一个标记用于控制ApiEvent的按钮label// 文档打开或切换时刷新表单模式按钮状态从文档变量/保护类型读取try{if(window.Application.ApiEvent){window.Application.ApiEvent.AddApiEventListener(DocumentOpen,ribbon.OnDocumentOpenForFormMode)window.Application.ApiEvent.AddApiEventListener(WindowActivate,ribbon.OnWindowActivateForFormMode)window.Application.ApiEvent.AddApiEventListener(DocumentBeforeSave,ribbon.OnDocumentBeforeSave)}}catch(e){console.warn(注册文档事件失败:,e)}// 先设置默认模型列表确保有数据显示setDefaultModels()// 从存储恢复选中的模型索引无有效选中时默认选中 OpenAIconststoredIndexwindow.Application.PluginStorage.getItem(selectedModelIndex)if(storedIndex!undefinedstoredIndex!null){constidxparseInt(storedIndex,10)if(!isNaN(idx))selectedModelIndexidx}else{selectedModelIndexgetOpenAIModelIndex(getModelList())}// 然后尝试从接口加载异步loadModelList()returntrue2. AI 助手 URLShowDialog 第一个参数必须是可加载的完整 URL含 hash 与路由段。阅读源码摘录时请把它当作「定位入口」而非完整实现同一函数可能在其他分支还有早退条件或 try/catch。修改默认行为前建议用最小文档手工走一遍相关助手或对话框并观察任务清单与日志中的字段是否与预期一致再决定是否做数据迁移或配置重置。// src/components/ribbon.js 第96-105行functionopenAIAssistantDialog(query{}){constqueryStringnewURLSearchParams(query).toString()constaiUrlUtil.GetUrlPath()Util.GetRouterHash()/ai-assistant${queryString??${queryString}:}window.Application.ShowDialog(aiUrl,察元 AI 助手,900*(window.devicePixelRatio||1),700*(window.devicePixelRatio||1),false)