代码:
panels:
Object { title="服务查询", url="widget/serviceQuery.do", wId=1},
Object { title="服务订阅", url="widget/serviceOrder.do", wId=2},
Object { title="订阅审批", url="widget/serviceOrderApprove.do"
...
jquery.cookie.js:
$.cookie(‘the_cookie’); // 读取 cookie
$.cookie(‘the_cookie’, 'the_value’); // 存储 cookie
$.cookie(‘the_cookie’, 'the_value’, { expires: 7 }); // 存储一个带7天期限的 cookie
$.cookie(‘the_cookie’, '', { expires: -1 }); // 删除 cookie
用户表SYS_USER中有个WIDGET_STATE字段,用于保存当前用户的widget状态,
其中
:分割列
,分割行
48,44:46,49 即表示有两行两列,第一列的两个widget ID 为48 44
state:
"1,3,5:2,4"
:分割列
,分割行
登录之后:
function afterLogin(data) { var returnStr = ""; if ("1" == data) { returnStr = "用户名或密码错误,请重新输入!"; focusPassword(); } if ("2" == data) { returnStr = "用户已经登录!"; } if ("3" == data) { returnStr = "密码错误!"; } if ("4" == data) { returnStr = "用户不存在!"; } if ("5" == data) { returnStr = "用户角色不存在!"; } if ("6" == data) { returnStr = "登录出错!"; } if ("0" == data ) { location.href = root + 'main.do'; } showErrorMessage(returnStr); }
@RequestMapping(value="/main.do",method=RequestMethod.GET) public String main(HttpServletRequest request,HttpSession session) { logger.info("main..."); return "admin"; }
layout.xml:
<tiles-definitions> <definition name="admin" template="/WEB-INF/layouts/admin.jsp"> <put-attribute name="header" value="/WEB-INF/views/header.jsp" /> <put-attribute name="menu" value="/WEB-INF/views/menu.jsp" /> <put-attribute name="footer" value="/WEB-INF/views/footer.jsp" /> <put-attribute name="body" value="" /> </definition> <definition name="content" template="/WEB-INF/layouts/content.jsp"> </definition> </tiles-definitions>
系统登录后页面admin.jsp:
<body class="easyui-layout"> <!-- north --> <div id="header" class="top_body" data-options="region:'north',border:false"> <tiles:insertAttribute name="header"/> </div> <!-- west --> <div id="menu" data-options="region:'west',split:true" style="width: 200px; overflow: hidden;"> <div id="firstMenu" class="easyui-accordion" animate="false" data-options="fit:true,border:false"></div> </div> <!-- center --> <div id="content" data-options="region:'center'" style="overflow: hidden;"> <div id="centerTabs" class="easyui-tabs" data-options="fit:true,border:false"> </div> <!-- centerMenu --> <div id="tabsMenu" style="width: 100px; display: none;"> <div type="close"> <spring:message code="index.close" text="关闭"/> </div> <div type="closeOther"> <spring:message code="index.closeOther" text="关闭其他" /> </div> <div type="closeAll"> <spring:message code="index.closeAll" text="关闭所有"/> </div> </div> </div> <!-- south --> <div id="footer" data-options="region:'south',border:false" style="height: 20px; padding: 3px; background: #dadada; overflow: hidden;"> <tiles:insertAttribute name="footer"/> </div> <div id="addAppDialog" style="overflow:hidden;"></div> </body>
登录后进入的页面的JS:
$(function () { // west var firstMenu = $('#firstMenu'); //var fistMenuUrl = root + 'js/app/home/menuMain.json'; // ================================================================================ $.ajax({ url : root + "login/initRootMenu.do", type : 'POST', dataType : 'json', success : function(data) { //构造左侧树 addAccordions(data); //构造进入时默认内容页(即默认的个人工作台的TAB页,各Widget都放在该TAB里) addHome(); } }); var centerTabs = $('#centerTabs'); //个人工作台右侧的“添加组件”按钮 //点击弹出“添加组件”页面 centerTabs.tabs({ fit : true, border : false, onContextMenu : function(e, title) { e.preventDefault(); tabsMenu.menu('show', { left : e.pageX, top : e.pageY }).data('tabTitle', title); }, tools : [{ iconCls : 'icon-add', text : '添加组件', handler : function() { addAppDialog(1); } }] }); addHome = function(){ var title = '个人工作台'; if(centerTabs.tabs('exists', title)){ centerTabs.tabs('select', title); }else{ var url = "/index.do"; centerTabs.tabs( 'add', { title : title, closable : false, content : '<iframe src="' + url + '" frameborder="0" style="border:0;width:100%;height:99.4%;"></iframe>' }); } } ..
此处用于构造一个个人工作台的TAB页
跳转到真正的个人工作台页面index.jsp:
@RequestMapping(value="/index.do",method=RequestMethod.GET) public String index(HttpServletRequest request,HttpSession session) { SysUser currentUser = (SysUser) session.getAttribute(SessionKeys.SESSION_SYS_USER); request.setAttribute("USER_ID", currentUser.getId()); return "index"; } <definition extends="content" name="index"> <put-attribute name="body" value="/WEB-INF/views/index.jsp"/> </definition>
index.jsp页面:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%> <link type="text/css" rel="stylesheet" href="<%=request.getContextPath()%>/js/easyui-portal/portal.css"></link> <script type="text/javascript" src="<%=request.getContextPath()%>/js/app/common/jquery.cookie.js" charset="UTF-8"></script> <script type="text/javascript" src="<%=request.getContextPath()%>/js/easyui-portal/jquery.portal.js" charset="UTF-8"></script> <script type="text/javascript" src="<%=request.getContextPath()%>/js/app/common/widget.js" charset="UTF-8"></script> <script type="text/javascript" src="<%=request.getContextPath()%>/js/app/common/portal.js" charset="UTF-8"></script> <body> <script> </script> <div class="easyui-layout" data-options="fit:true" id="portalDiv"> <div region="center" border="false" style="width: 500px; height: 306px; overflow: hidden;"> <div id="portal${USER_ID}" style="width: 100%; height: 99.4%;"></div> <div id="maxWidget${USER_ID}" style="width: 100%; height: 99.4%; display: none; overflow-y:auto;overflow-x: hidden;"></div> </div> </div> </body>
个人工作台展示部分:
入口portal.js:
$(function() { $.ajax({ url : root + "widget/initPortalPage.do", type : 'post', cache : false, success : function(response) { if (response.flag == '0') { responseObj = response.data; initPortalPage(); } else { $.messager.alert('系统提示', '获取Widget失败!', 'error'); return; } }, error:function(data){ $.messager.alert('系统提示', '获取Widget失败!', 'error'); return; } }); });
个人工作台,所以可以使用用户Bean定位:
/** * 初始化所有Widget * @param session * @return */ @RequestMapping(value="widget/initPortalPage.do",method=RequestMethod.POST) @ResponseBody public Map<String,Object> initPortalPage(HttpSession session) { logger.info("initPortalPage begin .. "); SysUser currentUser = (SysUser) session.getAttribute(SessionKeys.SESSION_SYS_USER); Map<String,Object> result = new HashMap<String,Object>(); List<EsbWidgetV> ls = esbWidgetDS.findWidgetVListByUserId(currentUser.getId()); List<Map> rList = new ArrayList<Map>(); for(EsbWidgetV w : ls){ Map wMap = new HashMap(); wMap.put("wId", w.getId()); wMap.put("title", w.getMenuName()); wMap.put("url", w.getUrl()); rList.add(wMap); } currentUser.setPorlets(rList); result.put("flag", "0"); result.put("data", currentUser); logger.info("initPortalPage end .. "); return result; }
CREATE OR REPLACE VIEW ESB_WIDGET_V AS SELECT W.ID, W.MENU_ID, W.USER_ID, M.MENU_NAME, W.URL, W.ENABLED_FLAG FROM ESB_WIDGET W LEFT JOIN SYS_MENU M ON W.MENU_ID = M.ID;
widget.java:
@Entity @Table(name = "ESB_WIDGET", uniqueConstraints= {@UniqueConstraint(columnNames={"MENU_ID", "USER_ID"})}) public class EsbWidget implements java.io.Serializable { private static final long serialVersionUID = 7332317625490883826L; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "ID", nullable = false) private Long id; @Column(name = "MENU_ID") private Long menuId; @Column(name = "USER_ID") private Long userId; @Column(name = "URL") private String url; .. }
widget表数据:
widgetV数据:
widght表中含有USER_ID、MENU_ID,对应各个用户的菜单Widght
各Widght其实就是各菜单的快速入口
添加并展示Widget:
function initPortalPage(){ var maxWidgetId = $('#maxWidget' + responseObj.id) // 最大工作台 var portalId = $('#portal' + responseObj.id); portalId.children().remove(); var panels = responseObj.porlets; // 工作台下widget明细 if (panels.length == 0) { $.cookie("portal"+responseObj.id, null); var content = '<div class="add-component"><p>抱歉,在<span class="workbench"><a href="#" onFocus="this.blur()">个人工作台</a></span>中未找到相关组件.</p> <div style="height:20px"></div></div>' portalId.panel({ fit : true, border : false, content : content }) } else { responseObj.columnType = 6; ///////////////////////////////// /*portalId.append(" <div style='width:33%'></div><div style='width:34%'></div><div style='width:35%'></div>"); responseObj.columnTemplate = 3;*/ portalId.append(" <div style='width:50%'></div><div style='width:50%'></div>"); responseObj.columnTemplate = 2; var columnTemplate = responseObj.columnTemplate; // 列 var portal = portalId.portal({ border : false, fit : true, // cid : responseObj.cid, // cname : responseObj.cname,// 自定义属性 cname onStateChange : function() { var id = $(this).attr('id'); var oldS = $.cookie(id).split(':'); // 拖动前cookie var state = getPortalState(id); $.cookie(id, state, { expires : 7 }); var newS = $.cookie(id).split(':');// 拖动后cookie // 更新用户工作台widget状态 updateUserPlatformState(id.substring(6), state); // 拖动后更新tab类型widget updateTabWidget(oldS, newS); } }); var state = responseObj.state; if (yxui.replaceAll(state, ':', '') == '') {// 工作台下无widget state = null; } else if (state.split(':').length != responseObj.columnTemplate) {// 工作台模板变更 state = null; } else {// 工作台上已有widget编号与工作台widget状态比较 var flag = false; var compareState = yxui.replaceAll(state, ':', ',').split(','); for (var i = 0; i < panels.length; i++) { flag = false; var wid = panels[i].wId; for (var j = 0; j < compareState.length; j++) { if (wid == compareState[j]) { flag = true; break; } } if (flag) { continue; } else { break; } } if (!flag) { state = null; } } if (!state) { var col0 = [], col1 = [], col2 = [], col3 = [], col4 = [], stateArr = []; for (var i = 1; i <= panels.length; i++) { var mo = i % columnTemplate; switch (mo) { case 0 : col0.push(panels[i - 1].wId); ////////////////////id => wId break; case 1 : col1.push(panels[i - 1].wId); break; case 2 : col2.push(panels[i - 1].wId); break; case 3 : col3.push(panels[i - 1].wId); break; case 4 : col4.push(panels[i - 1].wId); break; } } if (col1.join(",") != '') { stateArr.push(col1.join(",")); } if (col2.join(",") != '') { stateArr.push(col2.join(",")); } if (col3.join(",") != '') { stateArr.push(col3.join(",")); } if (col4.join(",") != '') { stateArr.push(col4.join(",")); } if (col0.join(",") != '') { stateArr.push(col0.join(",")); } // state = 'w1,w2:w3';/* 冒号代表列,逗号代表行 state = stateArr.join(":"); var stateCha = columnTemplate - stateArr.length; if (stateCha > 0) { for (var i = 0; i < stateCha; i++) { state = state + ":"; } } $.cookie('portal' + responseObj.id, state, { expires : 7 }); // 更新用户工作台widget状态 updateUserPlatformState(responseObj.id, state); } else { $.cookie('portal' + responseObj.id, state, { expires : 7 }); } addPanels(portal, panels, state); portal.portal('resize'); } }
组件Widget操作widget.js:
/* * 初始化添加widget */ function addPanels(portal, panels, portalState) { var columns = portalState.split(':'); for (var columnIndex = 0; columnIndex < columns.length; columnIndex++) { var cc = columns[columnIndex].split(','); for (var j = 0; j < cc.length; j++) { var tmp = ""; if(cc[j] != ""){ tmp = parseInt(cc[j]); } var options = getPanelOptions(tmp, panels); if (options) { // panelWidgetUrlSet options.url = panelWidgetUrlSet(options); var p = $('<div style="overflow:hidden;"/>').attr('id', options.wId).appendTo('body'); var result = /^http:\/\/+/.test(options.url); // 是否外网 if (result) { options.content = '<iframe src="' + options.url + '" frameborder="0" style="border:0;width:100%;height:99.4%;"></iframe>'; options.href = ''; } else { options.content = ''; options.href = options.url; } /*options.collapsible = true; options.closable = true;*/ options.tools = panelToolsSet(options); p.panel(options); // panelAddTips panelAddTips(p); portal.portal('add', { panel : p, columnIndex : columnIndex }); } } } }
几个其中的主要JS方法:
/* * 更新用户工作台widget状态 */ function updateUserPlatformState(userId, state) { $.ajax({ url : root + "widget/updateUserState.do", type : 'post', data : {'state' : state}, cache : false }); } /* * 获取工作台状态,组装state */ function getPortalState(id) { var columnTemplate = $('#' + id).children().children().children().children().length; var aa = []; for (var columnIndex = 0; columnIndex < columnTemplate; columnIndex++) { var cc = []; var panels = $('#' + id).portal('getPanels', columnIndex); for (var i = 0; i < panels.length; i++) { cc.push(panels[i].attr('id')); } aa.push(cc.join(',')); } return aa.join(':'); }
/* * 刷新widget */ function panelRefresh(id, isMax) { var isMax = isMax == null ? false : isMax; var $wid = $('#' + id); var options = $wid.panel('options'); if(options.url.indexOf("widget") < 0){ options.url = options.href; } var result = /^http:\/\/+/.test(options.url); // 是否外网 if (result) { options.content = '<iframe src="' + options.url + '" frameborder="0" style="border:0;width:100%;height:99.4%;"></iframe>'; $('#' + id).children().remove(); $('#' + id).append(options.content); } else { options.content = ''; if (isMax) { $('#' + id).panel('refresh', yxui.refreshUrlLink(options.url, 'isMax=true')); } else { $('#' + id).panel('refresh', options.url); } } } /* * panel的工具设置 */ function panelToolsSet(options) { var argObj = yxui.getUrlArg(options.url); var toolSet = '111'; // 刷新/折叠/最大化/删除 if (argObj != null && argObj._toolset != null && argObj._toolset.length == 4) { toolSet = argObj._toolset; } var tools = [];// 返回工具数组对象 for (var i = 0; i < toolSet.length; i++) { // 刷新 if (i == 0 && toolSet.substr(i, 1) == 1) { tools.push({ iconCls : 'icon-reload', handler : function(button) { panelRefresh(findId(this)); } }); } // 折叠 if (i == 1 && toolSet.substr(i, 1) == 1) { tools.push({ iconCls : 'panel-tool-collapse', handler : function() { if ($(this).attr('class') == 'panel-tool-collapse') { panelCollapse(findId(this)); } else { panelExpand(findId(this)); } } }); } // 删除 if (i == 2 && toolSet.substr(i, 1) == 1) { tools.push({ iconCls : 'panel-tool-close', handler : function() { var id = findId(this); var message = '您确定删除此组件?'; $.messager.confirm('系统提示', message, function(r) { if (r) { panelClose(id); } }); } }); } } return tools; }
/* * 最大化widget */ function panelMax(wId,userId,maxUrl) { var portalId = $('#portal' + userId); var maxWidgetId = $('#maxWidget' + userId); portalId.hide(); var wOptions = $('#' + wId).panel('options'); // widget options var maxOptions = { fit : true, title : wOptions.title, style : { padding : '10px' } } wOptions.url = maxUrl; var result = /^http:\/\/+/.test(wOptions.url); // is other adderss if (result) { maxOptions.content = '<iframe src="' + wOptions.url + '" frameborder="0" style="border:0;width:100%;height:99.4%;"></iframe>'; maxOptions.url = wOptions.url; } else { maxOptions.content = ''; maxOptions.url = wOptions.url; } maxOptions.tools = [{ iconCls : 'icon-reload', handler : function(button) { panelRefresh(findId(this), true); } }, { iconCls : 'panel-tool-restore', handler : function() { maxWidgetId.hide().panel('close'); portalId.show(); refreshAll(userId); } }]; // panelWidgetUrlSet maxOptions.url = panelWidgetUrlSet(maxOptions) maxOptions.maxUrl = yxui.refreshUrlLink(maxOptions.url, 'isMax=true'); /*if(type!=null) { maxOptions.maxUrl = yxui.refreshUrlLink(maxOptions.maxUrl, 'type=true'); }*/ maxWidgetId.panel(maxOptions); result = /^http:\/\/+/.test(maxOptions.url); if (result) { maxWidgetId.show().panel('open').panel('refresh'); } else { maxWidgetId.show().panel('open').panel('refresh', maxOptions.maxUrl); } // panelAddTips panelAddTips(maxWidgetId, true); } /* * 查找widget id */ function findId(button) { return $(button).parent().parent().next().attr("id"); } /* * 折叠widget */ function panelCollapse(id) { $('#' + id).panel('collapse', true); } /* * 展开widget */ function panelExpand(id) { $('#' + id).panel('expand', true); } /* * 关闭widget */ function panelClose(wid) { $.ajax({ url : root + "widget/deleteWidget.do", data : { wId : wid }, type : 'post', cache : false, success : function(response) { if (response.flag == '0') { var user = response.data; // $('#' + wid).panel('close'); var portalId = 'portal'+ user.id; var cookieState = $.cookie(portalId); //alert("userId : "+user.id+" cookieState : "+cookieState); var portal = $('#' + portalId); portal.portal('remove', $('#' + wid)); // 更新用户工作台widget状态 var newState = getPortalState(portalId); updateUserPlatformState(user.id, newState); var state = yxui.replaceAll(newState, ':', ''); if (state == '') { $.cookie(portalId, null); var content = '<div class="add-component"><p>抱歉,在<span class="workbench"><a href="#" onFocus="this.blur()">个人工作台</a></span>中未找到相关组件.</p> <div style="height:20px"></div></div>' portal.panel({ fit : true, border : false, content : content }); } else { $.cookie(portalId, newState, { expires : 7 }); } } } }); } function getPanelOptions(id, panels) { for (var i = 0; i < panels.length; i++) { var wid = panels[i].wId; if (id == wid) { return panels[i]; } } return undefined; }
..
每个widget的展示模块:
/** * 服务查询WIdget * @param request * @return */ @RequestMapping(value="widget/serviceQuery.do",method=RequestMethod.GET) public String serviceQuery(HttpServletRequest request) { logger.info("add serviceOrder widget begin..."); Page page = new Page(); EsbServiceV esbServiceV = new EsbServiceV(); PageQueryParameter pageQueryParameter = new PageQueryParameter(); pageQueryParameter.setRows(Constants.WIDGET_PAGE_ROWS); pageQueryParameter.setPage(Constants.WIDGET_CURRENT_PAGE); List<EsbServiceV> esbServiceVList = esbServiceVDS.findEsbServiceVPagedList(pageQueryParameter, esbServiceV); long rows = esbServiceVDS.getAllEsbServiceVsTotalCount(pageQueryParameter, esbServiceV); page.setTotal(rows); page.setRows(esbServiceVList); SysUser currentUser = getCurrentUser(); request.setAttribute("USER_ID", currentUser.getId()); request.setAttribute("SRV_DATA", esbServiceVList); request.setAttribute("SRV_MAX_URL", "esbService/query.do"); logger.info("add serviceQuery widget end..."); return "srvQueryWidget"; } <!-- widget --> <definition extends="content" name="srvQueryWidget"> <put-attribute name="body" value="/WEB-INF/views/widget/srvQueryWidget.jsp"/> </definition>
srvQueryWidget.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%> <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%> <html> <head> <link type="text/css" rel="stylesheet" href="<%=request.getContextPath()%>/css/widget.css"></link> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>服务查询Widget</title> </head> <style> </style> <body> <script type="text/javascript"> getMoreQuery = function() { var widgetId = $('#srvQuery').parent().attr('id'); var userId = '${USER_ID}'; var maxUrl = '${SRV_MAX_URL}'; //alert("widgetId: "+ widgetId + " maxUrl: " + maxUrl); panelMax(widgetId,userId,maxUrl); } </script> <div id="srvQuery" style="padding: 4px 8px 0px 8px;"> <ul class="news_list"> <c:choose> <c:when test="${requestScope.SRV_DATA != null && fn:length(requestScope.SRV_DATA) > 0 }"> <c:forEach items="${requestScope.SRV_DATA}" var="notice"> <li> <span> <fmt:formatDate value="${notice.lastUpdateDate}" dateStyle="short" pattern="yy/MM/dd"></fmt:formatDate> </span> <a title="${notice.serviceNameEn}" href="esbService/getServiceById.do?id=${notice.id}" target="_blank">${notice.serviceNameEn}</a> </li> </c:forEach> </c:when> <c:otherwise> <li><span>暂无相关内容!</span></li> </c:otherwise> </c:choose> </ul> <c:if test="${requestScope.SRV_DATA != null && fn:length(requestScope.SRV_DATA) > 0 }"> <p> <span class="more"><a href="#" onclick="getMoreQuery()" onFocus="this.blur()">更多...</a> </span> </p> </c:if> </div> </body> </html>
添加组件模块:
appAdd.js:
var $addDialog; //入口方法,进入添加展示页面 function addAppDialog(typeId){ var titleStr = "添加应用"; if (typeId == 1) { titleStr = "添加组件"; } $addDialog = $('#addAppDialog'); $addDialog.dialog({ title: titleStr, iconCls : 'pag-add', href: root + "widget/initAddApp.do?type="+typeId, width : 600, height : 330, modal:true, cache: false, resizable : false, minimizable : false, maximizable : false, collapsible : false }); $addDialog.dialog('open'); } //真正添加方法 function addApp(menuId, type) { $.ajax({ url : root + "widget/addApp.do", type : 'post', cache : false, data : { 'type' : type, 'menuId' : menuId }, success : function(result) { var data = result.data; if (result.flag == '0' && data != null) { //$("#span-" + resId).html('<img src="/eip/layout/app/images/user_added_button.png" width="60" height="24" style="border:0px;"/>'); if (type == 1) { protalAddWidgets(data); } } else { $.messager.alert('系统提示', '添加失败!', 'error'); } $addDialog.dialog('close'); } }); } /* * 添加组件后更新工作台上widget */ function protalAddWidgets(data) { var widgetId = data.id; var userId = data.userId; var state = $.cookie('portal'+userId); //alert("userId : "+userId+" state : "+state); var centerTabs = $("#centerTabs"); var tab = centerTabs.tabs('getTab',0); var options = tab.panel('options'); var content = options.content; var iframe = $(content); var src = iframe.attr("src"); tab.panel('refresh',src); }
/** * 初始化Widget添加页面 * @param request * @param session * @param type * @return */ @RequestMapping(value="widget/initAddApp.do",method=RequestMethod.GET) public String initAddApp(HttpServletRequest request,HttpSession session,String type) { logger.info("initAddApp begin .. "); logger.info("parameter type : " + type); List<SysMenu> rootList = (List<SysMenu>) session.getAttribute(SessionKeys.SESSION_USER_ROOT_MENU); long resCount = 0l; List<SysMenu> widgetList = new ArrayList<SysMenu>(); for(SysMenu m : rootList){ String menuName = m.getMenuName().trim(); if(menuName.equals(Constants.SERVICE_DIRECTORY) || menuName.equals(Constants.SERVICE_MONITOR) || menuName.equals(Constants.MY_SERVICE)){ widgetList.add(m); } } for(SysMenu m : widgetList){ if(m.getChildren() != null && m.getChildren().size() > 0){ resCount += m.getChildren().size(); } } esbWidgetDS.initWidgetStatus(widgetList); session.setAttribute("WIDGET_LIST", widgetList); session.setAttribute("resCount", resCount); session.setAttribute("type", type); logger.info("initAddApp end .. "); return "appAdd"; } /** * 添加WIdget到工作台 * @param request * @param session * @param type * @param menuId * @return */ @RequestMapping(value="widget/addApp.do",method=RequestMethod.POST) @ResponseBody public Map<String,Object> addApp(HttpServletRequest request,HttpSession session,String type,Long menuId) { logger.info("addApp begin .. "); logger.info("parameter type : " + type); logger.info("parameter menuId : " + menuId); Map<String,Object> result = new HashMap<String,Object>(); EsbWidget widget = null; if("1".equals(type)){ try{ widget = esbWidgetDS.save(menuId); }catch(Exception e){ logger.error(e.getMessage()); result.put("flag", "1"); return result; } } result.put("flag", "0"); result.put("data", widget); logger.info("addApp end .. "); return result; }
view.xml
<definition extends="content" name="appAdd"> <put-attribute name="body" value="/WEB-INF/views/widget/appAdd.jsp"/> </definition>
添加页面appAdd.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8" import="java.util.*" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %> <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> <link type="text/css" rel="stylesheet" href="<%=request.getContextPath()%>/css/window.css"></link> <% String ctx = request.getContextPath(); request.setAttribute("ctx", ctx); String fullPath = request.getLocalAddr() + ":" + request.getLocalPort() + "/"; request.setAttribute("fullpath", fullPath); %> <style> a:link, a:visited { color: #666666; text-decoration: none; } a:hover { color: #3399CC; } .add-button A:link{ background:url(${ctx}/images/add_button.png) no-repeat 0px 0px; } </style> <script> </script> <table width="100%" border="0" height="99%" cellspacing="0" cellpadding="0"> <tr> <td colspan="2" class="window_panel_center"> <table width="100%" border="0" cellspacing="0" cellpadding="0"> <tr> <td align="center" class="title"><table width="100%" border="0" cellspacing="0" cellpadding="0"> <tr> <td class="title_left"><c:choose> <c:when test="${type==0}">应用列表</c:when> <c:otherwise>组件列表</c:otherwise> </c:choose> </td> <td align="right">共有<span class="number">${resCount}</span> <c:choose> <c:when test="${type==0}">个应用</c:when> <c:otherwise>个组件</c:otherwise> </c:choose> <!-- <input name="textfield" type="text" class="input_search" id="textfield" /> --></td> </tr> </table></td> </tr> <tr> <td height="277px"> <div style="width:96px; height:277px; float:left; background-color:#f2f2f2; border-right: 1px solid #c2c2c2;"> <div style="height:6px;"> </div> <c:if test="${fn:length(WIDGET_LIST)>0}"> <c:forEach var="res" items="${WIDGET_LIST}" varStatus="stat"> <c:choose> <c:when test="${stat.index==0}"> <div id="accordion${stat.index}-header" class="accordion_headings header_highlight">${res.menuName}</div> </c:when> <c:otherwise> <div id="accordion${stat.index}-header" class="accordion_headings">${res.menuName}</div> </c:otherwise> </c:choose> </c:forEach> </c:if> </div> <div style="float:right; width:460px;"> <c:if test="${fn:length(WIDGET_LIST)>0}"> <c:forEach var="res" items="${WIDGET_LIST}" varStatus="stat"> <div id="accordion${stat.index}-content" class="content" style="display:<c:if test="${stat.index>0}">none</c:if>"> <div style="overflow-y:auto; height:277px"> <table width="100%" border="0" cellspacing="0" cellpadding="0"> <c:if test="${fn:length(res.children)>0}"> <c:forEach items="${res.children}" var="t"> <tr> <td height="63" align="center" class="accordion_child"><table width="96%" border="0" cellspacing="0" cellpadding="0"> <tr> <td width="60" align="left"><%-- <img src="${t.imageUrl}" width="48" height="48" /> --%> <img src="${ctx}/images/005.png" width="48" height="48" /> </td> <td><table width="100%" border="0" cellspacing="0" cellpadding="0" style="table-layout: fixed"> <tr> <td align="left" class="list_title">${t.menuName}</td> </tr> <tr> <td style="word-wrap:break-word:" align="left" class="list"><a href="return false;" onclick="return false;" title="${t.remark}" target="_blank"> <c:choose> <c:when test="${fn:length(t.remark)>45}">${fn:substring(t.remark, 0, 45)}...</c:when> <c:otherwise>${t.remark}</c:otherwise> </c:choose> </a> </td> </tr> </table></td> <td width="80"><span id="span-${t.id}" class="add-button"> <c:choose> <c:when test="${t.isAdd==false}"> <a href="javascript:void(0);" onclick="addApp(${t.id},${type})"></a> </c:when> <c:otherwise> <img src="${ctx}/images/user_added_button.png" width="60" height="24" style="border:0px;" /> </c:otherwise> </c:choose> </span> </td> </tr> </table></td> </tr> </c:forEach> </c:if> </table> </div> </div> </c:forEach> </c:if> </div></td> </tr> </table></td> </tr> </table> <script type="text/javascript"> $(function() { $('.accordion_headings').click(function() { var this_id = $(this).attr('id').split('-')[0]; $(this).addClass('header_highlight').siblings().removeClass('header_highlight'); $('.content').each(function() { if ($(this).attr('id').split('-')[0] == this_id) { $(this).show(); } else { $(this).hide(); } }) }); }); </script>
添加方法DS:
public Boolean checkWidgetAdded(Long menuId){ SysUser currentUser = getCurrentUser(); String hql = "from EsbWidgetV w where w.menuId = " + menuId + " and w.userId = " + currentUser.getId() +" and w.enabledFlag = 'Y'"; List<EsbWidgetV> ls = esbWidgetVDao.findByHql(hql); if(ls != null && ls.size() > 0){ return true; } return false; } /** * 初始化Widget添加状态 , 默认都为“可添加” * @param menuId */ @Override public void initWidgetStatus(List<SysMenu> widgetList){ logger.info("initWidgetStatus begin .."); for(SysMenu m : widgetList){ for(SysMenu c : m.getChildren()){ Boolean isAdded = checkWidgetAdded(c.getId()); if(isAdded){ c.setIsAdd(true); }else{ c.setIsAdd(false); } } } logger.info("initWidgetStatus end .."); }
/** * 添加WIdget并更新添加状态,一个组件一条widget记录 */ @Transactional @Override public EsbWidget save(Long menuId) { SysUser currentUser = getCurrentUser(); HttpSession session = GlobalSession.getHttpSession(); Map<Long,SysMenu> allMenu = (Map<Long, SysMenu>) session.getAttribute(SessionKeys.SESSION_USER_ALL_MENU); SysMenu m = allMenu.get(menuId); if(m == null) return null; String widgetUrl = null; String menuName = m.getMenuName().trim(); if(menuName.equals(Constants.SERVICE_QUERY)){ widgetUrl = "widget/serviceQuery.do"; }else if(menuName.equals(Constants.SERVICE_ORDER)){ widgetUrl = "widget/serviceOrder.do"; }else if(menuName.equals(Constants.SERVICE_ORDER_APPROVE)){ widgetUrl = "widget/serviceOrderApprove.do"; }else if(menuName.equals(Constants.MONITOR_LOG)){ widgetUrl = "widget/monitorLog.do"; }else if(menuName.equals(Constants.MY_ORDER)){ widgetUrl = "widget/myOrder.do"; } EsbWidget widget = new EsbWidget(); widget.setMenuId(menuId); widget.setUrl(widgetUrl); widget.setUserId(currentUser.getId()); widget.setEnabledFlag(Constants.ENABLED_FLAG_Y); ObjectUtil.setCreatedBy(widget); widget = esbWidgetDao.save(widget); //更新添加状态 updateWidgetStatus(menuId,true); return widget; } /** * 添加、删除Widget后更新添加状态 * @param menuId * @param isAdd */ @Override public void updateWidgetStatus(Long menuId,Boolean isAdd){ logger.info("updateWidgetStatus begin .."); HttpSession session = GlobalSession.getHttpSession(); List<SysMenu> widgetList = (List<SysMenu>) session.getAttribute("WIDGET_LIST"); if(widgetList == null) return; for(SysMenu menu : widgetList){ SysMenu m = null; List<SysMenu> children = menu.getChildren(); for(int i = children.size()-1;i>=0;i--){ SysMenu tmp = children.get(i); if(tmp.getId() == menuId){ m = tmp; m.setIsAdd(isAdd); children.set(children.indexOf(tmp), m); break; } } if(m != null) break; } session.removeAttribute("WIDGET_LIST"); session.setAttribute("WIDGET_LIST",widgetList); logger.info("updateWidgetStatus end .."); }
效果:
点“更多”可以最大化Widget:
点“添加组件”可以添加:
..
相关推荐
#### Portal系统的工作流程 - **初始尝试访问**:用户尝试访问外网资源时,其HTTP请求首先被接入设备捕获并重定向至Portal服务器。 - **认证信息提交**:用户在Portal页面输入必要的认证信息。 - **后台交互**:接入...
- **我的工作台**: 整合各个系统的 Portlet,便于用户执行具体业务操作。 - **NC 集团应用**: 实现 NC 系统的集成。 - **NC 集团报表**: 集成了 IUFO 报表系统。 - **企业安全搜索**: 提供 SES 企业安全搜索功能。 -...
Portal的一大特性是个性化,它允许用户根据个人喜好定制Porlet的布局、显示内容以及交互方式。通过设置权限和角色,用户可以拥有自己的视图,而不同的用户群体看到的界面和服务可能大相径庭。 3. **聚合...
2. **企业 IT 基础架构整合 (Framework Services)**:通过门户程序简化后端应用系统的访问,实现内容的客户化定制和个人化设置,支持移动设备接入,整合安全系统等。 3. **文档与内容管理 (Content Services)**:...
1. **用户个性化**:门户允许用户根据自己的需求定制界面和显示的内容,比如设置个人工作台,选择关注的信息源。 2. **内容管理**:门户通常集成了内容管理系统(CMS),方便发布、更新和管理各种信息,如新闻、...
- **工作流支持:** 集成了工作流引擎,方便实现业务流程自动化。 - **交互式表单:** 在门户界面中加入互动元素,如动态表单等,提高了用户体验。 - **用户界面增强:** 改进了用户界面设计,提升了操作友好性。 - **...
WSRP (Web Services for Remote Portlets) 是另一种规范,它允许远程 Portlet 通过 Web 服务接口集成到 Portal 中,从而实现 Portlet 的远程部署和访问。 **1.2 什么是 Portal** ##### 1.2.1 Portal 服务器 Portal...
在学习或使用Wap Portal Server v11时,你需要掌握PHP编程基础、MySQL数据库操作以及WAP相关协议,例如WML(Wireless Markup Language)和WAP 2.0的XHTML MP(Mobile Profile)。同时,了解HTTP协议和Web服务器配置...
目前,医院内部拥有超过1000台PC工作站、50多台服务器以及40多个应用模块,这些模块涵盖了各种基于事务处理的传统业务系统以及越来越多的临床应用系统。由于医院内使用了超过20家不同厂商的产品,这些产品采用的技术...
7. **数据交换**:为了实现后端与前端的数据交互,ChordSpread_Job_Portal可能使用了AJAX(异步JavaScript和XML),通过XMLHttpRequest对象在后台与服务器通信,无需刷新整个页面就能获取或更新数据。 8. **安全性*...
- **用户交互**:用户可以通过Web Portal申请和使用虚拟桌面,看到可用资源和详细信息。 - **系统管理**:管理员可以进行用户管理、模板管理、虚机监控等操作,并记录运行日志,实现系统配置的动态调整。 这个...
4. **工作台**:整合各类工作应用,如CRM、ERP、项目管理工具等,提供快捷入口。 5. **协作工具**:集成Slack、Teams等沟通工具,方便团队协作。 6. **报表与数据分析**:通过Echarts、Highcharts等图表库,展示关键...
Portlets允许用户根据个人需求定制门户界面,实现个性化工作环境。 3. **Single Sign-On (SSO)**: SSO是IBM企业门户解决方案中的关键组件,它允许用户只需一次登录即可访问多个相互关联的应用程序和服务,提高了...
这一功能使得布局更加灵活,用户可以根据个人偏好定制工作空间。 ### 2. 关闭与展开 组件提供关闭和展开功能,用户可以轻松隐藏或显示特定的区域。这不仅有助于优化屏幕空间,还能在需要时快速访问相关信息,提高...
在IPv6地址生成系统的背景下,无客户端迁移方案可能涉及在服务器端生成地址,然后将这些地址动态分配给使用Web Portal的用户,从而实现无需安装客户端软件即可进行地址管理和服务迁移。 四、实际操作中的挑战和解决...
Java为iPhone应用实现推送服务主要涉及的是远程通知技术,这是iOS设备与服务器间通信的一种方式,...通过以上步骤,你可以使用Java为iPhone应用实现推送服务,让应用能够实时地与用户保持互动,提供及时的信息和服务。
- **人力资源管理(HRM):**员工通过门户访问个人绩效数据,数据中台处理薪酬、培训等数据。 - **企业资源规划(ERP):**门户提供跨部门流程监控,数据中台集成财务、生产等系统数据。 ### 实施挑战与策略 实施...