# 插件API手册
# onPluginReady
- 参数
callback: 初始化完成回调函数,签名:(data) => voiddata.actionName: 动作名称data.actionMatch: 匹配到的动作(ActionMatch | null)data.actionMatchFiles: 匹配到的文件列表(FileItem[])data.requestId: 请求IDdata.reenter: 是否重新进入,对于 singleton 的插件,当再次调用时为 truedata.isView: 是否是快捷面板data.type: 类型,可选值:"action"|"callPage"
- 返回
void: 无返回值
插件应用初始化完成时触发
focusany.onPluginReady((data) => {
// data.actionName 动作名称
// data.actionMatch 动作
// data.actionMatchFiles 匹配到的文件
// data.requestId 请求ID
// data.reenter 是否重新进入,对于 singleton 的插件,当再次调用时为 true
// data.isView 是否是快捷面板
// data.type 类型
});
2
3
4
5
6
7
8
9
# onPluginExit
- 参数
callback: 退出时的回调函数,签名:() => void
- 返回
void: 无返回值
插件应用退出时触发
focusany.onPluginExit(() => {
// 插件即将退出
});
2
3
# onPluginEvent
- 参数
event: 事件类型,可选值:"ClipboardChange"|"UserChange"callback: 事件回调函数data: 事件数据
- 返回
void: 无返回值
插件事件监听
// 剪切板变化
focusany.onPluginEvent('ClipboardChange', (data) => {
console.log('剪切板变化', data);
})
// 用户变化
focusany.onPluginEvent('UserChange', (data) => {
console.log('用户变化', data);
})
2
3
4
5
6
7
8
# offPluginEvent
- 参数
event: 事件类型,可选值:"ClipboardChange"|"UserChange"callback: 要移除的事件回调函数
- 返回
void: 无返回值
移除插件事件
focusany.offPluginEvent('ClipboardChange',cb);
focusany.offPluginEvent('UserChange',cb);
2
# offPluginEventAll
- 参数
event: 事件类型,可选值:"ClipboardChange"|"UserChange"
- 返回
void: 无返回值
移除所有插件事件
focusany.offPluginEventAll('ClipboardChange');
focusany.offPluginEventAll('UserChange');
2
# onMoreMenuClick
- 参数
callback: 菜单点击回调函数data: 点击数据name: 菜单项名称
- 返回
void: 无返回值
插件更多菜单点击事件
focusany.onMoreMenuClick((data) => {
console.log('更多菜单点击', data.name);
});
2
3
# registerHotkey
- 参数
key: 热键定义,支持多种格式:string: 简单热键字符串(如"ctrl+shift+a")string[]: 多个热键字符串数组HotkeyQuickType: 快捷热键类型(如"save")HotkeyType: 热键对象key: 按键modifiers: 修饰键数组,可选值:"Control"|"Option"|"Command"|"Ctrl"|"Alt"|"Win"|"Meta"|"Shift"
HotkeyType[]: 多个热键对象数组
callback: 热键触发回调函数
- 返回
void: 无返回值
注册热键
// 注册单个热键
focusany.registerHotkey('ctrl+shift+a', () => {
console.log('热键触发');
});
// 注册多个热键
focusany.registerHotkey(['ctrl+shift+a', 'cmd+shift+a'], () => {
console.log('热键触发');
});
// 注册快捷热键
focusany.registerHotkey('save', () => {
console.log('保存热键触发');
});
// 注册复杂热键
focusany.registerHotkey({
key: 'a',
modifiers: ['Control', 'Shift']
}, () => {
console.log('热键触发');
});
// 注册多个复杂热键
focusany.registerHotkey([
{ key: 'a', modifiers: ['Control', 'Shift'] },
{ key: 'a', modifiers: ['Command', 'Shift'] }
], () => {
console.log('热键触发');
});
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# unregisterHotkeyAll
- 参数
- 无
- 返回
void: 无返回值
取消注册所有热键
focusany.unregisterHotkeyAll();
# isMainWindowShown
- 参数
- 无
- 返回
boolean: 是否显示主窗口
插件主窗口是否显示
focusany.isMainWindowShown();
# hideMainWindow
- 参数
- 无
- 返回
boolean: 操作是否成功
隐藏插件主窗口
focusany.hideMainWindow();
# showMainWindow
- 参数
- 无
- 返回
boolean: 操作是否成功
显示插件主窗口
focusany.showMainWindow();
# isFastPanelWindowShown
- 参数
- 无
- 返回
boolean: 快捷面板窗口是否显示
快捷面板窗口是否显示
focusany.isFastPanelWindowShown();
# showFastPanelWindow
- 参数
- 无
- 返回
boolean: 操作是否成功
显示快捷面板窗口
focusany.showFastPanelWindow();
# hideFastPanelWindow
- 参数
- 无
- 返回
boolean: 操作是否成功
隐藏快捷面板窗口
focusany.hideFastPanelWindow();
# setExpendHeight
- 参数
height: 插件高度(像素)
- 返回
void: 无返回值
设置插件的高度
focusany.setExpendHeight(300);
# setSubInput
- 参数
onChange: 输入变化回调函数keywords: 输入的关键字
placeholder: 输入框占位符文本(可选)isFocus: 是否自动聚焦(可选)isVisible: 是否显示(可选)
- 返回
boolean: 设置是否成功
设置输入框监听
focusany.setSubInput((keywords) => {
console.log('输入变化', keywords);
}, '请输入关键字', true, true);
2
3
# removeSubInput
- 参数
- 无
- 返回
boolean: 移除是否成功
移除输入框监听
focusany.removeSubInput();
# setSubInputValue
- 参数
value: 要设置的输入框值
- 返回
boolean: 设置是否成功
设置子输入框的值
focusany.setSubInputValue('测试');
# subInputBlur
- 参数
- 无
- 返回
boolean: 操作是否成功
子输入框失去焦点
focusany.subInputBlur();
# getPluginRoot
- 参数
- 无
- 返回
string: 插件根目录路径
获取插件根目录
focusany.getPluginRoot();
# getPluginConfig
- 参数
- 无
- 返回
object | null: 插件配置对象name: 插件名称title: 插件标题version: 插件版本logo: 插件图标
获取插件配置文件 config.json
const config = focusany.getPluginConfig();
// config.name 插件名称
// config.title 插件标题
// config.version 插件版本
// config.logo 插件图标
2
3
4
5
# getPluginInfo
- 参数
- 无
- 返回
object: 插件信息对象nodeIntegration: 是否启用Node集成preloadBase: 预加载基础路径preload: 预加载文件路径main: 主文件路径mainView: 主视图文件路径width: 窗口宽度height: 窗口高度autoDetach: 是否自动分离singleton: 是否单例模式zoom: 缩放比例
获取插件信息
focusany.getPluginInfo();
# getPluginEnv
- 参数
- 无
- 返回
"dev" | "prod": 插件运行环境
获取插件环境
// dev 或 prod
focusany.getPluginEnv();
2
# getQuery
- 参数
requestId: 请求ID
- 返回
SearchQuery: 查询信息对象keywords: 搜索关键字currentFiles: 当前文件列表(可选)currentImage: 当前图片(可选)currentText: 当前文本(可选)
获取插件查询信息
focusany.onPluginReady((data) => {
const query = focusany.getQuery(data.requestId);
// query.keywords 关键字
// query.currentFiles 当前文件列表
// query.currentImage 当前图片
// query.currentText 当前文本
});
2
3
4
5
6
7
# createBrowserWindow
- 参数
url: 窗口加载的URL路径options: 窗口初始化选项(BrowserWindow.InitOptions)callback: 窗口创建完成回调函数(可选)
- 返回
BrowserWindow.WindowInstance: 窗口实例
创建窗口
const browserWindow = focusany.createBrowserWindow('path/to/page.html', {
width: 800,
height: 600,
}, () => {
console.log('窗口创建完成');
});
2
3
4
5
6
# outPlugin
- 参数
- 无
- 返回
boolean: 操作是否成功
关闭插件
focusany.outPlugin();
# isDarkColors
- 参数
- 无
- 返回
boolean: 是否为暗色主题
是否是暗色主题
focusany.isDarkColors();
# showUserLogin
- 参数
- 无
- 返回
void: 无返回值
显示用户登录窗口
focusany.showUserLogin();
# getUser
- 参数
- 无
- 返回
object: 用户信息对象isLogin: 是否已登录avatar: 用户头像nickname: 用户昵称vipFlag: 会员标识deviceCode: 设备代码openId: 用户OpenId
获取用户
const user = focusany.getUser();
// user.isLogin 是否登录
// user.avatar 头像
// user.nickname 昵称
// user.vipFlag 会员标识
// user.deviceCode 设备ID
// user.openId 用户OpenId,每个用户对每个插件的标识唯一
2
3
4
5
6
7
# getUserAccessToken
- 参数
- 无
- 返回
Promise<object>: 访问令牌信息token: 访问令牌expireAt: 过期时间戳
获取用户访问令牌
const accessToken = await focusany.getUserAccessToken();
// accessToken.token 访问令牌
// accessToken.expireAt 过期时间
2
3
# listGoods
- 参数
query: 查询参数(可选)ids: 商品ID数组(可选)
- 返回
Promise<array>: 商品列表id: 商品IDtitle: 商品标题cover: 商品封面priceType: 价格类型("fixed"|"dynamic")fixedPrice: 固定价格description: 商品描述
获取商品列表
const goods = await focusany.listGoods();
结果示例
[
{
"id": "goodsId",
"title": "商品名称",
"cover": "商品封面",
// 商品价格类型 fixed: 固定价格,dynamic: 动态价格
"priceType": "fixed",
// 固定价格
"fixedPrice": "0.01",
"description": "商品描述"
}
]
2
3
4
5
6
7
8
9
10
11
12
# openGoodsPayment
- 参数
options: 订单参数goodsId: 插件商品IDprice: 插件商品价格(可选,动态价格商品需传入)outOrderId: 第三方订单号(可选,最大长度64字符)outParam: 参数数据(可选,长度不超过200字符)
- 返回
Promise<object>: 支付结果paySuccess: 是否支付成功
创建订单并显示
const result = await focusany.openGoodsPayment({
// 插件商品ID
goodsId: 'xxx',
// 插件商品价格,固定价格商品无需传入,动态价格商品需传入价格,如 0.01
price: '0.01',
// 第三方订单号,字符串,最大长度 64 字符
outOrderId: 'xxxx',
// 参数数据,长度不超过 200 字符
outParam: 'xxxx',
});
// result.paySuccess 是否支付成功,注意,支付是否成功需要依赖服务端的回调,此处仅作参考
2
3
4
5
6
7
8
9
10
11
# queryGoodsOrders
- 参数
options: 查询参数goodsId: 插件商品ID(可选)page: 分页页码,从1开始(可选)pageSize: 分页大小,默认10(可选)
- 返回
Promise<object>: 订单查询结果page: 当前页数total: 总订单数records: 订单列表id: 订单号goodsId: 商品IDstatus: 订单状态("Paid"|"Unpaid")
查询插件商品订单
const result = await focusany.queryGoodsOrders({
// 插件商品ID,可选
goodsId: 'xxx',
// 分页页码,从 1 开始,可选
page: 1,
// 分页大小,可选,默认是 10
pageSize: 10,
})
2
3
4
5
6
7
8
结果示例
{
"total": 1,
"page": 1,
"records": [
{
// 订单号
"id": "xxxx",
// 插件商品ID
"goodsId": "xxx",
// 状态 Paid: 已支付, Unpaid: 未支付
"status": "Paid"
}
]
}
2
3
4
5
6
7
8
9
10
11
12
13
14
# apiPost
- 参数
url: 请求URLbody: 请求体数据option: 请求选项
- 返回
Promise<object>: 响应结果code: 状态码msg: 消息data: 响应数据
请求官方接口
const result = await focusany.apiPost('/api/test', { data: 'test' }, {});
// result.code 状态码
// result.msg 消息
// result.data 数据
2
3
4
# setAction
- 参数
action: 插件动作配置,支持单个或数组fullName: 完整名称(可选)name: 动作名称title: 动作标题matches: 匹配规则数组platform: 支持的平台数组(可选,"win"|"osx"|"linux")icon: 图标(可选)type: 动作类型(可选,"command"|"web"|"code"|"backend")
- 返回
boolean: 设置是否成功
动态设置插件动作
设置一个动作
focusany.setAction({
name: 'actionName',
title: '动作名称',
icon: 'icon',
type: 'web', // command | web | code | backend
platform: ['win', 'osx', 'linux'], // 支持的平台
matches: [
{
type: 'text',
text: '匹配文本',
minLength: 1,
maxLength: 100
}
]
})
2
3
4
5
6
7
8
9
10
11
12
13
14
15
设置多个动作
focusany.setAction([
{
name: 'actionName1',
title: '动作名称1',
icon: 'icon1',
type: 'web',
matches: []
},
{
name: 'actionName2',
title: '动作名称2',
icon: 'icon2',
type: 'command',
matches: []
},
]);
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# removeAction
- 参数
name: 要移除的动作名称
- 返回
boolean: 移除是否成功
移除插件动作
focusany.removeAction('actionName');
# getActions
- 参数
names: 动作名称数组(可选)
- 返回
PluginAction[]: 插件动作数组
获取插件动作
focusany.getActions();
示例结果
[
{
"fullName": "完整名称",
"name": "actionName",
"title": "动作名称",
"icon": "icon",
"type": "web",
}
]
2
3
4
5
6
7
8
9
# redirect
- 参数
keywordsOrAction: 关键字或动作名称,支持字符串或字符串数组query: 查询参数(可选)keywords: 搜索关键字currentFiles: 当前文件列表(可选)currentImage: 当前图片(可选)currentText: 当前文本(可选)
- 返回
void: 无返回值
打开插件动作
// 通过动作名称打开
focusany.redirect('actionName');
// 通过关键字打开
focusany.redirect('关键字');
// 通过多个关键字打开
focusany.redirect(['关键字1', '关键字2']);
// 带查询参数打开
focusany.redirect('actionName', {
keywords: '搜索关键字',
currentFiles: [], // 当前文件列表
currentImage: '', // 当前图片
currentText: '' // 当前文本
});
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# showToast
- 参数
body: 提示内容options: 提示选项(可选)duration: 显示持续时间(毫秒,可选)status: 提示状态(可选,"info"|"success"|"error")
- 返回
void: 无返回值
显示提示
focusany.showToast('提示内容', { duration: 3000, status: 'info' });
# showNotification
- 参数
body: 通知内容clickActionName: 点击通知时执行的动作名称(可选)
- 返回
void: 无返回值
显示通知
// 显示通知
focusany.showNotification('通知内容');
// 显示通知,点击执行动作
focusany.showNotification('通知内容','clickActionName');
2
3
4
# showMessageBox
- 参数
message: 消息内容options: 消息框选项title: 消息框标题(可选)yes: 确定按钮文本(可选)no: 取消按钮文本(可选)
- 返回
boolean: 如果点击"是"返回 true,如果点击"否"返回 false
显示消息框
const result = focusany.showMessageBox('消息内容', { title: '消息标题', yes: '确定', no: '取消' });
// result 为 true 或 false
2
# showOpenDialog
- 参数
options: 文件选择框选项title: 对话框标题(可选)defaultPath: 默认路径(可选)buttonLabel: 按钮标签(可选)filters: 文件过滤器数组(可选)name: 过滤器名称extensions: 文件扩展名数组
properties: 属性数组(可选)message: 消息(可选)securityScopedBookmarks: 安全范围书签(可选)
- 返回
string[] | undefined: 选择的文件路径数组
打开文件选择框
const result = focusany.showOpenDialog({
title: '选择文件',
defaultPath: '/home/user',
buttonLabel: '选择',
filters: [
{ name: '图片', extensions: ['jpg', 'png', 'gif'] },
{ name: '文档', extensions: ['pdf', 'doc', 'docx'] }
],
properties: ['openFile', 'multiSelections'],
message: '请选择文件',
securityScopedBookmarks: false
});
// result 为文件路径数组
2
3
4
5
6
7
8
9
10
11
12
13
# showSaveDialog
- 参数
options: 文件保存框选项title: 对话框标题(可选)defaultPath: 默认路径(可选)buttonLabel: 按钮标签(可选)filters: 文件过滤器数组(可选)name: 过滤器名称extensions: 文件扩展名数组
message: 消息(可选)nameFieldLabel: 名称字段标签(可选)showsTagField: 标签字段(可选)properties: 属性数组(可选)securityScopedBookmarks: 安全范围书签(可选)
- 返回
string | undefined: 保存的文件路径
打开文件保存框
const result = focusany.showSaveDialog({
title: '保存文件',
defaultPath: '/home/user/document.pdf',
buttonLabel: '保存',
filters: [
{ name: '图片', extensions: ['jpg', 'png', 'gif'] },
{ name: '文档', extensions: ['pdf', 'doc', 'docx'] }
],
message: '选择保存位置',
nameFieldLabel: '文件名',
showsTagField: '标签',
properties: ['showHiddenFiles', 'createDirectory'],
securityScopedBookmarks: false
});
// result 为保存的文件路径
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# screenCapture
- 参数
callback: 截图完成回调函数imgBase64: 截图的Base64编码字符串
- 返回
void: 无返回值
截图
focusany.screenCapture((imgBase64) => {
console.log('截图文件',imgBase64);
});
2
3
# getNativeId
- 参数
- 无
- 返回
string: 设备ID
获取设备ID
focusany.getNativeId();
# getAppVersion
- 参数
- 无
- 返回
string: 软件版本号
获取软件版本
focusany.getAppVersion();
# getPath
- 参数
name: 路径名称,可选值:"home"|"appData"|"userData"|"temp"|"exe"|"desktop"|"documents"|"downloads"|"music"|"pictures"|"videos"|"logs"
- 返回
string: 对应的系统路径
获取路径
// 获取用户目录
focusany.getPath('home');
// 获取应用数据目录
focusany.getPath('appData');
// 获取用户数据目录
focusany.getPath('userData');
// 获取临时目录
focusany.getPath('temp');
// 获取应用目录
focusany.getPath('exe');
// 获取桌面目录
focusany.getPath('desktop');
// 获取文档目录
focusany.getPath('documents');
// 获取下载目录
focusany.getPath('downloads');
// 获取音乐目录
focusany.getPath('music');
// 获取图片目录
focusany.getPath('pictures');
// 获取视频目录
focusany.getPath('videos');
// 获取日志目录
focusany.getPath('logs');
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# getFileIcon
- 参数
path: 文件路径
- 返回
string: 文件图标的Base64编码
获取文件图标
focusany.getFileIcon('path.txt');
# copyFile
- 参数
file: 文件路径,支持字符串或字符串数组
- 返回
boolean: 复制是否成功
复制文件到剪贴板
// 复制单个文件
focusany.copyFile('/path/to/file.txt');
// 复制多个文件
focusany.copyFile(['/path/to/file1.txt', '/path/to/file2.txt']);
2
3
4
5
# copyImage
- 参数
image: 图片路径或Base64编码
- 返回
boolean: 复制是否成功
复制图片到剪贴板
focusany.copyImage('/path/to/image.png');
# copyText
- 参数
text: 要复制的文本
- 返回
boolean: 复制是否成功
复制文本到剪贴板
focusany.copyText('text');
# getClipboardText
- 参数
- 无
- 返回
string: 剪贴板中的文本内容
获取剪贴板文本
// 输出剪贴板文本
const result = focusany.getClipboardText();
2
# getClipboardImage
- 参数
- 无
- 返回
string: 剪贴板中图片的Base64编码
获取剪贴板图片
// 输出图片的 base64 编码
const result = focusany.getClipboardImage();
2
# getClipboardFiles
- 参数
- 无
- 返回
FileItem[]: 剪贴板中的文件列表name: 文件名isDirectory: 是否为目录isFile: 是否为文件path: 文件路径fileExt: 文件扩展名
获取剪贴板文件
// 输出剪贴板文件
const result = focusany.getClipboardFiles();
2
结果示例
[
{
"name": "文件名",
"isDirectory": false,
"isFile": true,
"path": "文件路径",
"fileExt": "文件扩展名",
}
]
2
3
4
5
6
7
8
9
# listClipboardItems 剪贴板历史
- 参数
option: 选项(可选)limit: 限制返回数量(可选)
- 返回
Promise<array>: 剪贴板历史列表type: 类型("file"|"image"|"text")timestamp: 时间戳files: 文件列表(可选)image: 图片(可选)text: 文本(可选)
获取剪贴板历史
const items = await focusany.listClipboardItems({ limit: 10 });
# deleteClipboardItem 删除剪贴板项
- 参数
timestamp: 要删除的时间戳
- 返回
Promise<void>: 无返回值
根据时间戳删除剪贴板项
await focusany.deleteClipboardItem(1628760000000);
# clearClipboardItems 清空剪贴板
- 参数
- 无
- 返回
Promise<void>: 无返回值
清空剪贴板历史
await focusany.clearClipboardItems();
# shellOpenPath
- 参数
fullPath: 文件完整路径
- 返回
void: 无返回值
使用默认的应用打开文件
focusany.shellOpenPath('/path/to/file.doc');
# shellShowItemInFolder
- 参数
fullPath: 文件完整路径
- 返回
void: 无返回值
在文件管理器中显示文件
focusany.shellShowItemInFolder('/path/to/file.txt');
# shellOpenExternal
- 参数
url: 要打开的链接URL
- 返回
void: 无返回值
打开链接
focusany.shellOpenExternal('https://focusany.com');
# shellBeep
- 参数
- 无
- 返回
void: 无返回值
播放提示音
focusany.shellBeep();
# simulate 模拟操作
# simulate.keyboardTap 模拟按键
- 参数
key: 按键modifiers: 修饰键数组,可选值:"ctrl"|"shift"|"command"|"option"|"alt"
- 返回
Promise<void>: 无返回值
模拟键盘按键
// 模拟按键组合
await focusany.simulate.keyboardTap('a', ['ctrl', 'shift']);
// 支持的修饰键: 'ctrl', 'shift', 'command', 'option', 'alt'
await focusany.simulate.keyboardTap('c', ['ctrl']);
await focusany.simulate.keyboardTap('v', ['command']);
2
3
4
5
6
# simulate.typeString 模拟输入
- 参数
text: 要输入的文本
- 返回
Promise<void>: 无返回值
模拟输入字符串
await focusany.simulate.typeString('Hello World');
# simulate.mouseToggle 鼠标按下
- 参数
type: 动作类型("down"|"up")button: 鼠标按钮("left"|"right"|"middle")
- 返回
Promise<void>: 无返回值
模拟鼠标按下或松开
await focusany.simulate.mouseToggle('down', 'left');
await focusany.simulate.mouseToggle('up', 'left');
2
# simulate.mouseMove 鼠标移动
- 参数
x: X坐标y: Y坐标
- 返回
Promise<void>: 无返回值
模拟鼠标移动
await focusany.simulate.mouseMove(100, 200);
# simulate.mouseClick 鼠标点击
- 参数
button: 鼠标按钮("left"|"right"|"middle")double: 是否双击(可选)
- 返回
Promise<void>: 无返回值
模拟鼠标点击
await focusany.simulate.mouseClick('left');
await focusany.simulate.mouseClick('left', true); // 双击
2
# getCursorScreenPoint
- 参数
- 无
- 返回
object: 鼠标位置坐标x: X坐标y: Y坐标
获取鼠标位置
// 输出 {x: 100, y: 200}
const result = focusany.getCursorScreenPoint();
2
# getDisplayNearestPoint
- 参数
point: 坐标点x: X坐标y: Y坐标
- 返回
any: 显示器信息对象
获取指定位置最近的显示器信息
const result = focusany.getDisplayNearestPoint({ x: 100, y: 200 });
输出示例
{
"id": "显示器ID",
"bounds": {
"x": 0,
"y": 0,
"width": 1920,
"height": 1080
},
"workArea": {
"x": 0,
"y": 0,
"width": 1920,
"height": 1080
},
"scaleFactor": 1.0
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# isMacOs
- 参数
- 无
- 返回
boolean: 是否为MacOS系统
是否是MacOS
focusany.isMacOs();
# isWindows
- 参数
- 无
- 返回
boolean: 是否为Windows系统
是否是Windows
focusany.isWindows();
# isLinux
- 参数
- 无
- 返回
boolean: 是否为Linux系统
是否是Linux
focusany.isLinux();
# getPlatformArch
- 参数
- 无
- 返回
"x86" | "arm64" | null: 平台架构
获取平台架构
// 返回值: 'x86' | 'arm64' | null
const arch = focusany.getPlatformArch();
2
# sendBackendEvent
- 参数
event: 事件名称data: 事件数据(可选)option: 选项(可选)timeout: 超时时间(毫秒)
- 返回
Promise<any>: 事件响应数据
发送后端事件
// 发送事件
focusany.sendBackendEvent('event', { data }, { timeout: 3000 });
// 发送事件并等待响应
const result = await focusany.sendBackendEvent('event', { data }, { timeout: 3000 });
2
3
4
5
# registerCallPage
- 参数
type: 类型callback: 回调函数resolve: 解决函数data: 输出数据
reject: 拒绝函数error: 错误信息
data: 输入数据
option: 选项(可选)timeout: 超时时间(毫秒)
- 返回
void: 无返回值
在 web 中注册后端调用器
focusany.registerCallPage('type', (resolve, reject, data) => {
// 处理数据
resolve({ result: 'success' });
}, { timeout: 5000 });
2
3
4
# callPage
- 参数
type: 类型data: 数据(可选)option: 选项(可选)waitReadyTimeout: 等待就绪超时时间(毫秒,默认 10000)timeout: 超时时间(毫秒,默认 60000)showWindow: 是否显示窗口(默认 true)autoClose: 是否自动关闭(默认 true)
- 返回
Promise<any>: 响应数据
从后端脚本调用后端
const result = await focusany.callPage('type', { input: 'data' }, {
waitReadyTimeout: 10000,
timeout: 60000,
showWindow: true,
autoClose: true
});
2
3
4
5
6
# llmListModels
- 参数
- 无
- 返回
Promise<array>: 大语言模型列表providerId: 提供商IDproviderLogo: 提供商图标providerTitle: 提供商名称modelId: 模型IDmodelName: 模型名称
获取大语言模型列表
const models = await focusany.llmListModels();
// models 为模型列表
2
结果示例
[
{
"providerId": "openai",
"providerLogo": "https://example.com/logo.png",
"providerTitle": "OpenAI",
"modelId": "gpt-3.5-turbo",
"modelName": "GPT-3.5 Turbo"
}
]
2
3
4
5
6
7
8
9
# llmChat
- 参数
callInfo: 调用信息providerId: 提供商IDmodelId: 模型IDmessage: 消息内容
- 返回
Promise<object>: 对话响应结果code: 状态码msg: 消息data: 响应数据(可选)message: 回复消息
调用大语言模型对话
const result = await focusany.llmChat({
providerId: 'openai',
modelId: 'gpt-3.5-turbo',
message: '你好'
});
// result.code 状态码
// result.msg 消息
// result.data.message 回复内容
2
3
4
5
6
7
8
# logInfo
- 参数
label: 日志标签data: 日志数据(可选)
- 返回
void: 无返回值
写入信息日志
focusany.logInfo('日志标签', { data: '数据' });
# logError
- 参数
label: 错误标签data: 错误数据(可选)
- 返回
void: 无返回值
写入错误日志
focusany.logError('错误标签', { error: '错误信息' });
# logPath
- 参数
- 无
- 返回
Promise<string>: 日志文件路径
获取日志文件路径
const logPath = await focusany.logPath();
# logShow
- 参数
- 无
- 返回
void: 无返回值
显示日志文件
focusany.logShow();
# addLaunch 添加启动
- 参数
keyword: 关键字name: 名称hotkey: 热键配置key: 按键modifiers: 修饰键数组
- 返回
Promise<void>: 无返回值
添加启动项
await focusany.addLaunch('test', '测试应用', {
key: 'T',
modifiers: ['Control', 'Shift']
});
2
3
4
# removeLaunch 移除启动
- 参数
keywords: 关键字
- 返回
void: 无返回值
移除启动项
focusany.removeLaunch('test');
# activateLatestWindow 激活最新窗口
- 参数
- 无
- 返回
Promise<void>: 无返回值
激活最新使用的窗口
await focusany.activateLatestWindow();
# db
数据库操作
# db.put
- 参数
doc: 文档对象(DbDoc类型)_id: 文档ID_rev: 文档版本(可选)
- 返回
DbReturn: 操作结果id: 文档IDrev: 文档版本(可选)ok: 操作是否成功(可选)error: 是否有错误(可选)name: 错误名称(可选)message: 错误消息(可选)
添加文档
focusany.db.put(doc);
# db.get
- 参数
id: 文档ID
- 返回
DbDoc<T> | null: 文档对象或null
获取文档
focusany.db.get(id);
# db.remove
- 参数
doc: 文档ID字符串或文档对象
- 返回
DbReturn: 操作结果
删除文档
focusany.db.remove(doc);
# db.bulkDocs
- 参数
docs: 文档对象数组
- 返回
DbReturn[]: 操作结果数组
批量添加文档
focusany.db.bulkDocs(docs);
# db.allDocs
- 参数
key: 键名(可选)
- 返回
DbDoc<T>[]: 文档数组
批量获取文档
focusany.db.allDocs(key);
# db.postAttachment
- 参数
docId: 文档IDattachment: 附件数据(Uint8Array)type: 附件类型
- 返回
DbReturn: 操作结果
保存附件
focusany.db.postAttachment(docId, attachment, type);
# db.getAttachment
- 参数
docId: 文档ID
- 返回
Uint8Array | null: 附件数据或null
获取附件
focusany.db.getAttachment(docId);
# db.getAttachmentType
- 参数
docId: 文档ID
- 返回
string | null: 附件类型或null
获取附件类型
focusany.db.getAttachmentType(docId);
# dbStorage
本地存储
# dbStorage.setItem
- 参数
key: 存储键名value: 存储值
- 返回
void: 无返回值
设置存储
focusany.dbStorage.setItem('key', 'value');
focusany.dbStorage.setItem('key', { data: 'object' });
2
# dbStorage.getItem
- 参数
key: 存储键名
- 返回
T: 存储的值
获取存储
const value = focusany.dbStorage.getItem('key');
const object = focusany.dbStorage.getItem('key');
2
# dbStorage.removeItem
- 参数
key: 存储键名
- 返回
void: 无返回值
移除存储
focusany.dbStorage.removeItem('key');
# setRemoteWebRuntime
- 参数
info: 运行时信息userAgent: 用户代理字符串urlMap: URL映射对象types: 类型数组domains: 域名数组blocks: 阻止列表数组
- 返回
Promise<undefined>: 无返回值
设置远程Web运行时
await focusany.setRemoteWebRuntime({
userAgent: 'Mozilla/5.0...',
urlMap: {
'example.com': 'https://proxy.example.com'
},
types: ['text/html', 'application/json'],
domains: ['example.com', 'api.example.com'],
blocks: ['ads.example.com']
});
2
3
4
5
6
7
8
9
# file
文件操作
# file.exists
- 参数
path: 文件或目录路径
- 返回
Promise<boolean>: 是否存在
判断文件或目录是否存在
const exists = await focusany.file.exists('/path/to/file.txt');
# file.read
- 参数
path: 文件路径
- 返回
Promise<string>: 文件内容
读取文件内容
const content = await focusany.file.read('/path/to/file.txt');
# file.write
- 参数
path: 文件路径data: 文件内容
- 返回
Promise<void>: 无返回值
写入文件内容
await focusany.file.write('/path/to/file.txt', 'file content');
# file.remove
- 参数
path: 文件或目录路径
- 返回
Promise<void>: 无返回值
删除文件或目录
await focusany.file.remove('/path/to/file.txt');
# file.ext
- 参数
path: 文件路径
- 返回
Promise<string>: 文件扩展名
获取文件后缀
const ext = await focusany.file.ext('/path/to/file.txt'); // 返回 '.txt'
# file.writeTemp
- 参数
ext: 文件扩展名data: 文件数据,支持字符串或Uint8Arrayoption: 选项(可选)isBase64: 是否为Base64数据(可选)
- 返回
Promise<string>: 临时文件路径
保存文件到临时路径
const tempPath = await focusany.file.writeTemp('txt', 'file content');
const tempPath2 = await focusany.file.writeTemp('png', base64Data, { isBase64: true });
2
# fad
快捷文件操作
# fad.read
- 参数
type: 文件类型path: 文件路径
- 返回
Promise<any>: 文件内容
读取快捷文件内容
const data = await focusany.fad.read('type', '/path/to/file');
# fad.write
- 参数
type: 文件类型path: 文件路径data: 文件数据
- 返回
Promise<void>: 无返回值
写入快捷文件内容
await focusany.fad.write('type', '/path/to/file', { data: 'content' });
# view
智能区域
# view.setHeight
- 参数
height: 高度(像素)
- 返回
void: 无返回值
设置快捷面板当前插件渲染区域的高度
focusany.view.setHeight(300);
# view.getHeight
- 参数
- 无
- 返回
Promise<number>: 当前高度
获取快捷面板当前插件渲染区域的高度
const height = await focusany.view.getHeight();
# detach
分离窗口
# detach.setTitle
- 参数
title: 窗口标题
- 返回
void: 无返回值
设置分离窗口的标题
focusany.detach.setTitle('窗口标题');
# detach.setOperates
- 参数
operates: 操作按钮数组name: 操作名称title: 操作标题click: 点击回调函数
- 返回
void: 无返回值
设置分离窗口的操作按钮
focusany.detach.setOperates([
{
name: 'save',
title: '保存',
click: () => {
console.log('保存按钮点击');
}
},
{
name: 'close',
title: '关闭',
click: () => {
console.log('关闭按钮点击');
}
}
]);
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# detach.setPosition
- 参数
position: 窗口位置,可选值:"center"|"right-bottom"|"left-top"|"right-top"|"left-bottom"
- 返回
void: 无返回值
设置分离窗口的位置
// 可选位置: 'center' | 'right-bottom' | 'left-top' | 'right-top' | 'left-bottom'
focusany.detach.setPosition('center');
2
# detach.setAlwaysOnTop
- 参数
alwaysOnTop: 是否置顶
- 返回
void: 无返回值
设置分离窗口是否置顶
focusany.detach.setAlwaysOnTop(true);
# detach.setSize
- 参数
width: 窗口宽度height: 窗口高度
- 返回
void: 无返回值
设置分离窗口的大小
focusany.detach.setSize(800, 600);
# util
工具类
# util.randomString
- 参数
length: 随机字符串长度
- 返回
string: 随机字符串
生成随机字符串
const randomStr = focusany.util.randomString(10);
# util.bufferToBase64
- 参数
buffer: Uint8Array类型的数据
- 返回
string: Base64编码字符串
Buffer 转 Base64
const base64 = focusany.util.bufferToBase64(buffer);
# util.base64ToBuffer
- 参数
base64: Base64编码字符串
- 返回
Uint8Array: Buffer数据
Base64 转 Buffer
const buffer = focusany.util.base64ToBuffer('base64string');
# util.datetimeString
- 参数
- 无
- 返回
string: 当前时间戳字符串
获取当前时间戳字符串
const datetime = focusany.util.datetimeString();
# util.base64Encode
- 参数
data: 要编码的数据
- 返回
string: Base64编码字符串
数据转 Base64
const encoded = focusany.util.base64Encode({ data: 'test' });
# util.base64Decode
- 参数
data: Base64编码字符串
- 返回
any: 解码后的数据
Base64 转数据
const decoded = focusany.util.base64Decode('encodedString');
# util.md5
- 参数
data: 要计算MD5的字符串
- 返回
string: MD5哈希值
MD5 摘要
const hash = focusany.util.md5('input string');
# util.save
- 参数
filename: 文件名data: 文件数据,支持字符串或Uint8Arrayoption: 选项(可选)isBase64: 是否为Base64数据(可选)
- 返回
boolean: 保存是否成功
保存文件
// 保存文本文件
focusany.util.save('filename.txt', 'text content');
// 保存Base64数据
focusany.util.save('filename.png', 'base64data', { isBase64: true });
// 保存Buffer数据
focusany.util.save('filename.bin', bufferData);
2
3
4
5
6
7
8