页面树结构

版本比较

标识

  • 该行被添加。
  • 该行被删除。
  • 格式已经改变。

本章节介绍如何部署二次开发环境,并通过两个简单示例让用户快速上手仪表盘二次开发。使用Vue框架的功能模块:仪表盘、指标管理、流程引擎、基于模型创建的即席查询

本章节介绍如何部署二次开发环境,并以仪表盘为示例让用户快速上手Vue框架相关功能的二次开发。

  

目录

1、基础要求

注意

本次环境配置,只需在 “扩展包开发环境” 的基础上增加二开扩展包环境即可,用户预先安装扩展包开发环境,部署方式请参考 扩展包开发环境部署

(1)通过安装包:node-v16.14.2-win-x64.zip 安装node环境,详情可参考:node环境安装文档

(2)此版本已经自带npm,对于二开人员:

  • 学习命令操作可参考: npm命令使用文档
  • 学习框架开发可参考:Vue官网(注意:版本为Vue2,暂不支持其它Vue版本)

2、环境配置

注意

(1)V10.5以下版本不支持仪表盘二次开发;

(2)对于仪表盘二次开发:可在原有扩展包基础上加上包:webpack .zip(包含下面两个示例的基础文件,下载后按说明可直接使用)

(1)进入扩展包根目录的src;

(2)解压webpack项目,打开终端控制台cd 到webpack目录,运行下载smartbi二开环境基础包命令:

代码块
linenumberstrue
npm install smartbi-ext-env

得到的目录结构如下:

在二开环境中,常用命令如下:

  • 开发调试命令:
代码块
linenumberstrue
npm run dev  //开发调试命令
  • 打包命令:


代码块
linenumberstrue
npm run build  //打包命令

3、开发调试

运行开发调试命令:

代码块
linenumberstrue
npm run dev 

每当代码修改的时候,系统会帮你自动编译,刷新页面即可看到新的效果。

3.1 常见问题

问题:为什么改了代码,没有效果?

解决方法:请仔细查看以下几个步骤:

1、如果要调试smartbi,最好在url中增加debug=true参数(如:http://192.168.1.10:16000/smartbi/vision/index.jsp?debug=true),否则扩展包会有缓存,代码修改后不会更新。

2、配置extension.list;

3、修改SmartbiPluginApp/apache-tomcat-7.0.42/webapps/smartbi/WEB-INF下的web.xml文件:

  • 在文件中加入 DevEnv 对应的四行代码;
  • 在文件中找到 ProductName 的 <context-param>;
  • 在其下面添加 DevEnv 对应的四行<context-param>,其值为 true。

修改同样是web.xml中如图所示的位置

Image Added

具体调试技巧可参考:调试&定位技巧

4、仪表盘组件新增和修改

4.1

组件新增示例4.1.1 入门版

功能修改示例

(1)需求场景

在仪表盘的组件选择器中,新增一个组件,组件中显示一个简单的文字hello。在仪表盘预览菜单栏,点击工具栏弹出hello。

(2)示例效果

Image RemovedImage Added

(3)操作步骤

信息
iconfalse
title说明
  • index文件是入口文件;
  • providerMetaInfo是入口方法;
  • vue文件是具体实现的业务文件;

    a.在根目录下的src/webpack/src/plugins/addExtenders中创建组件文件夹:modifyExtenders下创建组件文件夹,下面以仪表盘预览菜单栏为例:

    • 添加文件夹helloView添加文件夹dashFlexMenuExtension;
    • 在文件夹下创建index.js及HelloViewjs及FlexMenuExtension.vuejs两个文件;

    Image RemovedImage Added

    b.在index.js文件中实现providerMetaInfo方法,返回的是一个对象,具体对象的属性可以参考仪表盘组件接口文档js文件中实现provdieMetaInfo方法,FlexMenuExtension.vue导出的是一个FlexMenuExtension对象:

    js
    代码块
    language
    linenumberstrue
    collapsetrue
    import HelloViewFlexMenuExtension from './HelloView.vueFlexMenuExtension'
    
    const provideMetaInfo = () => {
    //入口方法     return// {二开文件
        return { nameimplement: '模版DEMO', // 组件名称
      FlexMenuExtension}
     }
    export default {
       type: 'HELLO', // 组件类型(不能轻易修改)
          svg: 'db-left-widget__chart-pie',
          entry: { // 组件入口,可以从仪表盘工具栏中直接添加(不配置就只能通过智能配图切换出来)
       provideMetaInfo
    }

    c.FlexMenuExtension.js:

    信息
    title说明
    • BaseDashExtender是一个基类,系统提供了内置方法
    • install是入口方法
    • on方法是向系统添加某个事件的处理程序,系统在这个时机就会触发此方法回调。


    代码块
    languagejs
    linenumberstrue
    collapsetrue
    import SmartBIExt from  'smartbi-ext'
    let {
      DashModule: {
        DashEventEmum: {
          title: 'Hello入口', // 在组件入口中显示的名称,不填显示组件名称
     PAGE_ON_FLEX_MENU_INIT
        },
        BaseDashExtender
      }
    order:} 15,= //SmartBIExt
    组件入口中的顺序,默认放在最后
    class FlexMenuExtender extends BaseDashExtender {
     }, 
      constructor() {
     // 组件文件  super()
        portletImplement:HelloView}
    
       }
    }
    
    export default {
      provideMetaInfo
    }

    c.在HelloView.vue中编写自己的业务代码

    代码块
    linenumberstrue
    collapsetrue
    <template>install () {
        <div>hello</div>
    </template> <script> exportpage菜单初始化
    default {   name: 'hello'
    }
    </script>

    4.1.2 简单版

    (1)需求场景

    在仪表盘的组件选择器中,新增一个清单表组件,具备取数功能。

    this.on(PAGE_ON_FLEX_MENU_INIT, iFlexMenu => {
          iFlexMenu.removeItem(1)
          iFlexMenu.insertItem(3, {
            id: 'TEST',
            icon: 'sx-icon-like',
            label: '测试',
            color: '#ed6b1f',
            handler: () => {
              alert('测试按钮')
            }
          })
        })
      }  
    
    }
    
    export default FlexMenuExtender

    4.2 组件新增示例

    注意
    title注意

    组件新增场景仅支持仪表盘。

    4.2.1 入门版

    (1)需求场景

    在仪表盘的组件选择器中,新增一个组件,组件中显示一个简单的文字hello。

    (2)示例效果

    Image Added

    (3)操作步骤

    信息
    iconfalse
    title说明
    • index文件是入口文件;
    • providerMetaInfo是入口方法;
    • vue文件是具体实现的业务文件;

    a.在根目录下的src/webpack/src/plugins/addExtenders中创建组件文件夹:

    • 添加文件夹helloView
    • 在文件夹下创建index.js及HelloView.vue

    Image Added

    b.在index.js文件中实现providerMetaInfo方法,返回的是一个对象,具体对象的属性可以参考仪表盘组件接口文档

    代码块
    languagejs
    linenumberstrue
    collapsetrue
    import HelloView from './HelloView.vue'
    
    const provideMetaInfo = () => { //入口方法
        return {
          name: '模版DEMO', // 组件名称
          type: 'HELLO', // 组件类型(不能轻易修改)
          svg: 'db-left-widget__chart-pie',
          entry: { // 组件入口,可以从仪表盘工具栏中直接添加(不配置就只能通过智能配图切换出来)
              title: 'Hello入口', // 在组件入口中显示的名称,不填显示组件名称
              order: 15, // 组件入口中的顺序,默认放在最后
          },
          // 组件文件
          portletImplement:HelloView
        }
    }
    
    export default {
      provideMetaInfo
    }

    c.在HelloView.vue中编写自己的业务代码

    代码块
    linenumberstrue
    collapsetrue
    <template>
      <div>hello</div>
    </template>
    <script>
    export default {
      name: 'hello'
    }
    </script>

    4.2.2 简单版

    (1)需求场景

    在仪表盘的组件选择器中,新增一个清单表组件,具备取数功能。

    (2)示例效果

    (3)操作步骤

    a.在根目录下的src/webpack/src/plugins/addExtenders下创建组件文件夹:

    • 添加文件夹newTableView;
    • 在文件夹下创建index.js及NewTableView.vue;

    Image Modified

    b.在index.js文件中实现providerMetaInfo方法,返回的是一个对象,具体对象的属性可以参考仪表盘组件接口文档

    代码块
    languagejs
    linenumberstrue
    collapsetrue
    import NewTableView from './NewTableView.vue'
    function provideMetaInfo () {
      return {
        name: '新清单表', // 组件名称
        type: 'NEW_TABLE', // 组件类型
        svg: 'db-left-widget__table-list',
        icon: 'sx-icon-widget-table-list icon-16',
        class: 'TABLE_LIST',
        entry: { // 组件入口
          id: 'Table', // 组件入口中的分类类别 Chart | Table | Indicator,默认为Custom
          index: 1, // 组件入口中的顺序,默认放在最后,注意:这里是分类中包含所有子类型的排序
          canSwitch: true // 是否能切换组件
        },
        freeSize: {
          width: 400,
          height: 260
        },
        fieldRules: [{ // 字段区配置,可以理解为行列区和标记区配置
          areaType: 'cols',
          tips: '',
          rule: {
            fieldCount: {
              min: 0
            }
          }
        }],
        // 组件文件
        portletImplement: NewTableView
      }
    }
    
    export default {
      provideMetaInfo
    }

    (说明:fieldRules:是字段区配置,可以理解为行列区和标记区规则配置

    c.在NewTableView.vue中编写自己的业务代码:

    • Smartbi 节点下main节点下,refresh方法,是系统通知组件更新的一个时机
    • this.pageProxy.api.fetchPortletData(queryFields)是组件主动调用系统取数api,进行取数。
    代码块
    linenumberstrue
    collapsetrue
    <template>
       <div slot="notEmpty" style="height: 100%;" >
         <table v-if = "gridDataModel">
           <th>
             <td
               v-for="field in gridDataModel.getFields()"
               :key="field.uniqueId">
               {{ field.alias }}
             </td>
           </th>
           <tr
             v-for="row in gridDataModel.getRowCount()"
             :key="row">
             <td
               v-for="field in gridDataModel.getFields()"
               :key="row + field.uniqueId">
               {{ gridDataModel.getDisplayValueByRowAndUid(row - 1, field.uniqueId) }}
             </td>
           </tr>
         </table>
       </div>
    </template>
    <script>
    export default {
      name: 'NewTableView',
      data () {
          return {
            options: {},
            gridDataModel: null
          }
       },
       props: {
           pageProxy: {}
       },
      smartbi: {
        main: {
          refresh () {
            this.fetchData()
          }
        }
      }, {
        methodsmain: {
          async fetchDatarefresh () {
            consolethis.logfetchData(123)
          }
     let queryFields = this.generateQueryFields()}
      },
         if (queryFields.length === 0)methods: {
          async fetchData () {
    return         }console.log(123)
            let optionsqueryFields = await this.pageProxy.api.fetchPortletDatagenerateQueryFields(queryFields)
            let {
       if (queryFields.length === 0) {
          gridDataModel, // 二维表模型,提供基本的数据获取方法  return
            gridData,}
    // 原始二维表对象       let    queryFields: fields, // 实际取数查询的字段
      options = await this.pageProxy.api.fetchPortletData(queryFields)
           drillableFields, //let 可下钻字段{
              drilledFieldPathgridDataModel, // 二维表模型,提供基本的数据获取方法
    当前下钻字段路径         } =gridData, options// 原始二维表对象
           this.options = options queryFields: fields, // 实际取数查询的字段
        this.gridDataModel = gridDataModel    drillableFields, // 可下钻字段
       // 刷新取数完成后需调用commitRefresh通知系统该组件已完成刷新,否则可能影响导出截图和定时刷新功能      drilledFieldPath // 当前下钻字段路径
     this.pageProxy.portlet.commitRefresh(true)       }, = options
        generateQueryFields  () { this.options = options
         let queryFields = this.pageProxy.field.getFieldsByZones(['cols'])gridDataModel = gridDataModel
             // 不需要groupBy的字段如提示区的字段可通过接口生成对应的groupBy字段,在取数时不groupBy
    刷新取数完成后需调用commitRefresh通知系统该组件已完成刷新,否则可能影响导出截图和定时刷新功能
           let tooltipFields = this.pageProxy.fieldportlet.getFieldsByZonecommitRefresh('tooltip'true)
          },
          returngenerateQueryFields queryFields.concat(tooltipFields.map(field =>() {
            let queryFields return= this.pageProxy.field.createGroupByField(field, false)
    getFieldsByZones(['cols'])
            // 不需要groupBy的字段如提示区的字段可通过接口生成对应的groupBy字段,在取数时不groupBy
           })) let tooltipFields = this.pageProxy.field.getFieldsByZone('tooltip')
      }     } }
    </script>

    4.2 功能修改示例

    (1)需求场景

    在仪表盘预览菜单栏,点击工具栏弹出hello

    (2)示例效果

    Image Removed

    (3)操作步骤

    a.在根目录下的src/webpack/src/plugins/modifyExtenders下创建组件文件夹,下面以仪表盘预览菜单栏为例:

    • 添加文件夹dashFlexMenuExtension;
    • 在文件夹下创建index.js及FlexMenuExtension.js两个文件;

    Image Removed

    b.在index.js文件中实现provdieMetaInfo方法,FlexMenuExtension.vue导出的是一个FlexMenuExtension对象:

    代码块
    linenumberstrue
    collapsetrue
    import FlexMenuExtension from './FlexMenuExtension'
    const provideMetaInfo = () => {return queryFields.concat(tooltipFields.map(field => {
              return this.pageProxy.field.createGroupByField(field, false)
            }))
         // 二开文件}
        return}
    { implement: FlexMenuExtension}
     }
    export default {
      provideMetaInfo
    }
    c.FlexMenuExtension.j s:
    }
    </script>

    自定义多语言
    自定义多语言

    4.3 自定义多语言示例

    (1)需求场景

    修改仪表盘的多语言文字信息

    (2)示例效果

    将“柱图”改为“自定义”

    Image Added

    (3)操作步骤

    a.在根目录下的src/webpack/src/plugins/modifyExtenders下创建文件夹

    • 添加文件夹langExtension;
    • 在文件夹下创建index.js及Extender.js两个文件;

    Image Added

    b.在index.js文件中实现provdieMetaInfo方法,customLang对象就是自定义的多语言对象,需要将它导出:

    js
    信息
    title说明
    • BaseDashExtender是一个基类,系统提供了内置方法
    • install是入口方法
    • on方法是向系统添加某个事件的处理程序,系统在这个时机就会触发此方法回调。
    代码块
    language
    • zh:中文,tw:台湾,en:英文
    • 想要修改某个多语言文字,需要从源文件中找到对应的json路径,如示例中的dashboard:{chartBar}代表修改仪表盘下的"柱图"



    代码块
    linenumberstrue
    collapsetrue
    import SmartBIExtExtender from  'smartbi-ext'
    let {
      DashModule'./Extender'
    
    const provideMetaInfo = () => {
      let customLang =
      {
        zh: {
          dashboard: {
        DashEventEmum: {    chartBar: '自定义',
     PAGE_ON_FLEX_MENU_INIT     },
        BaseDashExtender
    },
     } } = SmartBIExttw: {
    class FlexMenuExtender extends BaseDashExtender {  dashboard: {
      constructor() {     super()
    chartBar: '自定義',
     }    install ()}
    {    },
    //  page菜单初始化  en:   this.on(PAGE_ON_FLEX_MENU_INIT, iFlexMenu => {{
          dashboard: {
      iFlexMenu.removeItem(1)       iFlexMenu.insertItem(3chartBar: 'custom',
    {      }
      id: 'TEST', }
      }
      return { iconimplement: 'sx-icon-like'Extender, customLang: customLang }
    }
    export default {
     label: '测试',
            color: '#ed6b1f', provideMetaInfo
    }

    c.Extension.js这里不用做任何事情,只要正常声明就可以:

    代码块
    languagejs
    linenumberstrue
    collapsetrue
    import SmartBIExt from 'smartbi-ext'
    let {
      DashModule: {
        BaseDashExtender
      }
    handler: ()} => {SmartBIExt
     
    class Extender extends BaseDashExtender {
    
      alertconstructor('测试按钮') {
        super()
      }
     
      install  }() {
       })
     
    }  
     }
    
    export default FlexMenuExtenderExtender

    5、打包部署

    • 本地打包:系统会帮自动打包vue文件变成js,本地直接再打包成扩展包;

    • 服务器打包:开发者要运行打包命令,将vue文件打包成js文件,然后开发者将扩展包代码提交到仓库,服务器打包的时候会运行build.xml 脚本进行打包;

    • 两者区别:本地打包帮你直接打包扩展包,服务器打包是将你的编译后的js文件提交到服务器打包;

    • 部署:将服务器打好的包,打开系统监控,扩展包管理页面进行上传。

    5.1 服务器打包

    (1)运行npm run build命令;

    (2)将扩展包代码提交仓库;

    (3)当服务器打包的时候会运行扩展包代码中的的build.xml 文件 打包成扩展包;

    5.2 本地打包

    注意

    本地打包非必要时候,不建议使用!

    如果有需要本地打包的话,请配置添加localBuild.xml文件。

    (1)复制原来的build.xml文件,修改名字为localBuild.xml;

    (2)在taget标签下添加排除webpack路径下的内容;

    代码块
    linenumberstrue
    <exclude name="**/webpack/" />

    (3)添加webpack命令;

    代码块
    linenumberstrue
    <target name="webpack"  description="webpack npm build">
       <exec executable="cmd.exe">
          <arg line="/c "cd ${basedir}/src/webpack && npm run build " "/>
       </exec>
    </target>

    (4)修改dist命令编译部分如下,添加webpack相关的编译;


    代码块
    linenumberstrue
    <target name="dist" depends="init">
       <parallel failonany="true">
          <echo>==============</echo>
          <antcall target="webpack" />
          <echo>webpack npm build</echo>
          <echo>${ant.project.name}: dist</echo>
          <echo>==============</echo>
          <antcall target="compile" />
       </parallel>
       <antcall target="jar" />
    </target>

    (5)修改打包名称;

    (6)效果如下:

    5.3 部署

    (1)打开系统监控

    (2)上传扩展包

    (3)选择扩展包

    6、学习资料汇总

    (1)node环境安装: https://www.cnblogs.com/xinaixia/p/8279015.html
    (2)npm命令使用:https://www.jianshu.com/p/4643a8e43b79
    (3)Vue框架开发:https://cn.vuejs.org/index.html