【仅供内部供应商使用,不提供对外解答和培训】

Page tree

【仅供内部供应商使用,不提供对外解答和培训】

Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 21 Next »


概要:一个主题的美观度是由大背景图片+主题配色+主题包三大部分共同决定的。整体配色主要由背景图片和配色决定,这些可以在决策平台-管理系统-平台外观里自己配置;整体的交互和布局主要是由主题包来完成的,代码写的越多,可以变化的东西也越多,当然背景图片和主题配色可以都通过开放的API来在主题包的代码中来修改,并不局限于平台外观配置。

如何以插件形式开发主题,可查看示例决策平台主题

主题包格式

fs-theme-[主题名]  (注:主题名建议使用非中文)
        |----style.css   //导入样式
        |----theme.js      //导入脚本
        |----cover.png   //主题包封面( 建议尺寸240*170 )
        |----其他目录(包括需要使用到的一些自定义资源文件)

 

组件开放接口

框架中总共有5大组件,分别是框架布局,目录树组件,多tab组件,Navigation组件和Gallery组件。如果需要的接口没有,可以到开发者龙门群里提(群号:179499938)。

主题总配置
{
    isCustom: true, //是否是自定义主题
    name: 'myTheme', //主题名称
    //框架布局配置属性
    config4frame: {},
    //Navigation配置属性
    config4navigation: {},
    //目录树组件配置属性
    config4MenuTree: {},
    //多tab组件配置属性
    config4tabPane: {}
}
框架布局配置属性
config4frame = {
    resizable: false,  //是否可以拖拽分割线调整左右区域的大小
    //上区域
    north: {
        height: 80 //上方导航栏高度设置(不设置默认60px)
        visible: true //是否可见
    },
    //下区域
    south: {
        visible: false //是否可见
    },
    //左区域
    west: {
        width: 220 //宽度
    },
    //右区域
    east: {}
}
目录树组件配置属性
config4MenuTree = {
    region: 'west',  //默认所在区域
    onBeforeInit: null, //初始化前事件,参数:[element]
    onAfterInit: null, //初始化后事件,参数:[element]
    onDataFilter: null, //节点数据过滤事件,参数:[node, childNodes]
    onBeforeNodeClick: null, //函数,节点点击前事件,参数: [node, $node, $li]
    onNodeClick: null, //函数,节点点击事件,参数: [node, $node, $li]
    onAfterNodeClick: null, //函数,节点点击后事件,参数: [node, $node, $li]
    onBeforeNodeCreate: null, //函数,节点创建前事件,参数:[node, $node, $li]
    onNodeCreate: null, //函数,节点创建事件,参数:[node, $node, $li]
    onAfterNodeCreate: null, //函数,节点创建后事件,参数:[node, $node, $li]
    onBeforeNodeExpand: null, //函数,节点展开前事件,参数:[node, $node, $li]
    onNodeExpand: null, //函数,节点展开事件,参数:[node, $node, $li]
    onAfterNodeExpand: null, //函数,节点展开后事件,参数:[node, $node, $li]
    onBeforeNodeCollapse: null, //函数,节点收起前事件,参数:[node, $node, $li]
    onNodeCollapse: null, //函数,节点收起事件,参数:[node, $node, $li]
    onAfterNodeCollapse: null, //函数,节点收起后事件,参数:[node, $node, $li]
    onBeforeDisplayNodes: null, //函数,节点展示前事件,参数:[node, $node, $li]
    onDisplayNodes: null, //函数,节点展示事件,参数:[node, $node, $li]
    onAfterDisplayNodes: null //函数,节点展示后事件,参数:[node, $node, $li]
}
 
参数说明:
1. node - 节点对象
    node = {
        text: '日报', //entry名 
        id: '213',   //entry id
        isexpand: false, //是否展开
        hasChildren: true,  //是否具有子节点
        ChildNodes: [],  //子节点数组
        isModule: false, //是否是标签页节点
        level: 1 //树深度,从0计数
    }

2. $node - 节点的DOM对象
3. $li - 节点所处的父层DOM对象
多tab组件配置属性
config4tabPane = {
    region: 'east', //默认所在区域
    style: 'alpha',  //内置样式,包括alpha和bravo两种选择
    tabWidth: 150,  //单个tab标签的最大宽度
    isCollapsible: true,  //是否可以收起
    hasHomepageBtn: false,  //是否有主页按钮
    onCreateTab: null,  //函数,创建Tab标签时的操作,可修改标签样式(全局),参数:[$tab, entry]
    onSelectTab: null,  //函数,选中每个Tab页面时的操作,可修改内容(全局),参数:[$tab, $content, entry]
    onCloseTab: null,  //函数,关闭每个Tab页面时的操作(全局),参数:[$tab, $content, entry]
    afterLoadTab: null,  //函数,加载每个Tab页面时的操作(全局),参数:[$tab, $content, entry]

}
开放方法
FS.tabPane.addItem(item)
方法: 向多tab组件里添加并打开一个tab,如果tab已经存在,则直接选中;若不存在,则添加并选中。
参数: item {JSON} 
         item = {
             text: 'newTab', //必须, tab标签名
             id: '213', //entry id
             src: 'http://www.finereport.com', //可选,正文内容为链接,iframe嵌入
             onCreate: null,  //函数,创建Tab标签时的操作,可修改标签样式,参数:[$tab, entry]
             onSelect: null,  //函数,选中每个Tab页面时的操作,可修改内容,参数:[$tab, $content, entry]
             onClose: null,  //函数,关闭每个Tab页面时的操作,参数:[$tab, $content, entry]
             afterLoad: null,  //函数,加载每个Tab页面时的操作,参数:[$tab, $content, entry]
         }
Navigation配置属性
config4navigation = {
    onBeforeInit: null,  //初始化前事件
    onAfterInit: null,   //初始化后事件
	naviComponents: null //自定义导航栏组件, 可以往里面push自定义组件, 自定义render和onClick事件;
}

自定义导航栏组件示例

Gallery配置属性
config4Gallery: {
    region: null   //默认所在区域
} 

主题扩展接口 

框架中新增了对应主题自定义图标的接口,原有的图标均为图标字体形式,扩展后可以支持png图标的自定义配置。如果需要的接口没有,可以到开发者龙门群里提(群号:179499938)。

 

自定义图标接口
FS.Plugin.CustomIcon.push({
   //获取菜单节点的自定义图标
   getMenuNodeCustomIcon: function (icon) {
       return null;
   },
   //添加自定义图标到图标列表
   addCustomIconItem : function(configSetting){
   },
   //删除之前选中的自定义图标
   removePreCustomIconSelected : function(folders) {
   },
   //添加自定义图标到目录节点上
   addItem2Folders : function(eachFolder, $folders) {
   },
   //初始化已经选中的自定义图标
   initSelectedCustomIcon : function(selectedFolder) {
   },
   //获取自定义图标的附件ID
   getCustomIconAttachID : function (folder) {
       return null;
   }
});


主题包开发

自定义主题包实为引入的外部js、css以及资源文件等。

为了使用主题接口,首先我们在theme.js里需要对FS.Theme配置进行扩展,具体代码如下:

(function ($) {
    FS.THEME = $.extend(true, FS.THEME, {
        /**需要扩展的配置属性**/
    });
})(jQuery);

内置Classic主题采用默认配置:

{
    config4frame: {
        resizable: true,
        //上区域
        north: {
            visible: true //是否可见
        },
        //下区域
        south: {
            visible: false //是否可见
        },
        //左区域
        west: {
            width: 230 //宽度
        },
        //右区域
        east: {}
    },
    config4Gallery: {
        region: null
    },
    config4MenuTree: {
        region: 'west'
    },
    config4tabPane: {
        region: 'east',
        style: 'bravo',
        isCollapsible: false,
        hasHomepageBtn: true
    },
    config4navigation: {
        onBeforeInit: null,
        onAfterInit: null
    }
}

 

内置Modern主题采用如下配置:
{
    config4frame: {
        resizable: false,
            south: {
            visible: true
        }
    },
    config4Gallery: {
        region: 'east'
    },
    config4MenuTree: {
        onNodeExpand: function (node, $node, $parent) {
            return node.level !== 0;
        },
        onNodeClick: function (node, $node, $parent) {
            $('#fs-frame-wrapper') .empty();
            return false;
        }
    },
    config4tabPane: {
        style: 'alpha',
        region: 'south',
        isCollapsible: true,
        hasHomepageBtn: false
    }
}

主题包Demo:

 

style.css
.node-navi{
	position: relative;
	float: right;
	right: 30px;
	list-style: none;
	height: 60px;
	top: 0;
}

.node-navi li{
	position: relative;
	float: left;
	left: 0;
	display: block;
	height: 60px;
	line-height: 60px;
	color: #fff;
	font-size: 14px;
	padding: 0 15px;
	cursor: pointer;
}

.node-navi li:hover{
	color: #6fd3ff;
}

.node-pane{
	position: absolute;
	top: 60px;
	left: 0;
	-webkit-border-radius: 0 0 3px 3px;
	-moz-border-radius: 0 0 3px 3px;
	z-Index: 10000;
}
.node-pane-inner{
	position: relative;
	_height: 200px;
	overflow-x: hidden;
	overflow-y: auto;
	background: rgb(41, 90, 148);
	background: rgba(41, 90, 148, 0.85);
	*width:200px;
}
.node-select{
	background: #295a94;
}

.node-pane a, .node-title{
	position: relative;
	white-space: nowrap;
	text-overflow: ellipsis;
	overflow: hidden;
	display: block;
	min-width: 160px;
	_width:180px;
	height: 20px;
	line-height: 20px;
	font-size: 14px;
	color: white;
	padding: 3px 5px 3px 12px;
	cursor: pointer;
}

.node-pane a:hover{
	background: rgb(41, 90, 148);
}
.node-title{
	padding: 5px 5px 5px 4px;
	cursor: default;
	color: #6fd3ff;
	font-weight: bold;
}
theme.js
(function ($) {
   FS.THEME = $.extend(true, FS.THEME, {
       config4navigation: {
           onAfterInit: function () {
               var self = this;
               $('#fs-frame-search').remove();
               var $reg = $('#fs-frame-reg');
               if ($reg.length > 0) {
                   $reg.remove();
               }
               $.ajax({
                   url: FR.servletURL + "?op=fs_main&cmd=module_getrootreports",
                   type: 'POST',
                   data: {id: -1},
                   success: function (res, status) {
                       var nodes = $.parseJSON(res);
                       $.ajax({
                          url: FR.servletURL + "?op=fs_main&cmd=getmoduleitems",
                          type: 'POST',
                          async: false,
                          data: {id: 1},
                          success: function(res){
                              nodes.push($.parseJSON(res));
                          }
                        });
                       var $ul = $('<ul class="node-navi"/>').appendTo($('#fs-frame-header'));
                       $.each(nodes, function (index, root) {
                           var $node = $('<li class="node-navi-li"/>').appendTo($ul);
                           $('<div/>').text(root.text)
                               .appendTo($node)
                               .click(function () {
                                   if($node.hasClass('node-select')){
                                       return;
                                   }
                                   $ul.find('.node-select').removeClass('node-select');
                                   $node.addClass('node-select');
                                   var $dropdown = $(this).data('DATA');
                                   if (!$dropdown) {
                                       $dropdown = $('<div class="node-pane"/>').appendTo($node);
                                       $(this).data('DATA', $dropdown);
                                       var $pane = $('<div class="node-pane-inner"/>')
                                           .css({
                                               'max-height': document.body.clientHeight - 90
                                           }).appendTo($dropdown);
                                       if (root.hasChildren && root.ChildNodes) {
                                           var $other = $('<div class="node-wrapper"/>').appendTo($pane);
                                           $.each(root.ChildNodes, function (index, child) {
                                               if (child.hasChildren) {
                                                   var $w = $('<div class="node-wrapper"/>').appendTo($pane);
                                                   $('<div class="node-title"/>').text(child.text).appendTo($w);
                                                   var childs = [];
                                                   _collectAllChildNodes(child, childs);
                                                   $.each(childs, function (i, n) {
                                                       _createItem(n, $dropdown, $node).appendTo($w);
                                                   });
                                               } else {
                                                   _createItem(child, $dropdown, $node).appendTo($other);
                                               }
                                           });
                                       } else {
                                           return;
                                       }
                                   }
                                   $dropdown.fadeIn('fast');
                                   $(document).bind('mouseover.nodepane', function (e) {
                                       var $t = $(e.target);
                                       if ($t.closest('.node-pane').length <= 0) {
                                           $node.removeClass('node-select');
                                           $dropdown.fadeOut('fast');
                                           $(document).unbind('mouseover.nodepane');
                                       }
                                   });
                               }
                           );
                       });
                   }
               });
           }
       },
       config4frame: {
           west: {
               width: 0 
           }
       }
   });
   var _createItem = function (node, $pane, $node) {
       return $('<a href="#"/>').text(node.text)
           .click(function () {
               FS.tabPane.addItem(node);
               $node.removeClass('node-select');
               $pane.hide();
               $(document).unbind('mousedown.nodepane');
           });
   };
   var _collectAllChildNodes = function (node, childs) {
       var self = this;
       if (!node.ChildNodes) {
           return;
       }
       $.each(node.ChildNodes, function (index, child) {
           if (child.hasChildren) {
               _collectAllChildNodes(child, childs);
           } else {
               childs.push(child);
           }
       });
   };
})(jQuery);

效果图如下:

 

为了使用主题扩展接口,首先我们在theme.js里需要对FS.Plugin.CustomIcon配置进行扩展,theme.js的代码代码如下:

自定义图标接口
(function($){
	//主题配置属性
	FS.THEME = $.extend(true, FS.THEME, {
        /**需要扩展的配置属性**/
    });
	
	//自定义图标需要扩展的接口
	FS.Plugin.CustomIcon.push({
		/*获取菜单节点的自定义图标*/
		getMenuNodeCustomIcon: function (icon) {
			return null;
		},
		/*添加自定义图标到图标列表*/
		addCustomIconItem : function(configSetting){
		},
		/*删除之前选中的自定义图标*/
		removePreCustomIconSelected : function(folders) {
		},
		/*添加自定义图标到目录节点上*/
		addItem2Folders : function(eachFolder, $folders) {
		},
		/*初始化已经选中的自定义图标*/
		initSelectedCustomIcon : function(selectedFolder) {
		},
		/*获取自定义图标的附件ID*/
		getCustomIconAttachID : function (folder) {
			return null;
		}
	});
})(jQuery);

自定义图标的demo:

theme.js

自定义图标demo
(function ($) {

    FS.Plugin.LookAndFeelSettings.push({
        item: function(ctx) {
            return {
                title: FR.i18nText(""),
                content: $("<div />")
            };
        },
        action: function (tabPane) {
        }
    });

    FS.THEME = $.extend(true, FS.THEME, {
		/**需要扩展的配置属性**/
    });
	
    FS.Plugin.CustomIcon.push({
        getMenuNodeCustomIcon: function (icon) {
            /*这边定义了一个op,用于处理图标图片的文件读取和加载,不同的主题op不能相同,否则会有冲突!*/
            /*这边定义了一个cmd=read_img,把png图标从文件中读入到内存以及缓存中*/
            var config = {
                url: FR.servletURL + '?op=custom_icon&cmd=read_img',
                data: {
                    id : icon
                }
            };
            var attach = FS.Sync.ajax(config);
            var $icon = $('<span/>').addClass("fs-menu-icon");
            /*这边定义了一个cmd=getattach,从缓存中获取之前读入的附件png图标,图片的文件名存入img的alt属性中,后续保存的时候也可以方便处理*/
            var url = FR.servletURL + ('?op=custom_icon&cmd=get_attach&id=' + attach.attachid + '&isAdjust=false');
            $('<img>').attr('src',url).attr('alt', attach.attachfile).addClass('fs-menu-node-icon').appendTo($icon);
            return $icon;
        },
        removePreCustomIconSelected : function(folders) {
            //选择之前先删除之前的选择
            var curFolder = $('.fs-icon-folder-item.selected .folder-icon', folders);
            $('.fs-icon-folder-item.selected .fs-folder-customIcon-selected', folders).remove();
            curFolder.removeAttr('style');
        },
        addCustomIconItem : function(configSetting){
            var self = configSetting;

            var config = {
                url: FR.servletURL + '?op=custom_icon&cmd=read_img',
                data: {
                    id : ''
                }
            };
            var completeFn = function (res, status) {
                var result = FR.jsonDecode(res.responseText);
                $.each(result, function(index, attach){
                    var $icon = $('<div class="fs-icon-item"/>').hover(function () {
                        $(this).addClass('icon-hover');
                    }, function () {
                        if (!$(this).hasClass('selected')) {
                            $(this).removeClass('icon-hover');
                        }
                    }).click(function () {
                        self.selectIconItem($(this));
                    });
                    var url = FR.servletURL + ('?op=custom_icon&cmd=get_attach&id=' + attach.attachid + '&isAdjust=false');
                    $('<img>').attr('src', url).attr('alt', attach.attachfile).addClass('fs-customIcon-list-item').appendTo($icon);
                    $icon.data('ENTRY', {text: attach,onSelect: function ($icon) {
                        var curFolder = $('.fs-icon-folder-item.selected .folder-icon', self.$folders);
                        //选择之前先删除之前的选择
                        $('.fs-icon-folder-item.selected .fs-folder-customIcon-selected', self.$folders).remove();
                        curFolder.removeAttr('style');

                        var url = $('.fs-customIcon-list-item', $icon).attr('src');
                        var altText = $('.fs-customIcon-list-item', $icon).attr('alt');
                        var img = $('<img>').attr('src',url).attr('alt', altText).addClass('fs-folder-customIcon-selected');
                        curFolder.attr('style', 'padding-left:0px').html("");
                        img.insertBefore($('.fs-icon-folder-item.selected .folder-icon', self.$folders));
                    }});
                    $icon.appendTo(self.$icons);
                });
            };
            FS.Async.ajax(config, completeFn);
        },
        addItem2FolderNodes : function(eachFolder, $folders) {
            var config = {
                url: FR.servletURL + '?op=custom_icon&cmd=read_img',
                data: {
                    id : eachFolder.value
                }
            };
            var attach = FS.Sync.ajax(config);
            if(attach.attachid && attach.attachfile) {
                var url = FR.servletURL + ('?op=custom_icon&cmd=get_attach&id=' + attach.attachid + '&isAdjust=false');
                $('<img>').attr('src', url).attr('alt', attach.attachfile).addClass('fs-folder-customIcon-selected').appendTo($folders);
                $('<i class="folder-icon"/>').attr('style', 'padding-left:0px').html("").appendTo($folders);
            }
        },
        initSelectedCustomIcon : function(selectedFolder) {
            var altText = $('.fs-folder-customIcon-selected', selectedFolder).attr('alt');
            $.each(FSCS.View.$icons.children(), function(i, folderIcon){
                if (($('.fs-customIcon-list-item', folderIcon).attr('alt'))) {
                    if (altText === ($('.fs-customIcon-list-item', folderIcon).attr('alt'))) {
                        FSCS.View.selectIconItem(FSCS.View.$icons.children().eq(i));
                    }
                }
            })
        },
        getCustomIconAttachID : function (folder) {
            //寻找自定义的图标img的alt值
            return ($('.fs-folder-customIcon-selected', $(folder)).attr('alt'));
        }
    });

})(jQuery);

style.css

自定义图标demo
.fs-menu-node-icon {
    width: 25px;
    height: 16px;
}

.fs-folder-customIcon-selected {
    width:25px;
    height:16px;
    padding-left:10px;
}

.fs-customIcon-list-item {
    width:80px;
    height:80px
}

对应的后台处理以及完整的代码见示例demo

效果图如下:

在编辑目录图标的下方可以识别指定目录下的png图片,然后加载进来,以供选择,图片的大小尺寸请自行调整(示例上是80*80)

 

系统配色

系统配色主要有4种:高亮色、图标外框色、底栏色和文字色,可通过复写css来修改任意地方的样式或者配色

 

 

  1. 颜色1——高亮色。“收藏”“消息”“个人中心”三个图标选中状态及tab选中项提亮色,
  2. 颜色2——图标外框色。导航栏图标外围色;
  3. 颜色3——底栏色。左侧导航栏激活项背景色以及Tab栏背景颜色;
  4. 颜色4——文字色。字体颜色。

系统配色分别对应如下css样式:

 

高亮色
.fui-bsb{
  background-color: @color;
}
.fui-bsc{
  color: @color;
}
.fui-bsd{
  border-color: @color;
}
图标外框色
.fui-fhc{
  color: @color;
}
.fui-fht{
  text-shadow: 0 0 3px @color;
}
底栏色
.fui-seb{
  background-color: @color;
}
文字色
.fui-fbc{
  color: @color;
}
.fui-fbt{
  text-shadow: 0 0 1px @color;
}

请求接口

获取管理系统节点

请求参数
FR.servletURL + "?op=fs_main&cmd=getmoduleitems"{id: -1}

获取目录树节点

请求参数
FR.servletURL + "?op=fs_main&cmd=module_getrootreports"{id: 1}

(BI)获取我创建的列表

请求参数callback
FR.servletURL + "?op=fr_bi&cmd=get_folder_report_list"{}[{lastModify:1466402196217,pId:"-1","id":"1",text:"功能演示",value:"348602efbb80f686"}]

(BI)新建分析

请求参数callback
FR.servletURL + "?op=fr_bi&cmd=add_report"{reportName:'模板名', reportLocation: '我是模板文件夹的id', realTime: false}{"reportId":23}

(BI)模板超链

请求参数callback
FR.servletURL + "?op=fr_bi&cmd=init_dezi_pane&reportId=23&edit=_bi_edit_"  

(BI)数据配置超链

请求参数callback
FR.servletURL + "?op=fr_bi_configure&cmd=init_configure_pane"  

标签页单独集成

FS.loadModule(render, moduleName)
方法:根据模块名加载对应模块配置页面,用于集成独立页面
参数: render 渲染dom
      moduleName 模块名
例如:FS.loadModule($('<div/>').appendTo('body'), 'report');

集成并加载指定标签模块,模块名列表如下:

模块名参数值
报表管理report
用户管理user
权限管理privilege
定时调度schedule
系统管理sysmgr
平台外观lookandfeel
注册信息register
系统监控monitor
移动平台mobile


注: 必须先做单点登录,只有登录FS才有访问标签页的权限。

用户注销

FS.signOut()
方法:注销当前登录的用户,并返回登录页面。
参数:无。

 

  • No labels