Files
st/docs/扩展加载面板.md
2026-02-14 06:20:05 +08:00

72 lines
4.1 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

你的实现逻辑应为扫描Vue 前端获取插件列表,读取每个插件的 manifest.json。识别寻找 settings_file 或类似的字段(或者约定插件根目录下的 settings.html 为面板入口)。渲染:点击插件设置时,由 Vue 动态创建一个 <iframe> 或受控的 DIV 来加载该 HTML。2. 前端实现:插件设置包装组件 (PluginSettingsWrapper.vue)由于 LittleWhiteBox 等插件是基于原生 HTML/JS 编写的,直接注入 Vue 可能会有 CSS 污染。推荐使用 Iframe 沙箱 模式。代码段<template>
<div class="plugin-settings-container">
<div class="flex justify-between items-center mb-4">
<h3 class="text-lg font-bold">{{ plugin.name }}</h3>
<el-switch v-model="isEnabled" @change="togglePlugin" />
</div>
<div v-if="hasSettingsUI" class="settings-iframe-wrapper">
<iframe
ref="settingsIframe"
:src="settingsUrl"
class="w-full h-[500px] border-none"
@load="injectBridge"
></iframe>
</div>
<div v-else class="text-gray-500">
该插件没有独立设置面板。
</div>
</div>
</template>
<script setup>
import { ref, computed, onMounted } from 'vue';
const props = defineProps(['plugin']); // 后端返回的插件对象
const settingsIframe = ref(null);
// 计算 HTML 入口地址:指向你的 Go 后端静态资源接口
const settingsUrl = computed(() => {
return `${import.meta.env.VITE_API_BASE}/plugins/files/${props.plugin.id}/settings.html`;
});
const hasSettingsUI = computed(() => props.plugin.has_settings);
// 核心注入桥接脚本Bridge
const injectBridge = () => {
const frame = settingsIframe.value;
if (!frame) return;
// 向 Iframe 注入一个全局变量,让插件能调用你的系统功能
// 例如LittleWhiteBox 里的 JS 可能会寻找 'SillyTavern' 对象
const bridgeScript = `
window.parent.SillyTavern = {
saveSettings: (data) => {
window.parent.postMessage({ type: 'SAVE_PLUGIN_SETTINGS', data: data }, '*');
},
getSettings: () => ${JSON.stringify(props.plugin.user_settings)}
};
`;
try {
const scriptTag = frame.contentDocument.createElement('script');
scriptTag.textContent = bridgeScript;
frame.contentDocument.head.appendChild(scriptTag);
} catch (e) {
console.error("跨域限制或插件加载失败", e);
}
};
</script>
3. 后端支持 (Go):静态资源与配置下发你的 Go 后端需要能够提供插件目录下的文件访问。Go// Go 伪代码:静态文件分发
r.GET("/plugins/files/:plugin_id/*filepath", func(c *gin.Context) {
pluginID := c.Param("plugin_id")
filePath := c.Param("filepath")
// 从数据库查询该插件的物理路径
basePath := db.GetPluginPath(pluginID)
// 返回对应的 HTML/JS/CSS
c.File(filepath.Join(basePath, filePath))
})
4. 针对 LittleWhiteBox 的适配建议通过分析 LittleWhiteBox 的代码,它包含了大量的模块(如 modules/tts, modules/novel-draw。这些模块通常通过 index.js 加载。如果你要完美支持它需要解决以下两个关键点CSS 样式映射LittleWhiteBox 的样式可能依赖原版酒馆的 CSS 类名(如 .menu_button, .panel。解决方案在你的 Vue 项目中,为插件 iframe 注入一个包含“酒馆兼容层样式”的 CSS 文件,模拟原版的 UI 环境。事件监听 (Event Bus)LittleWhiteBox 里的很多功能(如 modules/event-manager.js是基于事件触发的。解决方案在你的 PluginContext 中实现一个简单的事件中心,当你的 Vue 界面发生“消息发送”、“收到回复”等动作时,通过 postMessage 通知 Iframe 内的插件。5. 文档补全:插件设置渲染规范步骤开发者操作系统行为检测后端扫描 manifest.json发现 settings_file: "settings.html"。入口Vue 点击插件列表中的“设置”图标在右侧弹出 Drawer 或 Modal挂载 PluginSettingsWrapper。握手Iframe 加载完成后执行注入将当前用户的 PgSQL 配置注入插件内存。持久化插件内点击保存插件调用 SillyTavern.saveSettings -> Vue 捕获消息 -> Go 写入 PgSQL。