前端 OpenSDK 能力说明
1. 能力概览
观远 BI 自 6.3 版本开始提供全新的 OpenSDK , 可以通过调用特定方法实现数据获取、信息交互、页面改造、样式修改等定制化改造需求。
适用范围:自定义图表、StarNova 集成、前端插件、自定义筛选器。
示例代码:https://github.com/GuandataOSS/sdk-demo
适用开发语言:Javascript
能力列表:
| 接口类别 | 接口中文名 | 生效版本 | 
|---|---|---|
| 数据获取 | 获取当前用户信息 | 6.3.0 | 
| 交互触答 | 信息通知 | |
| 路由跳转 | ||
| 样式修改 | 隐藏特定元素 | |
| 插入或者删除样式 | ||
| 事件注册 | 事件注册 | |
| web-component注册 | web-component元素注册 | 5.2.0 | 
| 自定义筛选器 | 注册自定义筛选器 | 7.2.0 | 
| 获取自定义筛选器 | ||
| 资源加载 | 异步加载脚本 | |
| 获取资源链接 | 
特别说明:window, document, Function, globalThis, navigator, fetch, XMLHttpRequest 操作目前只允许在自定义图表、StarNova里使用;前端插件基于安全原因暂未开放相关能力。
2. 接口详情
2.1. 数据获取
获取当前登录用户信息
生效版本:6.3.0
使用方法
GD.getUser()
请求参数
无
返回值
Object
| 字段 | 类型 | 说明 | 
| domId | string | 域id | 
| domainName | string | 域名 | 
| uId | string | 用户id | 
| loginId | string | 账号 | 
| role | string[] | 角色列表 | 
| userProperties | Object[] | 用户属性 | 
其中 userProperties 的接口如下:
| 字段 | 类型 | 说明 | 
| key | string | 字段名 | 
| alias | string | 别名 | 
| value | string | 字段值 | 
| isUserDefined | boolean | 是否为用户自定义属性 | 
2.2. 交互触达
注意:
SDK 和插件加载会在 BI 渲染完成前,请勿在加载完成后直接调用 event- 的事件方法
调用消息通知
功能描述:支持特定操作后,提示用户操作的结果,如提示成功或者失败。消息样式与观远 BI 完全一致。
生效版本:6.3.0
使用方法
GD.dispatch(msgType, { msg, ntfType: 0 })
请求参数
| 字段 | 类型 | 说明 | 
| msgType | string | 消息类型: ·event-SYS_FETCH_SUCCESS 成功消息 ·event-SYS_FETCH_FAIL 失败消息 | 
| msg | string | 消息内容 | 
| ntfType | int | 默认为0 ,必填 | 
调用示例
GD.dispatch('event-SYS_FETCH_SUCCESS', { msg: '操作成功', ntfType: 0 })
GD.dispatch('event-SYS_FETCH_FAIL', { msg: '操作失败:原因是……', ntfType: 0 })
路由跳转
生效版本:6.3.0
使用方法
跳转:GD.dispatch('event-SYS_ROUTE_PUSH', url)
替换:GD.dispatch('event-SYS_ROUTE_REPLACE', url)
返回:GD.dispatch('event-SYS_ROUTE_BACK')
请求参数
| 字段 | 类型 | 说明 | 
| url | string | 跳转地址 | 
2.3. 样式修改
页面展示内容隐藏
完整前端页面隐藏功能,参考[前端页面元素隐藏](5-更多集成与开放能力/0-前端页面元素隐藏.md)。 功能描述: 隐藏页面特定元素,比如仪表板页面导出按钮等生效版本:6.3.0
使用方法
GD.dispatch('config-display-control', { hiddenKeys })
请求参数
| 字段 | 类型 | 说明 | 
| hiddenKeys | string[] | 隐藏内容标识的数组 | 
可识别的标识列表
| 标识名 | 展示内容 | 生效版本 | 
| webapp_export | 桌面端应用头部导出 | |
| page_operation_batch_export | 仪表板页面头部菜单【批量导出 PDF、批量导出 Excel 】 | 
请求示例
GD.dispatch('config-display-control', { hiddenKeys: ['webapp_export'] })
插入或者删除样式
生效版本:6.3.0
使用方法
GD.dispatch('style', { title, content })
请求参数
| 字段 | 类型 | 说明 | 
| title | string | 样式标题 | 
| content | string | 样式内容(支持url,不填则删除对应标题的插入样式内容) | 
常规的css,如 a、h1 均可以进行修改。
请求示例
// 插入标题为黑白的样式
GD.dispatch('style', { title: '黑白', content: 'body{ filter: grayscale(1); }' })
// 删除已插入的黑白样式
GD.dispatch('style', { title: '黑白' })
// 通过外链引入样式
GD.dispatch('style', { title: '外链1', content: 'http*' })
2.4. 事件注册
事件注册基础方法
生效版本:6.3.0
使用方法
GD.on(eventKey, callback, introduce)
请求参数
| 字段 | 类型 | 说明 | 
| eventKey | string | 事件名称 | 
| callback | function | 注册方法 | 
| introduce | string | 方法介绍(选填) | 
可识别的事件名称
| 方法介绍(选填) | 事件用途 | 生效版本 | 
| open-page | 自定义路由加载完成 | 6.3.0 | 
| gd-ready | sdk初始化完成 | 6.5.0 | 
| gd-route-change | 页面路由变化 | 6.5.0 | 
自定义路由加载完成 open-page
事件可用参数
| 字段 | 类型 | 说明 | 
| params | object | 参数对象 | 
params参数格式
| 字段 | 类型 | 说明 | 
| pathname | string | url路径 | 
| search | string | url参数 | 
| state | object | 状态对象 | 
事件调用示例
function openRedirect ({ pathname, search }) {
  if (pathname !== '/open/redirect') return
  const obj = {};
  const searchParams = new URLSearchParams(search);
  const userInfo = GD.getUser()
  for (const [key, value] of searchParams) {
    obj[key] = value;
  }
  if (!obj.get('redirectUrl')) return
  location.href = `${obj.get('redirectUrl')}?loginId=${userInfo.loginId}`
}
GD.on('open-page', openRedirect, '用户id拼接跳转')
SDK初始化完成 gd-ready
事件调用示例
let userInfo = GD.getUser()
console.log('userInfo-1', userInfo) // 无法获取到用户信息
GD.on('gd-ready', () => {
    userInfo = GD.getUser()
    console.log('userInfo-2', userInfo) // 能够获取到用户信息
})
页面路由变化 gd-route-change
事件可用参数
| 字段 | 类型 | 说明 | 
| params | object | 跳转路由信息 | 
params参数格式
| 字段 | 类型 | 说明 | 
| pathname | string | 当前url的路径部分 | 
| hash | string | 当前url的锚点部分 | 
| search | string | 当前url的参数部分 | 
事件调用示例
class PortalFloatActionButton {
  // ...
}
customElements.define('portal-float-action-button', PortalFloatActionButton)
GD.on('gd-route-change', params => {
    const { pathname } = params
    console.log('params', params)
    if (['/home', '/m/portal'].includes(pathname)) {
        if (compDiv) return
        compDiv = document.createElement('div');
        compDiv.className = 'pos-absolute scroll-hidden';
        compDiv.style.right = '0';
        compDiv.style.bottom = '80px';
        compDiv.style.zIndex = '999';
        compDiv.style.width = '48px';
        compDiv.style.height = '48px';
        
        // 创建portal-float-action-button元素
        const portalFloatActionButton = document.createElement('portal-float-action-button');
        const userInfo = GD.getUser()
        
        portalFloatActionButton.setAttribute('loginid', userInfo.loginId);
        portalFloatActionButton.setAttribute('userid', userInfo.uId);
        
        // 将portal-float-action-button元素添加到新的div元素中
        compDiv.appendChild(portalFloatActionButton);
        
        // 将新的div元素添加到body元素中
        document.getElementById('app').appendChild(compDiv);
    } else if (compDiv) {
        compDiv.remove()
        compDiv = null
    }
})
2.5. web-component注册
基础方法
生效版本:6.3.0
使用方法
window.customElements.define(elementKey, CustomElement)
请求参数
| 字段 | 类型 | 说明 | 
| elementKey | string | 元素名称 | 
| Component | element | 自定义元素 | 
请求示例 - 开放性路由
元素名称:open-page
支持版本:6.3.0
渲染场景:/open/* 路由页面中
渲染参数
| 字段 | 类型 | 说明 | 
| pathname | string | url路径 | 
| search | string | url参数 | 
示例代码
class MyListComponent extends HTMLElement {
  async renderPage1() {
    this.innerHTML = `
      这是一个页面    `
  }
  async renderPage2() {
    this.innerHTML = `
      这是另一个页面,只有管理员能看到    `
    
  }
  connectedCallback() {
    const pathname = this.getAttribute('pathname')
    const userInfo = GD.getUser()
    if (pathname ==='/open/page1') {
      this.renderPage1();
    } else if (pathname === '/open/page2' && userInfo.role.includes('admin')) {
      this.renderPage2()
    } else {
      this.innerHTML = '该页面不存在'
    }
  }
}
customElements.define('open-page', MyListComponent);
请求示例 - 仪表板悬浮按钮
元素名称:page-feedback
支持版本:5.2.0
渲染场景:仪表板页面右下角悬浮(支持移动端)
渲染参数
| 字段 | 类型 | 说明 | 
| pgid | string | 页面id | 
请求示例 - 仪表板/数据大屏 无权限
元素名称:request-permission
支持版本:6.3.0
渲染场景:【暂无访问权限】文案下方插入
渲染参数
| 字段 | 类型 | 说明 | 
| rid | string | 资源id | 
示例代码
class MyComponent extends HTMLElement {
  connectedCallback() {
    // 获取渲染参数
    const rId = this.getAttribute('rId');
    this.innerHTML = `
                      页面id: ${rId}        跳转                     `;
  }
}
customElements.define('request-permission', MyComponent);
2.6.自定义筛选器
注册自定义筛选器
GD.registerCustomSelector
功能描述
用于注册自定义筛选器组件。注册的组件可以在新建自定义筛选器时选择。
使用说明
// 参数类型
interface ICustomSelector {
    id: string       // 唯一标识符,相同 ID 会覆盖
    title: string    // 选择器标题,展示在列表中供用户选择
    desc: string     // 选择器描述,展示在列表中供用户选择
    tagName: string  // 选择器标签名,即作为 Web Component 注册和使用时的 tagName
    configFormSchema: any[]  // 配置表单定义,乐高表单系统的标准格式,参考:https://guandata.yuque.com/guandataweb/dsebtl/iefgq3
    load: () => void  // 加载函数
}
// 使用示例
const myCustomSelector = {
    id: 'my-custom-selector',
    title: '我的自定义选择器',
    desc: '这是一个自定义选择器示例',
    tagName: 'custom-tag',
    configFormSchema: [
        // 配置表单定义
    ],
    load: () => {
        // 在这里实现选择器的加载逻辑
        class MyCustomElement extends HTMLElement { ... }
        window.customElement.define(
            'custom-tag', // 和 tagName 对应
            MyCustomElement
        )
    }
};
GD.registerCustomSelector(myCustomSelector)
注意事项
- 如果注册的 id 已存在,将会覆盖现有选择器而不是添加新的筛选器
 - 可以通过 
GD.getCustomSelectors()函数获取所有已注册的自定义筛选器 
获取自定义筛选器
GD.getCustomSelectors
功能描述
用于获取 GD.registerCustomSelector 注册成功的所有自定义筛选器。返回值为数组,数组中的元素即位 GD.registerCustomSelector()调用时传入的对象
使用说明
GD.getCustomSelectors()
// => [ { id, title, tagName, ... }, { ... } ]
2.7.资源加载
异步加载脚本
GD.asyncLoadScript
功能描述
用于异步加载外部脚本或样式文件,返回一个 Promise 对象表示加载状态。该函数支持缓存,以 url 为唯一标识,确保同一资源只会被加载一次。
使用说明
// 加载普通 script 文件
await GD.asyncLoadScript('https://example.com/script.js')
// 结果:<script src="https://example.com/script.js" defer></script>
// 加载 ES 模块脚本
await GD.asyncLoadScript('https://example.com/module.js', { type: 'module' })
// 加载 CSS 样式文件
await GD.asyncLoadScript('https://example.com/styles.css', { tagName: 'link' })
// 设置自定义属性
await GD.asyncLoadScript('https://example.com/script.js', {
  async: true,
  crossOrigin: 'anonymous',
  integrity: 'sha384-...'
});
注意事项
- 
函数会缓存已加载的脚本,避免重复加载同一资源
 - 
脚本加载有三种状态:
- 未加载过或加载失败:需要重新加载
 - 加载中:返回正在进行的加载Promise
 - 加载成功:直接返回已解决的Promise
 
 - 
默认超时时间为120秒,超时后会自动失败并清理DOM元素
 - 
加载失败时会从DOM中移除创建的元素并重置缓存状态
 - 
可以在选项中传入额外属性来自定义脚本或样式的加载行为,以满足
type="module"等场景 - 
对于CSS文件,需要通过
{ tagName: 'link' }选项指定创建 link 标签而非 script 标签,以实现<link rel="stylesheet" type="text/css" href="..." >的效果 
获取资源链接
GD.getResourceUrl
功能描述
获取 BI 提供的几种固定的资源链接,返回资源链接字符串。
配合 GD.asyncLoadScript 用于加载 shoelace,lit 等资源。
目前提供的资源包含以下这些:
| 资源名称 | 资源说明 | 
| lit | Lit 框架核心资源,引入后可使用 window.lit | 
| shoelace | Shoelace autoloader,引入后可使用 window.shoelaceAutoloader | 
| shoelace-theme-light | Shoelace 浅色主题文件,css | 
| shoelace-theme-dark | Shoelace 深色主题文件,css | 
使用说明
// lit
const litUrl = GD.getResourceUrl('lit') // 如:"/static/vendor/lit@3.2.1/lit-core.min.js"
await GD.asyncLoadScript(litUrl, { type: 'module' })
// shoelace autoloader 和深浅色主题
await GD.asyncLoadScript(GD.getResourceUrl('shoelace'), { type: 'module' })
await GD.asyncLoadScript(GD.getResourceUrl('shoelace-theme-light'), { tagName: 'link' })
await GD.asyncLoadScript(GD.getResourceUrl('shoelace-theme-dark'), { tagName: 'link' })
