Appearance
插件开发
插件目录
每个插件是一个独立目录,放置在系统插件目录下(如 src/plugins/<name>/)。一个标准插件包含以下内容:
plugin-name/
├── index.js # 插件注册入口(fastify-plugin)
├── info.json # 插件元信息
├── trigger.json # 安装时生成的触发文件(记录被复制的文件)
├── data/
│ └── index.js # 后台菜单、API 路由、配置分类与配置项声明
├── fields/
│ └── schema.js # 嵌入已有模型的字段定义
├── hook/ # 应用钩子(文件名 = 应用名)
│ ├── music.js
│ ├── video.js
│ └── user.js
├── app/
│ ├── admin/controller/ # 后台控制器
│ └── index/controller/ # 前台控制器
├── library/ # 业务逻辑库
├── loader/ # 后台列表的动态列配置
└── model/ # 插件数据模型(集合名 aod_<name>)info.json
插件元信息声明文件:
json
{
"name": "vip",
"title": "VIP会员",
"intro": "付费会员、等级与点数系统",
"author": "DJAOD",
"website": "https://www.djaod.com",
"version": "1.0.0",
"state": 1,
"install": 1
}| 字段 | 说明 |
|---|---|
name | 插件唯一标识 |
title | 插件标题(展示名) |
intro | 插件简介 |
author / website | 作者与官网 |
version | 版本号 |
state | 状态,1 启用,0 禁用 |
install | 是否已安装,1 已安装 |
data/index.js
插件声明文件,导出以下配置:
AdminRules:后台菜单树(插件后台入口)AdminRoutes:后台 API 路由configTabs:配置分类configList:配置项列表
安装插件时系统据此注册菜单、路由与配置;卸载时据此清理。
fields/schema.js
用于向已有模型嵌入插件字段,例如 VIP 插件向音乐、视频、用户模型追加 vip、vip_level、vip_expiretime 等字段。嵌入式字段无需修改核心模型代码。
loader/
后台通用列表组件的动态列配置,定义表格列、搜索项、操作按钮与接口地址,按 action 名分文件存放。
插件生命周期
插件注册入口 index.js 中使用插件钩子注册生命周期:
js
// 安装
plugin.setHook('install', async () => {
// 注册配置、菜单、路由
});
// 卸载
plugin.setHook('uninstall', async () => {
// 清理配置、菜单、路由
});
// 启用 / 禁用 / 升级
plugin.setHook('enable', async () => {});
plugin.setHook('disable', async () => {});
plugin.setHook('upgrade', async () => {});系统在安装、卸载、启用、禁用、升级时自动调用对应钩子。
钩子函数
钩子是插件与核心系统、插件与应用之间的扩展机制,分为两类:
应用钩子(plugin_hooks)
plugin_hooks 用于扩展指定应用(音乐、视频、用户等),事件点由应用主动触发:
plugin_hooks(应用名, 事件名, 参数)常见事件点:
| 事件名 | 说明 |
|---|---|
formAppend | 后台表单追加字段(如音乐 / 视频表单追加「VIP等级」下拉) |
modelAfter | 模型查询结果追加数据(如为视频附加 VIP 权限信息) |
插件的 hook/ 目录中,以应用名命名的文件(类名 = 应用名),其方法名对应事件名。例如 hook/video.js 中的 formAppend、modelAfter 方法,会在音乐 / 视频相关表单与模型查询时被调用。
以 VIP 插件为例,modelAfter 会在视频模型查询后追加:
js
{
vipInfo: { title, label, icon }, // VIP 等级信息
vip_points: 1, // 是否为点数模式(1 点数模式)
isvip: true, // 用户是否 VIP
isPaid: false // 是否已购买 / 在有效期内
}前端据此控制播放、下载等操作按钮。
全局钩子(setHooks / getHooks)
全局钩子由系统在关键业务节点触发,插件通过 setHooks 监听,按注册顺序串行执行,单钩子超时与错误隔离,不影响主流程。
示例(监听订单支付完成):
js
fastify.setHooks('order_after', async ({ order, paytype, data }) => {
// 支付完成后的处理(如发放积分、赠送权益)
});全局钩子节点包括订单、模型等业务关键位置,具体事件名由各功能模块定义。
按钮权限注册
插件可以在后台列表注册操作按钮,并通过按钮权限控制可见性:
js
// 注册按钮权限
fastify.setAuthButtonsList({ user_list: ['set_vip'] });
// 获取当前管理员可见的按钮
fastify.getAuthButtonsList(request);
// 权限变更后刷新缓存
fastify.clearAuthButtonsCache();按钮权限按角色组规则过滤,管理员重新登录后生效。
开发建议
- 插件目录内新增内容时,遵循「安装时注册、卸载时清理」的原则。
- 嵌入字段使用
fields/schema.js,不要直接修改核心模型。 - 前台功能放在
app/index/controller,后台管理放在app/admin/controller。 - 插件配置统一通过配置分类声明,便于用户后台管理。