@lynker-desktop/web
v0.0.161
Published
lynker-web-sdk
Downloads
615
Readme
title: JSSDK order: 0 nav: title: JSSDK order: 0
Lynker Desktop Web SDK
一个功能强大的 JavaScript SDK,用于在 Web 环境中与 Lynker Desktop 桌面应用进行无缝交互。支持窗口管理、用户信息获取、文件操作、UI 组件调用等丰富的功能。
📋 目录
📦 安装
npm
npm install @lynker-desktop/webyarn
yarn add @lynker-desktop/webpnpm
pnpm add @lynker-desktop/web🚀 快速开始
基础用法
import jssdk from '@lynker-desktop/web';
// 检查是否在桌面端环境
if (jssdk.isDesktop) {
console.log('当前运行在桌面端环境');
// 获取用户信息
const userInfo = await jssdk.getUserInfo();
console.log('用户信息:', userInfo);
} else {
console.log('当前运行在浏览器环境');
}TypeScript 支持
import jssdk, { LynkerSDKConfig, UserInfo } from '@lynker-desktop/web';
// 类型安全的配置获取
const config: LynkerSDKConfig = await jssdk.getConfig();
const userInfo: UserInfo = await jssdk.getUserInfo();环境检测
// 推荐的环境检测方式
if (jssdk.isDesktop) {
// 桌面端环境下的操作
await jssdk.openWebWindow({
name: '新窗口',
url: 'https://example.com',
});
} else {
// 浏览器环境下的降级处理
window.open('https://example.com', '_blank');
}📚 API 参考
💡 提示: 所有 API 方法都是异步的,需要使用
await或.then()处理返回值。
基础功能
isDesktop - 检查是否在桌面端
readonly isDesktop: boolean检查当前是否在桌面端环境中运行。
platform - 获取平台信息
readonly platform: 'win32' | 'darwin' | 'linux' | 'android' | 'ios' | 'unknown'获取当前运行平台信息。
返回值: 平台标识符,包括 Windows、macOS、Linux、Android、iOS 或未知平台。
arch - 获取架构信息
readonly arch: 'x64' | 'ia32' | 'arm64' | 'unknown'获取当前系统架构信息。
返回值: 架构标识符,包括 x64、ia32、arm64 或未知架构。
env - 获取环境信息
readonly env: object获取 Electron 环境信息对象。
返回值: 包含 Electron 进程环境信息的对象。
isOnline - 检查网络状态
readonly isOnline: boolean检查当前网络连接状态。
返回值: true 表示在线,false 表示离线。
fs - 获取文件系统
readonly fs: typeof import('node:fs')获取 Node.js 文件系统模块(仅在桌面端可用)。
返回值: Node.js fs 模块对象。
path - 获取路径模块
readonly path: typeof import('node:path')获取 Node.js 路径模块(仅在桌面端可用)。
返回值: Node.js path 模块对象。
openDesktop(launchOptions?: string) - 打开桌面端
openDesktop(launchOptions?: string): void通过自定义协议打开桌面端应用。
参数:
launchOptions(可选): 启动参数字符串
示例:
jssdk.openDesktop();
jssdk.openDesktop('{"action": "openChat", "userId": "123"}');getConfig() - 获取配置信息
getConfig(): Promise<LynkerSDKConfig>获取桌面端的配置信息。
返回值: LynkerSDKConfig 对象,包含环境、域名、国际化等配置。
getLocalStorage(key: string) - 获取本地存储
getLocalStorage(key: string): Promise<string | null>获取桌面端主窗口的 localStorage 值。
setLocalStorage(key: string, value: string | null) - 设置本地存储
setLocalStorage(key: string, value: string | null): Promise<boolean>设置桌面端主窗口的 localStorage 值。
getLaunchOptions() - 获取启动参数
getLaunchOptions(): Promise<string | null>获取桌面端的启动/唤起参数。
delLaunchOptions() - 清除启动参数
delLaunchOptions(): Promise<string | null>清除桌面端的启动/唤起参数。
getRandomUUID(key?: string) - 生成随机 UUID
getRandomUUID(key?: string): string生成一个基于时间戳和随机数的唯一 UUID。
getH5Url(path, env?, clearCache?) - 获取 H5 URL
getH5Url(path: string, env?: LynkerSDKConfig['env'], clearCache?: boolean): string根据环境和路径生成 H5 URL。
参数:
path: 路径字符串env(可选): 环境标识,默认为 'PROD'clearCache(可选): 是否清除缓存,默认为 false
getH5UrlWithParams(options) - 获取带参数的 H5 URL
getH5UrlWithParams(options: {
path: string;
params: Record<string, any>;
}): Promise<string>获取带有环境参数的 H5 URL。
openPath(query) - 打开路径
openPath(query: MsgQuery['openPath']['query']): Promise<void>使用系统默认程序打开指定路径。
appStore(options) - 应用数据存储
appStore(options: {
name: string;
method: 'get' | 'set' | 'delete' | 'clear';
key?: string;
value?: any;
}): Promise<any>操作应用数据存储,支持获取、设置、删除和清空操作。
shell(options) - Shell 操作
shell(options: {
method: string;
options: string | string[];
}): Promise<any>执行系统 Shell 命令。
clipboard(options) - 剪贴板操作
clipboard(options: {
method: string;
options: string | string[];
}): Promise<any>操作系统剪贴板。
nativeImage(options) - 原生图片操作
nativeImage(options: {
method: string;
options: string | string[];
}): Promise<any>操作原生图片对象。
setDebug(debug: boolean) - 设置调试模式
setDebug(debug: boolean): void开启或关闭调试日志输出。
原始 ipcRenderer - ipcRenderer
readonly ipcRenderer: Electron.IpcRenderer | null⚠️ 已废弃: 请优先使用
ipc属性,该属性即将被移除。
原始 Electron IPC 渲染器实例,用于与主进程进行通信。
注意: 此属性已被标记为废弃,建议使用 ipc 属性替代。
基础 IPC 组件 - ipc
readonly ipc: RendererIPC基于 @lynker-desktop/electron-ipc 的基础 IPC 组件,提供更高级的进程间通信功能。
功能特性:
- 类型安全的 IPC 通信
- 自动错误处理
- 支持事件监听和响应
- 更好的开发体验
- 支持窗口间通信
IPC API 方法
主进程通信
invokeMain(channel, ...args) - 发送消息到主进程
static invokeMain(channel: string, ...args: any[]): Promise<any>发送消息到主进程,使用 Electron 原生的 invoke 方法,支持并发请求。
参数:
channel: 通信频道名称...args: 传递给主进程的参数
返回值: Promise - 主进程的响应数据
特性:
- 支持并发请求,不会互相干扰
- 使用 Electron 原生 invoke 方法
- 自动处理错误和超时
handleMain(channel, handler) - 处理主进程消息
static handleMain(
channel: string,
handler: (...args: any[]) => Promise<any>
): {
cancel: () => void;
}处理主进程发送过来的消息。
参数:
channel: 通信频道名称handler: 消息处理函数,接收除 requestId 外的所有参数
返回值: 返回取消函数,用于移除处理器
特性:
- 返回取消函数,支持动态移除处理器
- 处理函数必须返回 Promise
渲染进程通信
invokeRenderer(channel, ...args) - 发送消息到所有渲染进程
static invokeRenderer(channel: string, ...args: any[]): Promise<any>发送消息到所有渲染进程,使用唯一的 requestId 确保并发请求不会互相干扰。
参数:
channel: 通信频道名称...args: 传递给渲染进程的参数
返回值: Promise - 渲染进程的响应数据
特性:
- 向所有渲染进程发送消息
- 使用 requestId 机制避免并发冲突
- 自动等待渲染进程加载完成
handleRenderer(channel, handler) - 处理渲染进程消息
static handleRenderer(
channel: string,
handler: (...args: any[]) => Promise<any>
): {
cancel: () => void;
}处理渲染进程发送过来的消息。
参数:
channel: 通信频道名称handler: 消息处理函数,接收除 requestId 外的所有参数
返回值: 返回取消函数,用于移除处理器
特性:
- 返回取消函数,支持动态移除处理器
- 处理函数必须返回 Promise
工具方法
getCurrentWebContentId() - 获取当前渲染进程 ID
static getCurrentWebContentId(): Promise<number>获取当前渲染进程的 WebContents ID。
返回值: Promise - 当前渲染进程的 ID
openCurrentWebContentDevTools() - 打开开发者工具
static openCurrentWebContentDevTools(): Promise<number>打开当前窗口的开发者工具。
返回值: Promise - 操作结果
窗口管理
executeJavaScript(options) - 执行 JavaScript
executeJavaScript(options?: {
name?: string;
webContentsId?: number;
script?: string;
}): Promise<any>在指定窗口中执行 JavaScript 代码。
参数:
name(可选): 窗口名称webContentsId(可选): WebContents IDscript(可选): 要执行的 JavaScript 代码
getWebContentsId(options) - 获取 WebContents ID
getWebContentsId(options?: {
name?: string;
webContentsId?: number;
}): Promise<number | undefined>获取指定窗口的 WebContents ID。
focus(options) - 聚焦窗口
focus(options?: {
name?: string;
webContentsId?: number;
}): Promise<boolean>将指定窗口置于前台并聚焦。
blur(options) - 失焦窗口
blur(options?: {
name?: string;
webContentsId?: number;
}): Promise<boolean>使指定窗口失去焦点。
minimize(options) - 最小化窗口
minimize(options?: {
name?: string;
webContentsId?: number;
}): Promise<boolean>最小化指定窗口。
maximize(options) - 最大化窗口
maximize(options?: {
name?: string;
webContentsId?: number;
}): Promise<boolean>最大化指定窗口。
unmaximize(options) - 取消最大化窗口
unmaximize(options?: {
name?: string;
webContentsId?: number;
}): Promise<boolean>取消最大化指定窗口。
isMaximized(options) - 检查窗口是否最大化
isMaximized(options?: {
name?: string;
webContentsId?: number;
}): Promise<boolean>检查指定窗口是否处于最大化状态。
isFullScreen(options) - 检查窗口是否全屏
isFullScreen(options?: {
name?: string;
webContentsId?: number;
}): Promise<boolean>检查指定窗口是否处于全屏状态。
setFullScreen(options) - 设置窗口全屏
setFullScreen(options?: {
name?: string;
webContentsId?: number;
fullscreen?: boolean;
}): Promise<boolean>设置指定窗口的全屏状态。
goBack(options) - 后退
goBack(options?: {
name?: string;
webContentsId?: number;
}): Promise<boolean>在指定窗口中执行后退操作。
reload(options) - 重新加载
reload(options?: {
name?: string;
webContentsId?: number;
}): Promise<boolean>重新加载指定窗口的内容。
goForward(options) - 前进
goForward(options?: {
name?: string;
webContentsId?: number;
}): Promise<boolean>在指定窗口中执行前进操作。
loadURL(options) - 加载 URL
loadURL(options?: {
name?: string;
webContentsId?: number;
url?: string;
}): Promise<boolean>在指定窗口中加载指定的 URL。
close(options) - 关闭窗口
close(options?: {
name?: string;
webContentsId?: number;
}): Promise<boolean>关闭指定窗口。
restore(options) - 恢复窗口
restore(options?: {
name?: string;
webContentsId?: number;
}): Promise<boolean>从最小化状态恢复指定窗口。
setWindowOpenHandler(options) - 设置窗口打开处理程序
setWindowOpenHandler(options?: {
name?: string;
webContentsId?: number;
}): Promise<boolean>为指定窗口设置新窗口打开处理程序。
openDevTools(options) - 打开开发者工具
openDevTools(options?: {
name?: string;
webContentsId?: number;
}): Promise<boolean>为指定窗口打开开发者工具。
openWebWindow(options) - 打开 Web 窗口
openWebWindow(options: {
name: string;
url: string;
extraData?: string;
openDevTools?: boolean;
}): Promise<number>⚠️ 已废弃: 请优先使用
openWindow,该方法即将被移除。
openNewWindow(options) - 打开新窗口
openNewWindow(options: ElectronWindowsManagerOptions): Promise<number | undefined>openExternalWindow(options) - 打开外部窗口
openExternalWindow(options: {
url: string;
options?: ElectronWindowsManagerOptions;
}): Promise<BrowserWindow>openWindow(options, tabsID?) - 打开窗口(简化版)
openWindow(options?: Omit<MsgQuery['windowsTabs_openTab']['query']['options'], ''>, tabsID?: string): Promise<any>closeWindow(query?) - 关闭窗口
closeWindow(query?: MsgQuery['windowsTabs_closeTab']['query']): Promise<any>getCurrentWindow() - 获取当前窗口信息
getCurrentWindow(): Promise<MsgQuery['windowsTabs_openTab']['query'] | undefined>用户信息
getUserInfo() - 获取用户信息
getUserInfo(): Promise<UserInfo>获取当前登录用户的详细信息。
返回值: UserInfo 对象,包含用户 ID、昵称、头像、邮箱等信息。
getUniqueId() - 获取唯一 ID
getUniqueId(): Promise<string>获取桌面端的唯一标识符。
文件操作
previewImage(options) - 预览图片
previewImage(options: PreviewImageOptions | PreviewImageOptions2): Promise<void>previewVideo(options) - 预览视频
previewVideo(options: PreviewVideoOptions): Promise<void>previewFile(options) - 预览文件
previewFile(options: PreviewFileOptions): Promise<void>downloadFile(options) - 下载文件
downloadFile(options: DownloadFileOptions): Promise<string>startCapture() - 开始捕获
startCapture(): Promise<void>stopCapture() - 停止捕获
stopCapture(): Promise<void>transcodeVideo(options, callbacks?) - 转码视频
transcodeVideo(options: VideoDownloadOptions, callbacks?: (data: VideoTranscodeChangeCallback) => void): Promise<string>转码视频文件,支持进度回调。
参数:
options: 视频下载选项callbacks(可选): 转码进度回调函数
返回值: Promise - 转码后的文件路径
回调数据:
interface VideoTranscodeChangeCallback {
type: 'progress' | 'complete' | 'error';
data?: {
outputPath: string;
progress: number;
};
error?: string;
}cache(options) - 资源缓存
cache(options: {
method: 'add' | 'delete' | 'clear' | 'stats';
urls?: string | string[];
force?: boolean;
id?: string;
onProgress?: (progress: {
current: number; // 当前完成的 URL 数量
total: number; // 总 URL 数量
url: string; // 当前处理的 URL
success: boolean; // 当前 URL 是否成功
result?: { // 当前 URL 的处理结果
filePath?: string;
hostPath?: string;
mimeType?: string;
size?: number;
error?: string;
};
percentage: number; // 进度百分比 (0-100)
downloadProgress?: { // 下载进度(如果正在下载)
downloaded: number;
total: number;
percentage: number;
speed: number;
};
}) => void;
}): Promise<CacheResult>缓存资源文件(图片、视频、文件等),支持进度回调和批量操作。
参数:
method: 操作方法'add': 添加资源到缓存'delete': 删除缓存资源'clear': 清空所有缓存'stats': 获取缓存统计信息
urls(可选): 要缓存的 URL 或 URL 数组(仅add和delete方法需要)force(可选): 是否强制重新下载(默认 false)id(可选): 唯一标识符onProgress(可选): 进度回调函数
返回值:
method: 'add': 返回单个或数组形式的缓存结果对象{ url: string; success: boolean; filePath?: string; // 本地文件路径 hostPath?: string; // 可用于访问的本地路径 error?: string; mineType: string; size: number; } | Array<...>method: 'delete': 返回boolean- 是否删除成功method: 'clear': 返回boolean- 是否清空成功method: 'stats': 返回统计信息{ size: number; // 当前缓存大小(字节) totalSize: number; // 总缓存大小(字节) }
使用示例:
// 缓存单个资源
const result = await jssdk.cache({
method: 'add',
urls: 'https://example.com/image.jpg',
onProgress: (progress) => {
console.log(`进度: ${progress.percentage}%`);
if (progress.downloadProgress) {
console.log(`下载速度: ${progress.downloadProgress.speed} B/s`);
}
}
});
console.log('缓存路径:', result.hostPath);
// 批量缓存资源
const results = await jssdk.cache({
method: 'add',
urls: [
'https://example.com/image1.jpg',
'https://example.com/image2.jpg',
'https://example.com/video.mp4'
],
onProgress: (progress) => {
console.log(`处理 ${progress.current}/${progress.total}: ${progress.url}`);
}
});
// 删除缓存
await jssdk.cache({
method: 'delete',
urls: 'https://example.com/image.jpg'
});
// 获取缓存统计
const stats = await jssdk.cache({
method: 'stats'
});
console.log(`缓存大小: ${(stats.totalSize / 1024 / 1024).toFixed(2)} MB`);
// 清空所有缓存
await jssdk.cache({
method: 'clear'
});downloader(options) - 下载文件
downloader(options: {
url: string;
id?: string;
outputPath?: string;
outputDir?: string;
fileName?: string;
override?: boolean;
showSaveDialog?: boolean;
defaultPath?: string;
timeout?: number;
retry?: {
maxRetries?: number;
delay?: number;
};
onProgress?: (progress: {
url: string; // 正在下载的 URL
downloaded: number; // 已下载字节数
total: number; // 总字节数(如果服务器提供 Content-Length)
percentage: number; // 下载进度百分比 (0-100),如果 total 未知则为 -1
speed: number; // 下载速度(字节/秒)
}) => void;
httpRequestOptions?: {
headers?: Record<string, string>;
followRedirect?: boolean;
maxRedirects?: number;
};
}): Promise<{
success: boolean;
filePath?: string;
error?: string;
size?: number;
}>下载文件到本地,支持进度回调、重试机制和自定义 HTTP 请求选项。
参数:
url: 要下载的文件 URL(必需)id(可选): 唯一标识符(IPC 调用时必需)outputPath(可选): 输出文件完整路径(如果不提供则使用 URL 的文件名)outputDir(可选): 输出目录(如果不提供则使用当前目录)fileName(可选): 输出文件名(如果不提供则从 URL 提取)override(可选): 是否覆盖已存在的文件(默认 true)showSaveDialog(可选): 是否弹窗选择保存路径(默认 false)defaultPath(可选): 保存对话框的默认文件名timeout(可选): 超时时间(毫秒,默认 10 分钟)retry(可选): 重试配置maxRetries: 最大重试次数delay: 重试延迟(毫秒)
onProgress(可选): 下载进度回调函数httpRequestOptions(可选): HTTP 请求选项headers: 自定义请求头followRedirect: 是否跟随重定向(默认 true)maxRedirects: 最大重定向次数
返回值:
{
success: boolean; // 是否成功
filePath?: string; // 下载的文件路径
error?: string; // 错误信息
size?: number; // 文件大小(字节)
}使用示例:
// 基本下载
const result = await jssdk.downloader({
url: 'https://example.com/file.pdf',
fileName: 'document.pdf'
});
if (result.success) {
console.log('下载成功:', result.filePath);
}
// 带进度回调的下载
const result = await jssdk.downloader({
url: 'https://example.com/large-file.zip',
outputDir: '/path/to/downloads',
onProgress: (progress) => {
if (progress.percentage >= 0) {
console.log(`下载进度: ${progress.percentage.toFixed(2)}%`);
}
console.log(`下载速度: ${(progress.speed / 1024 / 1024).toFixed(2)} MB/s`);
console.log(`已下载: ${(progress.downloaded / 1024 / 1024).toFixed(2)} MB`);
if (progress.total > 0) {
console.log(`总大小: ${(progress.total / 1024 / 1024).toFixed(2)} MB`);
}
}
});
// 带重试机制的下载
const result = await jssdk.downloader({
url: 'https://example.com/unstable-file.zip',
retry: {
maxRetries: 3,
delay: 1000
},
onProgress: (progress) => {
console.log(`进度: ${progress.percentage}%`);
}
});
// 使用保存对话框
const result = await jssdk.downloader({
url: 'https://example.com/file.pdf',
showSaveDialog: true,
defaultPath: 'document.pdf'
});
// 自定义 HTTP 请求头
const result = await jssdk.downloader({
url: 'https://example.com/protected-file.zip',
httpRequestOptions: {
headers: {
'Authorization': 'Bearer token123',
'User-Agent': 'MyApp/1.0'
},
followRedirect: true,
maxRedirects: 5
},
onProgress: (progress) => {
console.log(`下载中: ${progress.percentage}%`);
}
});
// 格式化下载速度的工具函数
function formatSpeed(bytesPerSecond: number): string {
if (!bytesPerSecond || bytesPerSecond === 0) {
return '';
}
if (bytesPerSecond < 1024) {
return `${bytesPerSecond} B/s`;
}
if (bytesPerSecond < 1024 * 1024) {
return `${(bytesPerSecond / 1024).toFixed(1)} KB/s`;
}
return `${(bytesPerSecond / (1024 * 1024)).toFixed(1)} MB/s`;
}
// 在进度回调中使用
jssdk.downloader({
url: 'https://example.com/file.zip',
onProgress: (progress) => {
const speed = formatSpeed(progress.speed);
console.log(`速度: ${speed}, 进度: ${progress.percentage}%`);
}
});UI 组件
showMessage(options) - 显示消息
showMessage(options: {
id?: string;
theme?: 'info' | 'success' | 'warning' | 'error' | 'loading';
message: string;
width: number;
height?: number;
duration?: number;
customCode?: string;
winId?: number;
}): Promise<void>hideMessage(id?: string) - 隐藏消息
hideMessage(id?: string): Promise<void>showDialog(options) - 显示对话框
showDialog(options: {
id?: string;
theme?: 'confirm' | 'alert';
header?: string;
body: string;
confirmBtn?: string;
cancelBtn?: string;
closeBtn?: boolean;
width?: number;
customCode?: string;
winId?: number;
}): Promise<void>hideDialog(id?: string) - 隐藏对话框
hideDialog(id?: string): Promise<void>showDrawer(options) - 显示抽屉
showDrawer(options: {
id?: string;
placement?: 'right' | 'left' | 'top' | 'bottom';
header?: string;
body: string;
confirmBtn?: string;
cancelBtn?: string;
customCode?: string;
winId?: number;
}): Promise<void>hideDrawer(id?: string) - 隐藏抽屉
hideDrawer(id?: string): Promise<void>showNotification(options) - 显示通知
showNotification(options: {
id?: string;
theme?: 'info' | 'success' | 'warning' | 'error';
placement?: 'top-right' | 'top-left' | 'bottom-left' | 'bottom-right';
title: string;
content: string;
duration?: number;
width?: number;
height?: number;
icon?: boolean;
closeBtn?: boolean;
customCode?: string;
winId?: number;
}): Promise<void>hideNotification(id?: string) - 隐藏通知
hideNotification(id?: string): Promise<void>主菜单操作
mainMenu_openMessage() - 打开消息
mainMenu_openMessage(): Promise<void>mainMenu_openWorkBench(options) - 打开数智工场
mainMenu_openWorkBench(options: MainMenuOpenWorkBenchQuery): Promise<boolean | undefined>mainMenu_openSquare() - 打开广场
mainMenu_openSquare(): Promise<void>mainMenu_openDigitalPlatform(options?) - 打开数字平台
mainMenu_openDigitalPlatform(options?: {
teamId?: string;
query?: Record<string, string>;
}): Promise<void>mainMenu_openAddressBook() - 打开地址簿
mainMenu_openAddressBook(): Promise<void>mainMenu_openActivities() - 打开活动
mainMenu_openActivities(): Promise<void>mainMenu_openDisk() - 打开网盘
mainMenu_openDisk(): Promise<void>消息模块
message_openChat(options) - 打开聊天
message_openChat(options: {
main: string;
peer?: string;
group?: string;
assistant?: string;
extInfo?: {
type: 'service_content';
content: any;
};
rela?: string;
}): Promise<void>message_openMessage(options) - 打开消息
message_openMessage(options: {
messageId: string;
type: 'GROUP' | 'SINGLE';
cardId: string;
fromId: string;
}): Promise<void>message_openDrawerForWebview(options) - 打开抽屉(WebView)
message_openDrawerForWebview(options: {
id: string;
title: string;
url: string;
}): Promise<void>message_closeDrawerForWebview(options) - 关闭抽屉(WebView)
message_closeDrawerForWebview(options: {
id: string;
}): Promise<void>数智工场模块
workBench_getActiveTeamId() - 获取当前团队 ID
workBench_getActiveTeamId(): Promise<string | undefined>workBench_getTabList() - 获取标签列表
workBench_getTabList(): Promise<WorkBenchTabOptions[]>workBench_openTab(options) - 打开标签
workBench_openTab(options: WorkBenchOpenTabQuery): Promise<boolean | undefined>workBench_closeTab(options) - 关闭标签
workBench_closeTab(options: {
path_uuid: string;
}): Promise<void>workBench_updateTab(options) - 更新标签
workBench_updateTab(options: {
path_uuid: string;
title?: string;
icon?: string;
activeIcon?: string;
beforeCloseOptions?: WorkBenchTabOptions['beforeCloseOptions'];
beforeRefreshOptions?: WorkBenchTabOptions['beforeRefreshOptions'];
query?: Record<string, string>;
}): Promise<void>workBench_openTabForIframe(options) - 打开标签(iframe)
workBench_openTabForIframe(options: WorkBenchOpenTabForIframeQuery): Promise<boolean | undefined>workBench_openTabForWebview(options) - 打开标签(WebView)
workBench_openTabForWebview(options: WorkBenchOpenTabForWebviewQuery): Promise<boolean | undefined>workBench_openDrawerForWebview(options) - 打开抽屉(WebView)
workBench_openDrawerForWebview(options: {
id: string;
title: string;
url: string;
teamId?: string;
}): Promise<void>workBench_closeDrawerForWebview(options) - 关闭抽屉(WebView)
workBench_closeDrawerForWebview(options: {
id: string;
}): Promise<void>workBench_openTabForEnterprise(options) - 打开企业标签
workBench_openTabForEnterprise(options: WorkBenchOpenTabForEnterpriseQuery): Promise<boolean | undefined>workBench_openTabForMerchantApply(options) - 打开商户申请标签
workBench_openTabForMerchantApply(options: WorkBenchOpenTabForMerchantApplyQuery): Promise<boolean | undefined>workBench_openTabForReceiveDetail(options) - 打开接收详情标签
workBench_openTabForReceiveDetail(options: WorkBenchOpenTabForReceiveDetailQuery): Promise<boolean | undefined>workBench_openTabForRefundDetail(options) - 打开退款详情标签
workBench_openTabForRefundDetail(options: WorkBenchOpenTabForRefundDetailQuery): Promise<boolean | undefined>workBench_openTabForSettlementDetail(options) - 打开结算详情标签
workBench_openTabForSettlementDetail(options: WorkBenchOpenTabForSettlementDetailQuery): Promise<boolean | undefined>workBench_openTeamCertification(options) - 打开组织认证
workBench_openTeamCertification(options: {
teamId?: string;
}): Promise<void>workBench_reload() - 刷新数智工场
workBench_reload(): Promise<boolean>数字平台模块
digitalPlatform_setActiveTeamId(options) - 设置当前团队 ID
digitalPlatform_setActiveTeamId(options: {
teamId: string;
}): Promise<boolean>digitalPlatform_getActiveTeamId() - 获取当前团队 ID
digitalPlatform_getActiveTeamId(): Promise<string | undefined>digitalPlatform_reload() - 刷新数字平台
digitalPlatform_reload(): Promise<boolean>digitalPlatform_getTabList() - 获取标签列表
digitalPlatform_getTabList(): Promise<DigitalPlatformTabOptions[]>digitalPlatform_openTab(options) - 打开标签
digitalPlatform_openTab(options: DigitalPlatformOpenTabQuery): Promise<boolean | undefined>digitalPlatform_closeTab(options) - 关闭标签
digitalPlatform_closeTab(options: {
path_uuid: string;
}): Promise<void>digitalPlatform_updateTab(options) - 更新标签
digitalPlatform_updateTab(options: {
path_uuid: string;
title?: string;
icon?: string;
activeIcon?: string;
beforeCloseOptions?: {
title?: string;
content?: string;
};
beforeRefreshOptions?: {
title?: string;
content?: string;
};
query?: Record<string, string>;
}): Promise<void>digitalPlatform_openTabForWebview(options) - 打开标签(WebView)
digitalPlatform_openTabForWebview(options: DigitalPlatformOpenTabForWebviewQuery): Promise<boolean | undefined>广场模块
square_setActiveTeamId(options) - 设置当前团队 ID
square_setActiveTeamId(options: {
teamId: string;
}): Promise<boolean>square_getActiveTeamId() - 获取当前团队 ID
square_getActiveTeamId(): Promise<string | undefined>square_reload() - 刷新广场
square_reload(): Promise<boolean>square_openTab(options) - 打开标签
square_openTab(options: SquareOpenTabQuery): Promise<boolean>square_closeTab(options) - 关闭标签
square_closeTab(options: {
path_uuid: string;
title?: string;
beforeCloseOptions?: {
title?: string;
content?: string;
};
beforeRefreshOptions?: {
title?: string;
content?: string;
};
}): Promise<void>square_updateTab(options) - 更新标签
square_updateTab(options: {
path_uuid: string;
title?: string;
icon?: string;
activeIcon?: string;
beforeCloseOptions?: {
title?: string;
content?: string;
};
beforeRefreshOptions?: {
title?: string;
content?: string;
};
query?: Record<string, string>;
}): Promise<void>square_openTabForWebview(options) - 打开标签(WebView)
square_openTabForWebview(options: WorkBenchOpenTabForWebviewQuery): Promise<boolean | undefined>大市场模块
bigMarket_setActiveTeamId(options) - 设置当前团队 ID
bigMarket_setActiveTeamId(options: {
teamId: string;
}): Promise<boolean>bigMarket_getActiveTeamId() - 获取当前团队 ID
bigMarket_getActiveTeamId(): Promise<string | undefined>bigMarket_reload() - 刷新大市场
bigMarket_reload(): Promise<boolean>bigMarket_openTab(options) - 打开标签
bigMarket_openTab(options: BigMarketOpenTabQuery): Promise<boolean>bigMarket_closeTab(options) - 关闭标签
bigMarket_closeTab(options: {
path_uuid: string;
title?: string;
beforeCloseOptions?: {
title?: string;
content?: string;
};
beforeRefreshOptions?: {
title?: string;
content?: string;
};
}): Promise<void>bigMarket_updateTab(options) - 更新标签
bigMarket_updateTab(options: {
path_uuid: string;
title?: string;
icon?: string;
activeIcon?: string;
beforeCloseOptions?: {
title?: string;
content?: string;
};
beforeRefreshOptions?: {
title?: string;
content?: string;
};
query?: Record<string, string>;
}): Promise<void>bigMarket_openTabForWebview(options) - 打开标签(WebView)
bigMarket_openTabForWebview(options: WorkBenchOpenTabForWebviewQuery): Promise<boolean | undefined>身份卡管理
openIdentityCardEdit(options) - 打开身份卡编辑窗口
openIdentityCardEdit(options: MsgQuery['jssdk:windows:identityCardEdit:open']['query']): Promise<any>打开身份卡编辑窗口。
参数:
options: 身份卡编辑选项
openIdentityCardPreview(options) - 打开身份卡预览窗口
openIdentityCardPreview(options: MsgQuery['jssdk:windows:identityCardPreview:open']['query']): Promise<any>打开身份卡预览窗口。
参数:
options: 身份卡预览选项
独立窗口标签
windowsTabs_openTab(options) - 打开标签
windowsTabs_openTab(options: {
options: {
id?: string;
title?: string;
url?: string;
icon?: string;
activeIcon?: string;
hideCloseButton?: boolean;
beforeCloseOptions?: {
title: string;
content?: string;
};
beforeRefreshOptions?: {
title?: string;
content?: string;
};
query?: Record<string, string>;
};
isOnlyOneTabHideTabs?: boolean;
showBrowserTools?: boolean;
tabsId?: string | 'square' | 'digitalPlatform' | 'smartWorkshop' | 'bigMarket';
tabsTitle?: string;
}): Promise<void>windowsTabs_closeTab(options) - 关闭标签
windowsTabs_closeTab(options?: {
id?: string;
tabsId?: string | 'square' | 'digitalPlatform' | 'smartWorkshop' | 'bigMarket';
}): Promise<void>windowsTabs_getCurrentTab() - 获取当前标签信息
windowsTabs_getCurrentTab(): Promise<MsgQuery['windowsTabs_openTab']['query'] | undefined>其他功能
openBrowser(url) - 打开浏览器
openBrowser(url: string): Promise<boolean>openMyHelpWindow(options?) - 打开帮助中心
openMyHelpWindow(options?: {
id: number;
module_id: number;
directory_id: number;
}): Promise<number | undefined>openMyOrderWindow(options?) - 打开我的订单
openMyOrderWindow(options?: any): Promise<number | undefined>openMyInvoiceWindow() - 打开发票中心
openMyInvoiceWindow(): Promise<number | undefined>openSelectMember(options?) - 打开选人组件
openSelectMember(options?: {
webContentsId?: number;
query?: {
menu?: string[];
max?: number;
disableList?: any[];
selectList?: any[];
changeMenus?: boolean;
disabledCard?: boolean;
activeCardId?: string[];
showMyGroupMenu?: boolean;
showDropdownMenu?: boolean;
isImMember?: boolean;
groupID?: string;
diyData?: any[];
extend?: Record<string, any>;
extendFrom?: string[];
emptyCardId?: boolean;
useSelectedGroup?: boolean;
};
}): Promise<Array<any>>openJoinDigitalPlatformDrawer(options?) - 打开加入数字平台抽屉
openJoinDigitalPlatformDrawer(options?: {
webContentsId?: number;
query?: Record<string, any>;
}): Promise<Array<any>>openOrgAuthDrawer(options?) - 打开组织认证抽屉
openOrgAuthDrawer(options?: {
webContentsId?: number;
query: {
region: string;
teamId: string;
orgType: string;
showType: 'detail' | 'edit';
};
}): Promise<Array<any>>openAddContactsDialog(options?) - 打开添加联系人对话框
openAddContactsDialog(options?: {
webContentsId?: number;
query?: {
searchValue?: string;
};
}): Promise<Array<any>>openAnnualFeeDrawer(options?) - 打开年费抽屉
openAnnualFeeDrawer(options?: {
webContentsId?: number;
query?: {
teamId: string;
squareId?: string;
title?: string;
open?: boolean;
inviteCode?: string;
upgrade?: boolean;
};
}): Promise<{
type: 'success' | 'upgrade-loaded' | 'close';
data?: any;
}>openExternalApp(options) - 打开外部应用
openExternalApp(options: {
url: string;
title?: string;
isInApp?: boolean;
}): Promise<string>setEnv(env) - 设置环境
setEnv(env: 'DEV' | 'TEST' | 'PRE' | 'PROD' | 'RESET'): Promise<void>checkIsManualEnv() - 检查是否为手动环境
checkIsManualEnv(): Promise<boolean>openSettingWindow(query) - 打开设置窗口
openSettingWindow(query: string): Promise<BrowserWindow>openSetGroupWindow() - 打开设置组窗口
openSetGroupWindow(): Promise<BrowserWindow>openMyAddressWindow(query) - 打开我的地址窗口
openMyAddressWindow(query: string): Promise<BrowserWindow>openPolicyDetailWindow(options) - 打开政策详情窗口
openPolicyDetailWindow(options: {
url: string;
}): Promise<BrowserWindow>openPolicyDetailWindow2(options) - 打开政策详情窗口 2
openPolicyDetailWindow2(options: {
url: string;
}): Promise<BrowserWindow>logout() - 注销
logout(): Promise<void>openDebugTools() - 打开调试工具
openDebugTools(): Promise<void>💡 完整使用示例
💡 建议: 在每个示例前都先引入 jssdk:
import jssdk from '@lynker-desktop/web';
🎯 实际应用场景
场景 1: 用户登录后获取信息
async function handleUserLogin() {
if (!jssdk.isDesktop) {
console.warn('请在桌面端环境中使用此功能');
return;
}
try {
// 获取用户信息
const userInfo = await jssdk.getUserInfo();
console.log('用户登录成功:', userInfo.title);
// 获取配置信息
const config = await jssdk.getConfig();
console.log('当前环境:', config.env);
// 显示欢迎消息
await jssdk.showMessage({
theme: 'success',
message: `欢迎回来,${userInfo.title}!`,
width: 300,
duration: 3000,
});
} catch (error) {
console.error('获取用户信息失败:', error);
}
}场景 2: 文件预览和下载
async function handleFileOperation(fileUrl: string, fileName: string) {
if (!jssdk.isDesktop) {
// 浏览器环境降级处理
window.open(fileUrl, '_blank');
return;
}
try {
// 预览文件
await jssdk.previewFile({
title: fileName,
url: fileUrl,
type: 'pdf',
size: 1024 * 1024,
});
// 提供下载选项
const shouldDownload = await jssdk.showDialog({
theme: 'confirm',
header: '文件预览',
body: '是否下载此文件?',
confirmBtn: '下载',
cancelBtn: '取消',
});
if (shouldDownload) {
const filePath = await jssdk.downloadFile({
title: fileName,
url: fileUrl,
});
console.log('文件已下载到:', filePath);
}
} catch (error) {
console.error('文件操作失败:', error);
}
}场景 3: 资源缓存和文件下载
// 缓存资源文件
async function cacheResources(imageUrls: string[]) {
if (!jssdk.isDesktop) return;
try {
const results = await jssdk.cache({
method: 'add',
urls: imageUrls,
onProgress: (progress) => {
console.log(`缓存进度: ${progress.percentage}%`);
if (progress.downloadProgress) {
const speed = (progress.downloadProgress.speed / 1024 / 1024).toFixed(2);
console.log(`下载速度: ${speed} MB/s`);
}
}
});
// 处理缓存结果
if (Array.isArray(results)) {
results.forEach((result, index) => {
if (result.success) {
console.log(`图片 ${index + 1} 缓存成功:`, result.hostPath);
} else {
console.error(`图片 ${index + 1} 缓存失败:`, result.error);
}
});
} else if (results.success) {
console.log('缓存成功:', results.hostPath);
}
// 获取缓存统计
const stats = await jssdk.cache({ method: 'stats' });
console.log(`缓存总大小: ${(stats.totalSize / 1024 / 1024).toFixed(2)} MB`);
} catch (error) {
console.error('缓存失败:', error);
}
}
// 下载文件并显示进度
async function downloadFileWithProgress(fileUrl: string, fileName: string) {
if (!jssdk.isDesktop) {
// 浏览器环境降级处理
const link = document.createElement('a');
link.href = fileUrl;
link.download = fileName;
link.click();
return;
}
try {
const result = await jssdk.downloader({
url: fileUrl,
fileName: fileName,
showSaveDialog: true,
onProgress: (progress) => {
if (progress.percentage >= 0) {
console.log(`下载进度: ${progress.percentage.toFixed(2)}%`);
}
const speed = (progress.speed / 1024 / 1024).toFixed(2);
const downloaded = (progress.downloaded / 1024 / 1024).toFixed(2);
console.log(`已下载: ${downloaded} MB, 速度: ${speed} MB/s`);
}
});
if (result.success) {
console.log('文件下载成功:', result.filePath);
await jssdk.showMessage({
theme: 'success',
message: '文件下载成功',
width: 200,
duration: 3000
});
} else {
throw new Error(result.error || '下载失败');
}
} catch (error) {
console.error('下载失败:', error);
await jssdk.showMessage({
theme: 'error',
message: '文件下载失败',
width: 200,
duration: 3000
});
}
}
// 视频播放前先缓存
async function playVideoWithCache(videoUrl: string) {
if (!jssdk.isDesktop) return videoUrl;
try {
// 先缓存视频
const cacheResult = await jssdk.cache({
method: 'add',
urls: videoUrl,
onProgress: (progress) => {
if (progress.downloadProgress) {
const percentage = progress.downloadProgress.percentage;
console.log(`视频缓存进度: ${percentage.toFixed(2)}%`);
}
}
});
// 使用缓存后的路径
if (cacheResult && typeof cacheResult === 'object' && 'hostPath' in cacheResult) {
return cacheResult.hostPath || videoUrl;
}
return videoUrl;
} catch (error) {
console.error('视频缓存失败,使用原始 URL:', error);
return videoUrl;
}
}场景 4: 工作台标签管理
async function manageWorkbenchTabs() {
if (!jssdk.isDesktop) return;
try {
// 获取当前标签列表
const tabs = await jssdk.workBench_getTabList();
console.log('当前标签:', tabs);
// 打开新标签
await jssdk.workBench_openTab({
options: {
fullPath: '/workbench/new-tab',
title: '新标签页',
icon: 'icon-url',
teamId: 'team-001',
},
openWorkBench: true,
});
// 更新标签信息
await jssdk.workBench_updateTab({
path_uuid: 'tab-uuid',
title: '更新后的标题',
icon: 'new-icon-url',
});
} catch (error) {
console.error('标签管理失败:', error);
}
}1. 判断是否在桌面端
if (jssdk.isDesktop) {
console.log('当前运行在桌面端环境');
}2. 打开桌面端
jssdk.openDesktop();
// 或带参数
jssdk.openDesktop('{"action": "openChat", "userId": "123"}');3. 获取桌面端配置信息
const config = await jssdk.getConfig();
console.log(config.env); // DEV/TEST/PRE/PROD
console.log(config.h5Host); // 域名配置
console.log(config.token); // 用户token4. 获取 LocalStorage
const token = await jssdk.getLocalStorage('token');
console.log(token);5. 设置 LocalStorage
await jssdk.setLocalStorage({ key: 'token', value: '测试' });6. 获取启动/唤起参数
const launchOptions = await jssdk.getLaunchOptions();
console.log(launchOptions);7. 清除启动/唤起参数
await jssdk.delLaunchOptions();8. 打开 web 窗口
await jssdk.openWebWindow({
name: '新窗口',
url: 'https://www.baidu.com',
extraData: '自定义数据',
openDevTools: false,
});9. 打开浏览器
await jssdk.openBrowser('https://www.baidu.com');10. 打开帮助中心
await jssdk.openMyHelpWindow({
id: 1,
module_id: 2,
directory_id: 3,
});
// 或无参数
await jssdk.openMyHelpWindow();11. 打开我的订单
await jssdk.openMyOrderWindow();12. 打开发票中心
await jssdk.openMyInvoiceWindow();13. 打开选人组件
const members = await jssdk.openSelectMember({
query: {
menu: ['recent', 'friend'],
max: 5,
selectList: [],
changeMenus: true,
},
});
// 返回数组
console.log(members);14. 打开新窗口
await jssdk.openNewWindow({
name: '新窗口',
url: 'https://www.baidu.com',
width: 800,
height: 600,
// 其他 ElectronWindowsManagerOptions 字段
});15. 设置 debug 模式
jssdk.setDebug(true);16. 获取用户信息
const userInfo = await jssdk.getUserInfo();
console.log(userInfo.openid, userInfo.title, userInfo.email);17. 使用原始 IPC 渲染器(已废弃)
// ⚠️ 已废弃,请使用 jssdk.ipc 替代
if (jssdk.ipcRenderer) {
const result = await jssdk.ipcRenderer.invoke('some-channel', {
data: 'test',
});
console.log(result);
}18. 使用基础 IPC 组件
18.1 主进程通信
// 发送消息到主进程
const result1 = await jssdk.ipc.invokeMain('get-app-version');
console.log('应用版本:', result1);
// 发送消息到主进程(支持并发请求)
const result2 = await jssdk.ipc.invokeMain('get-user-data', { userId: '123' });
console.log('用户数据:', result2);
// 处理主进程发送过来的消息
const handler = jssdk.ipc.handleMain('config-updated', async (newConfig) => {
console.log('配置已更新:', newConfig);
// 更新本地状态
return 'config-received';
});
// 处理完成后可以取消处理器
// handler.cancel();
// 处理应用初始化消息
jssdk.ipc.handleMain('app-ready', async () => {
console.log('应用已准备就绪');
return 'renderer-ready';
});18.2 渲染进程通信
// 发送消息到所有渲染进程
const result3 = await jssdk.ipc.invokeRenderer('sync-data', { data: 'sync' });
console.log('同步结果:', result3);
// 发送消息到所有渲染进程
const result4 = await jssdk.ipc.invokeRenderer('window-message', {
message: 'Hello from all windows',
});
console.log('窗口响应:', result4);
// 处理其他渲染进程发送的消息
const rendererHandler = jssdk.ipc.handleRenderer('window-communication', async (data) => {
console.log('收到其他窗口消息:', data);
return { status: 'received' };
});
// 处理完成后可以取消处理器
// rendererHandler.cancel();
// 处理初始化同步消息
jssdk.ipc.handleRenderer('initial-sync', async (initData) => {
console.log('初始同步数据:', initData);
return 'sync-complete';
});18.3 工具方法使用
// 获取当前渲染进程ID
const currentId = await jssdk.ipc.getCurrentWebContentId();
console.log('当前窗口ID:', currentId);
// 打开开发者工具
await jssdk.ipc.openCurrentWebContentDevTools();
console.log('开发者工具已打开');18.4 实际应用场景
// 场景1: 监听配置变化
jssdk.ipc.handleRenderer('__APP_CONFIG_CHANGE__', async (config) => {
console.log('配置已更新:', config);
// 更新UI状态
updateUIWithConfig(config);
return 'OK';
});
// 场景2: 窗口间数据同步
async function syncDataBetweenWindows(data) {
try {
// 向所有渲染进程发送同步数据
await jssdk.ipc.invokeRenderer('sync-data', data);
console.log('数据同步完成');
} catch (error) {
console.error('数据同步失败:', error);
}
}
// 场景3: 处理主进程事件
jssdk.ipc.handleMain('user-login', async (userInfo) => {
console.log('用户登录:', userInfo);
// 更新用户状态
updateUserState(userInfo);
return 'login-processed';
});
// 场景4: 错误处理
async function safeIpcCall() {
try {
const result = await jssdk.ipc.invokeMain('risky-operation');
return result;
} catch (error) {
console.error('IPC调用失败:', error);
// 降级处理
return null;
}
}
// 场景5: 消息模块通信
async function openMessageChat(options) {
try {
// 打开消息窗口
await jssdk.mainMenu_openMessage();
// 发送消息到消息模块
await jssdk.ipc.invokeRenderer('message-open-chat', options);
} catch (error) {
console.error('打开聊天失败:', error);
}
}
// 场景6: 数智工场模块通信
async function manageWorkbench() {
try {
// 检查数智工场是否已初始化
const isInited = await jssdk.ipc.invokeRenderer('zhixing-is-inited');
if (!isInited) {
console.warn('数智工场未初始化');
return;
}
// 获取当前团队ID
const teamId = await jssdk.ipc.invokeRenderer('zhixing-get-active-team-id');
console.log('当前团队ID:', teamId);
// 刷新数智工场
await jssdk.ipc.invokeRenderer('zhixing-reload');
} catch (error) {
console.error('数智工场操作失败:', error);
}
}
// 场景7: 广场模块通信
async function manageSquare() {
try {
// 检查广场是否已初始化
const isInited = await jssdk.ipc.invokeRenderer('square-is-inited');
if (!isInited) {
console.warn('广场未初始化');
return;
}
// 设置当前团队ID
await jssdk.ipc.invokeRenderer('square-set-active-team-id', { teamId: 'team-001' });
// 获取标签列表
const tabs = await jssdk.ipc.invokeRenderer('get-square-tab-list');
console.log('广场标签列表:', tabs);
// 打开新标签
await jssdk.ipc.invokeRenderer('open-square-tab-item', {
label: '新标签',
fullPath: '/square/new-tab',
teamId: 'team-001'
});
} catch (error) {
console.error('广场操作失败:', error);
}
}
// 场景8: 大市场模块通信
async function manageBigMarket() {
try {
// 检查大市场是否已初始化
const isInited = await jssdk.ipc.invokeRenderer('big-market-is-inited');
if (!isInited) {
console.warn('大市场未初始化');
return;
}
// 设置当前团队ID
await jssdk.ipc.invokeRenderer('big-market-set-active-team-id', { teamId: 'team-001' });
// 刷新大市场
await jssdk.ipc.invokeRenderer('big-market-reload');
} catch (error) {
console.error('大市场操作失败:', error);
}
}
// 场景9: 应用初始化处理
async function handleAppInitialization() {
// 处理应用初始化消息
const initHandler = jssdk.ipc.handleMain('app-ready', async () => {
console.log('应用已准备就绪');
// 执行初始化逻辑
await initializeApp();
return 'initialization-complete';
});
// 发送初始化完成信号
await jssdk.ipc.invokeMain('renderer-ready');
// 初始化完成后可以取消处理器
// initHandler.cancel();
}
// 场景10: 窗口间文件共享
async function shareFileBetweenWindows(fileData) {
try {
// 发送文件数据到所有渲染进程
await jssdk.ipc.invokeRenderer('file-share', {
fileName: fileData.name,
fileContent: fileData.content,
fileType: fileData.type
});
console.log('文件共享成功');
} catch (error) {
console.error('文件共享失败:', error);
}
}19. 获取唯一 ID
const uniqueId = await jssdk.getUniqueId();
console.log(uniqueId);20. 设置环境
await jssdk.setEnv('DEV'); // DEV/TEST/PRE/PROD/RESET21. 检查是否为手动环境
const isManual = await jssdk.checkIsManualEnv();
console.log(isManual);22. 获取当前窗口
const win = await jssdk.getCurrentWindow();
console.log(win.id, win.title);23. 打开外部窗口
await jssdk.openExternalWindow({
url: 'https://www.baidu.com',
options: {
width: 800,
height: 600,
// 其他 ElectronWindowsManagerOptions 字段
},
});24. 打开设置窗口
await jssdk.openSettingWindow('general');25. 打开设置组窗口
await jssdk.openSetGroupWindow();26. 打开我的地址窗口
await jssdk.openMyAddressWindow('user-address-key');27. 打开政策详情窗口
await jssdk.openPolicyDetailWindow({ url: 'https://example.com/policy/123' });28. 打开政策详情窗口 2
await jssdk.openPolicyDetailWindow2({ url: 'https://example.com/policy/456' });29. 注销
await jssdk.logout();30. 打开调试工具
await jssdk.openDebugTools();31. 预览图片
await jssdk.previewImage({
images: ['https://example.com/image1.png', 'https://example.com/image2.png'],
index: 0,
url: 'https://example.com/image1.png',
});32. 预览视频
await jssdk.previewVideo({
title: '演示视频',
url: 'https://example.com/video.mp4',
type: 'mp4',
size: 1024 * 1024 * 10,
});33. 预览文件
await jssdk.previewFile({
title: '文档',
url: 'https://example.com/file.pdf',
type: 'pdf',
size: 1024 * 1024,
officeId: 'office-123',
});34. 下载文件
const filePath = await jssdk.downloadFile({
title: '下载文件',
url: 'https://example.com/file.pdf',
});
console.log(filePath);35. 开始捕获
await jssdk.startCapture();36. 停止捕获
await jssdk.stopCapture();37. 显示消息
await jssdk.showMessage({
theme: 'success',
message: '操作成功',
width: 200,
duration: 3000,
});38. 显示对话框
await jssdk.showDialog({
theme: 'confirm',
header: '确认操作',
body: '您确定要执行此操作吗?',
confirmBtn: '确定',
cancelBtn: '取消',
});39. 显示抽屉
await jssdk.showDrawer({
placement: 'right',
header: '设置',
body: '抽屉内容',
confirmBtn: '保存',
cancelBtn: '取消',
});40. 显示通知
await jssdk.showNotification({
theme: 'info',
placement: 'top-right',
title: '通知标题',
content: '通知内容',
duration: 5000,
});41. 主菜单打开数智工场
await jssdk.mainMenu_openWorkBench({
url: 'https://example.com/workbench',
selected_path_uuid: 'uuid1',
click_path_uuid: 'uuid2',
teamId: 'team-001',
});42. 数智工场打开标签
await jssdk.workBench_openTab({
options: {
fullPath: '/workbench/tab',
title: '标签页',
icon: 'icon-url',
teamId: 'team-001',
},
openWorkBench: true,
});43. 数智工场打开标签用于 iframe
await jssdk.workBench_openTabForIframe({
title: 'iframe标签',
url: 'https://example.com/iframe',
teamId: 'team-001',
});44. 数智工场打开标签用于 webview
await jssdk.workBench_openTabForWebview({
title: 'webview标签',
url: 'https://example.com/webview',
teamId: 'team-001',
});45. 数智工场打开标签用于企业
await jssdk.workBench_openTabForEnterprise({
teamId: 'team-001',
menuId: 'menu-001',
});46. 数智工场打开标签用于商户申请
await jssdk.workBench_openTabForMerchantApply({
teamId: 'team-001',
});47. 数智工场打开标签用于接收详情
await jssdk.workBench_openTabForReceiveDetail({
title: '接收详情',
url: 'https://example.com/receive',
teamId: 'team-001',
sn: 'SN123456',
});48. 数智工场打开标签用于退款详情
await jssdk.workBench_openTabForRefundDetail({
title: '退款详情',
url: 'https://example.com/refund',
teamId: 'team-001',
sn: 'SN654321',
openLeftMenu: true,
});49. 数智工场打开标签用于结算详情
await jssdk.workBench_openTabForSettlementDetail({
title: '结算详情',
url: 'https://example.com/settlement',
teamId: 'team-001',
sn: 'SN789012',
});50. 数智工场打开组织认证
await jssdk.workBench_openTeamCertification({
teamId: 'team-001',
});51. 数智工场刷新
await jssdk.workBench_reload();52. 数字平台操作
// 设置当前团队ID
await jssdk.digitalPlatform_setActiveTeamId({ teamId: 'team-001' });
// 获取当前团队ID
const teamId = await jssdk.digitalPlatform_getActiveTeamId();
// 打开标签
await jssdk.digitalPlatform_openTab({
options: {
name: '数字平台页面',
path: '/digital-platform',
title: '数字平台',
icon: 'icon-url',
teamId: 'team-001',
},
});
// 刷新
await jssdk.digitalPlatform_reload();53. 广场操作
// 设置当前团队ID
await jssdk.square_setActiveTeamId({ teamId: 'team-001' });
// 打开标签
await jssdk.square_openTab({
options: {
label: '广场页面',
fullPath: '/square',
teamId: 'team-001',
},
});
// 刷新
await jssdk.square_reload();54. 大市场操作
// 设置当前团队ID
await jssdk.bigMarket_setActiveTeamId({ teamId: 'team-001' });
// 打开标签
await jssdk.bigMarket_openTab({
options: {
label: '大市场页面',
fullPath: '/big-market',
teamId: 'team-001',
},
});
// 刷新
await jssdk.bigMarket_reload();55. 独立窗口标签操作
// 打开标签
await jssdk.windowsTabs_openTab({
options: {
id: 'tab-001',
title: '独立标签',
url: 'https://example.com',
icon: 'icon-url',
},
tabsId: 'window-001',
tabsTitle: '窗口标题',
});
// 获取当前标签信息
const currentTab = await jssdk.windowsTabs_getCurrentTab();
// 关闭标签
await jssdk.windowsTabs_closeTab({
id: 'tab-001',
tabsId: 'window-001',
});56. 消息模块操作
// 打开聊天
await jssdk.message_openChat({
main: 'card-001',
peer: 'card-002',
});
// 打开消息
await jssdk.message_openMessage({
messageId: 'msg-001',
type: 'SINGLE',
cardId: 'card-001',
fromId: 'user-001',
});
// 打开抽屉(WebView)
await jssdk.message_openDrawerForWebview({
id: 'drawer-001',
title: '消息抽屉',
url: 'https://example.com/message-drawer',
});57. 打开外部应用
await jssdk.openExternalApp({
url: 'https://example.com',
title: '外部应用',
isInApp: true,
});58. 打开加入数字平台抽屉
const result = await jssdk.openJoinDigitalPlatformDrawer({
query: {
teamId: 'team-001',
inviteCode: 'INVITE123',
},
});59. 打开组织认证抽屉
const result = await jssdk.openOrgAuthDrawer({
query: {
region: 'CN',
teamId: 'team-001',
orgType: 'enterprise',
showType: 'detail',
},
});60. 打开添加联系人对话框
const result = await jssdk.openAddContactsDialog({
query: {
searchValue: '联系人名称',
},
});61. 打开年费抽屉
const result = await jssdk.openAnnualFeeDrawer({
query: {
teamId: 'team-001',
title: '年费管理',
open: true,
upgrade: false,
},
});62. 平台检测
// 获取平台信息
console.log('当前平台:', jssdk.platform); // 'win32' | 'darwin' | 'linux' | 'android' | 'ios' | 'unknown'
console.log('系统架构:', jssdk.arch); // 'x64' | 'ia32' | 'arm64' | 'unknown'
console.log('网络状态:', jssdk.isOnline); // true | false
// 获取环境信息
console.log('环境信息:', jssdk.env);63. 窗口管理
// 执行 JavaScript
await jssdk.executeJavaScript({
script: 'console.log("Hello from SDK");'
});
// 窗口操作
await jssdk.focus(); // 聚焦当前窗口
await jssdk.minimize(); // 最小化当前窗口
await jssdk.maximize(); // 最大化当前窗口
await jssdk.setFullScreen({ fullscreen: true }); // 设置全屏
// 浏览器操作
await jssdk.goBack(); // 后退
await jssdk.goForward(); // 前进
await jssdk.reload(); // 重新加载
await jssdk.loadURL({ url: 'https://example.com' }); // 加载新 URL64. 工具类操作
// 获取 H5 URL
const h5Url = jssdk.getH5Url('/path/to/page', 'PROD', true);
console.log('H5 URL:', h5Url);
// 获取带参数的 H5 URL
const urlWithParams = await jssdk.getH5UrlWithParams({
path: '/dashboard',
params: { userId: '123', theme: 'dark' }
});
// 应用数据存储
await jssdk.appStore({
name: 'myApp',
method: 'set',
key: 'userSettings',
value: { theme: 'dark', language: 'zh-CN' }
});
const settings = await jssdk.appStore({
name: 'myApp',
method: 'get',
key: 'userSettings'
});
// Shell 操作
await jssdk.shell({
method: 'openPath',
options: '/path/to/file'
});
// 剪贴板操作
await jssdk.clipboard({
method: 'writeText',
options: 'Hello World'
});65. 视频转码
// 转码视频
const outputPath = await jssdk.transcodeVideo({
url: 'https://example.com/video.mp4',
outputPath: '/path/to/output',
format: 'mp4',
quality: 'high'
}, (data) => {
if (data.type === 'progress') {
console.log('转码进度:', data.data.progress + '%');
} else if (data.type === 'complete') {
console.log('转码完成:', data.data.outputPath);
} else if (data.type === 'error') {
console.error('转码失败:', data.error);
}
});66. 身份卡管理
// 打开身份卡编辑窗口
await jssdk.openIdentityCardEdit({
cardId: 'card-123',
mode: 'edit',
data: {
name: '张三',
department: '技术部',
position: '工程师'
}
});
// 打开身份卡预览窗口
await jssdk.openIdentityCardPreview({
cardId: 'card-123',
readonly: true
});67. Pinia 持久化插件使用
// main.ts
import { createApp } from 'vue';
import { createPinia } from 'pinia';
import { createPiniaPersistPlugin } from '@lynker-desktop/web';
import App from './App.vue';
const app = createApp(App);
const pinia = createPinia();
// 添加持久化插件
pinia.use(createPiniaPersistPlugin(), {
rkPersistEnable: true,
piniaPersistTempKey: 'my-app'
});
app.use(pinia);
app.mount('#app');
// store/user.ts
import { defineStore } from 'pinia';
export const useUserStore = defineStore('user', {
state: () => ({
name: '',
avatar: '',
preferences: {}
}),
actions: {
updateUser(userData) {
this.name = userData.name;
this.avatar = userData.avatar;
// 状态会自动同步到桌面端应用存储
}
}
});
// 在组件中使用
const userStore = useUserStore();
userStore.updateUser({ name: '张三', avatar: 'avatar.jpg' });
// 状态变化会自动同步到其他窗口Pinia 持久化插件
createPiniaPersistPlugin() - 创建 Pinia 持久化插件
createPiniaPersistPlugin(): PiniaPluginContext<{ options: PiniaPersistOptions }>['plugin']创建 Pinia 持久化插件,支持在桌面端环境中自动同步状态到应用存储。
功能特性:
- 自动将 Pinia 状态同步到桌面端应用存储
- 支持多窗口状态同步
- 防止死循环更新
- 仅在桌面端环境中生效
使用示例:
import { createPinia } from 'pinia';
import { createPiniaPersistPlugin } from '@lynker-desktop/web';
const pinia = createPinia();
// 添加持久化插件
pinia.use(createPiniaPersistPlugin(), {
rkPersistEnable: true,
/** 是否持久化存储(重启后保留数据)
* - true: 持久化存储,数据在应用重启后保留
* - false: 临时存储,数据在应用重启后清空(默认值)
*
* 注意:临时存储的文件名会添加 __temp__ 前缀标识
*/
rkPersistIsPersistent: true
});
// 在组件中使用
const store = useStore();
// 状态变化会自动同步到桌面端应用存储
store.updateData(newData);配置选项:
interface PiniaPersistOptions {
rkPersistEnable: boolean; // 是否启用持久化
rkPersistIsPersistent?: boolean; // 是否持久化存储(重启后保留数据)
}注意事项:
- 仅在桌面端环境中生效,浏览器环境中会被忽略
- 状态同步是异步的,可能存在短暂延迟
- 建议在应用初始化时设置,避免中途启用导致状态不一致
📝 类型定义
核心接口
LynkerSDKConfig
interface LynkerSDKConfig {
readonly env: 'DEV' | 'TEST' | 'PRE' | 'PROD';
readonly h5Host: h5HostEnum;
readonly h5Getway: h5GetwayEnum;
i18n: string;
token: string;
launchOptions: string;
preloadPath: string;
viteConfig: {
VITE_APP_TITLE: string;
VITE_MAP_KEY: string;
VITE_APP_REGION: string;
VITE_API_ENV: string;
VITE_IM_KEY: string;
VITE_WPS_KEY: string;
VITE_UMEN_PID: string;
VITE_USER_NODE_ENV: string;
VITE_APP_CONFIG_INFO: string;
VITE_APP_MAS: boolean;
};
}UserInfo
interface UserInfo {
openid: string;
title: string;
avatar: string;
gender: number;
email: string;
cellphone: string;
telephone: string;
birthday: number;
region: string;
hidden: null;
slogan: string;
attachments: {
options: AttachmentOption[];
};
area: string;
link_id: string;
account_email: string;
account_mobile: string;
account_mobile_region: string;
removed: boolean;
address: string;
apply_removed: boolean;
psn_auth: boolean;
channel: string;
channel_params: string;
account_login_info: AccountLoginInfo;
}WorkBenchTabOptions
interface WorkBenchTabOptions {
fullPath: string;
title: string;
icon: string;
teamId?: string;
activeIcon?: string;
pathName?: string;
updateKey?: string;
type?: number;
query?: Record<string, string>;
beforeCloseOptions?: {
title?: string;
content?: string;
};
beforeRefreshOptions?: {
title?: string;
content?: string;
};
}枚举类型
h5HostEnum
enum h5HostEnum {
'TEST' = 'https://web-qa.ringkol.com',
'DEV' = 'https://web-dev.ringkol.com',
'PRE' = 'https://web-pre.ringkol.com',
'PROD' = 'https://web.ringkol.com',
}h5GetwayEnum
enum h5GetwayEnum {
'TEST' = 'https://h5-qa.ringkol.com',
'DEV' = 'https://h5-dev.ringkol.com',
'PRE' = 'https://h5-pre.ringkol.com',
'PROD' = 'https://h5.ringkol.com',
}RendererIPC
/**
* 基于 @lynker-desktop/electron-ipc 的渲染进程 IPC 通信类
* 提供类型安全的进程间通信功能,支持并发请求和 requestId 机制
*/
class RendererIPC {
/**
* 原生 ipcRenderer 实例
* 提供对 Electron 原生 IPC 功能的访问
*/
static get ipcRenderer(): Electron.IpcRenderer;
// ==================== 主进程通信 ====================
/**
* 发送消息到主进程
* 使用 Electron 原生的 invoke 方法,支持并发请求
*
* @param channel 消息通道名称
* @param args 传递给处理器的参数
* @returns Promise<any> 返回处理结果
*
* 特性:
* - 支持并发请求,不会互相干扰
* - 使用 Electron 原生 invoke 方法
* - 自动处理错误和超时
*/
static invokeMain(channel: string, ...args: any[]): Promise<any>;
/**
* 处理主进程发送过来的消息
*
* @param channel 消息通道名称
* @param handler 处理函数,接收除 requestId 外的所有参数
* @returns 返回取消函数,用于移除处理器
*
* 特性:
* - 返回取消函数,支持动态移除处理器
* - 处理函数必须返回 Promise
*/
static handleMain(
channel: string,
handler: (...args: any[]) => Promise<any>
): {
cancel: () => void;
};
// ==================== 渲染进程通信 ====================
/**
* 发送消息到所有渲染进程
* 使用唯一的 requestId 确保并发请求不会互相干扰
*
* @param channel 消息通道名称
* @param args 传递给渲染进程的参数
* @returns Promise<any> 返回渲染进程的处理结果
*
* 特性:
* - 向所有渲染进程发送消息
* - 使用 requestId 机制避免并发冲突
* - 自动等待渲染进程加载完成
*/
static invokeRenderer(channel: string, ...args: any[]): Promise<any>;
/**
* 处理渲染进程发送过来的消息
* @param channel 消息通道名称
* @param handler 处理函数,接收除 requestId 外的所有参数
* @returns 返回取消函数,用于移除处理器
*
* 特性:
* - 返回取消函数,支持动态移除处理器
* - 处理函数必须返回 Promise
*/
static handleRenderer(
channel: string,
handler: (...args: any[]) => Promise<any>
): {
cancel: () => void;
};
// ==================== 工具方法 ====================
/**
* 获取当前渲染进程的 WebContents ID
* @returns Promise<number> 当前渲染进程的 ID
*/
static getCurrentWebContentId(): Promise<number>;
/**
* 打开当前窗口的开发者工具
* @returns Promise<number> 操作结果
*/
static openCurrentWebContentDevTools(): Promise<number>;
}MainIPC
/**
* 主进程 IPC 通信类
* 负责处理主进程与渲染进程之间的消息通信
* 使用单例模式确保全局唯一实例
*
* 修复说明:
* - 为每个请求生成唯一的 requestId,解决并发请求数据错乱问题
* - 确保请求和响应能够正确匹配,避免多个并发请求互相干扰
*/
class MainIPC {
static instance: MainIPC;
private eventEmitter: EventEmitter;
constructor();
// ==================== 主进程通信 ====================
/**
* 发送给主进程消息
* 使用唯一的 requestId 确保并发请求不会互相干扰
*
* @param channel 消息通道名称
* @param args 传递给处理器的参数
* @returns Promise<unknown> 返回处理结果
*
* 修复说明:
* - 为每个请求生成唯一的 requestId
* - 监听 `${channel}-reply-${requestId}` 事件,确保只接收对应请求的回复
* - 发送请求时包含 requestId,让处理器知道如何回复
*/
invokeMain(channel: string, ...args: any[]): Promise<unknown>;
/**
* 处理主进程发送过来的消息
* 持续监听指定通道的消息
*
* @param channel 消息通道名称
* @param handler 处理函数,接收除 requestId 外的所有参数
* @returns 返回取消函数,用于移除处理器
*
* 修复说明:
* - 接收 requestId 作为第一个参数
* - 使用 `${channel}-reply-${requestId}` 发送回复,确保回复给正确的请求
* - 支持多个并发请求,每个请求都有独立的回复通道
*/
handleMain(
channel: string,
handler: (...args: any[]) => Promise<any>
): {
cancel: () => void;
};
// ==================== 渲染进程通信 ====================
/**
* 发送给渲染进程消息
* 使用唯一的 requestId 确保并发请求不会互相干扰
*
* @param webContents 目标渲染进程的 WebContents 对象
* @param channel 消息通道名称
* @param args 传递给渲染进程的参数
* @returns Promise<any> 返回渲染进程的处理结果
*
* 修复说明:
* - 为每个请求生成唯一的 requestId
* - 监听 `${channel}-reply-${requestId}` 事件,确保只接收对应请求的回复
* - 发送请求时包含 requestId,让渲染进程知道如何回复
* - 等待渲染进程加载完成后再发送消息,确保消息能够被正确接收
*/
invokeRenderer(
webContents: Electron.WebContents,
channel: string,
...args: any[]
): Promise<any>;
/**
* 发送给所有渲染进程消息
* 向所有渲染进程发送消息并收集所有响应
*
* @param channel 消息通道名称
* @param args 传递给所有渲染进程的参数
* @returns Promise<any> 返回所有渲染进程的处理结果数组
*
* 修复说明:
* - 为每个请求生成唯一的 requestId
* - 收集所有渲染进程的响应,当所有响应都收到时才 resolve
* - 使用 `${channel}-reply-${requestId}` 确保只接收对应请求的回复
* - 如果没有渲染进程,直接返回空数组
* - 等待每个渲染进程加载完成后再发送消息
*/
invokeAllRenderer(channel: string, ...args: any[]): Promise<any>;
/**
* 处理渲染进程发送过来的消息
* 持续监听指定通道的消息,支持超时处理
*
* @param channel 消息通道名称
* @param handler 处理函数,接收除 requestId 外的所有参数
* @returns 返回取消函数,用于移除处理器
*
* 修复说明:
* - 接收 requestId 作为第一个参数
* - 使用 ipcMain.handle 替代 ipcMain.on,提供更好的错误处理
* - 支持 8 秒超时机制,避免长时间等待
* - 支持并发请求,每个请求都有独立的处理流程
* - 提供详细的错误日志记录
*/
handleRenderer(
channel: string,
handler: (...args: any[]) => Promise<any>
): {
cancel: () => void;
};
// ==================== 消息中继 ====================
/**
* 初始化消息中继功能
* 设置消息转发和回复机制,支持跨渲染进程通信
*
* 功能说明:
* - relay-message: 转发消息到指定的渲染进程或所有渲染进程
* - relay-reply: 处理回复消息,广播给所有渲染进程
* - __GetCurrentWebContentId__: 获取当前 WebContent ID
* - __OpenCurrentWebContentDevTools__: 打开当前 WebContent 的开发者工具
*/
relayMessage(): void;
}
/**
* 全局 MainIPC 实例
* 使用全局变量确保单例模式,避免重复创建实例
*/
declare const mainIPC: MainIPC;
/**
* 初始化 IPC 通信系统
* 设置消息中继功能,确保跨进程通信正常工作
*
* @returns MainIPC 实例
*
* 功能说明:
* - 检查是否已经初始化,避免重复初始化
* - 设置消息中继功能,支持跨渲染进程通信
* - 返回全局 MainIPC 实例
*/
declare const initialize: () => MainIPC;❓ 常见问题
Q: 如何判断当前是否在桌面端环境?
A: 使用 jssdk.isDesktop 属性进行判断:
if (jssdk.isDesktop) {
// 桌面端环境
} else {
// 浏览器环境
}Q: 为什么某些 API 调用失败?
A: 可能的原因包括:
- 未在桌面端环境中运行
- 桌面端应用版本过低
- 网络连接问题
- 权限不足
Q: 如何处理异步操作?
A: 所有 API 方法都是异步的,建议使用 async/await:
try {
const result = await jssdk.getUserInfo();
console.log(result);
} catch (error) {
console.error('操作失败:', error);
}Q: 如何开启调试模式?
A: 调用 jssdk.setDebug(true) 开启调试日志:
jssdk.setDebug(true);
// 现在会输出详细的调试信息Q: IPC 通信失败怎么办?
A: 可能的原因和解决方案:
- 检查频道名称是否正确
- 确保主进程已注册对应的处理器
- 检查参数类型是否匹配
- 使用 try-catch 处理异步错误
Q: 如何选择合适的 IPC 方法?
A: 根据使用场景选择:
invokeMain/handleMain: 主进程通信,支持并发请求invokeRenderer/handleRenderer: 广播消息到所有渲染进程- 使用
cancel()方法可以动态移除处理器
Q: IPC 消息处理函数必须返回 Promise 吗?
A: 是的,所有 IPC 消息处理函数都必须返回 Promise,即使没有异步操作:
// ✅ 正确
jssdk.ipc.handleMain('sync-data', async (data) => {
console.log(data);
return 'success'; // 返回普通值
});
// ✅ 正确
jssdk.ipc.handleMain('async-operation', async (data) => {
const result = await someAsyncOperation(data);
return result; // 返回Promise
});Q: 如何调试 IPC 通信问题?
A: 可以通过以下方式调试:
// 1. 开启调试模式
jssdk.setDebug(true);
// 2. 添加日志记录
jssdk.ipc.handleMain('debug-channel', async (data) => {
console.log('收到主进程消息:', data);
return { received: true, ti