Skip to main content
Glama
01.插件开发.md11.5 kB
--- title: "插件开发" date: "2022-01-30T10:16:07.000Z" permalink: "/pages/plugin/dev/" --- # 开发准备 * 熟悉Java * 熟悉Spring Boot * 熟悉Vue3、JavaScript(如果涉及到前端的话) # 目录结构 magic-api-plugin-xxx ├─src │ ├─console --- 存放前端源码 │ │ ├─src │ │ │ ├─components --- 存放前端组件信息 │ │ │ ├─i18n --- i18n相关信息 │ │ │ ├─icons --- 图标相关资源 │ │ │ ├─service --- js运行服务 | | | └─magic-api.js --- 前端入口 | | ├─vite.config.js --- 打包配置 | | └─package.json │ └─main │ ├─java │ │ └─org │ │ └─ssssssss │ │ └─magicapi │ │ └─xxx --- 插件后端源码 │ └─resources │ └─META-INF │ └─spring.factories --- spring factory配置 └ pom.xml --- pom.xml pom.xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <!-- 父依赖 --> <parent> <groupId>org.ssssssss</groupId> <artifactId>magic-api-plugins</artifactId> <version>magic-api-lastest-version</version> </parent> <artifactId>magic-api-plugin-xxx</artifactId> <packaging>jar</packaging> <name>magic-api-plugin-xxx</name> <description>magic-api-plugin-xxx</description> <dependencies> <!-- 添加你需要加的依赖 --> </dependencies> <!-- 如果有前端代码的话,则添加下方配置,如果没有则不需要。 --> <build> <plugins> <!-- npm install && npm run build --> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>1.6.0</version> <executions> <execution> <id>exec-npm-install</id> <phase>generate-resources</phase> <goals> <goal>exec</goal> </goals> <configuration> <executable>npm</executable> <arguments> <argument>install</argument> </arguments> <workingDirectory>${basedir}/src/console</workingDirectory> </configuration> </execution> <execution> <id>exec-npm-run-build</id> <phase>generate-resources</phase> <goals> <goal>exec</goal> </goals> <configuration> <executable>npm</executable> <arguments> <argument>run</argument> <argument>build</argument> </arguments> <workingDirectory>${basedir}/src/console</workingDirectory> </configuration> </execution> </executions> </plugin> <plugin> <artifactId>maven-resources-plugin</artifactId> <version>3.2.0</version> <executions> <execution> <id>copy-resource</id> <phase>generate-resources</phase> <goals> <goal>copy-resources</goal> </goals> <configuration> <outputDirectory>${basedir}/target/classes/magic-editor/plugins</outputDirectory> <resources> <resource> <directory>${basedir}/src/console/dist</directory> </resource> </resources> </configuration> </execution> </executions> </plugin> </plugins> </build> </project> Java入口 @Configuration public class MagicAPITaskConfiguration implements MagicPluginConfiguration { @Override public Plugin plugin() { return new Plugin("定时任务"); // 如果有前端的话,需要返回此格式。 // return new Plugin("定时任务", "MagicTask", "magic-task.1.0.0.iife.js"); } /** * 注册Controller,如果有的话 */ @Override public MagicControllerRegister controllerRegister() { return (mapping, configuration) -> mapping.registerController(new MagicAPITaskController(configuration)); } // 在这里你可以定义你需要的Bean。以实现插件机制,关于magic-api支持的,可以查看高级应用中的说明。 } spring.factories org.springframework.boot.autoconfigure.EnableAutoConfiguration=org.ssssssss.magicapi.task.starter.MagicAPITaskConfiguration package.json { "name": "magic-test", "version": "1.0.0", "main": "magic-api.js", "scripts": { "build": "vite build" }, "devDependencies": { "vue": "^3.2.31", "@vitejs/plugin-vue": "^2.2.4", "vite-plugin-svg-icons": "^1.1.0", "vite": "^2.8.6" } } vite.config.js import vue from '@vitejs/plugin-vue' import viteSvgIcons from 'vite-plugin-svg-icons' import path from 'path' import pkg from './package.json' export default { base: './', build: { minify: false, cssCodeSplit: true, // 将组件的 style 打包到 js 文件中 outDir: 'dist', lib: { target: 'esnext', formats: ['iife'], entry: path.resolve(__dirname, 'src/magic-api.js'), name: 'MagicTask', fileName: (format) => `magic-task.${pkg.version}.${format}.js` }, rollupOptions: { // 确保外部化处理那些你不想打包进库的依赖 external: ['vue'], output: { // 在 UMD 构建模式下为这些外部化的依赖提供一个全局变量 globals: { vue: 'Vue' } } } }, plugins: [ vue(), viteSvgIcons({ iconDirs: [path.resolve(process.cwd(), 'src/icons')], symbolId: 'magic-task-[name]' }), ] } 前端入口 magic-api.js import MagicTask from './service/magic-task.js' import localZhCN from './i18n/zh-cn.js' import localEn from './i18n/en.js' import MagicTaskInfo from './components/magic-task-info.vue' import 'vite-plugin-svg-icons/register' export default (opt) => { const i18n = opt.i18n // 添加i18n 国际化信息 i18n.add('zh-cn', localZhCN) i18n.add('en', localEn) return { // 左侧资源 resource: [{ // 资源类型,和后端存储结构一致 type: 'task', // 展示图标 icon: '#magic-task-task', // #开头表示图标在插件中 // 展示名称 title: 'task.name', // 运行服务 service: MagicTask(opt.bus, opt.constants, i18n.format, opt.Message, opt.request), }], // 右侧资源 // datasources: [{ // // 资源类型,和后端存储结构一致 // type: 'redis', // // 展示图标 // icon: '#magic-redis-redis', // #开头表示图标在插件中 // // 展示标题 // title: 'Redis', // // 展示名称 // name: i18n.format('redis.name'), // // 表单组件 // component: MagicDataResourceRedis // }] // 底部工具条 toolbars: [{ // 当打开的资源类型为 task 时显示 type: 'task', // 工具条展示的标题 title: 'task.title', // 展示图标 icon: 'parameter', // 对应的组件 component: MagicTaskInfo, }] } } service.js 左侧资源案例 export default function (bus, constants, $i, Message, request) { return { // svg text getIcon: item => ['TASK', '#9012FE'], // 任务名称 name: $i('task.name'), // 脚本语言 language: 'magicscript', // 执行测试的逻辑 doTest: (opened) => { opened.running = true const info = opened.item const requestConfig = { baseURL: constants.SERVER_URL, url: '/task/execute', method: 'POST', responseType: 'json', headers: {}, withCredentials: true } bus.$emit(Message.SWITCH_TOOLBAR, 'log') requestConfig.headers[constants.HEADER_REQUEST_CLIENT_ID] = constants.CLIENT_ID requestConfig.headers[constants.HEADER_REQUEST_SCRIPT_ID] = opened.item.id requestConfig.headers[constants.HEADER_MAGIC_TOKEN] = constants.HEADER_MAGIC_TOKEN_VALUE // 设置断点 requestConfig.headers[constants.HEADER_REQUEST_BREAKPOINTS] = (opened.decorations || []).filter(it => it.options.linesDecorationsClassName === 'breakpoints').map(it => it.range.startLineNumber).join(',') const fullName = opened.path() bus.status(`开始测试定时任务「${fullName}」`) request.sendPost('/task/execute', { id: info.id }, requestConfig).success(res => { opened.running = false }).end(() => { bus.status(`定时任务「${fullName}」测试完毕`) opened.running = false }) }, // 是否允许执行测试 runnable: true, // 是否需要填写路径 requirePath: true, // 合并 merge: item => item } } 右侧资源案例 export default (request, $i, modal, JavaClass)=> { let findResources // 设置代码提示 JavaClass.setExtensionAttribute('org.ssssssss.magicapi.mongo.MongoModule', () => { return findResources && (findResources('mongo')[0]?.children || []).filter(it => it.key).map(it => { return { name: it.key, type: 'org.ssssssss.magicapi.pro.mongo.MongoModule', comment: it.name } }) || [] }) return { // 注入查找资源的方法 injectResources: fn => findResources = fn, dialogWidth: '1100px', // 创建数据源的dialog宽度 // 执行测试连接 doTest: info => { request.sendJson('/datasource/mongo/test', info).success(res => { if(res === 'ok'){ modal.alert($i('datasource.connected'), $i('datasource.test')) }else { modal.alert($i('datasource.connectFailed', res), $i('datasource.test')) } }) } } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Dwsy/magic-api-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server