# 插件API手册

# onPluginReady

  • 参数
    • callback: 初始化完成回调函数,签名:(data) => void
      • data.actionName: 动作名称
      • data.actionMatch: 匹配到的动作(ActionMatch | null
      • data.actionMatchFiles: 匹配到的文件列表(FileItem[]
      • data.requestId: 请求ID
      • data.reenter: 是否重新进入,对于 singleton 的插件,当再次调用时为 true
      • data.isView: 是否是快捷面板
  • 返回
    • void: 无返回值

插件应用初始化完成时触发

focusany.onPluginReady((data) => {
    // data.actionName 动作名称
    // data.actionMatch 动作
    // data.actionMatchFiles 匹配到的文件
    // data.requestId 请求ID
    // data.reenter 是否重新进入,对于 singleton 的插件,当再次调用时为 true
    // data.isView 是否是快捷面板
});
1
2
3
4
5
6
7
8

# onPluginExit

  • 参数
    • callback: 退出时的回调函数,签名:() => void
  • 返回
    • void: 无返回值

插件应用退出时触发

focusany.onPluginExit(() => {
    // 插件即将退出
});
1
2
3

# onPluginEvent

  • 参数
    • event: 事件类型,可选值:"ClipboardChange" | "UserChange"
    • callback: 事件回调函数
      • data: 事件数据
  • 返回
    • void: 无返回值

插件事件监听

// 剪切板变化
focusany.onPluginEvent('ClipboardChange', (data) => {
    console.log('剪切板变化', data);
})
// 用户变化
focusany.onPluginEvent('UserChange', (data) => {
    console.log('用户变化', data);
})
1
2
3
4
5
6
7
8

# offPluginEvent

  • 参数
    • event: 事件类型,可选值:"ClipboardChange" | "UserChange"
    • callback: 要移除的事件回调函数
  • 返回
    • void: 无返回值

移除插件事件

focusany.offPluginEvent('ClipboardChange',cb);
focusany.offPluginEvent('UserChange',cb);
1
2

# offPluginEventAll

  • 参数
    • event: 事件类型,可选值:"ClipboardChange" | "UserChange"
  • 返回
    • void: 无返回值

移除所有插件事件

focusany.offPluginEventAll('ClipboardChange');
focusany.offPluginEventAll('UserChange');
1
2

# onMoreMenuClick

  • 参数
    • callback: 菜单点击回调函数
      • data: 点击数据
        • name: 菜单项名称
  • 返回
    • void: 无返回值

插件更多菜单点击事件

focusany.onMoreMenuClick((data) => {
    console.log('更多菜单点击', data.name);
});
1
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('热键触发');
});
1
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();
1

# isMainWindowShown

  • 参数
  • 返回
    • boolean: 是否显示主窗口

插件主窗口是否显示

focusany.isMainWindowShown();
1

# hideMainWindow

  • 参数
  • 返回
    • boolean: 操作是否成功

隐藏插件主窗口

focusany.hideMainWindow();
1

# showMainWindow

  • 参数
  • 返回
    • boolean: 操作是否成功

显示插件主窗口

focusany.showMainWindow();
1

# isFastPanelWindowShown

  • 参数
  • 返回
    • boolean: 快捷面板窗口是否显示

快捷面板窗口是否显示

focusany.isFastPanelWindowShown();
1

# showFastPanelWindow

  • 参数
  • 返回
    • boolean: 操作是否成功

显示快捷面板窗口

focusany.showFastPanelWindow();
1

# hideFastPanelWindow

  • 参数
  • 返回
    • boolean: 操作是否成功

隐藏快捷面板窗口

focusany.hideFastPanelWindow();
1

# setExpendHeight

  • 参数
    • height: 插件高度(像素)
  • 返回
    • void: 无返回值

设置插件的高度

focusany.setExpendHeight(300);
1

# setSubInput

  • 参数
    • onChange: 输入变化回调函数
      • keywords: 输入的关键字
    • placeholder: 输入框占位符文本(可选)
    • isFocus: 是否自动聚焦(可选)
    • isVisible: 是否显示(可选)
  • 返回
    • boolean: 设置是否成功

设置输入框监听

focusany.setSubInput((keywords) => {
    console.log('输入变化', keywords);
}, '请输入关键字', true, true);
1
2
3

# removeSubInput

  • 参数
  • 返回
    • boolean: 移除是否成功

移除输入框监听

focusany.removeSubInput();
1

# setSubInputValue

  • 参数
    • value: 要设置的输入框值
  • 返回
    • boolean: 设置是否成功

设置子输入框的值

focusany.setSubInputValue('测试');
1

# subInputBlur

  • 参数
  • 返回
    • boolean: 操作是否成功

子输入框失去焦点

focusany.subInputBlur();
1

# getPluginRoot

  • 参数
  • 返回
    • string: 插件根目录路径

获取插件根目录

focusany.getPluginRoot();
1

# getPluginConfig

  • 参数
  • 返回
    • any: 插件配置对象

获取插件配置文件 config.json

focusany.getPluginConfig();
1

# getPluginInfo

  • 参数
  • 返回
    • object: 插件信息对象
      • nodeIntegration: 是否启用Node集成
      • preloadBase: 预加载基础路径
      • preload: 预加载文件路径
      • main: 主文件路径
      • mainView: 主视图文件路径
      • width: 窗口宽度
      • height: 窗口高度
      • autoDetach: 是否自动分离
      • singleton: 是否单例模式
      • zoom: 缩放比例

获取插件信息

focusany.getPluginInfo();
1

# getPluginEnv

  • 参数
  • 返回
    • "dev" | "prod": 插件运行环境

获取插件环境

// dev 或 prod
focusany.getPluginEnv();
1
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 当前文本
});
1
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('窗口创建完成');
});
1
2
3
4
5
6

# outPlugin

  • 参数
  • 返回
    • boolean: 操作是否成功

关闭插件

focusany.outPlugin();
1

# isDarkColors

  • 参数
  • 返回
    • boolean: 是否为暗色主题

是否是暗色主题

focusany.isDarkColors();
1

# showUserLogin

  • 参数
  • 返回
    • void: 无返回值

显示用户登录窗口

focusany.showUserLogin();
1

# 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,每个用户对每个插件的标识唯一
1
2
3
4
5
6
7

# getUserAccessToken

  • 参数
  • 返回
    • Promise<object>: 访问令牌信息
      • token: 访问令牌
      • expireAt: 过期时间戳

获取用户访问令牌

const accessToken = await focusany.getUserAccessToken();
// accessToken.token 访问令牌
// accessToken.expireAt 过期时间
1
2
3

# listGoods

  • 参数
    • query: 查询参数(可选)
      • ids: 商品ID数组(可选)
  • 返回
    • Promise<array>: 商品列表
      • id: 商品ID
      • title: 商品标题
      • cover: 商品封面
      • priceType: 价格类型("fixed" | "dynamic"
      • fixedPrice: 固定价格
      • description: 商品描述

获取商品列表

const goods = await focusany.listGoods();
1

结果示例

[
    {
        "id": "goodsId",
        "title": "商品名称",
        "cover": "商品封面",
        // 商品价格类型 fixed: 固定价格,dynamic: 动态价格
        "priceType": "fixed",
        // 固定价格
        "fixedPrice": "0.01",
        "description": "商品描述"
    }
]
1
2
3
4
5
6
7
8
9
10
11
12

# openGoodsPayment

  • 参数
    • options: 订单参数
      • goodsId: 插件商品ID
      • price: 插件商品价格(可选,动态价格商品需传入)
      • 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 是否支付成功,注意,支付是否成功需要依赖服务端的回调,此处仅作参考
1
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: 商品ID
        • status: 订单状态("Paid" | "Unpaid"

查询插件商品订单

const result = await focusany.queryGoodsOrders({
    // 插件商品ID,可选
    goodsId: 'xxx',
    // 分页页码,从 1 开始,可选
    page: 1,
    // 分页大小,可选,默认是 10
    pageSize: 10,
})
1
2
3
4
5
6
7
8

结果示例

{
    "total": 1,
    "page": 1,
    "records": [
        {
            // 订单号
            "id": "xxxx",
            // 插件商品ID
            "goodsId": "xxx",
            // 状态 Paid: 已支付, Unpaid: 未支付
            "status": "Paid"
        }
    ]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# apiPost

  • 参数
    • url: 请求URL
    • body: 请求体数据
    • option: 请求选项
  • 返回
    • Promise<object>: 响应结果
      • code: 状态码
      • msg: 消息
      • data: 响应数据

请求官方接口

const result = await focusany.apiPost('/api/test', { data: 'test' }, {});
// result.code 状态码
// result.msg 消息
// result.data 数据
1
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
        }
    ]
})
1
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: []
    },
]);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# removeAction

  • 参数
    • name: 要移除的动作名称
  • 返回
    • boolean: 移除是否成功

移除插件动作

focusany.removeAction('actionName');
1

# getActions

  • 参数
    • names: 动作名称数组(可选)
  • 返回
    • PluginAction[]: 插件动作数组

获取插件动作

focusany.getActions();
1

示例结果

[
    {
        "fullName": "完整名称",
        "name": "actionName",
        "title": "动作名称",
        "icon": "icon",
        "type": "web",
    }
]
1
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: ''   // 当前文本
});
1
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' });
1

# showNotification

  • 参数
    • body: 通知内容
    • clickActionName: 点击通知时执行的动作名称(可选)
  • 返回
    • void: 无返回值

显示通知

// 显示通知
focusany.showNotification('通知内容');
// 显示通知,点击执行动作
focusany.showNotification('通知内容','clickActionName');
1
2
3
4

# showMessageBox

  • 参数
    • message: 消息内容
    • options: 消息框选项
      • title: 消息框标题(可选)
      • yes: 确定按钮文本(可选)
      • no: 取消按钮文本(可选)
  • 返回
    • void: 无返回值

显示消息框

focusany.showMessageBox('消息内容', { title: '消息标题', yes: '确定', no: '取消' });
1

# 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 为文件路径数组
1
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 为保存的文件路径
1
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);
});
1
2
3

# getNativeId

  • 参数
  • 返回
    • string: 设备ID

获取设备ID

focusany.getNativeId();
1

# getAppVersion

  • 参数
  • 返回
    • string: 软件版本号

获取软件版本

focusany.getAppVersion();
1

# 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');
1
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');
1

# copyFile

  • 参数
    • file: 文件路径,支持字符串或字符串数组
  • 返回
    • boolean: 复制是否成功

复制文件到剪贴板

// 复制单个文件
focusany.copyFile('/path/to/file.txt');

// 复制多个文件
focusany.copyFile(['/path/to/file1.txt', '/path/to/file2.txt']);
1
2
3
4
5

# copyImage

  • 参数
    • image: 图片路径或Base64编码
  • 返回
    • boolean: 复制是否成功

复制图片到剪贴板

focusany.copyImage('/path/to/image.png');
1

# copyText

  • 参数
    • text: 要复制的文本
  • 返回
    • boolean: 复制是否成功

复制文本到剪贴板

focusany.copyText('text');
1

# getClipboardText

  • 参数
  • 返回
    • string: 剪贴板中的文本内容

获取剪贴板文本

// 输出剪贴板文本
const result = focusany.getClipboardText();
1
2

# getClipboardImage

  • 参数
  • 返回
    • string: 剪贴板中图片的Base64编码

获取剪贴板图片

// 输出图片的 base64 编码
const result = focusany.getClipboardImage();
1
2

# getClipboardFiles

  • 参数
  • 返回
    • FileItem[]: 剪贴板中的文件列表
      • name: 文件名
      • isDirectory: 是否为目录
      • isFile: 是否为文件
      • path: 文件路径
      • fileExt: 文件扩展名

获取剪贴板文件

// 输出剪贴板文件
const result = focusany.getClipboardFiles();
1
2

结果示例

[
    {
        "name": "文件名",
        "isDirectory": false,
        "isFile": true,
        "path": "文件路径",
        "fileExt": "文件扩展名",
    }
]
1
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 });
1

# deleteClipboardItem 删除剪贴板项

  • 参数
    • timestamp: 要删除的时间戳
  • 返回
    • Promise<void>: 无返回值

根据时间戳删除剪贴板项

await focusany.deleteClipboardItem(1628760000000);
1

# clearClipboardItems 清空剪贴板

  • 参数
  • 返回
    • Promise<void>: 无返回值

清空剪贴板历史

await focusany.clearClipboardItems();
1

# shellOpenPath

  • 参数
    • fullPath: 文件完整路径
  • 返回
    • void: 无返回值

使用默认的应用打开文件

focusany.shellOpenPath('/path/to/file.doc');
1

# shellShowItemInFolder

  • 参数
    • fullPath: 文件完整路径
  • 返回
    • void: 无返回值

在文件管理器中显示文件

focusany.shellShowItemInFolder('/path/to/file.txt');
1

# shellOpenExternal

  • 参数
    • url: 要打开的链接URL
  • 返回
    • void: 无返回值

打开链接

focusany.shellOpenExternal('https://focusany.com');
1

# shellBeep

  • 参数
  • 返回
    • void: 无返回值

播放提示音

focusany.shellBeep();
1

# 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']);
1
2
3
4
5
6

# simulate.typeString 模拟输入

  • 参数
    • text: 要输入的文本
  • 返回
    • Promise<void>: 无返回值

模拟输入字符串

await focusany.simulate.typeString('Hello World');
1

# simulate.mouseToggle 鼠标按下

  • 参数
    • type: 动作类型("down" | "up"
    • button: 鼠标按钮("left" | "right" | "middle"
  • 返回
    • Promise<void>: 无返回值

模拟鼠标按下或松开

await focusany.simulate.mouseToggle('down', 'left');
await focusany.simulate.mouseToggle('up', 'left');
1
2

# simulate.mouseMove 鼠标移动

  • 参数
    • x: X坐标
    • y: Y坐标
  • 返回
    • Promise<void>: 无返回值

模拟鼠标移动

await focusany.simulate.mouseMove(100, 200);
1

# simulate.mouseClick 鼠标点击

  • 参数
    • button: 鼠标按钮("left" | "right" | "middle"
    • double: 是否双击(可选)
  • 返回
    • Promise<void>: 无返回值

模拟鼠标点击

await focusany.simulate.mouseClick('left');
await focusany.simulate.mouseClick('left', true); // 双击
1
2

# getCursorScreenPoint

  • 参数
  • 返回
    • object: 鼠标位置坐标
      • x: X坐标
      • y: Y坐标

获取鼠标位置

// 输出 {x: 100, y: 200}
const result = focusany.getCursorScreenPoint();
1
2

# getDisplayNearestPoint

  • 参数
    • point: 坐标点
      • x: X坐标
      • y: Y坐标
  • 返回
    • any: 显示器信息对象

获取指定位置最近的显示器信息

const result = focusany.getDisplayNearestPoint({ x: 100, y: 200 });
1

输出示例

{
    "id": "显示器ID",
    "bounds": {
        "x": 0,
        "y": 0,
        "width": 1920,
        "height": 1080
    },
    "workArea": {
        "x": 0,
        "y": 0,
        "width": 1920,
        "height": 1080
    },
    "scaleFactor": 1.0
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# isMacOs

  • 参数
  • 返回
    • boolean: 是否为MacOS系统

是否是MacOS

focusany.isMacOs();
1

# isWindows

  • 参数
  • 返回
    • boolean: 是否为Windows系统

是否是Windows

focusany.isWindows();
1

# isLinux

  • 参数
  • 返回
    • boolean: 是否为Linux系统

是否是Linux

focusany.isLinux();
1

# getPlatformArch

  • 参数
  • 返回
    • "x86" | "arm64" | null: 平台架构

获取平台架构

// 返回值: 'x86' | 'arm64' | null
const arch = focusany.getPlatformArch();
1
2

# sendBackendEvent

  • 参数
    • event: 事件名称
    • data: 事件数据(可选)
    • option: 选项(可选)
      • timeout: 超时时间(毫秒)
  • 返回
    • Promise<any>: 事件响应数据

发送后端事件

// 发送事件
focusany.sendBackendEvent('event', { data }, { timeout: 3000 });

// 发送事件并等待响应
const result = await focusany.sendBackendEvent('event', { data }, { timeout: 3000 });
1
2
3
4
5

# llmListModels

  • 参数
  • 返回
    • Promise<array>: 大语言模型列表
      • providerId: 提供商ID
      • providerLogo: 提供商图标
      • providerTitle: 提供商名称
      • modelId: 模型ID
      • modelName: 模型名称

获取大语言模型列表

const models = await focusany.llmListModels();
// models 为模型列表
1
2

结果示例

[
    {
        "providerId": "openai",
        "providerLogo": "https://example.com/logo.png",
        "providerTitle": "OpenAI",
        "modelId": "gpt-3.5-turbo",
        "modelName": "GPT-3.5 Turbo"
    }
]
1
2
3
4
5
6
7
8
9

# llmChat

  • 参数
    • callInfo: 调用信息
      • providerId: 提供商ID
      • modelId: 模型ID
      • message: 消息内容
  • 返回
    • 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 回复内容
1
2
3
4
5
6
7
8

# logInfo

  • 参数
    • label: 日志标签
    • data: 日志数据(可选)
  • 返回
    • void: 无返回值

写入信息日志

focusany.logInfo('日志标签', { data: '数据' });
1

# logError

  • 参数
    • label: 错误标签
    • data: 错误数据(可选)
  • 返回
    • void: 无返回值

写入错误日志

focusany.logError('错误标签', { error: '错误信息' });
1

# logPath

  • 参数
  • 返回
    • Promise<string>: 日志文件路径

获取日志文件路径

const logPath = await focusany.logPath();
1

# logShow

  • 参数
  • 返回
    • void: 无返回值

显示日志文件

focusany.logShow();
1

# addLaunch 添加启动

  • 参数
    • keyword: 关键字
    • name: 名称
    • hotkey: 热键配置
      • key: 按键
      • modifiers: 修饰键数组
  • 返回
    • Promise<void>: 无返回值

添加启动项

await focusany.addLaunch('test', '测试应用', {
    key: 'T',
    modifiers: ['Control', 'Shift']
});
1
2
3
4

# removeLaunch 移除启动

  • 参数
    • keywords: 关键字
  • 返回
    • void: 无返回值

移除启动项

focusany.removeLaunch('test');
1

# activateLatestWindow 激活最新窗口

  • 参数
  • 返回
    • Promise<void>: 无返回值

激活最新使用的窗口

await focusany.activateLatestWindow();
1

# db

数据库操作

# db.put

  • 参数
    • doc: 文档对象(DbDoc类型)
      • _id: 文档ID
      • _rev: 文档版本(可选)
  • 返回
    • DbReturn: 操作结果
      • id: 文档ID
      • rev: 文档版本(可选)
      • ok: 操作是否成功(可选)
      • error: 是否有错误(可选)
      • name: 错误名称(可选)
      • message: 错误消息(可选)

添加文档

focusany.db.put(doc);
1

# db.get

  • 参数
    • id: 文档ID
  • 返回
    • DbDoc<T> | null: 文档对象或null

获取文档

focusany.db.get(id);
1

# db.remove

  • 参数
    • doc: 文档ID字符串或文档对象
  • 返回
    • DbReturn: 操作结果

删除文档

focusany.db.remove(doc);
1

# db.bulkDocs

  • 参数
    • docs: 文档对象数组
  • 返回
    • DbReturn[]: 操作结果数组

批量添加文档

focusany.db.bulkDocs(docs);
1

# db.allDocs

  • 参数
    • key: 键名(可选)
  • 返回
    • DbDoc<T>[]: 文档数组

批量获取文档

focusany.db.allDocs(key);
1

# db.postAttachment

  • 参数
    • docId: 文档ID
    • attachment: 附件数据(Uint8Array)
    • type: 附件类型
  • 返回
    • DbReturn: 操作结果

保存附件

focusany.db.postAttachment(docId, attachment, type);
1

# db.getAttachment

  • 参数
    • docId: 文档ID
  • 返回
    • Uint8Array | null: 附件数据或null

获取附件

focusany.db.getAttachment(docId);
1

# db.getAttachmentType

  • 参数
    • docId: 文档ID
  • 返回
    • string | null: 附件类型或null

获取附件类型

focusany.db.getAttachmentType(docId);
1

# dbStorage

本地存储

# dbStorage.setItem

  • 参数
    • key: 存储键名
    • value: 存储值
  • 返回
    • void: 无返回值

设置存储

focusany.dbStorage.setItem('key', 'value');
focusany.dbStorage.setItem('key', { data: 'object' });
1
2

# dbStorage.getItem

  • 参数
    • key: 存储键名
  • 返回
    • T: 存储的值

获取存储

const value = focusany.dbStorage.getItem('key');
const object = focusany.dbStorage.getItem('key');
1
2

# dbStorage.removeItem

  • 参数
    • key: 存储键名
  • 返回
    • void: 无返回值

移除存储

focusany.dbStorage.removeItem('key');
1

# 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']
});
1
2
3
4
5
6
7
8
9

# file

文件操作

# file.exists

  • 参数
    • path: 文件或目录路径
  • 返回
    • Promise<boolean>: 是否存在

判断文件或目录是否存在

const exists = await focusany.file.exists('/path/to/file.txt');
1

# file.read

  • 参数
    • path: 文件路径
  • 返回
    • Promise<string>: 文件内容

读取文件内容

const content = await focusany.file.read('/path/to/file.txt');
1

# file.write

  • 参数
    • path: 文件路径
    • data: 文件内容
  • 返回
    • Promise<void>: 无返回值

写入文件内容

await focusany.file.write('/path/to/file.txt', 'file content');
1

# file.remove

  • 参数
    • path: 文件或目录路径
  • 返回
    • Promise<void>: 无返回值

删除文件或目录

await focusany.file.remove('/path/to/file.txt');
1

# file.ext

  • 参数
    • path: 文件路径
  • 返回
    • Promise<string>: 文件扩展名

获取文件后缀

const ext = await focusany.file.ext('/path/to/file.txt'); // 返回 '.txt'
1

# fad

快捷文件操作

# fad.read

  • 参数
    • type: 文件类型
    • path: 文件路径
  • 返回
    • Promise<any>: 文件内容

读取快捷文件内容

const data = await focusany.fad.read('type', '/path/to/file');
1

# fad.write

  • 参数
    • type: 文件类型
    • path: 文件路径
    • data: 文件数据
  • 返回
    • Promise<void>: 无返回值

写入快捷文件内容

await focusany.fad.write('type', '/path/to/file', { data: 'content' });
1

# view

智能区域

# view.setHeight

  • 参数
    • height: 高度(像素)
  • 返回
    • void: 无返回值

设置快捷面板当前插件渲染区域的高度

focusany.view.setHeight(300);
1

# view.getHeight

  • 参数
  • 返回
    • Promise<number>: 当前高度

获取快捷面板当前插件渲染区域的高度

const height = await focusany.view.getHeight();
1

# detach

分离窗口

# detach.setTitle

  • 参数
    • title: 窗口标题
  • 返回
    • void: 无返回值

设置分离窗口的标题

focusany.detach.setTitle('窗口标题');
1

# detach.setOperates

  • 参数
    • operates: 操作按钮数组
      • name: 操作名称
      • title: 操作标题
      • click: 点击回调函数
  • 返回
    • void: 无返回值

设置分离窗口的操作按钮

focusany.detach.setOperates([
    {
        name: 'save',
        title: '保存',
        click: () => {
            console.log('保存按钮点击');
        }
    },
    {
        name: 'close',
        title: '关闭',
        click: () => {
            console.log('关闭按钮点击');
        }
    }
]);
1
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');
1
2

# detach.setAlwaysOnTop

  • 参数
    • alwaysOnTop: 是否置顶
  • 返回
    • void: 无返回值

设置分离窗口是否置顶

focusany.detach.setAlwaysOnTop(true);
1

# detach.setSize

  • 参数
    • width: 窗口宽度
    • height: 窗口高度
  • 返回
    • void: 无返回值

设置分离窗口的大小

focusany.detach.setSize(800, 600);
1

# util

工具类

# util.randomString

  • 参数
    • length: 随机字符串长度
  • 返回
    • string: 随机字符串

生成随机字符串

const randomStr = focusany.util.randomString(10);
1

# util.bufferToBase64

  • 参数
    • buffer: Uint8Array类型的数据
  • 返回
    • string: Base64编码字符串

Buffer 转 Base64

const base64 = focusany.util.bufferToBase64(buffer);
1

# util.base64ToBuffer

  • 参数
    • base64: Base64编码字符串
  • 返回
    • Uint8Array: Buffer数据

Base64 转 Buffer

const buffer = focusany.util.base64ToBuffer('base64string');
1

# util.datetimeString

  • 参数
  • 返回
    • string: 当前时间戳字符串

获取当前时间戳字符串

const datetime = focusany.util.datetimeString();
1

# util.base64Encode

  • 参数
    • data: 要编码的数据
  • 返回
    • string: Base64编码字符串

数据转 Base64

const encoded = focusany.util.base64Encode({ data: 'test' });
1

# util.base64Decode

  • 参数
    • data: Base64编码字符串
  • 返回
    • any: 解码后的数据

Base64 转数据

const decoded = focusany.util.base64Decode('encodedString');
1

# util.md5

  • 参数
    • data: 要计算MD5的字符串
  • 返回
    • string: MD5哈希值

MD5 摘要

const hash = focusany.util.md5('input string');
1

# util.save

  • 参数
    • filename: 文件名
    • data: 文件数据,支持字符串或Uint8Array
    • option: 选项(可选)
      • 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);
1
2
3
4
5
6
7
8
Last Updated: 7 days ago