浏览代码

springboot init

springboot init
shimingxy 6 年之前
父节点
当前提交
ba4514164e
共有 65 个文件被更改,包括 2270 次插入204 次删除
  1. 5 6
      maxkey-core/src/main/java/org/maxkey/web/MaxKeyFreeMarkerConfigurer.java
  2. 2 0
      maxkey-protocols/maxkey-protocol-authorize/bin/main/.gitignore
  3. 2 0
      maxkey-protocols/maxkey-protocol-ltpa/bin/main/.gitignore
  4. 2 13
      maxkey-web-manage/.classpath
  5. 2 1
      maxkey-web-manage/.settings/org.eclipse.core.resources.prefs
  6. 2 0
      maxkey-web-manage/.settings/org.eclipse.wst.common.component
  7. 10 3
      maxkey-web-manage/src/main/java/org/maxkey/MaxKeyMgtApplication.java
  8. 2 2
      maxkey-web-manage/src/main/java/org/maxkey/MaxKeyMgtConfig.java
  9. 18 5
      maxkey-web-manage/src/main/java/org/maxkey/web/interceptor/PermissionAdapter.java
  10. 22 0
      maxkey-web-manage/src/main/resources/application.properties
  11. 1 1
      maxkey-web-manage/src/main/resources/config/applicationLogin.properties
  12. 6 36
      maxkey-web-manage/src/main/resources/messages/message.properties
  13. 5 10
      maxkey-web-manage/src/main/resources/spring/maxkey-mgt-web.xml
  14. 207 7
      maxkey-web-manage/src/main/resources/static/css/base.css
  15. 二进制
      maxkey-web-manage/src/main/resources/static/images/cert.png
  16. 二进制
      maxkey-web-manage/src/main/resources/static/images/exit.jpg
  17. 二进制
      maxkey-web-manage/src/main/resources/static/images/exit1.jpg
  18. 二进制
      maxkey-web-manage/src/main/resources/static/images/exit2.jpg
  19. 二进制
      maxkey-web-manage/src/main/resources/static/images/exit4.png
  20. 二进制
      maxkey-web-manage/src/main/resources/static/images/grid.png
  21. 二进制
      maxkey-web-manage/src/main/resources/static/images/grid_sel.png
  22. 二进制
      maxkey-web-manage/src/main/resources/static/images/list.png
  23. 二进制
      maxkey-web-manage/src/main/resources/static/images/list_sel.png
  24. 二进制
      maxkey-web-manage/src/main/resources/static/images/menu-left.png
  25. 二进制
      maxkey-web-manage/src/main/resources/static/images/menu.png
  26. 二进制
      maxkey-web-manage/src/main/resources/static/images/progress_bar.gif
  27. 二进制
      maxkey-web-manage/src/main/resources/static/images/side-nav.png
  28. 335 0
      maxkey-web-manage/src/main/resources/static/jquery/metisMenu-v3.0.4/cjs/index.js
  29. 44 0
      maxkey-web-manage/src/main/resources/static/jquery/metisMenu-v3.0.4/css/app.css
  30. 1 0
      maxkey-web-manage/src/main/resources/static/jquery/metisMenu-v3.0.4/css/demo.css
  31. 55 0
      maxkey-web-manage/src/main/resources/static/jquery/metisMenu-v3.0.4/css/mini.css
  32. 11 0
      maxkey-web-manage/src/main/resources/static/jquery/metisMenu-v3.0.4/css/mm-faq.css
  33. 37 0
      maxkey-web-manage/src/main/resources/static/jquery/metisMenu-v3.0.4/css/mm-folder.css
  34. 80 0
      maxkey-web-manage/src/main/resources/static/jquery/metisMenu-v3.0.4/css/mm-horizontal.css
  35. 73 0
      maxkey-web-manage/src/main/resources/static/jquery/metisMenu-v3.0.4/css/mm-vertical-hover.css
  36. 71 0
      maxkey-web-manage/src/main/resources/static/jquery/metisMenu-v3.0.4/css/mm-vertical.css
  37. 3 0
      maxkey-web-manage/src/main/resources/static/jquery/metisMenu-v3.0.4/js/index.js
  38. 54 0
      maxkey-web-manage/src/main/resources/static/jquery/metisMenu-v3.0.4/js/mm-ajax.js
  39. 5 0
      maxkey-web-manage/src/main/resources/static/jquery/metisMenu-v3.0.4/js/mm-animate.js
  40. 11 0
      maxkey-web-manage/src/main/resources/static/jquery/metisMenu-v3.0.4/js/mm-bs-card.js
  41. 47 0
      maxkey-web-manage/src/main/resources/static/jquery/metisMenu-v3.0.4/js/mm-dispose.js
  42. 38 0
      maxkey-web-manage/src/main/resources/static/jquery/metisMenu-v3.0.4/js/mm-event.js
  43. 7 0
      maxkey-web-manage/src/main/resources/static/jquery/metisMenu-v3.0.4/js/mm-event2.js
  44. 10 0
      maxkey-web-manage/src/main/resources/static/jquery/metisMenu-v3.0.4/js/mm-faq.js
  45. 5 0
      maxkey-web-manage/src/main/resources/static/jquery/metisMenu-v3.0.4/js/mm-folder.js
  46. 7 0
      maxkey-web-manage/src/main/resources/static/jquery/metisMenu-v3.0.4/js/mm-horizontal.js
  47. 5 0
      maxkey-web-manage/src/main/resources/static/jquery/metisMenu-v3.0.4/js/mm-vertical-hover.js
  48. 11 0
      maxkey-web-manage/src/main/resources/static/jquery/metisMenu-v3.0.4/js/mm-vertical.js
  49. 130 0
      maxkey-web-manage/src/main/resources/static/jquery/metisMenu-v3.0.4/metisMenu.css
  50. 0 0
      maxkey-web-manage/src/main/resources/static/jquery/metisMenu-v3.0.4/metisMenu.css.map
  51. 340 0
      maxkey-web-manage/src/main/resources/static/jquery/metisMenu-v3.0.4/metisMenu.js
  52. 0 0
      maxkey-web-manage/src/main/resources/static/jquery/metisMenu-v3.0.4/metisMenu.js.map
  53. 8 0
      maxkey-web-manage/src/main/resources/static/jquery/metisMenu-v3.0.4/metisMenu.min.css
  54. 0 0
      maxkey-web-manage/src/main/resources/static/jquery/metisMenu-v3.0.4/metisMenu.min.css.map
  55. 7 0
      maxkey-web-manage/src/main/resources/static/jquery/metisMenu-v3.0.4/metisMenu.min.js
  56. 0 0
      maxkey-web-manage/src/main/resources/static/jquery/metisMenu-v3.0.4/metisMenu.min.js.map
  57. 331 0
      maxkey-web-manage/src/main/resources/static/jquery/metisMenu-v3.0.4/modules/index.js
  58. 0 0
      maxkey-web-manage/src/main/resources/templates/views/apps/appsList.ftl
  59. 9 0
      maxkey-web-manage/src/main/resources/templates/views/layout/common.cssjs.ftl
  60. 154 0
      maxkey-web-manage/src/main/resources/templates/views/layout/sidenav.ftl
  61. 36 50
      maxkey-web-manage/src/main/resources/templates/views/layout/top.ftl
  62. 20 21
      maxkey-web-manage/src/main/resources/templates/views/login.ftl
  63. 0 0
      maxkey-web-manage/src/main/resources/templates/views/main.ftl
  64. 39 42
      maxkey-web-manage/src/main/resources/templates/views/userinfo/usersList.ftl
  65. 0 7
      maxkey-web-maxkey/src/main/resources/spring/maxkey-web.xml

+ 5 - 6
maxkey-core/src/main/java/org/maxkey/web/MaxKeyFreeMarkerConfigurer.java

@@ -5,8 +5,9 @@ import java.util.Map;
 
 import javax.annotation.PostConstruct;
 
-import org.maxkey.web.tag.BaseTagDirective;
 import org.maxkey.web.tag.FreemarkerTag;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.BeansException;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.ApplicationContext;
@@ -18,22 +19,20 @@ import freemarker.template.TemplateException;
 
 @Component
 public class MaxKeyFreeMarkerConfigurer  implements ApplicationContextAware {
-	
+	private static final Logger _logger = LoggerFactory.getLogger(MaxKeyFreeMarkerConfigurer.class);
 	ApplicationContext applicationContext ;
 	
 	@Autowired 
 	Configuration configuration; 
- 
-	@Autowired
-	BaseTagDirective baseTagDirective;
+
  
 	@PostConstruct // 在项目启动时执行方法
 	public void setSharedVariable() throws IOException, TemplateException {
-		// configuration.setSharedVariable("base", baseTagDirective);
 		// 根据注解FreemarkerTag获取bean ,key is bean name ,value is bean object
 		Map<String, Object> map = this.applicationContext.getBeansWithAnnotation(FreemarkerTag.class);
 		for (String key : map.keySet()) {
 			configuration.setSharedVariable(key, map.get(key));
+			_logger.debug("FreeMarker Template "+key);
 		}
 
 	}

+ 2 - 0
maxkey-protocols/maxkey-protocol-authorize/bin/main/.gitignore

@@ -0,0 +1,2 @@
+/META-INF/
+/org/

+ 2 - 0
maxkey-protocols/maxkey-protocol-ltpa/bin/main/.gitignore

@@ -0,0 +1,2 @@
+/META-INF/
+/org/

+ 2 - 13
maxkey-web-manage/.classpath

@@ -1,18 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <classpath>
-	<classpathentry kind="src" output="bin/main" path="src/main/java">
-		<attributes>
-			<attribute name="gradle_scope" value="main"/>
-			<attribute name="gradle_used_by_scope" value="main,test"/>
-		</attributes>
-	</classpathentry>
-	<classpathentry kind="src" output="bin/main" path="src/main/resources">
-		<attributes>
-			<attribute name="gradle_scope" value="main"/>
-			<attribute name="gradle_used_by_scope" value="main,test"/>
-		</attributes>
-	</classpathentry>
-	<classpathentry kind="src" path="static"/>
+	<classpathentry kind="src" path="src/main/resources"/>
+	<classpathentry kind="src" path="src/main/java"/>
 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8/"/>
 	<classpathentry kind="con" path="org.eclipse.jst.j2ee.internal.web.container"/>
 	<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer">

+ 2 - 1
maxkey-web-manage/.settings/org.eclipse.core.resources.prefs

@@ -1,2 +1,3 @@
 eclipse.preferences.version=1
-encoding/<project>=UTF-8
+encoding//src/main/resources/templates/views/login.ftl=UTF-8
+encoding/<project>=UTF-8

+ 2 - 0
maxkey-web-manage/.settings/org.eclipse.wst.common.component

@@ -5,6 +5,8 @@
 		<wb-resource deploy-path="/WEB-INF/classes" source-path="src/main/java"/>
 		<wb-resource deploy-path="/" source-path="src/main/webapp"/>
         <wb-resource deploy-path="/WEB-INF/classes" source-path="/static"/>
+        <wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/resources"/>
+        <wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/java"/>
 		<dependent-module deploy-path="/WEB-INF/lib" handle="module:/resource/maxkey-core/maxkey-core">
 			<dependency-type>uses</dependency-type>
 		</dependent-module>

+ 10 - 3
maxkey-web-manage/src/main/java/org/maxkey/MaxKeyApplication.java → maxkey-web-manage/src/main/java/org/maxkey/MaxKeyMgtApplication.java

@@ -5,16 +5,23 @@ import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.boot.builder.SpringApplicationBuilder;
 import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.ImportResource;
 
 @SpringBootApplication
-public class MaxKeyApplication extends SpringBootServletInitializer {
+@ImportResource(locations={"classpath:spring/maxkey-mgt.xml"})
+@ComponentScan(basePackages = {
+		"org.maxkey.MaxKeyConfig"
+	}
+)
+public class MaxKeyMgtApplication extends SpringBootServletInitializer {
 
 	public static void main(String[] args) {
-		SpringApplication.run(MaxKeyApplication.class, args);
+		SpringApplication.run(MaxKeyMgtApplication.class, args);
 	}
 
 	protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
-		return application.sources(MaxKeyApplication.class);
+		return application.sources(MaxKeyMgtApplication.class);
 	}
 
 }

+ 2 - 2
maxkey-web-manage/src/main/java/org/maxkey/MaxKeyConfig.java → maxkey-web-manage/src/main/java/org/maxkey/MaxKeyMgtConfig.java

@@ -1,10 +1,10 @@
 package org.maxkey;
 
+import org.springframework.context.annotation.ComponentScan;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.ImportResource;
 
 @Configuration
-@ImportResource(locations={"classpath:spring/maxkey-mgt.xml"})
-public class MaxKeyConfig {
+public class MaxKeyMgtConfig {
 
 }

+ 18 - 5
maxkey-web-manage/src/main/java/org/maxkey/web/interceptor/PermissionAdapter.java

@@ -32,7 +32,7 @@ public class PermissionAdapter extends HandlerInterceptorAdapter {
 	@Qualifier("applicationConfig")
 	private ApplicationConfig applicationConfig;
 	
-	static ConcurrentHashMap<String ,String >navigationsMap=null;
+	static  ConcurrentHashMap<String ,String >navigationsMap=null;
 	/*
 	 * 请求前处理
 	 *  (non-Javadoc)
@@ -42,9 +42,9 @@ public class PermissionAdapter extends HandlerInterceptorAdapter {
 	public boolean preHandle(HttpServletRequest request,HttpServletResponse response, Object handler) throws Exception {
 		 _logger.debug("PermissionAdapter preHandle");
 		 //加载定义的功能菜单地址
-		if(navigationsMap==null){
+		/*if(navigationsMap==null){
 			List<Navigations>   navigationsList=((NavigationsService)WebContext.getBean("navigationsService")).query(null);
-			navigationsMap=new ConcurrentHashMap<String ,String >();
+			navigationsMap=new  ConcurrentHashMap<String ,String >();
 			for(Navigations nav : navigationsList){
 				if(nav.getUrl()==null)continue;
 				if(nav.getUrl().endsWith("/")){
@@ -58,7 +58,7 @@ public class PermissionAdapter extends HandlerInterceptorAdapter {
 		
 		UserInfo userInfo =WebContext.getUserInfo();//取得登录用户
 		
-		if(userInfo==null){//判断用户和角色,判断用户是否登录用户
+		if(userInfo==null||WebContext.getRoles()==null){//判断用户和角色,判断用户是否登录用户
 			RequestDispatcher dispatcher = request.getRequestDispatcher("/login");
 			dispatcher.forward(request, response);
 			return false;
@@ -76,7 +76,20 @@ public class PermissionAdapter extends HandlerInterceptorAdapter {
 		}
 		
 		boolean hasNavAccess=true;
-
+		//菜单权限匹配
+		if(navigationsMap.containsKey(accessURI)){//判断当前访问URL地址是否需要进行权限校验
+			hasNavAccess=false;
+			for(Navigations nav : WebContext.getNavigations()){//获取当前登录用户拥有URL访问列表
+				String haveURL=nav.getUrl();
+				if(haveURL==null)continue;
+				if(!haveURL.endsWith("/")){haveURL="/"+haveURL+"/";}
+				if(haveURL.endsWith(accessURI)){
+					hasNavAccess=true;
+				}
+			}
+			_logger.debug("Access URI : "+accessURI+" , hasNavAccess "+hasNavAccess);
+			if(hasNavAccess)return true;
+		}
 		
 		/*	
 		boolean preHandler = super.preHandle(request, response, handler);

+ 22 - 0
maxkey-web-manage/src/main/resources/application.properties

@@ -0,0 +1,22 @@
+#server config
+#spring.profiles.active=dev
+#server port
+server.port=9521
+#web app context path
+server.servlet.context-path=/maxkey-mgt
+
+#for freemarker
+spring.freemarker.template-loader-path=classpath:/templates/views
+spring.freemarker.cache=false
+spring.freemarker.charset=UTF-8
+spring.freemarker.check-template-location=true
+spring.freemarker.content-type=text/html
+spring.freemarker.expose-request-attributes=false
+spring.freemarker.expose-session-attributes=false
+spring.freemarker.request-context-attribute=request
+spring.freemarker.suffix=.ftl
+
+#static resources
+spring.mvc.static-path-pattern=/static/**
+
+spring.main.allow-bean-definition-overriding=true

+ 1 - 1
maxkey-web-manage/src/main/resources/config/applicationLogin.properties

@@ -4,7 +4,7 @@
 #                domain name configuration
 config.domain.name=sso.maxkey.org
 config.server.name=http://${config.domain.name}
-config.server.maxkey.uri=${config.server.name}/maxkey-mgt
+config.server.maxkey.uri=${config.server.name}:9521/maxkey-mgt
 
 ############################################################################ 
 #                Login configuration

+ 6 - 36
maxkey-web-manage/src/main/resources/messages/message.properties

@@ -1,4 +1,4 @@
-global.application=MaxKey\u5E94\u7528\u5B89\u5168\u7CFB\u7EDF
+global.application=MaxKey\u5E94\u7528\u5B89\u5168\u7BA1\u7406\u7CFB\u7EDF
 global.change.language=\u8BED\u97F3\u9009\u62E9
 global.change.language.en=\u82F1\u6587
 global.change.language.zh=\u4E2D\u6587
@@ -13,7 +13,6 @@ global.logout.text.prefix=\u60A8\u5DF2\u7ECF\u6210\u529F\u9000\u51FA\u767B\u5F55
 login.session.timeout.tip=\u767B\u5F55\u4F1A\u8BDD\u8D85\u65F6
 login.session.timeout.prefix=\u60A8\u7684\u767B\u5F55\u4F1A\u8BDD\u5DF2\u7ECF\u8D85\u65F6\uFF0C\u8BF7
 login.session.timeout.suffix=\u91CD\u65B0\u767B\u5F55
-login.text.login.header=\u8D26\u53F7\u767B\u5F55
 
 common.window.title=\u7A97\u53E3
 common.alert.title=\u63D0\u793A\u4FE1\u606F
@@ -33,22 +32,6 @@ common.text.createdby=\u521B\u5EFA\u4EBA
 common.text.createddate=\u521B\u5EFA\u65F6\u95F4
 common.text.modifiedby=\u4FEE\u6539\u4EBA
 common.text.modifieddate=\u4FEE\u6539\u65F6\u95F4
-common.text.status=\u72B6\u6001
-common.text.status.0=\u5F00\u59CB
-common.text.status.1=\u6B63\u5E38
-common.text.status.2=\u505C\u6B62
-common.text.status.3=\u542F\u7528
-common.text.status.4=\u7981\u7528
-common.text.status.5=\u9501\u5B9A
-common.text.status.6=\u89E3\u9501
-common.text.status.7=\u65E0\u6548
-common.text.status.8=\u8FC7\u671F
-common.text.status.9=\u5220\u9664
-common.text.status.10=\u6709\u6548
-common.text.status.11=\u6D3B\u52A8
-common.text.status.12=\u4E0D\u6D3B\u52A8
-common.text.status.13=\u6279\u51C6
-
 		
 login.text.login.twofactor.obtain.valid=\u91CD\u65B0\u83B7\u53D6
 login.text.login.twofactor.obtain=\u83B7\u53D6\u52A8\u6001\u9A8C\u8BC1\u7801
@@ -56,7 +39,7 @@ login.text.login.twofactor.obtain.valid.unit=\u79D2
 login.text.login.twofactor.validTime=\u5269\u4F59\u65F6\u95F4
 login.text.login.twofactor.validTime.unit=\u79D2
 login.text.login.twofactor=\u5B89\u5168\u8BA4\u8BC1
-login.text.login.normal=\u57FA\u672C\u8BA4\u8BC1
+login.text.login.normal=\u7528\u6237\u8BA4\u8BC1
 login.text.username=\u7528\u6237\u540D
 login.text.password=\u5BC6&nbsp;&nbsp;&nbsp;&nbsp;\u7801
 login.text.captcha=\u9A8C\u8BC1\u7801
@@ -183,14 +166,13 @@ apps.category=\u7C7B\u578B
 button.text.action=\u8BBF\u95EE
 button.text.visit=\u8BBF\u95EE
 button.text.save=\u4FDD\u5B58
+button.text.add=\u65B0\u589E
+button.text.edit=\u7F16\u8F91
+button.text.delete=\u5220\u9664
 button.text.select=\u8BF7\u9009\u62E9
 button.text.search=\u67E5\u8BE2
 button.text.expandsearch=\u5C55\u5F00
 button.text.collapsesearch=\u6536\u7F29
-button.text.changepassword=\u4FEE\u6539\u5BC6\u7801
-button.text.add=\u65B0\u589E
-button.text.edit=\u4FEE\u6539
-button.text.delete=\u5220\u9664
 
 log.loginhistory.id=\u7F16\u53F7
 log.loginhistory.sessionId=\u4F1A\u8BDD
@@ -223,16 +205,4 @@ log.operate.message=\u6D88\u606F
 log.operate.content=\u5185\u5BB9
 log.operate.messageType=\u6D88\u606F\u7C7B\u578B
 log.operate.operateType=\u64CD\u4F5C\u7C7B\u578B
-log.operate.username=\u64CD\u4F5C\u4EBA
-
-passwordpolicy.minlength=\u6700\u5C0F\u957F\u5EA6
-passwordpolicy.maxlength=\u6700\u5927\u957F\u5EA6
-passwordpolicy.lowercase=\u5C0F\u5199
-passwordpolicy.uppercase=\u5927\u5199
-passwordpolicy.digits=\u6570\u5B57
-passwordpolicy.specialchar=\u7279\u6B8A\u5B57\u7B26
-passwordpolicy.attempts=\u767B\u5F55\u9519\u8BEF\u6B21\u6570
-passwordpolicy.duration=\u9501\u5B9A\u65F6\u95F4
-passwordpolicy.expiration=\u8FC7\u671F\u5929\u6570
-passwordpolicy.username=\u5305\u542B\u7528\u6237\u540D
-passwordpolicy.simplepasswords=\u7B80\u5355\u5BC6\u7801\u5217\u8868
+log.operate.username=\u64CD\u4F5C\u4EBA

+ 5 - 10
maxkey-web-manage/src/main/resources/spring/maxkey-mgt-web.xml

@@ -22,13 +22,6 @@
     <!-- language select must remove -->
 	<mvc:annotation-driven />
 	
-	<!-- Static resources -->
-	<!-- js images css -->
-	<mvc:resources mapping="/jquery/**" location="/jquery/" />
-	<mvc:resources mapping="/images/**" location="/images/" />
-	<mvc:resources mapping="/css/**" location="/css/" />
-	<mvc:resources mapping="/js/**" location="/js/" />
-	
 	<!-- Scans the classpath for annotated components that will be auto-registered as Spring beans.
  	 @Controller and @Service. Make sure to set the correct base-package-->
  
@@ -42,6 +35,11 @@
 	<context:component-scan base-package="org.maxkey.web.endpoint" />
 	<context:component-scan base-package="org.maxkey.web.contorller" />
 	<context:component-scan base-package="org.maxkey.web.apps.contorller" />
+	<context:component-scan base-package="org.maxkey.web.endpoint" />
+	<context:component-scan base-package="org.maxkey.authn" />
+	<context:component-scan base-package="org.maxkey.dao" />
+	<context:component-scan base-package="org.maxkey.web" />
+	<context:component-scan base-package="org.maxkey.web.tag" />
 	
 	<!-- LocaleResolver -->
 	<bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
@@ -126,9 +124,6 @@
 		</property>
 	</bean>
 
-	<!-- View Resolver -->
-	<bean id="viewResolver"  class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:prefix="/WEB-INF/views/" p:suffix=".jsp" p:order="2" />
-	
 	<!-- upload file support -->
     <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
     	<property name="maxUploadSize" value="4194304" />  

+ 207 - 7
maxkey-web-manage/src/main/resources/static/css/base.css

@@ -11,6 +11,212 @@ body{
 	font-family: "Arial", "Helvetica", "Verdana", "sans-serif";
 }
 
+.header {
+    display: block;
+    height: 65px;
+    width: 100%;
+    position: fixed;
+    padding: 0;
+    z-index: 1040;
+    background-color: #fff;
+    border-bottom: 1px solid #e9eaec;
+    margin-bottom: 0;
+    transition: all .2s ease;
+    -webkit-transition: all .2s ease;
+    -moz-transition: all .2s ease;
+    -o-transition: all .2s ease;
+    -ms-transition: all .2s ease;
+}
+.swlink {
+    text-indent: -9999px;
+    height: 0;
+    line-height: 0;
+    font-size: 0;
+    overflow: hidden;
+}
+
+header .header-container .nav-left>li, .header .header-container .nav-right>li {
+    float: left;
+}
+.search-box {
+    margin-right: 20px;
+    position: relative;
+}
+
+.header .header-container .nav-logo {
+    float: left;
+    padding-left: 40px;
+    padding-top: 8px;
+}
+
+.header .header-container .nav-left {
+    float: left;
+}
+.header .header-container .nav-left, .header .header-container .nav-right {
+    position: relative;
+    list-style: none;
+    padding-left: 0;
+    margin-bottom: 0;
+}
+
+.header .header-container .nav-right {
+    float: right;
+    margin-right: 30px;
+}
+.header .header-container .nav-left, .header .header-container .nav-right {
+    position: relative;
+    list-style: none;
+    padding-left: 0;
+    margin-bottom: 0;
+}
+
+.header .header-container .nav-left>li>a i, .header .header-container .nav-right>li>a i {
+    font-size: 18px;
+    vertical-align: middle;
+    color: #fff;
+    border-radius: 50%;
+    border: 1px solid #f1f1f1;
+    padding: 8px;
+    color: #999;
+    transition: all .3s ease-in-out;
+    -webkit-transition: all .3s ease-in-out;
+    -moz-transition: all .3s ease-in-out;
+    -o-transition: all .3s ease-in-out;
+    -ms-transition: all .3s ease-in-out;
+}
+
+.sidenav-fold-toggler{
+	
+}
+[class^=lni-], [class*=" lni-"] {
+    font-family: lineicons!important;
+    speak: none;
+    font-style: normal;
+    font-weight: 400;
+    font-variant: normal;
+    text-transform: none;
+    line-height: 1;
+    -webkit-font-smoothing: antialiased;
+    -moz-osx-font-smoothing: grayscale;
+}
+
+.side-nav-dark .side-nav {
+    background-color: #212529;
+    color: #99abb4;
+}
+.side-nav {
+    width: 250px;
+    background-color: #fff;
+    z-index: 1000;
+    top: 65px;
+    bottom: 0;
+    position: fixed;
+    overflow-y: auto;
+    transition: all .2s ease;
+    -webkit-transition: all .2s ease;
+    -moz-transition: all .2s ease;
+    -o-transition: all .2s ease;
+    -ms-transition: all .2s ease;
+}
+
+.side-nav-folded .side-nav {
+    width: 1px;
+    padding-right: 1px;
+    padding-left: 1px;
+}
+
+@media only screen and (min-width:992px) {
+	.side-nav-folded .page-container {
+		padding-left: 0px
+	}
+}
+
+@media only screen and (max-width:992px) {
+	.side-nav-folded .page-container {
+		padding-left: 0
+	}
+}
+
+.page-container {
+    min-height: 100vh;
+    padding-left: 250px;
+    transition: all .2s ease;
+    -webkit-transition: all .2s ease;
+    -moz-transition: all .2s ease;
+    -o-transition: all .2s ease;
+    -ms-transition: all .2s ease;
+}
+
+.page-container .main-content {
+    padding: calc(50px + 35px) 15px 15px;
+    min-height: calc(100vh - 65px);
+    background: #e6e8ea;
+    width: 100%;
+    flex-grow: 1;
+}
+
+.container-fluid {
+    width: 100%;
+    padding-right: 15px;
+    padding-left: 15px;
+    margin-right: auto;
+    margin-left: auto;
+    background-color: #f5f5f5;
+}
+
+.breadcrumb-wrapper h4 {
+    color: #515365;
+    font-weight: 500;
+    margin-top: 6px;
+    font-size: 18px;
+}
+
+.breadcrumb-wrapper .breadcrumb {
+    margin-bottom: 0;
+    padding: 0;
+    background: 0 0;
+}
+
+.breadcrumb-wrapper {
+    margin-bottom: 20px;
+    display: flex;
+    -webkit-box-align: center;
+    -ms-flex-align: center;
+    align-items: center;
+}
+
+.breadcrumb-wrapper .breadcrumb li {
+    display: inline-block;
+    font-size: 14px;
+    font-weight: 400;
+    margin-left: 3px;
+}
+
+.breadcrumb-wrapper .breadcrumb li a {
+    text-decoration: none;
+    color: #8a8a8a;
+    cursor: pointer;
+}
+.breadcrumb-wrapper .breadcrumb .active {
+    color: #e22a6f;
+}
+
+.content-footer .footer {
+    padding: 20px 0;
+    font-size: 14px;
+    border-top: 1px solid #e9eaec;
+}
+
+.wrapper-page {
+    margin: 7.5% auto;
+    position: relative;
+}
+
+.card-header .card-title {
+    margin-bottom: 0;
+    display: inline-block;
+}
+
 .form_title_bar{
 	width: 100%;
 	height: 36px;
@@ -57,13 +263,6 @@ body{
 	/*border-top: 1px solid #e5e5e5;*/
 }
 
-.container {
-	width: 990px;
-	margin-left: auto;
-	margin-right: auto;
-	padding: 0 10px
-}
-
 #mainFrame{
 	margin-top: 0px;
 	margin-left: auto;
@@ -236,3 +435,4 @@ body{
 }
 
 
+

二进制
maxkey-web-manage/src/main/resources/static/images/cert.png


二进制
maxkey-web-manage/src/main/resources/static/images/exit.jpg


二进制
maxkey-web-manage/src/main/resources/static/images/exit1.jpg


二进制
maxkey-web-manage/src/main/resources/static/images/exit2.jpg


二进制
maxkey-web-manage/src/main/resources/static/images/exit4.png


二进制
maxkey-web-manage/src/main/resources/static/images/grid.png


二进制
maxkey-web-manage/src/main/resources/static/images/grid_sel.png


二进制
maxkey-web-manage/src/main/resources/static/images/list.png


二进制
maxkey-web-manage/src/main/resources/static/images/list_sel.png


二进制
maxkey-web-manage/src/main/resources/static/images/menu-left.png


二进制
maxkey-web-manage/src/main/resources/static/images/menu.png


二进制
maxkey-web-manage/src/main/resources/static/images/progress_bar.gif


二进制
maxkey-web-manage/src/main/resources/static/images/side-nav.png


+ 335 - 0
maxkey-web-manage/src/main/resources/static/jquery/metisMenu-v3.0.4/cjs/index.js

@@ -0,0 +1,335 @@
+/*!
+* metismenu https://github.com/onokumus/metismenu#readme
+* A jQuery menu plugin
+* @version 3.0.4
+* @author Osman Nuri Okumus <onokumus@gmail.com> (https://github.com/onokumus)
+* @license: MIT 
+*/
+'use strict';
+
+function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
+
+var $ = _interopDefault(require('jquery'));
+
+function _extends() {
+  _extends = Object.assign || function (target) {
+    for (var i = 1; i < arguments.length; i++) {
+      var source = arguments[i];
+
+      for (var key in source) {
+        if (Object.prototype.hasOwnProperty.call(source, key)) {
+          target[key] = source[key];
+        }
+      }
+    }
+
+    return target;
+  };
+
+  return _extends.apply(this, arguments);
+}
+
+var Util = function ($) {
+  // eslint-disable-line no-shadow
+  var TRANSITION_END = 'transitionend';
+  var Util = {
+    // eslint-disable-line no-shadow
+    TRANSITION_END: 'mmTransitionEnd',
+    triggerTransitionEnd: function triggerTransitionEnd(element) {
+      $(element).trigger(TRANSITION_END);
+    },
+    supportsTransitionEnd: function supportsTransitionEnd() {
+      return Boolean(TRANSITION_END);
+    }
+  };
+
+  function getSpecialTransitionEndEvent() {
+    return {
+      bindType: TRANSITION_END,
+      delegateType: TRANSITION_END,
+      handle: function handle(event) {
+        if ($(event.target).is(this)) {
+          return event.handleObj.handler.apply(this, arguments); // eslint-disable-line prefer-rest-params
+        }
+
+        return undefined;
+      }
+    };
+  }
+
+  function transitionEndEmulator(duration) {
+    var _this = this;
+
+    var called = false;
+    $(this).one(Util.TRANSITION_END, function () {
+      called = true;
+    });
+    setTimeout(function () {
+      if (!called) {
+        Util.triggerTransitionEnd(_this);
+      }
+    }, duration);
+    return this;
+  }
+
+  function setTransitionEndSupport() {
+    $.fn.mmEmulateTransitionEnd = transitionEndEmulator; // eslint-disable-line no-param-reassign
+    // eslint-disable-next-line no-param-reassign
+
+    $.event.special[Util.TRANSITION_END] = getSpecialTransitionEndEvent();
+  }
+
+  setTransitionEndSupport();
+  return Util;
+}($);
+
+var NAME = 'metisMenu';
+var DATA_KEY = 'metisMenu';
+var EVENT_KEY = "." + DATA_KEY;
+var DATA_API_KEY = '.data-api';
+var JQUERY_NO_CONFLICT = $.fn[NAME];
+var TRANSITION_DURATION = 350;
+var Default = {
+  toggle: true,
+  preventDefault: true,
+  triggerElement: 'a',
+  parentTrigger: 'li',
+  subMenu: 'ul'
+};
+var Event = {
+  SHOW: "show" + EVENT_KEY,
+  SHOWN: "shown" + EVENT_KEY,
+  HIDE: "hide" + EVENT_KEY,
+  HIDDEN: "hidden" + EVENT_KEY,
+  CLICK_DATA_API: "click" + EVENT_KEY + DATA_API_KEY
+};
+var ClassName = {
+  METIS: 'metismenu',
+  ACTIVE: 'mm-active',
+  SHOW: 'mm-show',
+  COLLAPSE: 'mm-collapse',
+  COLLAPSING: 'mm-collapsing',
+  COLLAPSED: 'mm-collapsed'
+};
+
+var MetisMenu =
+/*#__PURE__*/
+function () {
+  // eslint-disable-line no-shadow
+  function MetisMenu(element, config) {
+    this.element = element;
+    this.config = _extends({}, Default, config);
+    this.transitioning = null;
+    this.init();
+  }
+
+  var _proto = MetisMenu.prototype;
+
+  _proto.init = function init() {
+    var self = this;
+    var conf = this.config;
+    var el = $(this.element);
+    el.addClass(ClassName.METIS); // add metismenu class to element
+
+    el.find(conf.parentTrigger + "." + ClassName.ACTIVE).children(conf.triggerElement).attr('aria-expanded', 'true'); // add attribute aria-expanded=true the trigger element
+
+    el.find(conf.parentTrigger + "." + ClassName.ACTIVE).parents(conf.parentTrigger).addClass(ClassName.ACTIVE);
+    el.find(conf.parentTrigger + "." + ClassName.ACTIVE).parents(conf.parentTrigger).children(conf.triggerElement).attr('aria-expanded', 'true'); // add attribute aria-expanded=true the triggers of all parents
+
+    el.find(conf.parentTrigger + "." + ClassName.ACTIVE).has(conf.subMenu).children(conf.subMenu).addClass(ClassName.COLLAPSE + " " + ClassName.SHOW);
+    el.find(conf.parentTrigger).not("." + ClassName.ACTIVE).has(conf.subMenu).children(conf.subMenu).addClass(ClassName.COLLAPSE);
+    el.find(conf.parentTrigger) // .has(conf.subMenu)
+    .children(conf.triggerElement).on(Event.CLICK_DATA_API, function (e) {
+      // eslint-disable-line func-names
+      var eTar = $(this);
+
+      if (eTar.attr('aria-disabled') === 'true') {
+        return;
+      }
+
+      if (conf.preventDefault && eTar.attr('href') === '#') {
+        e.preventDefault();
+      }
+
+      var paRent = eTar.parent(conf.parentTrigger);
+      var sibLi = paRent.siblings(conf.parentTrigger);
+      var sibTrigger = sibLi.children(conf.triggerElement);
+
+      if (paRent.hasClass(ClassName.ACTIVE)) {
+        eTar.attr('aria-expanded', 'false');
+        self.removeActive(paRent);
+      } else {
+        eTar.attr('aria-expanded', 'true');
+        self.setActive(paRent);
+
+        if (conf.toggle) {
+          self.removeActive(sibLi);
+          sibTrigger.attr('aria-expanded', 'false');
+        }
+      }
+
+      if (conf.onTransitionStart) {
+        conf.onTransitionStart(e);
+      }
+    });
+  };
+
+  _proto.setActive = function setActive(li) {
+    $(li).addClass(ClassName.ACTIVE);
+    var ul = $(li).children(this.config.subMenu);
+
+    if (ul.length > 0 && !ul.hasClass(ClassName.SHOW)) {
+      this.show(ul);
+    }
+  };
+
+  _proto.removeActive = function removeActive(li) {
+    $(li).removeClass(ClassName.ACTIVE);
+    var ul = $(li).children(this.config.subMenu + "." + ClassName.SHOW);
+
+    if (ul.length > 0) {
+      this.hide(ul);
+    }
+  };
+
+  _proto.show = function show(element) {
+    var _this = this;
+
+    if (this.transitioning || $(element).hasClass(ClassName.COLLAPSING)) {
+      return;
+    }
+
+    var elem = $(element);
+    var startEvent = $.Event(Event.SHOW);
+    elem.trigger(startEvent);
+
+    if (startEvent.isDefaultPrevented()) {
+      return;
+    }
+
+    elem.parent(this.config.parentTrigger).addClass(ClassName.ACTIVE);
+
+    if (this.config.toggle) {
+      var toggleElem = elem.parent(this.config.parentTrigger).siblings().children(this.config.subMenu + "." + ClassName.SHOW);
+      this.hide(toggleElem);
+    }
+
+    elem.removeClass(ClassName.COLLAPSE).addClass(ClassName.COLLAPSING).height(0);
+    this.setTransitioning(true);
+
+    var complete = function complete() {
+      // check if disposed
+      if (!_this.config || !_this.element) {
+        return;
+      }
+
+      elem.removeClass(ClassName.COLLAPSING).addClass(ClassName.COLLAPSE + " " + ClassName.SHOW).height('');
+
+      _this.setTransitioning(false);
+
+      elem.trigger(Event.SHOWN);
+    };
+
+    elem.height(element[0].scrollHeight).one(Util.TRANSITION_END, complete).mmEmulateTransitionEnd(TRANSITION_DURATION);
+  };
+
+  _proto.hide = function hide(element) {
+    var _this2 = this;
+
+    if (this.transitioning || !$(element).hasClass(ClassName.SHOW)) {
+      return;
+    }
+
+    var elem = $(element);
+    var startEvent = $.Event(Event.HIDE);
+    elem.trigger(startEvent);
+
+    if (startEvent.isDefaultPrevented()) {
+      return;
+    }
+
+    elem.parent(this.config.parentTrigger).removeClass(ClassName.ACTIVE); // eslint-disable-next-line no-unused-expressions
+
+    elem.height(elem.height())[0].offsetHeight;
+    elem.addClass(ClassName.COLLAPSING).removeClass(ClassName.COLLAPSE).removeClass(ClassName.SHOW);
+    this.setTransitioning(true);
+
+    var complete = function complete() {
+      // check if disposed
+      if (!_this2.config || !_this2.element) {
+        return;
+      }
+
+      if (_this2.transitioning && _this2.config.onTransitionEnd) {
+        _this2.config.onTransitionEnd();
+      }
+
+      _this2.setTransitioning(false);
+
+      elem.trigger(Event.HIDDEN);
+      elem.removeClass(ClassName.COLLAPSING).addClass(ClassName.COLLAPSE);
+    };
+
+    if (elem.height() === 0 || elem.css('display') === 'none') {
+      complete();
+    } else {
+      elem.height(0).one(Util.TRANSITION_END, complete).mmEmulateTransitionEnd(TRANSITION_DURATION);
+    }
+  };
+
+  _proto.setTransitioning = function setTransitioning(isTransitioning) {
+    this.transitioning = isTransitioning;
+  };
+
+  _proto.dispose = function dispose() {
+    $.removeData(this.element, DATA_KEY);
+    $(this.element).find(this.config.parentTrigger).has(this.config.subMenu).children(this.config.triggerElement).off('click');
+    this.transitioning = null;
+    this.config = null;
+    this.element = null;
+  };
+
+  MetisMenu.jQueryInterface = function jQueryInterface(config) {
+    // eslint-disable-next-line func-names
+    return this.each(function () {
+      var $this = $(this);
+      var data = $this.data(DATA_KEY);
+
+      var conf = _extends({}, Default, $this.data(), typeof config === 'object' && config ? config : {});
+
+      if (!data) {
+        data = new MetisMenu(this, conf);
+        $this.data(DATA_KEY, data);
+      }
+
+      if (typeof config === 'string') {
+        if (data[config] === undefined) {
+          throw new Error("No method named \"" + config + "\"");
+        }
+
+        data[config]();
+      }
+    });
+  };
+
+  return MetisMenu;
+}();
+/**
+ * ------------------------------------------------------------------------
+ * jQuery
+ * ------------------------------------------------------------------------
+ */
+
+
+$.fn[NAME] = MetisMenu.jQueryInterface; // eslint-disable-line no-param-reassign
+
+$.fn[NAME].Constructor = MetisMenu; // eslint-disable-line no-param-reassign
+
+$.fn[NAME].noConflict = function () {
+  // eslint-disable-line no-param-reassign
+  $.fn[NAME] = JQUERY_NO_CONFLICT; // eslint-disable-line no-param-reassign
+
+  return MetisMenu.jQueryInterface;
+};
+
+module.exports = MetisMenu;

+ 44 - 0
maxkey-web-manage/src/main/resources/static/jquery/metisMenu-v3.0.4/css/app.css

@@ -0,0 +1,44 @@
+:root {
+  --jumbotron-padding-y: 3rem;
+}
+
+.jumbotron {
+  padding-top: var(--jumbotron-padding-y);
+  padding-bottom: var(--jumbotron-padding-y);
+  margin-bottom: 0;
+  background-color: #fff;
+}
+@media (min-width: 768px) {
+  .jumbotron {
+    padding-top: calc(var(--jumbotron-padding-y) * 2);
+    padding-bottom: calc(var(--jumbotron-padding-y) * 2);
+  }
+}
+
+.jumbotron p:last-child {
+  margin-bottom: 0;
+}
+
+.jumbotron-heading {
+  font-weight: 300;
+}
+
+.jumbotron .container {
+  max-width: 40rem;
+}
+
+footer {
+  padding-top: 3rem;
+  padding-bottom: 3rem;
+}
+
+footer p {
+  margin-bottom: .25rem;
+}
+
+.box-shadow { box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .05); }
+
+#rtlh3 small {
+    transform: rotateY(180deg);
+    display: inline-block;
+}

+ 1 - 0
maxkey-web-manage/src/main/resources/static/jquery/metisMenu-v3.0.4/css/demo.css

@@ -0,0 +1 @@
+

+ 55 - 0
maxkey-web-manage/src/main/resources/static/jquery/metisMenu-v3.0.4/css/mini.css

@@ -0,0 +1,55 @@
+.wrap {
+  margin: 0 auto;
+  width: 100%;
+  position: relative;
+}
+.sidebar {
+  position: absolute;
+  top: 0;
+  left: 0;
+  bottom: 0;
+  border-right: 1px solid #b5b5b5;
+}
+.nav-mini {
+  width: 50px;
+}
+.nav-mini ul {
+  padding: 0;
+  margin: 0;
+  list-style: none;
+  background: #fbfbfb;
+}
+.nav-mini li {
+  position: relative;
+}
+.nav-mini li, .nav-mini a {
+  display: block;
+}
+.nav-mini a {
+  padding: 10px 5px;
+  text-decoration: none;
+  color: #808080;
+}
+.nav-mini a .title {
+  display: none;
+}
+.nav-mini .metismenu .collapse, .nav-mini .metismenu .collapsing {
+  position: absolute;
+  top: 0;
+  left: 100%;
+  min-width: 160px;
+}
+.nav-mini .metismenu .collapse .collapse, .nav-mini .metismenu .collapse .collapsing {
+  left: 0;
+  top: auto;
+}
+.nav-mini .metismenu > li {
+  border-bottom: 1px solid #b5b5b5;
+}
+.nav-mini .metismenu > li > a {
+  text-align: center;
+}
+.content {
+  padding-left: 60px;
+  background: #fff;
+}

+ 11 - 0
maxkey-web-manage/src/main/resources/static/jquery/metisMenu-v3.0.4/css/mm-faq.css

@@ -0,0 +1,11 @@
+.faq-link {
+  cursor: pointer;
+  padding: 15px;
+  background: #212529;
+  color: #adb5bd
+}
+
+.faq-item.active>.faq-link {
+  background-color: #d9480f;
+  color: #f8f9fa;
+}

+ 37 - 0
maxkey-web-manage/src/main/resources/static/jquery/metisMenu-v3.0.4/css/mm-folder.css

@@ -0,0 +1,37 @@
+.metisFolder {
+  padding-left: 0;
+}
+.metisFolder, .metisFolder ul {
+  list-style: none;
+}
+.metisFolder li {
+  position: relative;
+}
+.metisFolder li a {
+  display: block;
+  padding-top: 5px;
+  padding-bottom: 5px;
+  color: #333;
+  text-decoration: none;
+  outline: 0 none;
+}
+.metisFolder ul:before {
+  position: absolute;
+  border-left: 1px dotted #333;
+  content: "";
+  width: 30px;
+  top: 25px;
+  left: 5px;
+  bottom: 17px;
+}
+.metisFolder ul > li:before {
+  position: absolute;
+  border-top: 1px dotted #333;
+  content: "";
+  width: 30px;
+  top: 13px;
+  left: -33px;
+}
+li.active > a > span.fa-folder-o:before {
+  content: "\f115" !important;
+}

+ 80 - 0
maxkey-web-manage/src/main/resources/static/jquery/metisMenu-v3.0.4/css/mm-horizontal.css

@@ -0,0 +1,80 @@
+.topbar-nav {
+    background: #212529;
+}
+.topbar-nav ul {
+    padding: 0;
+    margin: 0;
+    list-style: none;
+    background: #212529;
+}
+.topbar-nav .metismenu {
+    display: -webkit-box;
+    display: -ms-flexbox;
+    display: flex;
+    -webkit-box-orient: vertical;
+    -webkit-box-direction: normal;
+        -ms-flex-direction: column;
+            flex-direction: column;
+}
+.topbar-nav .metismenu > li {
+    -webkit-box-flex: 1;
+        -ms-flex: 1 1 0%;
+            flex: 1 1 0%;
+    display: -webkit-box;
+    display: -ms-flexbox;
+    display: flex;
+    -webkit-box-orient: vertical;
+    -webkit-box-direction: normal;
+        -ms-flex-direction: column;
+            flex-direction: column;
+    position: relative;
+}
+
+.topbar-nav .metismenu a {
+    position: relative;
+    display: block;
+    padding: 15px;
+    color: #adb5bd;
+    outline-width: 0;
+    transition: all .3s ease-out;
+}
+
+
+.topbar-nav .metismenu a:hover,
+.topbar-nav .metismenu a:focus,
+.topbar-nav .metismenu a:active {
+    color: #f8f9fa;
+    text-decoration: none;
+    background: #0b7285;
+}
+
+@media (min-width: 992px) {
+    .topbar-nav .metismenu {
+        -webkit-box-orient: horizontal;
+        -webkit-box-direction: normal;
+            -ms-flex-direction: row;
+                flex-direction: row;
+    }
+    .topbar-nav .metismenu > li {
+        -webkit-box-orient: vertical;
+        -webkit-box-direction: normal;
+            -ms-flex-direction: column;
+                flex-direction: column;
+    }
+    .topbar-nav .metismenu > li > ul {
+        position: absolute;
+        top: 100%;
+        min-width: 100%;
+        z-index: 1001;
+    }
+    .topbar-nav.is-hoverable .metismenu > li > ul {
+      height: auto !important;
+    }
+    .topbar-nav.is-hoverable .metismenu > li:hover > ul {
+        display: block;
+    }
+    .topbar-nav.is-hoverable .metismenu > li:hover > a.has-arrow:after {
+        -webkit-transform: rotate(-135deg);
+                transform: rotate(-135deg);
+    }
+}

+ 73 - 0
maxkey-web-manage/src/main/resources/static/jquery/metisMenu-v3.0.4/css/mm-vertical-hover.css

@@ -0,0 +1,73 @@
+.sidebar-nav {
+    background: #212529;
+}
+.sidebar-nav ul {
+    padding: 0;
+    margin: 0;
+    list-style: none;
+    background: #212529;
+}
+
+.sidebar-nav .metismenu {
+    display: -webkit-box;
+    display: -ms-flexbox;
+    display: flex;
+    -webkit-box-orient: vertical;
+    -webkit-box-direction: normal;
+    -ms-flex-direction: column;
+    flex-direction: column;
+}
+
+.sidebar-nav .metismenu > li {
+    /*-webkit-box-flex: 1;
+    -ms-flex: 1 1 0%;
+    flex: 1 1 0%;*/
+    display: -webkit-box;
+    display: -ms-flexbox;
+    display: flex;
+    -webkit-box-orient: vertical;
+    -webkit-box-direction: normal;
+    -ms-flex-direction: column;
+    flex-direction: column;
+    position: relative;
+}
+.sidebar-nav .metismenu a {
+    position: relative;
+    display: block;
+    padding: 15px;
+    color: #adb5bd;
+    outline-width: 0;
+    transition: all .3s ease-out;
+}
+
+.sidebar-nav .metismenu a:hover,
+.sidebar-nav .metismenu a:focus,
+.sidebar-nav .metismenu a:active {
+    color: #f8f9fa;
+    text-decoration: none;
+    background: #0b7285;
+}
+
+@media (min-width: 992px) {
+    .sidebar-nav .metismenu li {
+        position: relative;
+    }
+    .sidebar-nav .metismenu > li > ul {
+        position: absolute;
+        left: 100%;
+        top: 0;
+        min-width: 200px;
+        z-index: 1001;
+    }
+    .sidebar-nav .metismenu > li:hover > ul {
+        height: auto !important;
+    }
+    .sidebar-nav .metismenu > li:hover > ul,
+    .sidebar-nav .metismenu > li:hover > ul.collapse {
+        display: block;
+    }
+
+    .sidebar-nav .metismenu > li:hover > a.has-arrow:after {
+        transform: rotate(135deg);
+    }
+}

+ 71 - 0
maxkey-web-manage/src/main/resources/static/jquery/metisMenu-v3.0.4/css/mm-vertical.css

@@ -0,0 +1,71 @@
+.sidebar-nav {
+    background: #212529;
+}
+.sidebar-nav ul {
+    padding: 0;
+    margin: 0;
+    list-style: none;
+    background: #343a40;
+}
+
+.sidebar-nav .metismenu {
+    background: #212529;
+    display: -webkit-box;
+    display: -ms-flexbox;
+    display: flex;
+    -webkit-box-orient: vertical;
+    -webkit-box-direction: normal;
+    -ms-flex-direction: column;
+    flex-direction: column;
+}
+
+.sidebar-nav .metismenu li + li {
+  margin-top: 5px;
+}
+
+.sidebar-nav .metismenu li:first-child {
+  margin-top: 5px;
+}
+.sidebar-nav .metismenu li:last-child {
+  margin-bottom: 5px;
+}
+
+
+.sidebar-nav .metismenu > li {
+    /*-webkit-box-flex: 1;
+    -ms-flex: 1 1 0%;
+    flex: 1 1 0%;*/
+    display: -webkit-box;
+    display: -ms-flexbox;
+    display: flex;
+    -webkit-box-orient: vertical;
+    -webkit-box-direction: normal;
+    -ms-flex-direction: column;
+    flex-direction: column;
+    position: relative;
+}
+.sidebar-nav .metismenu a {
+    position: relative;
+    display: block;
+    padding: 13px 15px;
+    color: #adb5bd;
+    outline-width: 0;
+    transition: all .3s ease-out;
+}
+
+.sidebar-nav .metismenu ul a {
+    padding: 10px 15px 10px 30px;
+}
+
+.sidebar-nav .metismenu ul ul a {
+    padding: 10px 15px 10px 45px;
+}
+
+.sidebar-nav .metismenu a:hover,
+.sidebar-nav .metismenu a:focus,
+.sidebar-nav .metismenu a:active,
+.sidebar-nav .metismenu .mm-active > a {
+    color: #f8f9fa;
+    text-decoration: none;
+    background: #0b7285;
+}

+ 3 - 0
maxkey-web-manage/src/main/resources/static/jquery/metisMenu-v3.0.4/js/index.js

@@ -0,0 +1,3 @@
+$(function() {
+  $('table').addClass('table table-bordered table-striped');
+});

+ 54 - 0
maxkey-web-manage/src/main/resources/static/jquery/metisMenu-v3.0.4/js/mm-ajax.js

@@ -0,0 +1,54 @@
+$(function() {
+
+  $('#menu').metisMenu();
+
+  $("#ajaxButton").one('click', function() {
+    var $this = $(this);
+    $.ajax({
+      url: "demo-ajax.html",
+      success: function(result) {
+
+        $('#menu').metisMenu('dispose');
+        $("#menu").append(result);
+
+        new Noty({
+            text: 'ajax menu appended to menu',
+            layout: 'topRight',
+            type: 'success',
+            theme: 'relax',
+            progressBar: true,
+            timeout: 2000
+        }).show();
+
+        $('#menu').metisMenu();
+        $this.attr('disabled', 'disabled');
+      }
+    });
+  });
+
+  $('#menu2').metisMenu();
+
+  $("[data-url]").each(function(){
+      $(this).one('click', function(event){
+        event.preventDefault();
+        var $this = $(this);
+        var url = $this.attr('data-url');
+        console.log(url);
+
+        $.ajax({
+          url: url,
+          success: function(result) {
+
+            $('#menu2').metisMenu('dispose');
+            $this.parent('li').append(result);
+
+            $('#menu2').metisMenu();
+
+            $this.click();
+          }
+        });
+
+      });
+  });
+
+});

+ 5 - 0
maxkey-web-manage/src/main/resources/static/jquery/metisMenu-v3.0.4/js/mm-animate.js

@@ -0,0 +1,5 @@
+$(function () {
+
+    $('#menu').metisMenu();
+
+});

+ 11 - 0
maxkey-web-manage/src/main/resources/static/jquery/metisMenu-v3.0.4/js/mm-bs-card.js

@@ -0,0 +1,11 @@
+$(function() {
+
+    $('.metismenu').metisMenu({
+      toggle: false,
+      triggerElement: '.card-header',
+      parentTrigger: '.card',
+      subMenu: '.card-body'
+    });
+  
+  });
+  

+ 47 - 0
maxkey-web-manage/src/main/resources/static/jquery/metisMenu-v3.0.4/js/mm-dispose.js

@@ -0,0 +1,47 @@
+$(function() {
+
+  $('#menu').metisMenu();
+
+  $('#stopMm').on('click', function(event) {
+    $('#menu').metisMenu('dispose');
+    new Noty({
+      text: 'metisMenu stopped',
+      layout: 'topRight',
+      type: 'error',
+      theme: 'relax',
+      progressBar: true,
+      timeout: 2000
+    }).show();
+  });
+
+  $('#startMm').on('click', function(event) {
+    $('#menu').metisMenu();
+    new Noty({
+      text: 'metisMenu restarted',
+      layout: 'topRight',
+      type: 'success',
+      theme: 'relax',
+      progressBar: true,
+      timeout: 2000
+    }).show();
+  });
+
+  $('#menu1').metisMenu();
+  $('#deleteElem').one('click', function(event) {
+    $(this).removeClass('btn-danger').addClass('btn-success').html('Menu 1 removed').attr('disabled', 'disabled');
+    $('#menu1').metisMenu('dispose');
+
+    $('#menu1 #removable').remove();
+    new Noty({
+      text: 'Menu 1 removed',
+      layout: 'topRight',
+      type: 'information',
+      theme: 'relax',
+      progressBar: true,
+      timeout: 2000
+    }).show();
+
+    $('#menu1').metisMenu();
+  });
+
+});

+ 38 - 0
maxkey-web-manage/src/main/resources/static/jquery/metisMenu-v3.0.4/js/mm-event.js

@@ -0,0 +1,38 @@
+$(function() {
+
+  $('#menu').metisMenu().on('show.metisMenu', function(event) {
+    new Noty({
+      text: $(event.target).parent('li').children('a').html() + ' opening ...',
+      layout: 'topRight',
+      type: 'information',
+      theme: 'relax',
+
+      timeout: 350
+    }).show();
+  }).on('shown.metisMenu', function(event) {
+    new Noty({
+      text: $(event.target).parent('li').children('a').html() + ' opened',
+      layout: 'topRight',
+      type: 'success',
+      theme: 'relax',
+      timeout: 350
+    }).show();
+  }).on('hide.metisMenu', function(event) {
+    new Noty({
+      text: $(event.target).parent('li').children('a').html() + ' collapsing ...',
+      layout: 'topRight',
+      type: 'warning',
+      theme: 'relax',
+      timeout: 350
+    }).show();
+  }).on('hidden.metisMenu', function(event) {
+    new Noty({
+      text: $(event.target).parent('li').children('a').html() + ' collapsed',
+      layout: 'topRight',
+      type: 'error',
+      theme: 'relax',
+      timeout: 350
+    }).show();
+  });
+
+});

+ 7 - 0
maxkey-web-manage/src/main/resources/static/jquery/metisMenu-v3.0.4/js/mm-event2.js

@@ -0,0 +1,7 @@
+$(function() {
+  $('#menu')
+    .metisMenu()
+    .on('shown.metisMenu', function(event) {
+      Jump("#menu")
+    });
+});

+ 10 - 0
maxkey-web-manage/src/main/resources/static/jquery/metisMenu-v3.0.4/js/mm-faq.js

@@ -0,0 +1,10 @@
+$(function() {
+
+  $('.faq-menu').metisMenu({
+    toggle: false,
+    triggerElement: '.faq-link',
+    parentTrigger: '.faq-item',
+    subMenu: '.faq-answer'
+  });
+
+});

+ 5 - 0
maxkey-web-manage/src/main/resources/static/jquery/metisMenu-v3.0.4/js/mm-folder.js

@@ -0,0 +1,5 @@
+$(function () {
+    $('.metisFolder').metisMenu({
+        toggle: false
+    });
+});

+ 7 - 0
maxkey-web-manage/src/main/resources/static/jquery/metisMenu-v3.0.4/js/mm-horizontal.js

@@ -0,0 +1,7 @@
+$(function() {
+
+  $('#menu1').metisMenu();
+
+  $('#menu2').metisMenu();
+
+});

+ 5 - 0
maxkey-web-manage/src/main/resources/static/jquery/metisMenu-v3.0.4/js/mm-vertical-hover.js

@@ -0,0 +1,5 @@
+$(function() {
+
+  $('#menu1').metisMenu();
+
+});

+ 11 - 0
maxkey-web-manage/src/main/resources/static/jquery/metisMenu-v3.0.4/js/mm-vertical.js

@@ -0,0 +1,11 @@
+$(function() {
+
+  $('#menu1').metisMenu();
+
+  $('#menu2').metisMenu({
+    toggle: false
+  });
+
+  $('#menu3').metisMenu();
+
+});

+ 130 - 0
maxkey-web-manage/src/main/resources/static/jquery/metisMenu-v3.0.4/metisMenu.css

@@ -0,0 +1,130 @@
+/*!
+* metismenu https://github.com/onokumus/metismenu#readme
+* A jQuery menu plugin
+* @version 3.0.4
+* @author Osman Nuri Okumus <onokumus@gmail.com> (https://github.com/onokumus)
+* @license: MIT 
+*/
+.metismenu .arrow {
+  float: right;
+  line-height: 1.42857;
+}
+*[dir="rtl"] .metismenu .arrow {
+  float: left;
+}
+
+/*
+ * Require Bootstrap 3.x
+ * https://github.com/twbs/bootstrap
+*/
+
+.metismenu .glyphicon.arrow:before {
+  content: "\e079";
+}
+.metismenu .mm-active > a > .glyphicon.arrow:before {
+  content: "\e114";
+}
+
+/*
+ * Require Font-Awesome
+ * http://fortawesome.github.io/Font-Awesome/
+*/
+
+.metismenu .fa.arrow:before {
+  content: "\f104";
+}
+.metismenu .mm-active > a > .fa.arrow:before {
+  content: "\f107";
+}
+
+/*
+ * Require Ionicons
+ * http://ionicons.com/
+*/
+
+.metismenu .ion.arrow:before {
+  content: "\f3d2"
+}
+.metismenu .mm-active > a > .ion.arrow:before {
+  content: "\f3d0";
+}
+.metismenu .plus-times {
+  float: right;
+}
+*[dir="rtl"] .metismenu .plus-times {
+  float: left;
+}
+.metismenu .fa.plus-times:before {
+  content: "\f067";
+}
+.metismenu .mm-active > a > .fa.plus-times {
+  -webkit-transform: rotate(45deg);
+          transform: rotate(45deg);
+}
+.metismenu .plus-minus {
+  float: right;
+}
+*[dir="rtl"] .metismenu .plus-minus {
+  float: left;
+}
+.metismenu .fa.plus-minus:before {
+  content: "\f067";
+}
+.metismenu .mm-active > a > .fa.plus-minus:before {
+  content: "\f068";
+}
+.metismenu .mm-collapse:not(.mm-show) {
+  display: none;
+}
+
+.metismenu .mm-collapsing {
+  position: relative;
+  height: 0;
+  overflow: hidden;
+  transition-timing-function: ease;
+  transition-duration: .35s;
+  transition-property: height, visibility;
+}
+
+.metismenu .has-arrow {
+  position: relative;
+}
+
+.metismenu .has-arrow::after {
+  position: absolute;
+  content: '';
+  width: .5em;
+  height: .5em;
+  border-width: 1px 0 0 1px;
+  border-style: solid;
+  border-color: currentColor;
+  border-color: initial;
+  right: 1em;
+  -webkit-transform: rotate(-45deg) translate(0, -50%);
+          transform: rotate(-45deg) translate(0, -50%);
+  -webkit-transform-origin: top;
+          transform-origin: top;
+  top: 50%;
+  transition: all .3s ease-out;
+}
+
+*[dir="rtl"] .metismenu .has-arrow::after {
+  right: auto;
+  left: 1em;
+  -webkit-transform: rotate(135deg) translate(0, -50%);
+          transform: rotate(135deg) translate(0, -50%);
+}
+
+.metismenu .mm-active > .has-arrow::after,
+.metismenu .has-arrow[aria-expanded="true"]::after {
+  -webkit-transform: rotate(-135deg) translate(0, -50%);
+          transform: rotate(-135deg) translate(0, -50%);
+}
+
+*[dir="rtl"] .metismenu .mm-active > .has-arrow::after,
+*[dir="rtl"] .metismenu .has-arrow[aria-expanded="true"]::after {
+  -webkit-transform: rotate(225deg) translate(0, -50%);
+          transform: rotate(225deg) translate(0, -50%);
+}
+
+/*# sourceMappingURL=metisMenu.css.map */

文件差异内容过多而无法显示
+ 0 - 0
maxkey-web-manage/src/main/resources/static/jquery/metisMenu-v3.0.4/metisMenu.css.map


+ 340 - 0
maxkey-web-manage/src/main/resources/static/jquery/metisMenu-v3.0.4/metisMenu.js

@@ -0,0 +1,340 @@
+/*!
+* metismenu https://github.com/onokumus/metismenu#readme
+* A jQuery menu plugin
+* @version 3.0.4
+* @author Osman Nuri Okumus <onokumus@gmail.com> (https://github.com/onokumus)
+* @license: MIT 
+*/
+(function (global, factory) {
+  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('jquery')) :
+  typeof define === 'function' && define.amd ? define(['jquery'], factory) :
+  (global = global || self, global.metisMenu = factory(global.jQuery));
+}(this, function ($) { 'use strict';
+
+  $ = $ && $.hasOwnProperty('default') ? $['default'] : $;
+
+  function _extends() {
+    _extends = Object.assign || function (target) {
+      for (var i = 1; i < arguments.length; i++) {
+        var source = arguments[i];
+
+        for (var key in source) {
+          if (Object.prototype.hasOwnProperty.call(source, key)) {
+            target[key] = source[key];
+          }
+        }
+      }
+
+      return target;
+    };
+
+    return _extends.apply(this, arguments);
+  }
+
+  var Util = function ($) {
+    // eslint-disable-line no-shadow
+    var TRANSITION_END = 'transitionend';
+    var Util = {
+      // eslint-disable-line no-shadow
+      TRANSITION_END: 'mmTransitionEnd',
+      triggerTransitionEnd: function triggerTransitionEnd(element) {
+        $(element).trigger(TRANSITION_END);
+      },
+      supportsTransitionEnd: function supportsTransitionEnd() {
+        return Boolean(TRANSITION_END);
+      }
+    };
+
+    function getSpecialTransitionEndEvent() {
+      return {
+        bindType: TRANSITION_END,
+        delegateType: TRANSITION_END,
+        handle: function handle(event) {
+          if ($(event.target).is(this)) {
+            return event.handleObj.handler.apply(this, arguments); // eslint-disable-line prefer-rest-params
+          }
+
+          return undefined;
+        }
+      };
+    }
+
+    function transitionEndEmulator(duration) {
+      var _this = this;
+
+      var called = false;
+      $(this).one(Util.TRANSITION_END, function () {
+        called = true;
+      });
+      setTimeout(function () {
+        if (!called) {
+          Util.triggerTransitionEnd(_this);
+        }
+      }, duration);
+      return this;
+    }
+
+    function setTransitionEndSupport() {
+      $.fn.mmEmulateTransitionEnd = transitionEndEmulator; // eslint-disable-line no-param-reassign
+      // eslint-disable-next-line no-param-reassign
+
+      $.event.special[Util.TRANSITION_END] = getSpecialTransitionEndEvent();
+    }
+
+    setTransitionEndSupport();
+    return Util;
+  }($);
+
+  var NAME = 'metisMenu';
+  var DATA_KEY = 'metisMenu';
+  var EVENT_KEY = "." + DATA_KEY;
+  var DATA_API_KEY = '.data-api';
+  var JQUERY_NO_CONFLICT = $.fn[NAME];
+  var TRANSITION_DURATION = 350;
+  var Default = {
+    toggle: true,
+    preventDefault: true,
+    triggerElement: 'a',
+    parentTrigger: 'li',
+    subMenu: 'ul'
+  };
+  var Event = {
+    SHOW: "show" + EVENT_KEY,
+    SHOWN: "shown" + EVENT_KEY,
+    HIDE: "hide" + EVENT_KEY,
+    HIDDEN: "hidden" + EVENT_KEY,
+    CLICK_DATA_API: "click" + EVENT_KEY + DATA_API_KEY
+  };
+  var ClassName = {
+    METIS: 'metismenu',
+    ACTIVE: 'mm-active',
+    SHOW: 'mm-show',
+    COLLAPSE: 'mm-collapse',
+    COLLAPSING: 'mm-collapsing',
+    COLLAPSED: 'mm-collapsed'
+  };
+
+  var MetisMenu =
+  /*#__PURE__*/
+  function () {
+    // eslint-disable-line no-shadow
+    function MetisMenu(element, config) {
+      this.element = element;
+      this.config = _extends({}, Default, config);
+      this.transitioning = null;
+      this.init();
+    }
+
+    var _proto = MetisMenu.prototype;
+
+    _proto.init = function init() {
+      var self = this;
+      var conf = this.config;
+      var el = $(this.element);
+      el.addClass(ClassName.METIS); // add metismenu class to element
+
+      el.find(conf.parentTrigger + "." + ClassName.ACTIVE).children(conf.triggerElement).attr('aria-expanded', 'true'); // add attribute aria-expanded=true the trigger element
+
+      el.find(conf.parentTrigger + "." + ClassName.ACTIVE).parents(conf.parentTrigger).addClass(ClassName.ACTIVE);
+      el.find(conf.parentTrigger + "." + ClassName.ACTIVE).parents(conf.parentTrigger).children(conf.triggerElement).attr('aria-expanded', 'true'); // add attribute aria-expanded=true the triggers of all parents
+
+      el.find(conf.parentTrigger + "." + ClassName.ACTIVE).has(conf.subMenu).children(conf.subMenu).addClass(ClassName.COLLAPSE + " " + ClassName.SHOW);
+      el.find(conf.parentTrigger).not("." + ClassName.ACTIVE).has(conf.subMenu).children(conf.subMenu).addClass(ClassName.COLLAPSE);
+      el.find(conf.parentTrigger) // .has(conf.subMenu)
+      .children(conf.triggerElement).on(Event.CLICK_DATA_API, function (e) {
+        // eslint-disable-line func-names
+        var eTar = $(this);
+
+        if (eTar.attr('aria-disabled') === 'true') {
+          return;
+        }
+
+        if (conf.preventDefault && eTar.attr('href') === '#') {
+          e.preventDefault();
+        }
+
+        var paRent = eTar.parent(conf.parentTrigger);
+        var sibLi = paRent.siblings(conf.parentTrigger);
+        var sibTrigger = sibLi.children(conf.triggerElement);
+
+        if (paRent.hasClass(ClassName.ACTIVE)) {
+          eTar.attr('aria-expanded', 'false');
+          self.removeActive(paRent);
+        } else {
+          eTar.attr('aria-expanded', 'true');
+          self.setActive(paRent);
+
+          if (conf.toggle) {
+            self.removeActive(sibLi);
+            sibTrigger.attr('aria-expanded', 'false');
+          }
+        }
+
+        if (conf.onTransitionStart) {
+          conf.onTransitionStart(e);
+        }
+      });
+    };
+
+    _proto.setActive = function setActive(li) {
+      $(li).addClass(ClassName.ACTIVE);
+      var ul = $(li).children(this.config.subMenu);
+
+      if (ul.length > 0 && !ul.hasClass(ClassName.SHOW)) {
+        this.show(ul);
+      }
+    };
+
+    _proto.removeActive = function removeActive(li) {
+      $(li).removeClass(ClassName.ACTIVE);
+      var ul = $(li).children(this.config.subMenu + "." + ClassName.SHOW);
+
+      if (ul.length > 0) {
+        this.hide(ul);
+      }
+    };
+
+    _proto.show = function show(element) {
+      var _this = this;
+
+      if (this.transitioning || $(element).hasClass(ClassName.COLLAPSING)) {
+        return;
+      }
+
+      var elem = $(element);
+      var startEvent = $.Event(Event.SHOW);
+      elem.trigger(startEvent);
+
+      if (startEvent.isDefaultPrevented()) {
+        return;
+      }
+
+      elem.parent(this.config.parentTrigger).addClass(ClassName.ACTIVE);
+
+      if (this.config.toggle) {
+        var toggleElem = elem.parent(this.config.parentTrigger).siblings().children(this.config.subMenu + "." + ClassName.SHOW);
+        this.hide(toggleElem);
+      }
+
+      elem.removeClass(ClassName.COLLAPSE).addClass(ClassName.COLLAPSING).height(0);
+      this.setTransitioning(true);
+
+      var complete = function complete() {
+        // check if disposed
+        if (!_this.config || !_this.element) {
+          return;
+        }
+
+        elem.removeClass(ClassName.COLLAPSING).addClass(ClassName.COLLAPSE + " " + ClassName.SHOW).height('');
+
+        _this.setTransitioning(false);
+
+        elem.trigger(Event.SHOWN);
+      };
+
+      elem.height(element[0].scrollHeight).one(Util.TRANSITION_END, complete).mmEmulateTransitionEnd(TRANSITION_DURATION);
+    };
+
+    _proto.hide = function hide(element) {
+      var _this2 = this;
+
+      if (this.transitioning || !$(element).hasClass(ClassName.SHOW)) {
+        return;
+      }
+
+      var elem = $(element);
+      var startEvent = $.Event(Event.HIDE);
+      elem.trigger(startEvent);
+
+      if (startEvent.isDefaultPrevented()) {
+        return;
+      }
+
+      elem.parent(this.config.parentTrigger).removeClass(ClassName.ACTIVE); // eslint-disable-next-line no-unused-expressions
+
+      elem.height(elem.height())[0].offsetHeight;
+      elem.addClass(ClassName.COLLAPSING).removeClass(ClassName.COLLAPSE).removeClass(ClassName.SHOW);
+      this.setTransitioning(true);
+
+      var complete = function complete() {
+        // check if disposed
+        if (!_this2.config || !_this2.element) {
+          return;
+        }
+
+        if (_this2.transitioning && _this2.config.onTransitionEnd) {
+          _this2.config.onTransitionEnd();
+        }
+
+        _this2.setTransitioning(false);
+
+        elem.trigger(Event.HIDDEN);
+        elem.removeClass(ClassName.COLLAPSING).addClass(ClassName.COLLAPSE);
+      };
+
+      if (elem.height() === 0 || elem.css('display') === 'none') {
+        complete();
+      } else {
+        elem.height(0).one(Util.TRANSITION_END, complete).mmEmulateTransitionEnd(TRANSITION_DURATION);
+      }
+    };
+
+    _proto.setTransitioning = function setTransitioning(isTransitioning) {
+      this.transitioning = isTransitioning;
+    };
+
+    _proto.dispose = function dispose() {
+      $.removeData(this.element, DATA_KEY);
+      $(this.element).find(this.config.parentTrigger).has(this.config.subMenu).children(this.config.triggerElement).off('click');
+      this.transitioning = null;
+      this.config = null;
+      this.element = null;
+    };
+
+    MetisMenu.jQueryInterface = function jQueryInterface(config) {
+      // eslint-disable-next-line func-names
+      return this.each(function () {
+        var $this = $(this);
+        var data = $this.data(DATA_KEY);
+
+        var conf = _extends({}, Default, $this.data(), typeof config === 'object' && config ? config : {});
+
+        if (!data) {
+          data = new MetisMenu(this, conf);
+          $this.data(DATA_KEY, data);
+        }
+
+        if (typeof config === 'string') {
+          if (data[config] === undefined) {
+            throw new Error("No method named \"" + config + "\"");
+          }
+
+          data[config]();
+        }
+      });
+    };
+
+    return MetisMenu;
+  }();
+  /**
+   * ------------------------------------------------------------------------
+   * jQuery
+   * ------------------------------------------------------------------------
+   */
+
+
+  $.fn[NAME] = MetisMenu.jQueryInterface; // eslint-disable-line no-param-reassign
+
+  $.fn[NAME].Constructor = MetisMenu; // eslint-disable-line no-param-reassign
+
+  $.fn[NAME].noConflict = function () {
+    // eslint-disable-line no-param-reassign
+    $.fn[NAME] = JQUERY_NO_CONFLICT; // eslint-disable-line no-param-reassign
+
+    return MetisMenu.jQueryInterface;
+  };
+
+  return MetisMenu;
+
+}));
+//# sourceMappingURL=metisMenu.js.map

文件差异内容过多而无法显示
+ 0 - 0
maxkey-web-manage/src/main/resources/static/jquery/metisMenu-v3.0.4/metisMenu.js.map


+ 8 - 0
maxkey-web-manage/src/main/resources/static/jquery/metisMenu-v3.0.4/metisMenu.min.css

@@ -0,0 +1,8 @@
+/*!
+* metismenu https://github.com/onokumus/metismenu#readme
+* A jQuery menu plugin
+* @version 3.0.4
+* @author Osman Nuri Okumus <onokumus@gmail.com> (https://github.com/onokumus)
+* @license: MIT 
+*/.metismenu .arrow{float:right;line-height:1.42857}[dir=rtl] .metismenu .arrow{float:left}.metismenu .glyphicon.arrow:before{content:"\e079"}.metismenu .mm-active>a>.glyphicon.arrow:before{content:"\e114"}.metismenu .fa.arrow:before{content:"\f104"}.metismenu .mm-active>a>.fa.arrow:before{content:"\f107"}.metismenu .ion.arrow:before{content:"\f3d2"}.metismenu .mm-active>a>.ion.arrow:before{content:"\f3d0"}.metismenu .plus-times{float:right}[dir=rtl] .metismenu .plus-times{float:left}.metismenu .fa.plus-times:before{content:"\f067"}.metismenu .mm-active>a>.fa.plus-times{-webkit-transform:rotate(45deg);transform:rotate(45deg)}.metismenu .plus-minus{float:right}[dir=rtl] .metismenu .plus-minus{float:left}.metismenu .fa.plus-minus:before{content:"\f067"}.metismenu .mm-active>a>.fa.plus-minus:before{content:"\f068"}.metismenu .mm-collapse:not(.mm-show){display:none}.metismenu .mm-collapsing{position:relative;height:0;overflow:hidden;transition-timing-function:ease;transition-duration:.35s;transition-property:height,visibility}.metismenu .has-arrow{position:relative}.metismenu .has-arrow:after{position:absolute;content:"";width:.5em;height:.5em;border-style:solid;border-width:1px 0 0 1px;border-color:initial;right:1em;-webkit-transform:rotate(-45deg) translateY(-50%);transform:rotate(-45deg) translateY(-50%);-webkit-transform-origin:top;transform-origin:top;top:50%;transition:all .3s ease-out}[dir=rtl] .metismenu .has-arrow:after{right:auto;left:1em;-webkit-transform:rotate(135deg) translateY(-50%);transform:rotate(135deg) translateY(-50%)}.metismenu .has-arrow[aria-expanded=true]:after,.metismenu .mm-active>.has-arrow:after{-webkit-transform:rotate(-135deg) translateY(-50%);transform:rotate(-135deg) translateY(-50%)}[dir=rtl] .metismenu .has-arrow[aria-expanded=true]:after,[dir=rtl] .metismenu .mm-active>.has-arrow:after{-webkit-transform:rotate(225deg) translateY(-50%);transform:rotate(225deg) translateY(-50%)}
+/*# sourceMappingURL=metisMenu.min.css.map */

文件差异内容过多而无法显示
+ 0 - 0
maxkey-web-manage/src/main/resources/static/jquery/metisMenu-v3.0.4/metisMenu.min.css.map


文件差异内容过多而无法显示
+ 7 - 0
maxkey-web-manage/src/main/resources/static/jquery/metisMenu-v3.0.4/metisMenu.min.js


文件差异内容过多而无法显示
+ 0 - 0
maxkey-web-manage/src/main/resources/static/jquery/metisMenu-v3.0.4/metisMenu.min.js.map


+ 331 - 0
maxkey-web-manage/src/main/resources/static/jquery/metisMenu-v3.0.4/modules/index.js

@@ -0,0 +1,331 @@
+/*!
+* metismenu https://github.com/onokumus/metismenu#readme
+* A jQuery menu plugin
+* @version 3.0.4
+* @author Osman Nuri Okumus <onokumus@gmail.com> (https://github.com/onokumus)
+* @license: MIT 
+*/
+import $ from 'jquery';
+
+function _extends() {
+  _extends = Object.assign || function (target) {
+    for (var i = 1; i < arguments.length; i++) {
+      var source = arguments[i];
+
+      for (var key in source) {
+        if (Object.prototype.hasOwnProperty.call(source, key)) {
+          target[key] = source[key];
+        }
+      }
+    }
+
+    return target;
+  };
+
+  return _extends.apply(this, arguments);
+}
+
+var Util = function ($) {
+  // eslint-disable-line no-shadow
+  var TRANSITION_END = 'transitionend';
+  var Util = {
+    // eslint-disable-line no-shadow
+    TRANSITION_END: 'mmTransitionEnd',
+    triggerTransitionEnd: function triggerTransitionEnd(element) {
+      $(element).trigger(TRANSITION_END);
+    },
+    supportsTransitionEnd: function supportsTransitionEnd() {
+      return Boolean(TRANSITION_END);
+    }
+  };
+
+  function getSpecialTransitionEndEvent() {
+    return {
+      bindType: TRANSITION_END,
+      delegateType: TRANSITION_END,
+      handle: function handle(event) {
+        if ($(event.target).is(this)) {
+          return event.handleObj.handler.apply(this, arguments); // eslint-disable-line prefer-rest-params
+        }
+
+        return undefined;
+      }
+    };
+  }
+
+  function transitionEndEmulator(duration) {
+    var _this = this;
+
+    var called = false;
+    $(this).one(Util.TRANSITION_END, function () {
+      called = true;
+    });
+    setTimeout(function () {
+      if (!called) {
+        Util.triggerTransitionEnd(_this);
+      }
+    }, duration);
+    return this;
+  }
+
+  function setTransitionEndSupport() {
+    $.fn.mmEmulateTransitionEnd = transitionEndEmulator; // eslint-disable-line no-param-reassign
+    // eslint-disable-next-line no-param-reassign
+
+    $.event.special[Util.TRANSITION_END] = getSpecialTransitionEndEvent();
+  }
+
+  setTransitionEndSupport();
+  return Util;
+}($);
+
+var NAME = 'metisMenu';
+var DATA_KEY = 'metisMenu';
+var EVENT_KEY = "." + DATA_KEY;
+var DATA_API_KEY = '.data-api';
+var JQUERY_NO_CONFLICT = $.fn[NAME];
+var TRANSITION_DURATION = 350;
+var Default = {
+  toggle: true,
+  preventDefault: true,
+  triggerElement: 'a',
+  parentTrigger: 'li',
+  subMenu: 'ul'
+};
+var Event = {
+  SHOW: "show" + EVENT_KEY,
+  SHOWN: "shown" + EVENT_KEY,
+  HIDE: "hide" + EVENT_KEY,
+  HIDDEN: "hidden" + EVENT_KEY,
+  CLICK_DATA_API: "click" + EVENT_KEY + DATA_API_KEY
+};
+var ClassName = {
+  METIS: 'metismenu',
+  ACTIVE: 'mm-active',
+  SHOW: 'mm-show',
+  COLLAPSE: 'mm-collapse',
+  COLLAPSING: 'mm-collapsing',
+  COLLAPSED: 'mm-collapsed'
+};
+
+var MetisMenu =
+/*#__PURE__*/
+function () {
+  // eslint-disable-line no-shadow
+  function MetisMenu(element, config) {
+    this.element = element;
+    this.config = _extends({}, Default, config);
+    this.transitioning = null;
+    this.init();
+  }
+
+  var _proto = MetisMenu.prototype;
+
+  _proto.init = function init() {
+    var self = this;
+    var conf = this.config;
+    var el = $(this.element);
+    el.addClass(ClassName.METIS); // add metismenu class to element
+
+    el.find(conf.parentTrigger + "." + ClassName.ACTIVE).children(conf.triggerElement).attr('aria-expanded', 'true'); // add attribute aria-expanded=true the trigger element
+
+    el.find(conf.parentTrigger + "." + ClassName.ACTIVE).parents(conf.parentTrigger).addClass(ClassName.ACTIVE);
+    el.find(conf.parentTrigger + "." + ClassName.ACTIVE).parents(conf.parentTrigger).children(conf.triggerElement).attr('aria-expanded', 'true'); // add attribute aria-expanded=true the triggers of all parents
+
+    el.find(conf.parentTrigger + "." + ClassName.ACTIVE).has(conf.subMenu).children(conf.subMenu).addClass(ClassName.COLLAPSE + " " + ClassName.SHOW);
+    el.find(conf.parentTrigger).not("." + ClassName.ACTIVE).has(conf.subMenu).children(conf.subMenu).addClass(ClassName.COLLAPSE);
+    el.find(conf.parentTrigger) // .has(conf.subMenu)
+    .children(conf.triggerElement).on(Event.CLICK_DATA_API, function (e) {
+      // eslint-disable-line func-names
+      var eTar = $(this);
+
+      if (eTar.attr('aria-disabled') === 'true') {
+        return;
+      }
+
+      if (conf.preventDefault && eTar.attr('href') === '#') {
+        e.preventDefault();
+      }
+
+      var paRent = eTar.parent(conf.parentTrigger);
+      var sibLi = paRent.siblings(conf.parentTrigger);
+      var sibTrigger = sibLi.children(conf.triggerElement);
+
+      if (paRent.hasClass(ClassName.ACTIVE)) {
+        eTar.attr('aria-expanded', 'false');
+        self.removeActive(paRent);
+      } else {
+        eTar.attr('aria-expanded', 'true');
+        self.setActive(paRent);
+
+        if (conf.toggle) {
+          self.removeActive(sibLi);
+          sibTrigger.attr('aria-expanded', 'false');
+        }
+      }
+
+      if (conf.onTransitionStart) {
+        conf.onTransitionStart(e);
+      }
+    });
+  };
+
+  _proto.setActive = function setActive(li) {
+    $(li).addClass(ClassName.ACTIVE);
+    var ul = $(li).children(this.config.subMenu);
+
+    if (ul.length > 0 && !ul.hasClass(ClassName.SHOW)) {
+      this.show(ul);
+    }
+  };
+
+  _proto.removeActive = function removeActive(li) {
+    $(li).removeClass(ClassName.ACTIVE);
+    var ul = $(li).children(this.config.subMenu + "." + ClassName.SHOW);
+
+    if (ul.length > 0) {
+      this.hide(ul);
+    }
+  };
+
+  _proto.show = function show(element) {
+    var _this = this;
+
+    if (this.transitioning || $(element).hasClass(ClassName.COLLAPSING)) {
+      return;
+    }
+
+    var elem = $(element);
+    var startEvent = $.Event(Event.SHOW);
+    elem.trigger(startEvent);
+
+    if (startEvent.isDefaultPrevented()) {
+      return;
+    }
+
+    elem.parent(this.config.parentTrigger).addClass(ClassName.ACTIVE);
+
+    if (this.config.toggle) {
+      var toggleElem = elem.parent(this.config.parentTrigger).siblings().children(this.config.subMenu + "." + ClassName.SHOW);
+      this.hide(toggleElem);
+    }
+
+    elem.removeClass(ClassName.COLLAPSE).addClass(ClassName.COLLAPSING).height(0);
+    this.setTransitioning(true);
+
+    var complete = function complete() {
+      // check if disposed
+      if (!_this.config || !_this.element) {
+        return;
+      }
+
+      elem.removeClass(ClassName.COLLAPSING).addClass(ClassName.COLLAPSE + " " + ClassName.SHOW).height('');
+
+      _this.setTransitioning(false);
+
+      elem.trigger(Event.SHOWN);
+    };
+
+    elem.height(element[0].scrollHeight).one(Util.TRANSITION_END, complete).mmEmulateTransitionEnd(TRANSITION_DURATION);
+  };
+
+  _proto.hide = function hide(element) {
+    var _this2 = this;
+
+    if (this.transitioning || !$(element).hasClass(ClassName.SHOW)) {
+      return;
+    }
+
+    var elem = $(element);
+    var startEvent = $.Event(Event.HIDE);
+    elem.trigger(startEvent);
+
+    if (startEvent.isDefaultPrevented()) {
+      return;
+    }
+
+    elem.parent(this.config.parentTrigger).removeClass(ClassName.ACTIVE); // eslint-disable-next-line no-unused-expressions
+
+    elem.height(elem.height())[0].offsetHeight;
+    elem.addClass(ClassName.COLLAPSING).removeClass(ClassName.COLLAPSE).removeClass(ClassName.SHOW);
+    this.setTransitioning(true);
+
+    var complete = function complete() {
+      // check if disposed
+      if (!_this2.config || !_this2.element) {
+        return;
+      }
+
+      if (_this2.transitioning && _this2.config.onTransitionEnd) {
+        _this2.config.onTransitionEnd();
+      }
+
+      _this2.setTransitioning(false);
+
+      elem.trigger(Event.HIDDEN);
+      elem.removeClass(ClassName.COLLAPSING).addClass(ClassName.COLLAPSE);
+    };
+
+    if (elem.height() === 0 || elem.css('display') === 'none') {
+      complete();
+    } else {
+      elem.height(0).one(Util.TRANSITION_END, complete).mmEmulateTransitionEnd(TRANSITION_DURATION);
+    }
+  };
+
+  _proto.setTransitioning = function setTransitioning(isTransitioning) {
+    this.transitioning = isTransitioning;
+  };
+
+  _proto.dispose = function dispose() {
+    $.removeData(this.element, DATA_KEY);
+    $(this.element).find(this.config.parentTrigger).has(this.config.subMenu).children(this.config.triggerElement).off('click');
+    this.transitioning = null;
+    this.config = null;
+    this.element = null;
+  };
+
+  MetisMenu.jQueryInterface = function jQueryInterface(config) {
+    // eslint-disable-next-line func-names
+    return this.each(function () {
+      var $this = $(this);
+      var data = $this.data(DATA_KEY);
+
+      var conf = _extends({}, Default, $this.data(), typeof config === 'object' && config ? config : {});
+
+      if (!data) {
+        data = new MetisMenu(this, conf);
+        $this.data(DATA_KEY, data);
+      }
+
+      if (typeof config === 'string') {
+        if (data[config] === undefined) {
+          throw new Error("No method named \"" + config + "\"");
+        }
+
+        data[config]();
+      }
+    });
+  };
+
+  return MetisMenu;
+}();
+/**
+ * ------------------------------------------------------------------------
+ * jQuery
+ * ------------------------------------------------------------------------
+ */
+
+
+$.fn[NAME] = MetisMenu.jQueryInterface; // eslint-disable-line no-param-reassign
+
+$.fn[NAME].Constructor = MetisMenu; // eslint-disable-line no-param-reassign
+
+$.fn[NAME].noConflict = function () {
+  // eslint-disable-line no-param-reassign
+  $.fn[NAME] = JQUERY_NO_CONFLICT; // eslint-disable-line no-param-reassign
+
+  return MetisMenu.jQueryInterface;
+};
+
+export default MetisMenu;

+ 0 - 0
maxkey-web-manage/src/main/resources/templates/views/apps/appsList.jsp → maxkey-web-manage/src/main/resources/templates/views/apps/appsList.ftl


+ 9 - 0
maxkey-web-manage/src/main/resources/templates/views/layout/common.cssjs.ftl

@@ -36,9 +36,18 @@
 	<script src ="<@base />/static/jquery/jsonformatter.js" type="text/javascript" ></script>
 	<script src ="<@base />/static/jquery/switchtab/switchtab.js" type="text/javascript" ></script>
 	<link 	href="<@base />/static/jquery/switchtab/switchtab.css" type="text/css" rel="stylesheet" />
+	<#-- metisMenu-v3.0.4 -->
+	<link   href="<@base />/static/jquery/metisMenu-v3.0.4/css/mm-vertical.css"  rel="stylesheet" >
+	<link   href="<@base />/static/jquery/metisMenu-v3.0.4/metisMenu.min.css"  rel="stylesheet" >
+	<script src ="<@base />/static/jquery/metisMenu-v3.0.4/metisMenu.min.js" type="text/javascript" ></script>
 	<#-- common script start -->
 	<script type="text/javascript">
 		$(function () {
+			 $(".sidenav-fold-toggler").on("click",function(e) {
+	        	   $(".app").toggleClass("side-nav-folded");
+                   e.preventDefault();
+	         });
+	         
 			$(".datetimepicker").datetimepicker({format:'Y-m-d H:i',lang:'<@locale/>'.substring(0, 2)});
 			$(".datepicker").datetimepicker({timepicker:false,format:'Y-m-d',lang:'<@locale/>'.substring(0, 2)});
 			

+ 154 - 0
maxkey-web-manage/src/main/resources/templates/views/layout/sidenav.ftl

@@ -0,0 +1,154 @@
+<div  dir="rtl">
+<ul class="metismenu" id="side-nav-menu" >
+	<li>
+		<a class="" href="<@base />/main/">
+       		<span class="fa fa-fw fa-github fa-lg"></span>
+       		首&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;页
+    	</a>
+	</li>
+   	<li>
+     	<a class="" href="<@base />/orgs/list/">
+      		<span class="fa fa-fw fa-github fa-lg"></span>
+       		机构管理
+     	</a>
+   	</li>
+   	<li>
+     	<a class="" href="<@base />/userinfo/list/">
+      		<span class="fa fa-fw fa-github fa-lg"></span>
+       		用户管理
+     	</a>
+   	</li>
+   	<li>
+     	<a class="has-arrow" href="#">
+      		<span class="fa fa-fw fa-github fa-lg"></span>
+       		应用管理
+     	</a>
+     	<ul>
+     		<li>
+	         <a href="<@base />/apps/list/">
+	           <span class="fa fa-fw fa-code-fork"></span>
+	         	应用管理	
+	         </a>
+	       </li>
+	       <li>
+	         <a href="<@base />/app/accounts/list">
+	           <span class="fa fa-fw fa-code-fork"></span>
+	         	账号映射	
+	         </a>
+	       </li>
+	    </ul>
+   	</li>
+   	<li>
+     	<a class="has-arrow" href="#">
+      		<span class="fa fa-fw fa-github fa-lg"></span>
+       		组管理
+     	</a>
+     	<ul>
+     		<li>
+	         <a href="<@base />/groups/list/">
+	           <span class="fa fa-fw fa-code-fork"></span>
+	         	 组管理	
+	         </a>
+	       </li>
+	       <li>
+	         <a href="<@base />/groupMember/list">
+	           <span class="fa fa-fw fa-code-fork"></span>
+	         	 成员管理	
+	         </a>
+	       </li>
+	       <li>
+	         <a href="<@base />/groupApp/list">
+	           <span class="fa fa-fw fa-code-fork"></span>
+	         	 权限管理	
+	         </a>
+	       </li>
+	    </ul>
+   	</li>
+   		
+   	<li>
+     	<a class="has-arrow" href="#">
+      		<span class="fa fa-fw fa-github fa-lg"></span>
+       		配置管理
+     	</a>
+     	<ul>
+     		<li>
+	         <a href="<@base />/config/passwordpolicy/forward">
+	           <span class="fa fa-fw fa-code-fork"></span>
+	         	 密码策略
+	         </a>
+	       </li>
+	    </ul>
+	</li>
+   	<li>
+     	<a class="has-arrow" href="#">
+      		<span class="fa fa-fw fa-github fa-lg"></span>
+       		日志审计
+     	</a>
+     	<ul>
+	       <li>
+	         <a href="<@base />/logs/loginHistoryList">
+	           <span class="fa fa-fw fa-code-fork"></span>
+	         	 登录日志
+	         </a>
+	       </li>
+	       <li>
+	         <a href="<@base />/logs/loginAppsHistoryList">
+	           <span class="fa fa-fw fa-code-fork"></span>
+	         	 访问日志
+	         </a>
+	       </li>
+	       <li>
+	         <a href="<@base />/logs/list">
+	           <span class="fa fa-fw fa-code-fork"></span>
+	         	  操作日志
+	         </a>
+	       </li>
+	    </ul>
+   	</li>
+   	<li>
+     	<a class="has-arrow" href="#">
+      		<span class="fa fa-fw fa-github fa-lg"></span>
+       		统计报表
+     	</a>
+     	<ul>
+	       <li>
+	         <a href="<@base />/report/login/day">
+	           <span class="fa fa-fw fa-code-fork"></span>
+	         	  日报表
+	         </a>
+	       </li>
+	       <li>
+	         <a href="<@base />/report/login/month">
+	           <span class="fa fa-fw fa-code-fork"></span>
+	         	 月报表
+	         </a>
+	       </li>
+	       <li>
+	         <a href="<@base />/report/login/year">
+	           <span class="fa fa-fw fa-code-fork"></span>
+	         	  年报表
+	         </a>
+	       </li>
+	       <li>
+	         <a href="<@base />/report/login/app">
+	           <span class="fa fa-fw fa-code-fork"></span>
+	         	  应用登录报表
+	         </a>
+	       </li>
+	       <li>
+	         <a href="<@base />/report/login/browser">
+	           <span class="fa fa-fw fa-code-fork"></span>
+	         	 浏览器报表
+	         </a>
+	       </li>
+	    </ul>
+   	</li>
+   	
+ </ul>
+
+<script type="text/javascript"> 
+$(function(){
+	$('#side-nav-menu').metisMenu();
+});
+</script>
+</div>

+ 36 - 50
maxkey-web-manage/src/main/resources/templates/views/layout/top.ftl

@@ -1,53 +1,39 @@
-<div id="topBar"  > 
-	<div class="container">
-		<div style="float:left;margin-left:20px;margin-top: 5px;"><IMG SRC="<@base/>/static/images/logo.jpg" style="width:55px;heigth:55px"></div>
-		<div style="margin-top:15px;margin-left:10px;float:left">
-			<div style="letter-spacing:2px;font-size:28px;font-weight:bolder;"><@locale code="global.application"/></div>
-			
-		</div>
-		<div style="margin-top:25px;margin-right:10px;float:right;">
-			<table  style="height: 31px;">
-				<tr>
-					<td>
-						<@locale code="global.text.welcome"/>:
-						<#if  Session["current_user"]?exists>
-							${Session["current_user"].displayName}  ${Session["current_user"].username} 
-						</#if>
-						&nbsp;&nbsp;
-					</td>
-					<#if  Session["current_user"].gridList==0 >
-					<td>
-						<img src='<@base/>/static/images/grid_sel.png'  style="width=:31px;height:31px;border:0;">
-					</td>
-					<td>
-						<a href="<@base/>/appList?mnid=110101020000&gridList=1"><img src='<@base/>/static/images/list.png'  style="width=:31px;height:31px;border:0;"></a>
-					</td>
-					<#else>
-					<td>
-						<a href="<@base/>/appList?mnid=110101020000&gridList=0" ><img src='<@base/>/static/images/grid.png'  style="width=:31px;height:31px;border:0;"></a>
-					</td>
-					<td>
-						<img src='<@base/>/static/images/list_sel.png'  style="width=:31px;height:31px;border:0;">
-					</td>
-					</#if>
-					<td id="changepassword" nowrap>
-						<a  href="<@base/>/safe/forward/changePasswod">
-							<div  style="float:right;" >&nbsp;&nbsp;<@locale code="login.password.changepassword"/>&nbsp;&nbsp;</div>
-						</a>
-					</td>
-					<td id="manage" nowrap>
-						<a target="_blank"  href="<@base/>/authz/manage">
-							<div  style="float:right;" >&nbsp;&nbsp;<@locale code="global.text.manage"/>&nbsp;&nbsp;</div>
-						</a>
-					</td>
+<div class="header-container">
+	<div class="nav-logo">
+		<a href="<@base/>/main"> 
+			<IMG SRC="<@base/>/static/images/logo.jpg" alt="" style="width:40px;heigth:40px">	
+		</a>
+		<span class="logo">
 		
-					<td id="logout" class="ui-widget-header" >
-						<a  href="<@base/>/logout?reLoginUrl=login">
-							<div  style="float:right;" >&nbsp;&nbsp;<@locale code="global.text.logout"/>&nbsp;&nbsp;</div>
-						</a>
-					</td>
-				</tr>
-			</table>
-		</div>
+		</span>
 	</div>
+	<ul class="nav-left"  style="letter-spacing:2px;font-size:20px;font-weight:bolder;margin-top: 14px;">
+		<@locale code="global.application"/>
+	</ul>
+	<ul class="nav-right">
+		<li style="font-size: 18px; margin-top: 10px;">
+				<@locale code="global.text.welcome"/>:<b>
+				<#if  Session["current_user"]?exists>
+					${Session["current_user"].displayName}
+				</#if>
+				(
+					<#if  Session["current_user"]?exists>
+						${Session["current_user"].username} 
+					</#if>
+				)&nbsp;&nbsp;</b>
+		 </li>
+		<li class="scale-left">
+			<a class="sidenav-fold-toggler" href="javascript:void(0);"> 
+				<img  src="<@base/>/static/images/menu-left.png" alt="" style="width: 30px; height: 40px; padding-top: 10px;">
+			</a>
+		</li>
+		<li class="scale-left">
+			 &nbsp;
+		</li>
+		<li class="scale-left"> 
+			<a  href="<@base/>/logout?reLoginUrl=login">
+				<IMG SRC="<@base/>/static/images/exit4.png" alt="Exit" style="width: 40px; height: 45px; padding-top: 8px;">	
+			</a>
+		</li>
+	</ul>
 </div>

+ 20 - 21
maxkey-web-manage/src/main/resources/templates/views/login.jsp → maxkey-web-manage/src/main/resources/templates/views/login.ftl

@@ -1,22 +1,20 @@
-<%@ page   language="java" import="java.util.*" pageEncoding="UTF-8" contentType="text/html; charset=UTF-8" %>
-<%@ taglib prefix="c"       	uri="http://java.sun.com/jsp/jstl/core"  %>
-<%@ taglib prefix="s" 			uri="http://sso.maxkey.org/tags" %> 
 <!DOCTYPE HTML>
 <html xmlns="http://www.w3.org/1999/xhtml">
 <head>
-	<jsp:include page="layout/header.jsp"></jsp:include>
-	<jsp:include page="layout/common.cssjs.jsp"></jsp:include>
+	<#include  "layout/header.ftl"/>
+	<#include  "layout/common.cssjs.ftl"/>
 	<script type="text/javascript"> 
 	$(function(){
-		<c:if test="${'true'==isCaptcha}">
+		<#if true==isCaptcha>
 			$('#j_captchaimg').click(function () {//
-		           $(this).attr("src", "<s:Base />/captcha"); 
+		           $(this).attr("src", "<@base />/captcha"); 
 			}); 
-		 </c:if>
+		 </#if>
 	});
 	</script>
 </head>
 <body >
+<#include  "layout/nologintop.ftl"/>
 	<div class="wrapper-page">
 		<div class="container">
 			<div class="row justify-content-center">
@@ -24,43 +22,43 @@
 					<div class="card">
 						<div class="card-header border-bottom text-center">
 							<h4 class="card-title">
-								<s:Locale code="login.text.login.header" />
+								<locale code="login.text.login.normal" />
 							</h4>
 						</div>
 						<div class="card-body">
-							<form class="form-horizontal m-t-20" id="loginForm" name="loginForm" action="<s:Base />/logon.do" method="post">
+							<form class="form-horizontal m-t-20" id="loginForm" name="loginForm" action="<@base />/logon.do" method="post">
 								<div class="form-group">
 									<span class="input-group-addon"><i class="fa fa-user"></i></span>
-									<input id='j_username' name='j_username' value="admin" class="form-control" type="text" required="" placeholder="<s:Locale code="login.text.username"/>">
+									<input id='j_username' name='j_username' value="admin" class="form-control" type="text" required="" placeholder="<@locale code="login.text.username"/>">
 								</div>
 								<div class="form-group">
 									<span class="input-group-addon"><i class="fa fa-key"></i></span>
-									<input id='j_password' name='j_password' class="form-control" type="password" required=""	placeholder="<s:Locale code="login.text.password"/>">
+									<input id='j_password' name='j_password' class="form-control" type="password" required=""	placeholder="<@locale code="login.text.password"/>">
 								</div>
 								<div class="form-group">
-									<input id="j_captcha" name="j_captcha" class="form-control" type="text" required="" placeholder="<s:Locale code="login.text.captcha"/>" style="float: left; width: 70%;"> 
-									<img id="j_captchaimg" src="<c:url value="/captcha"/>" />
+									<input id="j_captcha" name="j_captcha" class="form-control" value="" type="text" required="" placeholder="<@locale code="login.text.captcha"/>" style="float: left; width: 70%;"> 
+									<img id="j_captchaimg" src="<@base/>/captcha" />
 								</div>
 								<div class="form-group text-center m-t-20">
 									<input type="hidden" name="j_auth_type" value="basic" /> 
 									<input type='hidden' id="sessionid" name="j_sessionid" value="${sessionid}" />
 									<button id="loginSubmit" class="button btn-primary btn btn-common btn-block" type="submit">
-										<s:Locale code="login.button.login" />
+										<@locale code="login.button.login" />
 									</button>
 								</div>
 								<div class="form-group">
 									<div class="float-right">
-										Locale : ${pageContext.response.locale} 
-										<a href="<s:BasePath />/login?language=en">
-											<s:Locale code="global.change.language.en" />
+										Locale : <@locale/>
+										<a href="<@basePath />/login?language=en">
+											<@locale code="global.change.language.en" />
 										</a>
 										|
-										<a href="<s:BasePath />/login?language=zh_CN">
-											<s:Locale code="global.change.language.zh" />
+										<a href="<@basePath />/login?language=zh_CN">
+											<@locale code="global.change.language.zh" />
 										</a>
 									</div>
 									<div class="float-left">
-										<s:Locale code="global.change.language" />:
+										<@locale code="global.change.language" />:
 
 									</div>
 								</div>
@@ -73,6 +71,7 @@
 	</div>
 	<div id="preloader">
 		<div class="loader" id="loader-1"></div>
+		<#include  "layout/footer.ftl"/>
 	</div>
 </body>
 </html>

+ 0 - 0
maxkey-web-manage/src/main/resources/templates/views/main.jsp → maxkey-web-manage/src/main/resources/templates/views/main.ftl


+ 39 - 42
maxkey-web-manage/src/main/resources/templates/views/userinfo/usersList.jsp → maxkey-web-manage/src/main/resources/templates/views/userinfo/usersList.ftl

@@ -1,21 +1,18 @@
-<%@ page   language="java" import="java.util.*" pageEncoding="UTF-8" contentType="text/html; charset=UTF-8" %>
-<%@ taglib prefix="c"       	uri="http://java.sun.com/jsp/jstl/core"  %>
-<%@ taglib prefix="s" 			uri="http://sso.maxkey.org/tags" %> 
 <!DOCTYPE HTML>
 <html xmlns="http://www.w3.org/1999/xhtml">
 <head>
-	<jsp:include page="../layout/header.jsp"></jsp:include>
-	<jsp:include page="../layout/common.cssjs.jsp"></jsp:include>
+	<#include  "../layout/header.ftl"/>
+	<#include  "../layout/common.cssjs.ftl"/>
 	<script type="text/javascript">	
 		function onSelectRow(id){		
-	   		$("#changepwdBtn").attr("wurl","<s:Base/>/users/forwardChangePassword/"+$.gridRowData("#list",id).id);
+	   		$("#changepwdBtn").attr("wurl","<@base/>/users/forwardChangePassword/"+$.gridRowData("#list",id).id);
 	   	}
 	   	
 	   	function genderFormatter(value, options, rData){
 	   		if(value==1){
-	   			return '<s:Locale code="userinfo.gender.female" />';
+	   			return '<@locale code="userinfo.gender.female" />';
 	   		}else{
-	   			return '<s:Locale code="userinfo.gender.male" />';
+	   			return '<@locale code="userinfo.gender.male" />';
 	   		}
 		};
 	</script>
@@ -24,11 +21,11 @@
 <div class="app header-default side-nav-dark">
 <div class="layout">
 	<div class="header navbar">
-		<jsp:include page="../layout/top.jsp"></jsp:include>
+		<#include  "../layout/top.ftl"/>
 	</div>
 	
 	<div class="col-md-3 sidebar-nav side-nav" >
- 		<jsp:include page="../layout/sidenav.jsp"></jsp:include>
+		<#include  "../layout/sidenav.ftl"/>
 	</div>
 	<div class="page-container">
 	
@@ -58,34 +55,34 @@
 		<table   class="table table-bordered">
 			<tr>
 				<td  width="120px">
-			 		 <s:Locale code="userinfo.username"/>:
+			 		 <@locale code="userinfo.username"/>:
 				</td>
 				<td  width="375px">
 					<form id="basic_search_form">
 				 			<input  class="form-control"  name="username" type="text" style ="width:150px;float:left;">
-				 			<input  class="button btn btn-primary mr-3"    id="searchBtn" type="button" size="50" value="<s:Locale code="button.text.search"/>">
-				 			<input  class="button btn btn-secondary"  id="advancedSearchExpandBtn" type="button" size="50"  value="<s:Locale code="button.text.expandsearch"/>" expandValue="<s:Locale code="button.text.expandsearch"/>"  collapseValue="<s:Locale code="button.text.collapsesearch"/>">
+				 			<input  class="button btn btn-primary mr-3"    id="searchBtn" type="button" size="50" value="<@locale code="button.text.search"/>">
+				 			<input  class="button btn btn-secondary"  id="advancedSearchExpandBtn" type="button" size="50"  value="<@locale code="button.text.expandsearch"/>" expandValue="<@locale code="button.text.expandsearch"/>"  collapseValue="<@locale code="button.text.collapsesearch"/>">
 					 	</form>
 				</td>
 				<td colspan="2"> 
 					 <div id="tool_box_right">
-					 	<input class="button btn btn-warning mr-3 window" id="changepwdBtn" type="button" value="<s:Locale code="button.text.changepassword"/>" 
-						 		    wurl="<s:Base/>/users/forwardChangePassword" wwidth="600px" wheight="250px" />
+					 	<input class="button btn btn-warning mr-3 window" id="changepwdBtn" type="button" value="<@locale code="login.password.changepassword"/>" 
+						 		    wurl="<@base/>/users/forwardChangePassword" wwidth="600px" wheight="250px" />
 						 		    
-						 <input class="button btn btn-success mr-3" id="addBtn" type="button" value="<s:Locale code="button.text.add"/>" 
-						 		    wurl="<s:Base/>/users/forwardSelectUserType"
+						 <input class="button btn btn-success mr-3" id="addBtn" type="button" value="<@locale code="button.text.add"/>" 
+						 		    wurl="<@base/>/users/forwardSelectUserType"
 						 		    wwidth="960"
 						 		    wheight="600"
 					 		    	target="window">	    	
 					 		    	
-					 	<input class="button btn btn-info mr-3 " id="modifyBtn" type="button" value="<s:Locale code="button.text.edit"/>" 
-					 				wurl="<s:Base/>/users/forwardUpdate"
+					 	<input class="button btn btn-info mr-3 " id="modifyBtn" type="button" value="<@locale code="button.text.edit"/>" 
+					 				wurl="<@base/>/users/forwardUpdate"
 					 				wwidth="960"
 						 		    wheight="600"
 					 		    	target="window"> 
 					 		    	
-					 	<input class="button btn btn-danger mr-3 "  id="deleteBtn" type="button" value="<s:Locale code="button.text.delete"/>"
-					 				wurl="<s:Base/>/users/delete" />
+					 	<input class="button btn btn-danger mr-3 "  id="deleteBtn" type="button" value="<@locale code="button.text.delete"/>"
+					 				wurl="<@base/>/users/delete" />
 					</div>
 				</td>
 			</tr>
@@ -98,35 +95,35 @@
  		<form id="advanced_search_form">
  			<table    class="table table-bordered">
 	 			<tr>
-	 				<td width="120px"><s:Locale code="userinfo.displayName"/></td>
+	 				<td width="120px"><@locale code="userinfo.displayName"/></td>
 		 			<td width="360px">
 		 				<input  class="form-control"  name="displayName" type="text" >
 		 			</td>
-		 			<td width="120px"><s:Locale code="userinfo.employeeNumber"/></td>
+		 			<td width="120px"><@locale code="userinfo.employeeNumber"/></td>
 		 			<td width="360px">
 						<input class="form-control"  type="text" id="employeeNumber" name="employeeNumber"  title="" value=""/>
 			 			</td>
 		 			
 			 </tr>
 			 <tr>
-					<td width="120px"><s:Locale code="userinfo.department"/></td>
+					<td width="120px"><@locale code="userinfo.department"/></td>
 		 			<td width="360px">
 			 			<input  class="form-control"  type="text" style="display:none;" id="departmentId" name="departmentId"  title="" value=""/>
 						<input  class="form-control"  style="width:70%;;float:left;"  type="text" id="department" name="department"  title="" value=""/>
-			 			<input class="window button btn btn-secondary mr-3 "  type="button"  size="50" value="<s:Locale code="button.text.select"/>" title="department" wurl="/orgs/orgsSelect/deptId/department" wwidth="300" wheight="400" />
+			 			<input class="window button btn btn-secondary mr-3 "  type="button"  size="50" value="<@locale code="button.text.select"/>" title="department" wurl="/orgs/orgsSelect/deptId/department" wwidth="300" wheight="400" />
 			 		</td>
-	 				<td width="120px"><s:Locale code="userinfo.userType"/></td>
+	 				<td width="120px"><@locale code="userinfo.userType"/></td>
 		 			<td width="360px">
 		 				<input class="form-control"  class="userTypeId" name="userType" type="text" style="display:none;"  >
 		 				<input class="form-control"  class="userTypeName" name="userTypeName" type="text" style="width:70%;;float:left;"  >
-		 				<input class="window button btn btn-secondary mr-3 " type="button"   size="50" value="<s:Locale code="button.text.select"/>" title="UserType" wurl="/usertype//selectUserTypeList" wwidth="700" wheight="500" />
+		 				<input class="window button btn btn-secondary mr-3 " type="button"   size="50" value="<@locale code="button.text.select"/>" title="UserType" wurl="/usertype//selectUserTypeList" wwidth="700" wheight="500" />
 		 			</td>
 		 			
 			 </tr>
 			</table>
  		</form>
  	</div>
- 	<table  data-url="<s:Base />/userinfo/grid"
+ 	<table  data-url="<@base/>/userinfo/grid"
 			id="datagrid"
 			data-toggle="table"
 			data-classes="table table-bordered table-hover table-striped"
@@ -140,17 +137,17 @@
 			data-side-pagination="server">
 		<thead>
 			<tr>
-			<th data-sortable="true" data-field="id"   data-visible="false"><s:Locale code="log.loginhistory.id"/></th>
-			<th data-field="icon"><s:Locale code="apps.icon"/></th>
-			<th data-field="username"><s:Locale code="userinfo.username"/></th>
-			<th data-field="displayName"><s:Locale code="userinfo.displayName"/></th>
-			<th data-field="employeeNumber"><s:Locale code="userinfo.employeeNumber"/></th>
-			<th data-field="organization"><s:Locale code="userinfo.organization"/></th>
-			<th data-field="department"><s:Locale code="userinfo.department"/></th>
-			<th data-field="jobTitle"><s:Locale code="userinfo.jobTitle"/></th>
-			<th data-field="mobile"><s:Locale code="userinfo.mobile"/></th>
-			<th data-field="email"><s:Locale code="userinfo.email"/></th>
-			<th data-field="gender"><s:Locale code="userinfo.gender"/></th>
+			<th data-sortable="true" data-field="id"   data-visible="false"><@locale code="log.loginhistory.id"/></th>
+			<th data-field="icon"><@locale code="apps.icon"/></th>
+			<th data-field="username"><@locale code="userinfo.username"/></th>
+			<th data-field="displayName"><@locale code="userinfo.displayName"/></th>
+			<th data-field="employeeNumber"><@locale code="userinfo.employeeNumber"/></th>
+			<th data-field="organization"><@locale code="userinfo.organization"/></th>
+			<th data-field="department"><@locale code="userinfo.department"/></th>
+			<th data-field="jobTitle"><@locale code="userinfo.jobTitle"/></th>
+			<th data-field="mobile"><@locale code="userinfo.mobile"/></th>
+			<th data-field="email"><@locale code="userinfo.email"/></th>
+			<th data-field="gender"><@locale code="userinfo.gender"/></th>
 			</tr>
 		</thead>
 	</table>
@@ -158,9 +155,9 @@
 	
 </div>
 					</div>
-					<footer class="content-footer">
-		<jsp:include page="../layout/footer.jsp"></jsp:include>
-	</footer>
+<footer class="content-footer">
+					<#include  "../layout/footer.ftl"/>
+</footer>
 
 	</div>
 	

+ 0 - 7
maxkey-web-maxkey/src/main/resources/spring/maxkey-web.xml

@@ -18,13 +18,6 @@
 	        http://www.springframework.org/schema/mvc 
 	        http://www.springframework.org/schema/mvc/spring-mvc.xsd">
 
-	<!-- Static resources -->
-	<!-- js images css -->
-	<mvc:resources mapping="/jquery/**" location="/jquery/" />
-	<mvc:resources mapping="/images/**" location="/images/" />
-	<mvc:resources mapping="/css/**" location="/css/" />
-	<mvc:resources mapping="/js/**" location="/js/" />
-	
 	<!-- LocaleResolver -->
 	<bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
 		<property name="cookieDomain" value="#{applicationConfig.subDomainName}"/>

部分文件因为文件数量过多而无法显示