【仅供内部供应商使用,不提供对外解答和培训】
【仅供内部供应商使用,不提供对外解答和培训】
概要:一个主题的美观度是由大背景图片+主题配色+主题包三大部分共同决定的。整体配色主要由背景图片和配色决定,这些可以在决策平台-管理系统-平台外观里自己配置;整体的交互和布局主要是由主题包来完成的,代码写的越多,可以变化的东西也越多,当然背景图片和主题配色可以都通过开放的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对象
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] }
config4navigation = { onBeforeInit: null, //初始化前事件 onAfterInit: null, //初始化后事件 naviComponents: null //自定义导航栏组件, 可以往里面push自定义组件, 自定义render和onClick事件; }
config4Gallery: { region: null //默认所在区域 }
框架中新增了对应主题自定义图标的接口,原有的图标均为图标字体形式,扩展后可以支持png图标的自定义配置。如果需要的接口没有,可以到开发者龙门群里提(群号:179499938)。
自定义主题包实为引入的外部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 } }
效果图如下:
为了使用主题扩展接口,首先我们在theme.js里需要对FS.Plugin.CustomIcon配置进行扩展,theme.js的代码代码如下:
自定义图标的demo:
theme.js
style.css
对应的后台处理以及完整的代码见示例demo
效果图如下:
在编辑目录图标的下方可以识别指定目录下的png图片,然后加载进来,以供选择,图片的大小尺寸请自行调整(示例上是80*80)
系统配色主要有4种:高亮色、图标外框色、底栏色和文字色,可通过复写css来修改任意地方的样式或者配色
系统配色分别对应如下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} |
请求 | 参数 | callback |
---|---|---|
FR.servletURL + "?op=fr_bi&cmd=get_folder_report_list" | {} | [{lastModify:1466402196217,pId:"-1","id":"1",text:"功能演示",value:"348602efbb80f686"}] |
请求 | 参数 | callback |
---|---|---|
FR.servletURL + "?op=fr_bi&cmd=add_report" | {reportName:'模板名', reportLocation: '我是模板文件夹的id', realTime: false} | {"reportId":23} |
请求 | 参数 | callback |
---|---|---|
FR.servletURL + "?op=fr_bi&cmd=init_dezi_pane&reportId=23&edit=_bi_edit_" |
请求 | 参数 | 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() 方法:注销当前登录的用户,并返回登录页面。 参数:无。
(function ($) {
FS.Plugin.LookAndFeelSettings.push({
item: function(ctx) {
return {
title: FR.i18nText(""),
content: $("<div />")
};
},
action: function (tabPane) {
}
});
FS.THEME = $.extend(true, FS.THEME, {
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;
},
onAfterInit: function () {
$('#fs-frame-banner .fs-banner-title').each(function(){
var text = $(this).text();
$(this).replaceWith('<a class="fs-banner-title fs-over-ellipsis" title="'+text+'" >'+text+'</a>');
});
$('#fs-frame-header').addClass('fui-seb');
$('#fs-frame-footer').css('background-color','').addClass('fui-seb');
$('.fs-tab-back').attr('title',FR.i18nText('Title_Menu_Back')).removeClass('fui-bsb');
$('.fs-tab-back').click(function () {
var title = $('.fs-tab-back .title-tab-dashboard');
if(FS.tabPane.isExpand){title.hide();}else{title.show();}
});
$('<span class="title-tab-dashboard fs-over-ellipsis"/>').text(FR.i18nText('Title_Menu_Back')).appendTo($('.fs-tab-back'));
$('<span />').text(FR.i18nText('More')).prependTo($('.fs-tab-more'));
$('iframe').attr({allowtransparency:true,frameborder:'0',border:'0',marginheight:'0',marginwidth:'0'});
var collapseBtn = $('<div class="fs-menu-hide"/>')
.click(function () {
var westWidth = FS.CONSTS.Regions["west"].width();
FS.CONSTS.Regions["west"].css("width", 0);
FS._doResize();
var expandBtn = $('<div class="fs-menu-show"/>').click(function () {
$(this).remove();
FS.CONSTS.Regions["west"].css("width", westWidth);
FS._doResize();
}).appendTo(FS.CONSTS.Regions["east"]);
}).appendTo(FS.CONSTS.Regions["west"]);
collapseBtn.click();
},
onAfterDisplayNodes : function(node, $node, $parent){
var doProxy = function(){
$(this).toggleClass('over');
};
$('.fs-group-content .fs-content-card div')
.addClass('fs-content-title fs-over-ellipsis')
.bind('mouseover', doProxy)
.bind('mouseout', doProxy);
//$('.fs-group-content .fs-content-card').wrapInner('<div class="fs-content-card-body" />');
}
},
config4tabPane: {
style: 'alpha',
region: 'south',
isCollapsible: true,
hasHomepageBtn: false,
onSelectTab: function($tab, $content, entry){
if (!$tab.hasClass('select')) {
$('.select', this.$btns).removeClass('select fui-fhb').addClass('fui-bsb');
$tab.addClass('select fui-fhb');
}
$('.fs-tab-back .title-tab-dashboard').show();
var maxWidth = $('.fs-tab-btns').width()-$('.fs-tab-back').width()-$('.fs-tab-more').width();
FS.tabPane.$tabs.width(maxWidth);
var len = 0;
var els = [];
$('.fs-tab-names li').each(function(){
len += $(this).width();
if(len>maxWidth){
//$(this).hide();
}else{
els.push($(this));
}
});
FS.tabPane.visibleTabCount = els.length;
FS.tabPane._refreshMenu();
}
}
});
FS.Plugin.CustomIcon.push({
getMenuNodeCustomIcon: function (icon) {
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");
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) {
//��ȡ�Զ����ͼ���滻�ı�
return ($('.fs-folder-customIcon-selected', $(folder)).attr('alt'));
}
});
})(jQuery);