瀏覽代碼

1.新增bootstrap-table分页跳转
2.新增select2组件,以及参数管理下拉
3.新增switchery组件,用于用户管理、参数管理
4.新增富文本编辑器组件,包括文件上传
5.新增开发组件见系统首页【开发组件】

zhouchenglin 6 年之前
父節點
當前提交
f932035970
共有 45 個文件被更改,包括 1182 次插入1061 次删除
  1. 0 219
      pom-war.xml
  2. 3 9
      src/main/java/net/chenlin/dp/DpApplication.java
  3. 29 3
      src/main/java/net/chenlin/dp/common/constant/SystemConstant.java
  4. 2 0
      src/main/java/net/chenlin/dp/common/support/config/ShiroConfig.java
  5. 43 0
      src/main/java/net/chenlin/dp/common/support/config/WebConfig.java
  6. 94 0
      src/main/java/net/chenlin/dp/common/utils/UploadUtils.java
  7. 39 0
      src/main/java/net/chenlin/dp/modules/base/controller/SysMacroController.java
  8. 2 0
      src/main/java/net/chenlin/dp/modules/base/dao/SysMacroMapper.java
  9. 3 1
      src/main/java/net/chenlin/dp/modules/base/manager/SysMacroManager.java
  10. 5 0
      src/main/java/net/chenlin/dp/modules/base/manager/impl/SysMacroManagerImpl.java
  11. 2 0
      src/main/java/net/chenlin/dp/modules/base/service/SysMacroService.java
  12. 7 2
      src/main/java/net/chenlin/dp/modules/base/service/impl/SysMacroServiceImpl.java
  13. 41 0
      src/main/java/net/chenlin/dp/modules/sys/controller/SysEditorUploadController.java
  14. 2 1
      src/main/java/net/chenlin/dp/modules/sys/controller/SysRoleController.java
  15. 3 2
      src/main/java/net/chenlin/dp/modules/sys/service/SysRoleService.java
  16. 2 3
      src/main/java/net/chenlin/dp/modules/sys/service/impl/SysRoleServiceImpl.java
  17. 1 0
      src/main/resources/application.yml
  18. 20 0
      src/main/resources/mapper/base/SysMacroMapper.xml
  19. 1 1
      src/main/resources/static/css/common.min.css
  20. 24 6
      src/main/resources/static/js/base/macro/list.js
  21. 27 6
      src/main/resources/static/js/base/quartz/list.js
  22. 9 27
      src/main/resources/static/js/base/user/add.js
  23. 7 51
      src/main/resources/static/js/base/user/edit.js
  24. 33 12
      src/main/resources/static/js/base/user/list.js
  25. 171 1
      src/main/resources/static/js/common.js
  26. 42 0
      src/main/resources/static/js/form.js
  27. 54 0
      src/main/resources/static/plugins/bootstrap-table/pagejump/bootstrap-table-pagejump.css
  28. 50 0
      src/main/resources/static/plugins/bootstrap-table/pagejump/bootstrap-table-pagejump.js
  29. 0 0
      src/main/resources/static/plugins/double-box/doublebox-bootstrap.css
  30. 0 681
      src/main/resources/static/plugins/double-box/doublebox-bootstrap.js
  31. 0 0
      src/main/resources/static/plugins/editor/editor.min.css
  32. 0 0
      src/main/resources/static/plugins/editor/editor.min.js
  33. 1 0
      src/main/resources/static/plugins/select2/i18n/zh-CN.min.js
  34. 0 0
      src/main/resources/static/plugins/select2/select2.min.css
  35. 0 0
      src/main/resources/static/plugins/select2/select2.min.js
  36. 1 0
      src/main/resources/static/plugins/switchery/switchery.min.css
  37. 0 0
      src/main/resources/static/plugins/switchery/switchery.min.js
  38. 91 0
      src/main/resources/templates/base/component/editor.html
  39. 215 0
      src/main/resources/templates/base/component/select2.html
  40. 98 0
      src/main/resources/templates/base/component/switchery.html
  41. 22 17
      src/main/resources/templates/base/user/add.html
  42. 22 17
      src/main/resources/templates/base/user/edit.html
  43. 6 1
      src/main/resources/templates/include/footer_js.html
  44. 3 1
      src/main/resources/templates/include/header_css.html
  45. 7 0
      src/main/resources/templates/system/index/main.html

+ 0 - 219
pom-war.xml

@@ -1,219 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-	<modelVersion>4.0.0</modelVersion>
-
-	<groupId>net.chenlin.dp</groupId>
-	<artifactId>dp</artifactId>
-	<version>0.0.1-SNAPSHOT</version>
-	<packaging>war</packaging><!-- clean package -f pom-war.xml -->
-
-	<name>dp-lte-boot</name>
-	<description>dp开发框架SpringBoot版本</description>
-
-	<parent>
-		<groupId>org.springframework.boot</groupId>
-		<artifactId>spring-boot-starter-parent</artifactId>
-		<version>1.5.7.RELEASE</version>
-		<relativePath/>
-	</parent>
-
-	<properties>
-		<!-- base setting -->
-		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
-		<java.version>1.8</java.version>
-
-		<!-- lib versions -->
-		<java-version>1.8</java-version>
-		<mybatis-springboot-version>1.3.0</mybatis-springboot-version>
-		<mysql-version>5.1.38</mysql-version>
-		<druid-version>1.1.2</druid-version>
-		<commons-lang-version>2.6</commons-lang-version>
-		<commons-fileupload-version>1.3.1</commons-fileupload-version>
-		<commons-io-version>2.5</commons-io-version>
-		<commons-codec-version>1.10</commons-codec-version>
-		<commons-configuration-version>1.10</commons-configuration-version>
-		<aspect-version>1.8.10</aspect-version>
-		<shiro-version>1.3.2</shiro-version>
-		<quartz-version>2.2.3</quartz-version>
-        <httpclient-version>4.5.3</httpclient-version>
-        <nekohtml-version>1.9.22</nekohtml-version>
-        <velocity-version>1.7</velocity-version>
-	</properties>
-
-	<dependencies>
-		<dependency>
-			<groupId>org.springframework.boot</groupId>
-			<artifactId>spring-boot-starter-test</artifactId>
-			<scope>test</scope>
-		</dependency>
-		<dependency>
-            <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-tomcat</artifactId>
-            <scope>provided</scope>
-        </dependency>
-		<dependency>
-			<groupId>org.springframework.boot</groupId>
-			<artifactId>spring-boot-starter-web</artifactId>
-		</dependency>
-		<dependency>
-            <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-thymeleaf</artifactId>
-        </dependency>
-		<dependency>
-			<groupId>org.springframework.boot</groupId>
-			<artifactId>spring-boot-starter-aop</artifactId>
-		</dependency>
-		<dependency>
-			<groupId>org.springframework</groupId>
-			<artifactId>spring-context-support</artifactId>
-		</dependency>
-		<dependency>
-			<groupId>org.springframework.boot</groupId>
-			<artifactId>spring-boot-starter-data-redis</artifactId>
-		</dependency>
-		<dependency>
-			<groupId>org.springframework.boot</groupId>
-			<artifactId>spring-boot-configuration-processor</artifactId>
-			<optional>true</optional>
-		</dependency>
-		<dependency>
-			<groupId>org.springframework.boot</groupId>
-			<artifactId>spring-boot-devtools</artifactId>
-			<optional>true</optional>
-		</dependency>
-		<dependency>
-			<groupId>org.mybatis.spring.boot</groupId>
-			<artifactId>mybatis-spring-boot-starter</artifactId>
-			<version>${mybatis-springboot-version}</version>
-		</dependency>
-		<dependency>
-			<groupId>mysql</groupId>
-			<artifactId>mysql-connector-java</artifactId>
-			<version>${mysql-version}</version><!--$NO-MVN-MAN-VER$-->
-		</dependency>
-		<dependency>
-			<groupId>com.alibaba</groupId>
-			<artifactId>druid-spring-boot-starter</artifactId>
-			<version>${druid-version}</version>
-		</dependency>
-		<dependency>
-			<groupId>org.quartz-scheduler</groupId>
-			<artifactId>quartz</artifactId>
-			<version>${quartz-version}</version>
-			<exclusions>
-				<exclusion>
-					<groupId>com.mchange</groupId>
-					<artifactId>c3p0</artifactId>
-				</exclusion>
-			</exclusions>
-		</dependency>
-		<dependency>
-			<groupId>commons-lang</groupId>
-			<artifactId>commons-lang</artifactId>
-			<version>${commons-lang-version}</version>
-		</dependency>
-		<dependency>
-			<groupId>commons-fileupload</groupId>
-			<artifactId>commons-fileupload</artifactId>
-			<version>${commons-fileupload-version}</version>
-		</dependency>
-		<dependency>
-			<groupId>commons-io</groupId>
-			<artifactId>commons-io</artifactId>
-			<version>${commons-io-version}</version>
-		</dependency>
-		<dependency>
-			<groupId>commons-codec</groupId>
-			<artifactId>commons-codec</artifactId>
-			<version>${commons-codec-version}</version><!--$NO-MVN-MAN-VER$-->
-		</dependency>
-		<dependency>
-			<groupId>commons-configuration</groupId>
-			<artifactId>commons-configuration</artifactId>
-			<version>${commons-configuration-version}</version>
-		</dependency>
-		<dependency>
-			<groupId>org.aspectj</groupId>
-			<artifactId>aspectjrt</artifactId>
-			<version>${aspect-version}</version><!--$NO-MVN-MAN-VER$-->
-		</dependency>
-		<dependency>
-			<groupId>org.aspectj</groupId>
-			<artifactId>aspectjweaver</artifactId>
-			<version>${aspect-version}</version><!--$NO-MVN-MAN-VER$-->
-		</dependency>
-		<dependency>
-			<groupId>org.apache.shiro</groupId>
-			<artifactId>shiro-core</artifactId>
-			<version>${shiro-version}</version>
-		</dependency>
-		<dependency>
-			<groupId>org.apache.shiro</groupId>
-			<artifactId>shiro-spring</artifactId>
-			<version>${shiro-version}</version>
-		</dependency>
-		<dependency>
-		    <groupId>org.apache.httpcomponents</groupId>
-		    <artifactId>httpclient</artifactId>
-		    <version>${httpclient-version}</version><!--$NO-MVN-MAN-VER$-->
-		</dependency>
-		<dependency>
-		    <groupId>net.sourceforge.nekohtml</groupId>
-		    <artifactId>nekohtml</artifactId>
-		    <version>${nekohtml-version}</version><!--$NO-MVN-MAN-VER$-->
-		</dependency>
-		<dependency>
-			<artifactId>velocity</artifactId>
-			<groupId>org.apache.velocity</groupId>
-			<version>${velocity-version}</version>
-		</dependency>
-	</dependencies>
-
-	<build>
-        <finalName>${project.artifactId}</finalName>
-        <plugins>
-            <plugin>
-                <groupId>org.springframework.boot</groupId>
-                <artifactId>spring-boot-maven-plugin</artifactId>
-                <configuration>
-                    <fork>true</fork>
-                </configuration>
-            </plugin>
-            <!-- 跳过单元测试 -->
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-surefire-plugin</artifactId>
-                <configuration>
-                    <skipTests>true</skipTests>
-                </configuration>
-            </plugin>
-        </plugins>
-	</build>
-
-    <repositories>
-        <repository>
-            <id>public</id>
-            <name>aliyun nexus</name>
-            <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
-            <releases>
-                <enabled>true</enabled>
-            </releases>
-        </repository>
-    </repositories>
-    <pluginRepositories>
-        <pluginRepository>
-            <id>public</id>
-            <name>aliyun nexus</name>
-            <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
-            <releases>
-                <enabled>true</enabled>
-            </releases>
-            <snapshots>
-                <enabled>false</enabled>
-            </snapshots>
-        </pluginRepository>
-    </pluginRepositories>
-
-</project>

+ 3 - 9
src/main/java/net/chenlin/dp/DpApplication.java

@@ -3,8 +3,7 @@ package net.chenlin.dp;
 import org.springframework.boot.Banner;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.boot.builder.SpringApplicationBuilder;
-import org.springframework.boot.web.support.SpringBootServletInitializer;
+import org.springframework.context.annotation.Configuration;
 
 /**
  * 应用启动器
@@ -14,8 +13,9 @@ import org.springframework.boot.web.support.SpringBootServletInitializer;
  * @url www.chenlintech.com
  * @date 2017年9月3日 上午1:53:12
  */
+@Configuration
 @SpringBootApplication
-public class DpApplication extends SpringBootServletInitializer {
+public class DpApplication {
 
     public static void main(String[] args) {
         SpringApplication application = new SpringApplication(DpApplication.class);
@@ -23,10 +23,4 @@ public class DpApplication extends SpringBootServletInitializer {
         application.run(args);
     }
 
-    @Override
-    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
-        application.bannerMode(Banner.Mode.OFF);
-        return application.sources(DpApplication.class);
-    }
-
 }

+ 29 - 3
src/main/java/net/chenlin/dp/common/constant/SystemConstant.java

@@ -19,11 +19,37 @@ public class SystemConstant {
 	 * 数据标识
 	 */
 	public static final String DATA_ROWS = "rows";
-	
+
+	/**
+	 * 文件上传协议
+	 */
+	private static final String UPLOAD_LOCATION_PROTOCOL = "file:";
+
+	/**
+	 * 文件上传物理路径
+	 */
+	public static String UPLOAD_LOCATION_PATH;
+
+	/**
+	 * 文件上传目录访问路径
+	 */
+	public static final String UPLOAD_LOCATION_MAPPING = "/upload/";
+
+	/**
+	 * 访问映射
+	 * @return
+	 */
+	public static String getResourceHandlerMapping() {
+		return SystemConstant.UPLOAD_LOCATION_MAPPING.concat("**");
+	}
+
 	/**
-	 * 未授权错误代码
+	 * 物理地址
+	 * @return
 	 */
-	public static final int UNAUTHORIZATION_CODE = 401;
+	public static String getResourceLocation() {
+		return SystemConstant.UPLOAD_LOCATION_PROTOCOL.concat(SystemConstant.UPLOAD_LOCATION_PATH);
+	}
 	
 	/**
 	 * 菜单类型

+ 2 - 0
src/main/java/net/chenlin/dp/common/support/config/ShiroConfig.java

@@ -1,5 +1,6 @@
 package net.chenlin.dp.common.support.config;
 
+import net.chenlin.dp.common.constant.SystemConstant;
 import org.apache.shiro.mgt.SecurityManager;
 import org.apache.shiro.session.mgt.SessionManager;
 import org.apache.shiro.spring.LifecycleBeanPostProcessor;
@@ -70,6 +71,7 @@ public class ShiroConfig {
         filterMap.put("/fonts/**", "anon");
         filterMap.put("/plugins/**", "anon");
         filterMap.put("/swagger/**", "anon");
+        filterMap.put(SystemConstant.getResourceHandlerMapping(), "anon");
         filterMap.put("/favicon.ico", "anon");
         filterMap.put("/", "anon");
         filterMap.put("/**", "oauth2");

+ 43 - 0
src/main/java/net/chenlin/dp/common/support/config/WebConfig.java

@@ -0,0 +1,43 @@
+package net.chenlin.dp.common.support.config;
+
+import net.chenlin.dp.common.constant.SystemConstant;
+import org.apache.commons.lang.StringUtils;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
+
+import java.io.File;
+
+/**
+ * web配置
+ * @author zcl<yczclcn@163.com>
+ */
+@Configuration
+public class WebConfig extends WebMvcConfigurerAdapter {
+
+    @Value("${spring.http.multipart.location}")
+    private String uploadDir;
+
+    /**
+     * 文件上传路径虚拟映射
+     * @param registry
+     */
+    @Override
+    public void addResourceHandlers(ResourceHandlerRegistry registry) {
+        if (StringUtils.isBlank(uploadDir)) {
+            throw new RuntimeException("文件上传路径为空,请先在application.yml中配置{spring.http.multipart.location}路径!");
+        }
+        if (!uploadDir.endsWith("/")) {
+            throw new RuntimeException("文件上传路径必须以 / 结束!");
+        }
+        File uploadDest = new File(uploadDir);
+        if (!uploadDest.exists()) {
+            throw new RuntimeException("配置的文件上传路径不存在,请配置已存在的路径!");
+        }
+        SystemConstant.UPLOAD_LOCATION_PATH = uploadDir;
+        registry.addResourceHandler(SystemConstant.getResourceHandlerMapping())
+                .addResourceLocations(SystemConstant.getResourceLocation());
+    }
+
+}

+ 94 - 0
src/main/java/net/chenlin/dp/common/utils/UploadUtils.java

@@ -0,0 +1,94 @@
+package net.chenlin.dp.common.utils;
+
+import net.chenlin.dp.common.constant.SystemConstant;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.multipart.MultipartHttpServletRequest;
+import org.springframework.web.multipart.commons.CommonsMultipartResolver;
+
+import javax.servlet.http.HttpServletRequest;
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.UUID;
+
+/**
+ * 文件上传工具类
+ * @author ZhouChenglin
+ * @date 2018/1/29
+ */
+public class UploadUtils {
+
+    private static Logger LOG = LoggerFactory.getLogger(UploadUtils.class);
+
+    /** 上传文件处理(支持批量) */
+    public static List<String> uploadFile(HttpServletRequest request) {
+        CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(
+                request.getSession().getServletContext());
+        List<String> fileNames = new ArrayList<>();
+        if (multipartResolver.isMultipart(request)) {
+            MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
+            File dirFile = new File(SystemConstant.UPLOAD_LOCATION_PATH);
+            if (!dirFile.isDirectory()) {
+                dirFile.mkdirs();
+            }
+            for (Iterator<String> iterator = multiRequest.getFileNames(); iterator.hasNext();) {
+                String key = iterator.next();
+                MultipartFile multipartFile = multiRequest.getFile(key);
+                if (multipartFile != null) {
+                    String name = multipartFile.getOriginalFilename();
+                    String uuid = UUID.randomUUID().toString();
+                    String postFix = name.substring(name.lastIndexOf(".")).toLowerCase();
+                    String fileName = uuid + postFix;
+                    String filePath = SystemConstant.UPLOAD_LOCATION_PATH + fileName;
+                    File file = new File(filePath);
+                    file.setWritable(true, false);
+                    try {
+                        multipartFile.transferTo(file);
+                        fileNames.add(SystemConstant.UPLOAD_LOCATION_MAPPING.concat(fileName));
+                    } catch (Exception e) {
+                        LOG.error(name + "保存失败", e);
+                    }
+                }
+            }
+        }
+        return fileNames;
+    }
+
+    /** 上传文件处理(支持批量) */
+    public static List<String> uploadFile(HttpServletRequest request, String path) {
+        CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(
+                request.getSession().getServletContext());
+        List<String> fileNames = new ArrayList<>();
+        if (multipartResolver.isMultipart(request)) {
+            MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
+            File dirFile = new File(SystemConstant.UPLOAD_LOCATION_PATH.concat(path));
+            if (!dirFile.isDirectory()) {
+                dirFile.mkdirs();
+            }
+            for (Iterator<String> iterator = multiRequest.getFileNames(); iterator.hasNext();) {
+                String key = iterator.next();
+                MultipartFile multipartFile = multiRequest.getFile(key);
+                if (multipartFile != null) {
+                    String name = multipartFile.getOriginalFilename();
+                    String uuid = UUID.randomUUID().toString();
+                    String postFix = name.substring(name.lastIndexOf(".")).toLowerCase();
+                    String fileName = uuid + postFix;
+                    String filePath = SystemConstant.UPLOAD_LOCATION_PATH + path + fileName;
+                    File file = new File(filePath);
+                    file.setWritable(true, false);
+                    try {
+                        multipartFile.transferTo(file);
+                        fileNames.add(SystemConstant.UPLOAD_LOCATION_MAPPING + path + fileName);
+                    } catch (Exception e) {
+                        LOG.error(name + "保存失败", e);
+                    }
+                }
+            }
+        }
+        return fileNames;
+    }
+
+}

+ 39 - 0
src/main/java/net/chenlin/dp/modules/base/controller/SysMacroController.java

@@ -5,6 +5,7 @@ import java.util.List;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 
 import net.chenlin.dp.common.annotation.SysLog;
@@ -77,6 +78,34 @@ public class SysMacroController extends AbstractController {
 	public R update(@RequestBody SysMacroEntity macro) {
 		return sysMacroService.updateMacro(macro);
 	}
+
+	/**
+	 * 显示字典
+	 * @param id
+	 * @return
+	 */
+	@SysLog("显示字典")
+	@RequestMapping("/enable")
+	public R updateStateShow(@RequestBody Long id) {
+		SysMacroEntity macro = new SysMacroEntity();
+		macro.setMacroId(id);
+		macro.setStatus(1);
+		return sysMacroService.updateMacro(macro);
+	}
+
+	/**
+	 * 隐藏字典
+	 * @param id
+	 * @return
+	 */
+	@SysLog("隐藏字典")
+	@RequestMapping("/disable")
+	public R updateStateHide(@RequestBody Long id) {
+		SysMacroEntity macro = new SysMacroEntity();
+		macro.setMacroId(id);
+		macro.setStatus(0);
+		return sysMacroService.updateMacro(macro);
+	}
 	
 	/**
 	 * 删除字典
@@ -88,5 +117,15 @@ public class SysMacroController extends AbstractController {
 	public R batchRemove(@RequestBody Long[] id) {
 		return sysMacroService.batchRemove(id);
 	}
+
+	/**
+	 * 获取某个类型所有参数值,用于前台构建下拉框
+	 * @param value
+	 * @return
+	 */
+	@RequestMapping("/value")
+	public List<SysMacroEntity> listMacroValue(@RequestParam String value) {
+		return sysMacroService.listMacroValue(value);
+	}
 	
 }

+ 2 - 0
src/main/java/net/chenlin/dp/modules/base/dao/SysMacroMapper.java

@@ -21,5 +21,7 @@ public interface SysMacroMapper extends BaseMapper<SysMacroEntity> {
 	List<SysMacroEntity> listNotMacro();
 	
 	int countMacroChildren(Long typeId);
+
+	List<SysMacroEntity> listMacroValue(String type);
 	
 }

+ 3 - 1
src/main/java/net/chenlin/dp/modules/base/manager/SysMacroManager.java

@@ -28,5 +28,7 @@ public interface SysMacroManager {
 	int batchRemove(Long[] id);
 	
 	boolean hasChildren(Long[] id);
-	
+
+	List<SysMacroEntity> listMacroValue(String type);
+
 }

+ 5 - 0
src/main/java/net/chenlin/dp/modules/base/manager/impl/SysMacroManagerImpl.java

@@ -65,4 +65,9 @@ public class SysMacroManagerImpl implements SysMacroManager {
 		return false;
 	}
 
+	@Override
+	public List<SysMacroEntity> listMacroValue(String type) {
+		return sysMacroMapper.listMacroValue(type);
+	}
+
 }

+ 2 - 0
src/main/java/net/chenlin/dp/modules/base/service/SysMacroService.java

@@ -26,5 +26,7 @@ public interface SysMacroService {
 	R updateMacro(SysMacroEntity macro);
 	
 	R batchRemove(Long[] id);
+
+	List<SysMacroEntity> listMacroValue(String type);
 	
 }

+ 7 - 2
src/main/java/net/chenlin/dp/modules/base/service/impl/SysMacroServiceImpl.java

@@ -59,7 +59,7 @@ public class SysMacroServiceImpl implements SysMacroService {
 
 	@Override
 	public R updateMacro(SysMacroEntity macro) {
-		int count = sysMacroManager.updateMacro(validateMacro(macro));
+		int count = sysMacroManager.updateMacro(macro);
 		return CommonUtils.msg(count);
 	}
 
@@ -72,7 +72,12 @@ public class SysMacroServiceImpl implements SysMacroService {
 		int count = sysMacroManager.batchRemove(id);
 		return CommonUtils.msg(id, count);
 	}
-	
+
+	@Override
+	public List<SysMacroEntity> listMacroValue(String type) {
+		return sysMacroManager.listMacroValue(type);
+	}
+
 	/**
 	 * 当为参数类型时,状态为显示
 	 * @param macro

+ 41 - 0
src/main/java/net/chenlin/dp/modules/sys/controller/SysEditorUploadController.java

@@ -0,0 +1,41 @@
+package net.chenlin.dp.modules.sys.controller;
+
+import net.chenlin.dp.common.utils.UploadUtils;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 富文本上传controller
+ * @author zcl<yczclcn@163.com>
+ */
+@RestController
+@RequestMapping("/editor")
+public class SysEditorUploadController {
+
+    private static final String EDITOR_IMG_UPLOAD_DIR = "editor/";
+
+    /**
+     * 上传图片
+     * @param request
+     * @return
+     */
+    @RequestMapping("/upload")
+    public Map<String, Object> editorUpload(HttpServletRequest request) {
+        // 大部分场景下,每次仅上传一张图片
+        Map<String, Object> results = new HashMap<>(1);
+        results.put("errno", 0);
+        try {
+            List<String> pathList = UploadUtils.uploadFile(request, EDITOR_IMG_UPLOAD_DIR);
+            results.put("data", pathList);
+        } catch (Exception e) {
+            results.put("errno", 500);
+        }
+        return results;
+    }
+
+}

+ 2 - 1
src/main/java/net/chenlin/dp/modules/sys/controller/SysRoleController.java

@@ -1,5 +1,6 @@
 package net.chenlin.dp.modules.sys.controller;
 
+import java.util.List;
 import java.util.Map;
 
 import org.springframework.beans.factory.annotation.Autowired;
@@ -47,7 +48,7 @@ public class SysRoleController extends AbstractController {
 	 * @return
 	 */
 	@RequestMapping("/select")
-	public R listRole() {
+	public List<SysRoleEntity> listRole() {
 		return sysRoleService.listRole();
 	}
 	

+ 3 - 2
src/main/java/net/chenlin/dp/modules/sys/service/SysRoleService.java

@@ -1,5 +1,6 @@
 package net.chenlin.dp.modules.sys.service;
 
+import java.util.List;
 import java.util.Map;
 
 import net.chenlin.dp.common.entity.Page;
@@ -25,8 +26,8 @@ public interface SysRoleService {
 	R updateRole(SysRoleEntity role);
 	
 	R batchRemove(Long[] id);
-	
-	R listRole();
+
+	List<SysRoleEntity> listRole();
 	
 	R updateRoleOptAuthorization(SysRoleEntity role);
 	

+ 2 - 3
src/main/java/net/chenlin/dp/modules/sys/service/impl/SysRoleServiceImpl.java

@@ -61,9 +61,8 @@ public class SysRoleServiceImpl implements SysRoleService {
 	}
 
 	@Override
-	public R listRole() {
-		List<SysRoleEntity> roleList = sysRoleManager.listRole();
-		return CommonUtils.msgNotCheckNull(roleList);
+	public List<SysRoleEntity> listRole() {
+		return sysRoleManager.listRole();
 	}
 
 	@Override

+ 1 - 0
src/main/resources/application.yml

@@ -21,6 +21,7 @@ spring:
             max-file-size: 100MB
             max-request-size: 100MB
             enabled: true
+            location: /Users/zhouchenglin/dev/dp-boot/
     # thymeleaf 模板引擎
     thymeleaf:
         cache: false

+ 20 - 0
src/main/resources/mapper/base/SysMacroMapper.xml

@@ -50,6 +50,26 @@
 		ORDER BY
 			order_num ASC
 	</select>
+
+	<select id="listMacroValue" resultType="net.chenlin.dp.modules.base.entity.SysMacroEntity">
+		SELECT
+			macro_id,
+			name,
+			value
+		FROM
+			sys_macro
+		WHERE
+			type_id = (
+				SELECT
+					macro_id
+				FROM
+					sys_macro
+				WHERE
+					value = #{value}
+			)
+		AND STATUS = 1
+		ORDER BY macro_id;
+	</select>
 	
 	<insert id="save">
 		INSERT INTO sys_macro (

+ 1 - 1
src/main/resources/static/css/common.min.css

@@ -20,7 +20,7 @@ tbody > tr > th {font-weight: normal; }
 .form .formValue select{padding: 4px;padding-left:4px;}
 .form .formValue .bootstrap-duallistbox-container{margin-top:-32px;margin-left: -12px;}
 .form .formValue .bootstrap-duallistbox-container .btn-box{margin: 78px 16px 0px 16px;}
-.form-control{color:#000;border-radius:0px;box-shadow:none;padding-top:0px;padding-bottom:1px;padding-right:0px;padding-left:5px;resize: none;}
+.form-control{color:#000;border-radius:0px;box-shadow:none;padding-top:6px;padding-right:0px;padding-left:5px;resize: none;}
 .form-control:focus{border-color:#337ab7;box-shadow:none;}
 .form textarea.form-control{padding-top: 5px;}
 .has-error .form-control:focus{border-color:#B94A48;}

+ 24 - 6
src/main/resources/static/js/base/macro/list.js

@@ -47,16 +47,34 @@ function getGrid() {
                 field: 'status',
                 width: '60px',
                 formatter: function (value, row, index) {
-                    if (row.status === 0) {
-                        return '<i class="fa fa-toggle-off"></i>';
-                    }
-                    if (row.status === 1) {
-                        return '<i class="fa fa-toggle-on"></i>';
+                    if(value === 0){
+                        return '<input type="checkbox" class="js-switch" data-id="'+row.macroId+'">';
+                    }else if(value === 1){
+                        return '<input type="checkbox" class="js-switch" data-id="'+row.macroId+'" checked>';
                     }
                 }
             },
             {title: '备注', field: 'remark'}
-        ]
+        ],
+        onPostBody: function() {
+            switchUtils.init({
+                selector: '.js-switch',
+                single: false,
+                change: function(switchContainer) {
+                    var url = '../../sys/macro/disable?_' + $.now();
+                    if (switchUtils.checked(switchContainer)) {
+                        url = '../../sys/macro/enable?_' + $.now();
+                    }
+                    $.AjaxForm({
+                        url: url,
+                        param: switchUtils.data(switchContainer, "id"),
+                        success: function(data) {
+                            vm.load();
+                        }
+                    });
+                }
+            });
+        }
     });
 }
 

+ 27 - 6
src/main/resources/static/js/base/quartz/list.js

@@ -50,11 +50,11 @@ function getGrid() {
 			title : "状态",
 			width : "60px",
 			formatter : function(value, row, index) {
-				if (value == '0') {
-					return '<span class="label label-danger">禁用</span>';
-				} else if (value == '1') {
-					return '<span class="label label-success">正常</span>';
-				}
+                if(value === 0){
+                    return '<input type="checkbox" class="js-switch" data-id="'+row.jobId+'">';
+                }else if(value === 1){
+                    return '<input type="checkbox" class="js-switch" data-id="'+row.jobId+'" checked>';
+                }
 			}
 		}, {
 			field : "gmtCreate",
@@ -63,7 +63,28 @@ function getGrid() {
 		}, {
 			field : "remark",
 			title : "备注"
-		} ]
+		} ],
+        onPostBody: function() {
+            switchUtils.init({
+                selector: '.js-switch',
+                single: false,
+                change: function(switchContainer) {
+                    var ids = [switchUtils.data(switchContainer, "id")];
+                    var url = '../../quartz/job/disable?_' + $.now();
+                    if (switchUtils.checked(switchContainer)) {
+                        url = '../../quartz/job/enable?_' + $.now();
+                    }
+                    $.AjaxForm({
+                        url: url,
+                        param: ids,
+                        success: function(data) {
+                            vm.load();
+                        }
+                    });
+
+                }
+            });
+        }
 	})
 }
 

+ 9 - 27
src/main/resources/static/js/base/user/add.js

@@ -1,8 +1,9 @@
 /**
  * 新增-用户管理js
  */
-var doublebox = null;
-
+$(function(){
+    vm.getRoleList();
+})
 var vm = new Vue({
 	el:'#dpLTE',
 	data: {
@@ -16,19 +17,11 @@ var vm = new Vue({
 	},
 	methods : {
         getRoleList: function(){
-            $.get('../../sys/role/select?_' + $.now(), function(r){
-                vm.roleList = r.rows;
-                doublebox = $('.rolebox').doublebox({
-                    selectorMinimalHeight: 187,
-                    filterPlaceHolder: '关键字...',
-                    preserveSelectionOnMove: 'moved',
-                    moveOnSelect: false,
-                    nonSelectedList: vm.roleList,
-                    selectedList:null,
-                    optionValue:"roleId",
-                    optionText:"roleName",
-                    doubleMove:true
-                });
+            $('.roleSelect').selectBindEx({
+                url: '../../sys/role/select?_' + $.now(),
+                placeholder: '请选择角色',
+                value: 'roleId',
+                text: 'roleName'
             });
         },
 		orgTree: function() {
@@ -45,18 +38,10 @@ var vm = new Vue({
 		    })
 		},
 		acceptClick: function() {
-            var roles = doublebox.getSelectedOptions();
-            if(isNullOrEmpty(roles)) {
-                dialogMsg('请先选择角色!');
-                return false;
-            }
             if (!$('#form').Validform()) {
                 return false;
             }
-            vm.user.roleIdList = [];
-            $.each(roles.split(','), function(idx, item){
-                vm.user.roleIdList.push(parseInt(item));
-            });
+            vm.user.roleIdList = $('.roleSelect').val();
 		    $.SaveForm({
 		    	url: '../../sys/user/save?_' + $.now(),
 		    	param: vm.user,
@@ -65,8 +50,5 @@ var vm = new Vue({
 		    	}
 		    });
 		}
-	},
-	created : function() {
-		this.getRoleList();
 	}
 })

+ 7 - 51
src/main/resources/static/js/base/user/edit.js

@@ -1,14 +1,9 @@
 /**
  * 编辑-用户管理js
  */
-var doublebox = null;
-
 var vm = new Vue({
 	el:'#dpLTE',
 	data: {
-		roleList:{},
-        selectedList:[],
-        nonselectedList:[],
 		user:{
 			orgId: 0,
 			orgName: null,
@@ -18,16 +13,12 @@ var vm = new Vue({
 	},
 	methods : {
         getRoleList: function(){
-            $.ajax({
-                type: 'get',
-                async: false,
-                contentType : 'application/json',
+            $('.roleSelect').selectBindEx({
                 url: '../../sys/role/select?_' + $.now(),
-                data: null,
-                success: function(r) {
-                    vm.roleList = r.rows;
-                },
-                dataType: 'json'
+                placeholder: '请选择角色',
+                value: 'roleId',
+                text: 'roleName',
+                selected: vm.user.roleIdList
             });
         },
 		orgTree: function() {
@@ -44,55 +35,20 @@ var vm = new Vue({
 		    })
 		},
 		setForm: function() {
-            this.getRoleList();
 			$.SetForm({
 				url: '../../sys/user/infoUser?_' + $.now(),
 		    	param: vm.user.userId,
 		    	success: function(data) {
                     vm.user = data;
-                    for(var i=0; i<vm.roleList.length; i++){
-                        var exist = true;
-                        inner:
-                            for(var j=0; j<vm.user.roleIdList.length; j++){
-                                if(vm.roleList[i].roleId == vm.user.roleIdList[j]){
-                                    vm.selectedList.push(vm.roleList[i]);
-                                    exist = true;
-                                    break inner;
-                                }else{
-                                    exist = false;
-                                }
-                            }
-                        if (!exist){
-                            vm.nonselectedList.push(vm.roleList[i]);
-                        }
-                    }
-                    doublebox = $('.rolebox').doublebox({
-                        selectorMinimalHeight: 187,
-                        filterPlaceHolder: '关键字...',
-                        preserveSelectionOnMove: 'moved',
-                        moveOnSelect: false,
-                        nonSelectedList: vm.nonselectedList,
-                        selectedList:vm.selectedList,
-                        optionValue:"roleId",
-                        optionText:"roleName",
-                        doubleMove:true
-                    });
+                    vm.getRoleList();
 		    	}
 			});
 		},
 		acceptClick: function() {
-            var roles = doublebox.getSelectedOptions();
-            if(isNullOrEmpty(roles)) {
-                dialogMsg('请先选择角色!');
-                return false;
-            }
             if (!$('#form').Validform()) {
                 return false;
             }
-            vm.user.roleIdList = [];
-            $.each(roles.split(','), function(idx, item){
-                vm.user.roleIdList.push(parseInt(item));
-            });
+            vm.user.roleIdList = $('.roleSelect').val();
 		    $.ConfirmForm({
 		    	url: '../../sys/user/update?_' + $.now(),
 		    	param: vm.user,

+ 33 - 12
src/main/resources/static/js/base/user/list.js

@@ -49,13 +49,13 @@ function getGrid() {
 			field : "status",
 			title : "状态",
 			width : "60px",
-			formatter : function(value, row, index) {
-				if (value == '0') {
-					return '<span class="label label-danger">禁用</span>';
-				} else if (value == '1') {
-					return '<span class="label label-success">正常</span>';
-				}
-			}
+            formatter : function(value , row, index) {
+                if(value === 0){
+                    return '<input type="checkbox" class="js-switch" data-id="'+row.userId+'">';
+                }else if(value === 1){
+                    return '<input type="checkbox" class="js-switch" data-id="'+row.userId+'" checked>';
+                }
+            }
 		}, {
 			field : "gmtCreate",
 			title : "创建时间",
@@ -63,7 +63,28 @@ function getGrid() {
 		}, {
 			field : "remark",
 			title : "备注"
-		} ]
+		} ],
+        onPostBody: function() {
+            switchUtils.init({
+                selector: '.js-switch',
+                single: false,
+                change: function(switchContainer) {
+                    var ids = [switchUtils.data(switchContainer, "id")];
+                    var url = '../../sys/user/disable?_' + $.now();
+                    if (switchUtils.checked(switchContainer)) {
+                        url = '../../sys/user/enable?_' + $.now();
+                    }
+                    $.AjaxForm({
+                        url: url,
+                        param: ids,
+                        success: function(data) {
+                            vm.load();
+                        }
+                    });
+
+                }
+            });
+        }
 	})
 }
 
@@ -80,8 +101,8 @@ var vm = new Vue({
 			dialogOpen({
 				title : '新增用户',
 				url : 'base/user/add.html?_' + $.now(),
-                width : '620px',
-                height : '524px',
+                width : '500px',
+                height : '456px',
 				scroll : true,
 				yes : function(iframeId) {
 					top.frames[iframeId].vm.acceptClick();
@@ -94,8 +115,8 @@ var vm = new Vue({
 				dialogOpen({
 					title : '编辑用户',
 					url : 'base/user/edit.html?_' + $.now(),
-                    width : '620px',
-                    height : '524px',
+                    width : '500px',
+                    height : '456px',
 					scroll : true,
 					success : function(iframeId) {
 						top.frames[iframeId].vm.user.userId = ck[0].userId;

+ 171 - 1
src/main/resources/static/js/common.js

@@ -51,12 +51,13 @@ $.fn.bootstrapTableEx = function(opt){
 		method: 'post',
 		dataType: 'json',
 		selectItemName: 'id',
-		clickToSelect: true,
+		clickToSelect: false,
 		pagination: true,
 		smartDisplay: false,
 		pageSize: 10,
 		pageList: [10, 20, 30, 40, 50],
         paginationLoop: false,
+        paginationShowPageGo: true,
 		sidePagination: 'server',
 		queryParamsType : null,
 		columns: []
@@ -422,3 +423,172 @@ $.currentIframe = function () {
     }
     return $(window.parent.document).contents().find('#'+tabiframeId())[0].contentWindow;//多层tab页嵌套
 }
+
+/**
+ * 根据ajax地址初始化select2选择器
+ * @param opt
+ * @returns {*}
+ */
+$.fn.selectBindEx = function(opt) {
+    var $select = $(this);
+    var defaults = {
+        url: '',
+        async: true,
+        text: 'name',
+        value: 'id',
+        placeholder: '请选择...',
+        selected: '',
+        allowClear: false,
+        theme: "bootstrap",
+        language: "zh-CN",
+        change: function(){}
+    }
+    if (opt.search === false) {
+        opt.minimumResultsForSearch = 'Infinity';
+    }
+    var option = $.extend({}, defaults, opt);
+    var selectControl = null;
+    $.ajax({
+        type: 'get',
+        async: option.async,
+        contentType : 'application/json',
+        url: option.url,
+        data: null,
+        success: function(r) {
+            selectControl = $select.select2(option);
+            $.each(r, function(idx, item){
+                selectControl.append("<option value='"+item[option.value]+"'>"+item[option.text]+"</option>");
+            })
+            $select.val(option.selected);
+            $select.on('change', function() {
+                option.change($select.val());
+            });
+        },
+        dataType: 'json'
+    });
+    return selectControl;
+}
+
+/**
+ * 初始化select2选择器
+ * @param placeholder
+ * @returns {*|void}
+ */
+$.fn.selectInitEx = function(placeholder, search) {
+    var opt = {
+        placeholder: placeholder,
+        theme: "bootstrap",
+        language: "zh-CN"
+    }
+    if (search === false) {
+        opt.minimumResultsForSearch = 'Infinity';
+    }
+    return $(this).select2(opt);
+}
+
+/**
+ * 富文本编辑器工具类
+ * @type {{init: editor.init}}
+ */
+editorUtils = {
+    init: function(opt) {
+        var defaults = {
+            element: '#editor',
+            change: function(){}
+        };
+        var option = $.extend({}, defaults, opt);
+        var editor = new window.wangEditor(option.element);
+        editor.customConfig.uploadImgServer = '/editor/upload';
+        editor.customConfig.uploadImgHeaders = {
+            'token': token
+        }
+        editor.customConfig.onchange= function(html) {
+            option.change(html);
+        };
+        editor.customConfig.customAlert = function(info) {
+            dialogAlert(info, 'error');
+        };
+        editor.create();
+        return editor;
+    },
+    set: function($editor, content) {
+        $editor.txt.html(content);
+    },
+    get: function($editor) {
+        return $editor.txt.html();
+    },
+    text: function($editor) {
+        return $editor.txt.text();
+    },
+    append: function($editor, content) {
+        $editor.txt.append(content)
+    },
+    clear: function($editor) {
+        $editor.txt.clear()
+    },
+    hasContents: function ($editor) {
+        var content = this.get($editor);
+        return isNotNullOrEmpty(this.get($editor)) && "<p><br></p>" !== content;
+    }
+}
+
+/**
+ * switchery开关组件
+ * @type {{}}
+ * 选择器selector用于获取选择状态,开关instance用于设置状态,禁用,启用
+ */
+switchUtils = {
+    init: function(opt) {
+        var defaults = {
+            selector: '#editor',
+            size: 'small',
+            single: true,
+            change: function(){}
+        };
+        var option = $.extend({}, defaults, opt);
+        var switchContainer = [], switchResults = [];
+        if (option.single) {
+            switchContainer.push(document.querySelector(option.selector));
+        } else {
+            switchContainer = document.querySelectorAll(option.selector);
+        }
+        $.each(switchContainer, function(idx, item) {
+            var $switchery = new Switchery(item, option);
+            var $item = $(item);
+            var result = {selector: item, instance: $switchery};
+            $item.on('change', function(event) {
+                option.change(result);
+            });
+            switchResults.push(result);
+        });
+        if (option.single) {
+            return switchResults[0];
+        }
+        return switchResults;
+    },
+    set: function($switch, checked) {
+        $switch = $switch.instance;
+        if ((checked && !$switch.isChecked()) || (!checked && $switch.isChecked())) {
+            $switch.setPosition(true);
+            $switch.handleOnchange(true);
+        }
+    },
+    on: function($switch) {
+        this.set($switch, true);
+    },
+    off: function($switch) {
+        this.set($switch, false);
+    },
+    disable: function($switch) {
+        $switch.instance.disable();
+    },
+    enable: function($switch) {
+        $switch.instance.enable();
+    },
+    checked: function($switch) {
+        return $switch.selector.checked;
+    },
+    data: function($switch, key) {
+        return $($switch.selector).data(key);
+    }
+}

+ 42 - 0
src/main/resources/static/js/form.js

@@ -207,3 +207,45 @@ $.ConfirmAjax = function(options) {
 		}, 500);
 	});
 }
+
+$.AjaxForm = function(opt) {
+    var defaults = {
+        url : "",
+        param : {},
+        type : "post",
+        dataType : "json",
+        contentType : "application/json",
+        success : null,
+        close : true
+    };
+    var options = $.extend(defaults, opt);
+    dialogLoading(true);
+    window.setTimeout(function() {
+        var postdata = options.param;
+        $.ajax({
+            url : options.url,
+            data : JSON.stringify(postdata),
+            type : options.type,
+            dataType : options.dataType,
+            contentType : options.contentType,
+            success : function(data) {
+                if (data.code == '500') {
+                    dialogAlert(data.msg, 'error');
+                } else if (data.code == '0') {
+                    dialogMsg(data.msg, 'success');
+                    options.success(data);
+                }
+            },
+            error : function(XMLHttpRequest, textStatus, errorThrown) {
+                dialogLoading(false);
+                dialogMsg(errorThrown, 'error');
+            },
+            beforeSend : function() {
+                dialogLoading(true);
+            },
+            complete : function() {
+                dialogLoading(false);
+            }
+        });
+    }, 500);
+}

+ 54 - 0
src/main/resources/static/plugins/bootstrap-table/pagejump/bootstrap-table-pagejump.css

@@ -0,0 +1,54 @@
+.pagination-jump {
+  margin: 0;
+}
+
+.pagination-jump {
+  display: inline-block;
+  padding-left: 1px;
+  border-radius: 4px;
+}
+
+.pagination-jump>li {
+  display: inline;
+}
+
+.pagination-jump>li>a, .pagination-jump>li>input, .pagination-jump>li>span {
+  position: relative;
+  float: left;
+  margin-left: -1px;
+  line-height: 1.42857143;
+  text-decoration: none;
+  background-color: #fff;
+}
+
+.pagination-jump>li>a {
+  color: #475059;
+  padding: 6px 12px;
+  border: 1px solid #ddd;
+  border-left: 0;
+  border-top-right-radius: 4px;
+  border-bottom-right-radius: 4px;
+}
+
+.pagination-jump>li>a:hover {
+  color: #475059;
+}
+
+.pagination-jump>li>input {
+  padding: 6px 0px;
+  border: 1px solid #ddd;
+  border-top-left-radius: 4px;
+  border-bottom-left-radius: 4px;
+  width: 36px;
+  text-align: center;
+}
+
+.pagination-jump>li>span{
+  padding: 6px 3px 6px 12px;
+}
+
+
+.pagination-jump>li>.jump-go {
+  margin-left: 0;
+  padding: 6px;
+}

+ 50 - 0
src/main/resources/static/plugins/bootstrap-table/pagejump/bootstrap-table-pagejump.js

@@ -0,0 +1,50 @@
+(function ($) {
+    'use strict';
+    $.extend($.fn.bootstrapTable.defaults, {
+        // 默认不显示
+        paginationShowPageGo: false
+    });
+
+    $.extend($.fn.bootstrapTable.locales, {
+        pageGo: function () {
+            return '跳转到';
+        }
+    });
+    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales);
+
+    var BootstrapTable = $.fn.bootstrapTable.Constructor,
+        _initPagination = BootstrapTable.prototype.initPagination;
+
+    BootstrapTable.prototype.initPagination = function() {
+        _initPagination.apply(this, Array.prototype.slice.apply(arguments));
+        if(this.options.paginationShowPageGo){
+            var $paginationContainer = this.$pagination;
+            var html = [];
+
+            html.push(
+                '<ul class="pagination-jump">',
+                '<li class=""><span>' + this.options.pageGo() + '</span></li>',
+                '<li class=""><input type="text" class="page-input form-control" value="' + this.options.pageNumber + '"   /></li>',
+                '<li class="page-go"><a class="jump-go" href="javascript:;">确定</a></li>',
+                '</ul>');
+            $paginationContainer.find('ul.pagination').after(html.join(''));
+
+            $paginationContainer.find('.page-go').off('click').on('click', $.proxy(this.onPageGo, this));
+            $paginationContainer.find('.page-input').off('keyup').on('keyup', function(event){
+                this.value = this.value.length == 1 ? this.value.replace(/[^1-9]/g,'') : this.value.replace(/\D/g,'');
+                if (event.which == 13) {
+                    $paginationContainer.find('.page-go').trigger('click');
+                }
+            });
+        }
+    };
+
+    BootstrapTable.prototype.onPageGo = function (event) {
+        var $toPage=this.$pagination.find('.page-input');
+        if (this.options.pageNumber === +$toPage.val()) {
+            return false;
+        }
+        this.selectPage(+$toPage.val());
+        return false;
+    };
+})(jQuery);

File diff suppressed because it is too large
+ 0 - 0
src/main/resources/static/plugins/double-box/doublebox-bootstrap.css


+ 0 - 681
src/main/resources/static/plugins/double-box/doublebox-bootstrap.js

@@ -1,681 +0,0 @@
-(function ($, window, document, undefined) {
-    var pluginName = "bootstrapDualListbox", defaults = {
-        bootstrap2Compatible: false,
-        filterTextClear: "show all",
-        filterPlaceHolder: "Filter",
-        moveSelectedLabel: "Move selected",
-        moveAllLabel: "Move all",
-        removeSelectedLabel: "Remove selected",
-        removeAllLabel: "Remove all",
-        moveOnSelect: true,
-        preserveSelectionOnMove: false,
-        selectedListLabel: false,
-        nonSelectedListLabel: false,
-        helperSelectNamePostfix: "_helper",
-        selectorMinimalHeight: 100,
-        showFilterInputs: true,
-        nonSelectedFilter: "",
-        selectedFilter: "",
-        filterOnValues: false,
-        doubleMove: false
-    }, isBuggyAndroid = /android/i.test(navigator.userAgent.toLowerCase());
-
-    function BootstrapDualListbox(element, options) {
-        this.element = $(element);
-        this.settings = $.extend({}, defaults, options);
-        this._defaults = defaults;
-        this._name = pluginName;
-        this.init()
-    }
-
-    function triggerChangeEvent(dualListbox) {
-        dualListbox.element.trigger("change")
-    }
-
-    function updateSelectionStates(dualListbox) {
-        dualListbox.element.find("option").each(function (index, item) {
-            var $item = $(item);
-            if (typeof($item.data("original-index")) === "undefined") {
-                $item.data("original-index", dualListbox.elementCount++)
-            }
-            if (typeof($item.data("_selected")) === "undefined") {
-                $item.data("_selected", false)
-            }
-        })
-    }
-
-    function changeSelectionState(dualListbox, original_index, selected) {
-        dualListbox.element.find("option").each(function (index, item) {
-            var $item = $(item);
-            if ($item.data("original-index") === original_index) {
-                $item.prop("selected", selected)
-            }
-        })
-    }
-
-    function formatString(s, args) {
-        return s.replace(/\{(\d+)\}/g, function (match, number) {
-            return typeof args[number] !== "undefined" ? args[number] : match
-        })
-    }
-
-    function refreshInfo(dualListbox) {
-        if (!dualListbox.settings.infoText) {
-            return
-        }
-        var visible1 = dualListbox.elements.select1.find("option").length,
-            visible2 = dualListbox.elements.select2.find("option").length,
-            all1 = dualListbox.element.find("option").length - dualListbox.selectedElements,
-            all2 = dualListbox.selectedElements, content = "";
-        if (all1 === 0) {
-            content = dualListbox.settings.infoTextEmpty
-        } else {
-            if (visible1 === all1) {
-                content = formatString(dualListbox.settings.infoText, [visible1, all1])
-            } else {
-                content = formatString(dualListbox.settings.infoTextFiltered, [visible1, all1])
-            }
-        }
-        dualListbox.elements.info1.html(content);
-        dualListbox.elements.box1.toggleClass("filtered", !(visible1 === all1 || all1 === 0));
-        if (all2 === 0) {
-            content = dualListbox.settings.infoTextEmpty
-        } else {
-            if (visible2 === all2) {
-                content = formatString(dualListbox.settings.infoText, [visible2, all2])
-            } else {
-                content = formatString(dualListbox.settings.infoTextFiltered, [visible2, all2])
-            }
-        }
-        dualListbox.elements.info2.html(content);
-        dualListbox.elements.box2.toggleClass("filtered", !(visible2 === all2 || all2 === 0))
-    }
-
-    function refreshSelects(dualListbox) {
-        dualListbox.selectedElements = 0;
-        dualListbox.elements.select1.empty();
-        dualListbox.elements.select2.empty();
-        dualListbox.element.find("option").each(function (index, item) {
-            var $item = $(item);
-            if ($item.prop("selected")) {
-                dualListbox.selectedElements++;
-                dualListbox.elements.select2.append($item.clone(true).prop("selected", $item.data("_selected")))
-            } else {
-                dualListbox.elements.select1.append($item.clone(true).prop("selected", $item.data("_selected")))
-            }
-        });
-        if (dualListbox.settings.showFilterInputs) {
-            filter(dualListbox, 1);
-            filter(dualListbox, 2)
-        }
-        refreshInfo(dualListbox)
-    }
-
-    function filter(dualListbox, selectIndex) {
-        if (!dualListbox.settings.showFilterInputs) {
-            return
-        }
-        saveSelections(dualListbox, selectIndex);
-        dualListbox.elements["select" + selectIndex].empty().scrollTop(0);
-        var regex = new RegExp($.trim(dualListbox.elements["filterInput" + selectIndex].val()), "gi"),
-            options = dualListbox.element;
-        if (selectIndex === 1) {
-            options = options.find("option").not(":selected")
-        } else {
-            options = options.find("option:selected")
-        }
-        options.each(function (index, item) {
-            var $item = $(item), isFiltered = true;
-            if (item.text.match(regex) || (dualListbox.settings.filterOnValues && $item.attr("value").match(regex))) {
-                isFiltered = false;
-                dualListbox.elements["select" + selectIndex].append($item.clone(true).prop("selected", $item.data("_selected")))
-            }
-            dualListbox.element.find("option").eq($item.data("original-index")).data("filtered" + selectIndex, isFiltered)
-        });
-        refreshInfo(dualListbox)
-    }
-
-    function saveSelections(dualListbox, selectIndex) {
-        dualListbox.elements["select" + selectIndex].find("option").each(function (index, item) {
-            var $item = $(item);
-            dualListbox.element.find("option").eq($item.data("original-index")).data("_selected", $item.prop("selected"))
-        })
-    }
-
-    function sortOptions(select) {
-        select.find("option").sort(function (a, b) {
-            return ($(a).data("original-index") > $(b).data("original-index")) ? 1 : -1
-        }).appendTo(select)
-    }
-
-    function clearSelections(dualListbox) {
-        dualListbox.elements.select1.find("option").each(function () {
-            dualListbox.element.find("option").data("_selected", false)
-        })
-    }
-
-    function move(dualListbox) {
-        if (dualListbox.settings.preserveSelectionOnMove === "all" && !dualListbox.settings.moveOnSelect) {
-            saveSelections(dualListbox, 1);
-            saveSelections(dualListbox, 2)
-        } else {
-            if (dualListbox.settings.preserveSelectionOnMove === "moved" && !dualListbox.settings.moveOnSelect) {
-                saveSelections(dualListbox, 1)
-            }
-        }
-        dualListbox.elements.select1.find("option:selected").each(function (index, item) {
-            var $item = $(item);
-            if (!$item.data("filtered1")) {
-                changeSelectionState(dualListbox, $item.data("original-index"), true)
-            }
-        });
-        refreshSelects(dualListbox);
-        triggerChangeEvent(dualListbox);
-        sortOptions(dualListbox.elements.select2)
-    }
-
-    function remove(dualListbox) {
-        if (dualListbox.settings.preserveSelectionOnMove === "all" && !dualListbox.settings.moveOnSelect) {
-            saveSelections(dualListbox, 1);
-            saveSelections(dualListbox, 2)
-        } else {
-            if (dualListbox.settings.preserveSelectionOnMove === "moved" && !dualListbox.settings.moveOnSelect) {
-                saveSelections(dualListbox, 2)
-            }
-        }
-        dualListbox.elements.select2.find("option:selected").each(function (index, item) {
-            var $item = $(item);
-            if (!$item.data("filtered2")) {
-                changeSelectionState(dualListbox, $item.data("original-index"), false)
-            }
-        });
-        refreshSelects(dualListbox);
-        triggerChangeEvent(dualListbox);
-        sortOptions(dualListbox.elements.select1)
-    }
-
-    function moveAll(dualListbox) {
-        if (dualListbox.settings.preserveSelectionOnMove === "all" && !dualListbox.settings.moveOnSelect) {
-            saveSelections(dualListbox, 1);
-            saveSelections(dualListbox, 2)
-        } else {
-            if (dualListbox.settings.preserveSelectionOnMove === "moved" && !dualListbox.settings.moveOnSelect) {
-                saveSelections(dualListbox, 1)
-            }
-        }
-        dualListbox.element.find("option").each(function (index, item) {
-            var $item = $(item);
-            if (!$item.data("filtered1")) {
-                $item.prop("selected", true)
-            }
-        });
-        refreshSelects(dualListbox);
-        triggerChangeEvent(dualListbox)
-    }
-
-    function removeAll(dualListbox) {
-        if (dualListbox.settings.preserveSelectionOnMove === "all" && !dualListbox.settings.moveOnSelect) {
-            saveSelections(dualListbox, 1);
-            saveSelections(dualListbox, 2)
-        } else {
-            if (dualListbox.settings.preserveSelectionOnMove === "moved" && !dualListbox.settings.moveOnSelect) {
-                saveSelections(dualListbox, 2)
-            }
-        }
-        dualListbox.element.find("option").each(function (index, item) {
-            var $item = $(item);
-            if (!$item.data("filtered2")) {
-                $item.prop("selected", false)
-            }
-        });
-        refreshSelects(dualListbox);
-        triggerChangeEvent(dualListbox)
-    }
-
-    function upSort(dualListbox) {
-        dualListbox.elements.select2.find("option:selected").each(function (index, item) {
-            var $item = $(item);
-            var $target = $item.prev();
-            $item.insertBefore($target)
-        })
-    }
-
-    function downSort(dualListbox) {
-        dualListbox.elements.select2.find("option:selected").each(function (index, item) {
-            var $item = $(item);
-            var $target = $item.next();
-            $item.insertAfter($target)
-        })
-    }
-
-    function bindEvents(dualListbox) {
-        dualListbox.elements.form.submit(function (e) {
-            if (dualListbox.elements.filterInput1.is(":focus")) {
-                e.preventDefault();
-                dualListbox.elements.filterInput1.focusout()
-            } else {
-                if (dualListbox.elements.filterInput2.is(":focus")) {
-                    e.preventDefault();
-                    dualListbox.elements.filterInput2.focusout()
-                }
-            }
-        });
-        dualListbox.element.on("bootstrapDualListbox.refresh", function (e, mustClearSelections) {
-            dualListbox.refresh(mustClearSelections)
-        });
-        dualListbox.elements.filterClear1.on("click", function () {
-            dualListbox.setNonSelectedFilter("", true)
-        });
-        dualListbox.elements.filterClear2.on("click", function () {
-            dualListbox.setSelectedFilter("", true)
-        });
-        dualListbox.elements.moveButton.on("click", function () {
-            move(dualListbox)
-        });
-        dualListbox.elements.moveAllButton.on("click", function () {
-            moveAll(dualListbox)
-        });
-        dualListbox.elements.removeButton.on("click", function () {
-            remove(dualListbox)
-        });
-        dualListbox.elements.removeAllButton.on("click", function () {
-            removeAll(dualListbox)
-        });
-        dualListbox.elements.upButton.on("click", function () {
-            upSort(dualListbox)
-        });
-        dualListbox.elements.downButton.on("click", function () {
-            downSort(dualListbox)
-        });
-        dualListbox.elements.filterInput1.on("change keyup", function () {
-            filter(dualListbox, 1)
-        });
-        dualListbox.elements.filterInput2.on("change keyup", function () {
-            filter(dualListbox, 2)
-        });
-        dualListbox.elements.filterInput2.on("change keyup", function () {
-            filter(dualListbox, 2)
-        })
-    }
-
-    BootstrapDualListbox.prototype = {
-        init: function () {
-            this.container = $("" + '<div class="bootstrap-duallistbox-container">' + ' <div class="box1">' + "   <label></label>" + '   <span class="info-container">' + '     <span class="info"></span>' + '     <button type="button" class="btn clear1 pull-right"></button>' + "   </span>" + '   <input class="filter form-control ue-form" type="text">' + '   <select multiple="multiple"></select>' + " </div>" + ' <div class="btn-box">' + '     <button type="button" class="btn db-btn move">' + "       <i></i>" + "     </button>" + '     <button type="button" class="btn db-btn moveall">' + "       <i></i>" + "       <i></i>" + "     </button>" + '     <p class="clearfix" style="margin-bottom:20px"></p>' + '     <button type="button" class="btn db-btn remove">' + "       <i></i>" + "     </button>" + '     <button type="button" class="btn db-btn removeall">' + "       <i></i>" + "       <i></i>" + "     </button>" + " </div>" + ' <div class="box2">' + "   <label></label>" + '   <span class="info-container">' + '     <span class="info"></span>' + '     <button type="button" class="btn clear2 pull-right"></button>' + "   </span>" + '   <input class="filter form-control ue-form" type="text">' + '   <select multiple="multiple"></select>' + " </div>" + ' <div class="settingUp-btns">' + '    <button class="btn db-btn upBtn">' + "      <i></i>" + "    </button>" + '    <button class="btn db-btn downBtn">' + "      <i></i>" + "    </button>" + " </div>" + "</div>").insertBefore(this.element);
-            this.elements = {
-                originalSelect: this.element,
-                box1: $(".box1", this.container),
-                box2: $(".box2", this.container),
-                filterInput1: $(".box1 .filter", this.container),
-                filterInput2: $(".box2 .filter", this.container),
-                filterClear1: $(".box1 .clear1", this.container),
-                filterClear2: $(".box2 .clear2", this.container),
-                label1: $(".box1 > label", this.container),
-                label2: $(".box2 > label", this.container),
-                info1: $(".box1 .info", this.container),
-                info2: $(".box2 .info", this.container),
-                select1: $(".box1 select", this.container),
-                select2: $(".box2 select", this.container),
-                moveButton: $(".btn-box .move", this.container),
-                removeButton: $(".btn-box .remove", this.container),
-                moveAllButton: $(".btn-box .moveall", this.container),
-                removeAllButton: $(".btn-box .removeall", this.container),
-                upButton: $(".settingUp-btns .upBtn", this.container),
-                downButton: $(".settingUp-btns .downBtn", this.container),
-                form: $($(".box1 .filter", this.container)[0].form)
-            };
-            this.originalSelectName = this.element.attr("name") || "";
-            var select1Id = "bootstrap-duallistbox-nonselected-list_" + this.originalSelectName,
-                select2Id = "bootstrap-duallistbox-selected-list_" + this.originalSelectName;
-            this.elements.select1.attr("id", select1Id);
-            this.elements.select2.attr("id", select2Id);
-            this.elements.label1.attr("for", select1Id);
-            this.elements.label2.attr("for", select2Id);
-            this.selectedElements = 0;
-            this.elementCount = 0;
-            this.setBootstrap2Compatible(this.settings.bootstrap2Compatible);
-            this.setFilterTextClear(this.settings.filterTextClear);
-            this.setFilterPlaceHolder(this.settings.filterPlaceHolder);
-            this.setMoveSelectedLabel(this.settings.moveSelectedLabel);
-            this.setMoveAllLabel(this.settings.moveAllLabel);
-            this.setRemoveSelectedLabel(this.settings.removeSelectedLabel);
-            this.setRemoveAllLabel(this.settings.removeAllLabel);
-            this.setMoveOnSelect(this.settings.moveOnSelect);
-            this.setPreserveSelectionOnMove(this.settings.preserveSelectionOnMove);
-            this.setSelectedListLabel(this.settings.selectedListLabel);
-            this.setNonSelectedListLabel(this.settings.nonSelectedListLabel);
-            this.setHelperSelectNamePostfix(this.settings.helperSelectNamePostfix);
-            this.setSelectOrMinimalHeight(this.settings.selectorMinimalHeight);
-            this.setDoubleMove(this.settings.doubleMove);
-            updateSelectionStates(this);
-            this.setShowFilterInputs(this.settings.showFilterInputs);
-            this.setNonSelectedFilter(this.settings.nonSelectedFilter);
-            this.setSelectedFilter(this.settings.selectedFilter);
-            this.setInfoText(this.settings.infoText);
-            this.setInfoTextFiltered(this.settings.infoTextFiltered);
-            this.setInfoTextEmpty(this.settings.infoTextEmpty);
-            this.setFilterOnValues(this.settings.filterOnValues);
-            this.element.hide();
-            bindEvents(this);
-            refreshSelects(this);
-            return this.element
-        }, setBootstrap2Compatible: function (value, refresh) {
-            this.settings.bootstrap2Compatible = value;
-            if (value) {
-                this.container.removeClass("row").addClass("row-fluid bs2compatible");
-                this.container.find(".box1, .box2").removeClass("col-md-5");
-                this.container.find(".btn-box").removeClass("col-md-1");
-                this.container.find(".clear1, .clear2").removeClass("btn-default btn-xs").addClass("btn-mini");
-                this.container.find("input, select").removeClass("form-control");
-                this.container.find(".btn").removeClass("btn-default");
-                this.container.find(".moveall > i, .move > i").removeClass("glyphicon glyphicon-arrow-right").addClass("icon-arrow-right");
-                this.container.find(".removeall > i, .remove > i").removeClass("glyphicon glyphicon-arrow-left").addClass("icon-arrow-left");
-                this.container.find(".upBtn > i").removeClass("glyphicon glyphicon-arrow-up").addClass("icon-arrow-up");
-                this.container.find(".downBtn > i").removeClass("glyphicon glyphicon-arrow-down").addClass("icon-arrow-down")
-            } else {
-                this.container.removeClass("row-fluid bs2compatible").addClass("row");
-                this.container.find(".box1, .box2").addClass("col-md-5");
-                this.container.find(".btn-box").addClass("col-md-1");
-                this.container.find(".clear1, .clear2").removeClass("btn-mini").addClass("btn-default btn-xs");
-                this.container.find("input, select").addClass("form-control");
-                this.container.find(".btn").addClass("btn-default");
-                this.container.find(".moveall > i, .move > i").removeClass("icon-arrow-right").addClass("glyphicon glyphicon-arrow-right");
-                this.container.find(".removeall > i, .remove > i").removeClass("icon-arrow-left").addClass("glyphicon glyphicon-arrow-left");
-                this.container.find(".upBtn > i").removeClass("icon-arrow-up").addClass("glyphicon glyphicon-arrow-up");
-                this.container.find(".downBtn > i").removeClass("icon-arrow-down").addClass("glyphicon glyphicon-arrow-down")
-            }
-            if (refresh) {
-                refreshSelects(this)
-            }
-            return this.element
-        }, setFilterTextClear: function (value, refresh) {
-            this.settings.filterTextClear = value;
-            this.elements.filterClear1.html(value);
-            this.elements.filterClear2.html(value);
-            if (refresh) {
-                refreshSelects(this)
-            }
-            return this.element
-        }, setFilterPlaceHolder: function (value, refresh) {
-            this.settings.filterPlaceHolder = value;
-            this.elements.filterInput1.attr("placeholder", value);
-            this.elements.filterInput2.attr("placeholder", value);
-            if (refresh) {
-                refreshSelects(this)
-            }
-            return this.element
-        }, setMoveSelectedLabel: function (value, refresh) {
-            this.settings.moveSelectedLabel = value;
-            this.elements.moveButton.attr("title", value);
-            if (refresh) {
-                refreshSelects(this)
-            }
-            return this.element
-        }, setMoveAllLabel: function (value, refresh) {
-            this.settings.moveAllLabel = value;
-            this.elements.moveAllButton.attr("title", value);
-            if (refresh) {
-                refreshSelects(this)
-            }
-            return this.element
-        }, setRemoveSelectedLabel: function (value, refresh) {
-            this.settings.removeSelectedLabel = value;
-            this.elements.removeButton.attr("title", value);
-            if (refresh) {
-                refreshSelects(this)
-            }
-            return this.element
-        }, setRemoveAllLabel: function (value, refresh) {
-            this.settings.removeAllLabel = value;
-            this.elements.removeAllButton.attr("title", value);
-            if (refresh) {
-                refreshSelects(this)
-            }
-            return this.element
-        }, setMoveOnSelect: function (value, refresh) {
-            if (isBuggyAndroid) {
-                value = true
-            }
-            this.settings.moveOnSelect = value;
-            if (this.settings.moveOnSelect) {
-                this.container.addClass("moveonselect");
-                var self = this;
-                this.elements.select1.on("change", function () {
-                    move(self)
-                });
-                this.elements.select2.on("change", function () {
-                    remove(self)
-                })
-            } else {
-                this.container.removeClass("moveonselect");
-                this.elements.select1.off("change");
-                this.elements.select2.off("change")
-            }
-            if (refresh) {
-                refreshSelects(this)
-            }
-            return this.element
-        }, setDoubleMove: function (value, refresh) {
-            if (isBuggyAndroid) {
-                value = false
-            }
-            this.settings.doubleMove = value;
-            if (this.settings.doubleMove) {
-                var self = this;
-                this.elements.select1.on("dblclick", function () {
-                    move(self)
-                });
-                this.elements.select2.on("dblclick", function () {
-                    remove(self)
-                })
-            } else {
-                this.elements.select1.off("dblclick");
-                this.elements.select2.off("dblclick")
-            }
-            if (refresh) {
-                refreshSelects(this)
-            }
-            return this.element
-        }, setPreserveSelectionOnMove: function (value, refresh) {
-            if (isBuggyAndroid) {
-                value = false
-            }
-            this.settings.preserveSelectionOnMove = value;
-            if (refresh) {
-                refreshSelects(this)
-            }
-            return this.element
-        }, setSelectedListLabel: function (value, refresh) {
-            this.settings.selectedListLabel = value;
-            if (value) {
-                this.elements.label2.show().html(value)
-            } else {
-                this.elements.label2.hide().html(value)
-            }
-            if (refresh) {
-                refreshSelects(this)
-            }
-            return this.element
-        }, setNonSelectedListLabel: function (value, refresh) {
-            this.settings.nonSelectedListLabel = value;
-            if (value) {
-                this.elements.label1.show().html(value)
-            } else {
-                this.elements.label1.hide().html(value)
-            }
-            if (refresh) {
-                refreshSelects(this)
-            }
-            return this.element
-        }, setHelperSelectNamePostfix: function (value, refresh) {
-            this.settings.helperSelectNamePostfix = value;
-            if (value) {
-                this.elements.select1.attr("name", this.originalSelectName + value + "1");
-                this.elements.select2.attr("name", this.originalSelectName + value + "2")
-            } else {
-                this.elements.select1.removeAttr("name");
-                this.elements.select2.removeAttr("name")
-            }
-            if (refresh) {
-                refreshSelects(this)
-            }
-            return this.element
-        }, setSelectOrMinimalHeight: function (value, refresh) {
-            this.settings.selectorMinimalHeight = value;
-            var height = this.element.height();
-            if (this.element.height() < value) {
-                height = value
-            }
-            this.elements.select1.height(height);
-            this.elements.select2.height(height);
-            if (refresh) {
-                refreshSelects(this)
-            }
-            return this.element
-        }, setShowFilterInputs: function (value, refresh) {
-            if (!value) {
-                this.setNonSelectedFilter("");
-                this.setSelectedFilter("");
-                refreshSelects(this);
-                this.elements.filterInput1.hide();
-                this.elements.filterInput2.hide()
-            } else {
-                this.elements.filterInput1.show();
-                this.elements.filterInput2.show()
-            }
-            this.settings.showFilterInputs = value;
-            if (refresh) {
-                refreshSelects(this)
-            }
-            return this.element
-        }, setNonSelectedFilter: function (value, refresh) {
-            if (this.settings.showFilterInputs) {
-                this.settings.nonSelectedFilter = value;
-                this.elements.filterInput1.val(value);
-                if (refresh) {
-                    refreshSelects(this)
-                }
-                return this.element
-            }
-        }, setSelectedFilter: function (value, refresh) {
-            if (this.settings.showFilterInputs) {
-                this.settings.selectedFilter = value;
-                this.elements.filterInput2.val(value);
-                if (refresh) {
-                    refreshSelects(this)
-                }
-                return this.element
-            }
-        }, setInfoText: function (value, refresh) {
-            this.settings.infoText = value;
-            if (refresh) {
-                refreshSelects(this)
-            }
-            return this.element
-        }, setInfoTextFiltered: function (value, refresh) {
-            this.settings.infoTextFiltered = value;
-            if (refresh) {
-                refreshSelects(this)
-            }
-            return this.element
-        }, setInfoTextEmpty: function (value, refresh) {
-            this.settings.infoTextEmpty = value;
-            if (refresh) {
-                refreshSelects(this)
-            }
-            return this.element
-        }, setFilterOnValues: function (value, refresh) {
-            this.settings.filterOnValues = value;
-            if (refresh) {
-                refreshSelects(this)
-            }
-            return this.element
-        }, getContainer: function () {
-            return this.container
-        }, refresh: function (mustClearSelections) {
-            updateSelectionStates(this);
-            if (!mustClearSelections) {
-                saveSelections(this, 1);
-                saveSelections(this, 2)
-            } else {
-                clearSelections(this)
-            }
-            refreshSelects(this)
-        }, destroy: function () {
-            this.container.remove();
-            this.element.show();
-            $.data(this, "plugin_" + pluginName, null);
-            return this.element
-        }
-    };
-    $.fn[pluginName] = function (options) {
-        var args = arguments;
-        if (options === undefined || typeof options === "object") {
-            return this.each(function () {
-                if (!$(this).is("select")) {
-                    $(this).find("select").each(function (index, item) {
-                        $(item).bootstrapDualListbox(options)
-                    })
-                } else {
-                    if (!$.data(this, "plugin_" + pluginName)) {
-                        $.data(this, "plugin_" + pluginName, new BootstrapDualListbox(this, options))
-                    }
-                }
-            })
-        } else {
-            if (typeof options === "string" && options[0] !== "_" && options !== "init") {
-                var returns;
-                this.each(function () {
-                    var instance = $.data(this, "plugin_" + pluginName);
-                    if (instance instanceof BootstrapDualListbox && typeof instance[options] === "function") {
-                        returns = instance[options].apply(instance, Array.prototype.slice.call(args, 1))
-                    }
-                });
-                return returns !== undefined ? returns : this
-            }
-        }
-    }
-})(jQuery, window, document);
-(function (root, factory) {
-    if (typeof exports === "object") {
-        module.exports = factory(root, require("jquery"))
-    } else {
-        if (typeof define === "function" && define.amd) {
-            define(["jquery"], function (jQuery) {
-                return factory(root, jQuery)
-            })
-        } else {
-            factory(root, root.jQuery)
-        }
-    }
-}(this, function (window, $, undefined) {
-    $.fn.doublebox = function (options) {
-        var box = this.bootstrapDualListbox(options);
-        var items = "";
-        box.selectElement = function () {
-            if (options.nonSelectedList != null) {
-                for (var i in options.nonSelectedList) {
-                    if (options.nonSelectedList.hasOwnProperty(i)) {
-                        items += "<option value='" + options.nonSelectedList[i][options.optionValue] + "'>" + options.nonSelectedList[i][options.optionText] + "</option>"
-                    }
-                }
-            }
-            if (options.selectedList != null) {
-                for (var i in options.selectedList) {
-                    if (options.selectedList.hasOwnProperty(i)) {
-                        items += "<option value='" + options.selectedList[i][options.optionValue] + "' selected>" + options.selectedList[i][options.optionText] + "</option>"
-                    }
-                }
-            }
-            box.append(items);
-            box.bootstrapDualListbox("refresh")
-        };
-        box.getSelectedOptions = function () {
-            var items = $("#bootstrap-duallistbox-selected-list_doublebox>option").map(function () {
-                return $(this).val()
-            }).get().join(",");
-            return items
-        };
-        box.selectElement();
-        return box
-    }
-}));

File diff suppressed because it is too large
+ 0 - 0
src/main/resources/static/plugins/editor/editor.min.css


File diff suppressed because it is too large
+ 0 - 0
src/main/resources/static/plugins/editor/editor.min.js


+ 1 - 0
src/main/resources/static/plugins/select2/i18n/zh-CN.min.js

@@ -0,0 +1 @@
+(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/zh-CN",[],function(){return{errorLoading:function(){return"无法载入结果。"},inputTooLong:function(e){var t=e.input.length-e.maximum,n="请删除"+t+"个字符";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="请再输入至少"+t+"个字符";return n},loadingMore:function(){return"载入更多结果…"},maximumSelected:function(e){var t="最多只能选择"+e.maximum+"个项目";return t},noResults:function(){return"未找到结果"},searching:function(){return"搜索中…"}}}),{define:e.define,require:e.require}})();

File diff suppressed because it is too large
+ 0 - 0
src/main/resources/static/plugins/select2/select2.min.css


File diff suppressed because it is too large
+ 0 - 0
src/main/resources/static/plugins/select2/select2.min.js


+ 1 - 0
src/main/resources/static/plugins/switchery/switchery.min.css

@@ -0,0 +1 @@
+.switchery{background-color:#fff;border:1px solid #dfdfdf;border-radius:20px;cursor:pointer;display:inline-block;height:30px;position:relative;vertical-align:middle;width:50px;-moz-user-select:none;-khtml-user-select:none;-webkit-user-select:none;-ms-user-select:none;user-select:none;box-sizing:content-box;background-clip:content-box}.switchery>small{background:#fff;border-radius:100%;box-shadow:0 1px 3px rgba(0,0,0,0.4);height:30px;position:absolute;top:0;width:30px}.switchery-small{border-radius:20px;height:20px;width:33px}.switchery-small>small{height:20px;width:20px}.switchery-large{border-radius:40px;height:40px;width:66px}.switchery-large>small{height:40px;width:40px}

File diff suppressed because it is too large
+ 0 - 0
src/main/resources/static/plugins/switchery/switchery.min.js


+ 91 - 0
src/main/resources/templates/base/component/editor.html

@@ -0,0 +1,91 @@
+<!DOCTYPE html>
+<html xmlns:th="http://www.thymeleaf.org">
+<head th:include="include/header_css :: header('富文本编辑器')"></head>
+<body>
+<div id="dpLTE" class="container-fluid" v-cloak>
+    <div class="panel panel-default" style="padding-bottom: 10px;margin-top:10px;">
+        <div class="panel-heading">wangEditor示例</div>
+        <div>
+            <h3>&nbsp;&nbsp;&nbsp;官方文档</h3>
+            <div class="row">
+                <div class="col-md-12">
+                    <a href="https://www.kancloud.cn/wangfupeng/wangeditor3/332599" target="_blank">https://www.kancloud.cn/wangfupeng/wangeditor3/332599</a>
+                </div>
+            </div>
+            <h3>&nbsp;&nbsp;&nbsp;基础示例</h3>
+            <div class="row">
+                <div class="col-md-12" id="editor"></div>
+            </div>
+            <div class="row">
+                <div class="col-md-1">
+                    <h3>富文本</h3>
+                </div>
+                <div class="col-md-5">
+                    <textarea v-model="htmlResult" rows="8" class="form-control"></textarea>
+                </div>
+                <div class="col-md-1">
+                    <h3>纯文本</h3>
+                </div>
+                <div class="col-md-5">
+                    <textarea v-model="textResult" rows="8" class="form-control"></textarea>
+                </div>
+            </div>
+            <div class="row">
+                <div class="col-md-12">
+                    <div class="btn-group">
+                        <a class="btn btn-default" @click="setContent">设置内容</a>
+                        <a class="btn btn-default" @click="getContent">获取内容</a>
+                        <a class="btn btn-default" @click="appendContent">追加内容</a>
+                        <a class="btn btn-default" @click="getText">获取纯文本</a>
+                        <a class="btn btn-default" @click="clearContent">清空内容</a>
+                        <a class="btn btn-default" @click="checkEmpty">校验是否为空</a>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>
+<div th:include="include/footer_js :: footer"></div>
+</body>
+<script type="text/javascript">
+    var vm = new Vue({
+        el : '#dpLTE',
+        data: {
+            htmlResult: '',
+            textResult: ''
+        },
+        methods: {
+            setContent: function() {
+                editorUtils.set(editor, '<p>用js设置的内容</p>');
+            },
+            getContent: function() {
+                this.htmlResult = editorUtils.get(editor);
+            },
+            appendContent: function() {
+                editorUtils.append(editor, '<p>用js追加的内容</p>');
+            },
+            getText: function() {
+                this.textResult = editorUtils.text(editor);
+            },
+            clearContent: function() {
+                editorUtils.clear(editor);
+            },
+            checkEmpty: function() {
+                if(editorUtils.hasContents(editor)) {
+                    dialogToastr('内容不为空');
+                } else {
+                    dialogToastr('内容为空');
+                }
+            }
+        }
+    });
+
+    var editor = editorUtils.init({
+        change: function(html) {
+            vm.getContent();
+            vm.getText();
+        }
+    });
+
+</script>
+</html>

+ 215 - 0
src/main/resources/templates/base/component/select2.html

@@ -0,0 +1,215 @@
+<!DOCTYPE html>
+<html xmlns:th="http://www.thymeleaf.org">
+<head th:include="include/header_css :: header('select2组件')"></head>
+<body>
+<div id="dpLTE" class="container-fluid" v-cloak>
+    <div class="panel panel-default" style="padding-bottom: 10px;margin-top:10px;">
+        <div class="panel-heading">select2示例</div>
+        <div>
+            <h3>&nbsp;&nbsp;&nbsp;官方文档</h3>
+            <div class="row">
+                <div class="col-md-12">
+                    <a href="https://github.com/select2/select2" target="_blank">https://github.com/select2/select2</a>
+                </div>
+            </div>
+            <h3>&nbsp;&nbsp;&nbsp;系统参数选择</h3>
+            <div class="row">
+                <div class="col-md-4">
+                    <select class="userState form-control"></select>
+                </div>
+                <div class="col-md-4">
+                    <select class="clientType form-control"></select>
+                </div>
+            </div>
+            <h3>&nbsp;&nbsp;&nbsp;带默认值&去除搜索框初始化选择</h3>
+            <div class="row">
+                <div class="col-md-4">
+                    <select class="userStateWithDefault form-control"></select>
+                </div>
+            </div>
+            <h3>&nbsp;&nbsp;&nbsp;省市区级联选择</h3>
+            <div class="row">
+                <div class="col-md-4">
+                    <select class="province form-control"></select>
+                </div>
+                <div class="col-md-4">
+                    <select class="city form-control"></select>
+                </div>
+                <div class="col-md-4">
+                    <select class="district form-control"></select>
+                </div>
+            </div>
+            <h3>&nbsp;&nbsp;&nbsp;带初始化默认值的省市区级联选择</h3>
+            <div class="row">
+                <div class="col-md-4">
+                    <select class="provinceWithValue form-control"></select>
+                </div>
+                <div class="col-md-4">
+                    <select class="cityWithValue form-control"></select>
+                </div>
+                <div class="col-md-4">
+                    <select class="districtWithValue form-control"></select>
+                </div>
+            </div>
+            <h3>&nbsp;&nbsp;&nbsp;多选&初始化</h3>
+            <div class="row">
+                <div class="col-md-4">
+                    <select class="provinceMuti form-control" multiple></select>
+                </div>
+                <div class="col-md-4">
+                    <select class="cityMuti form-control" multiple></select>
+                </div>
+            </div>
+            <h3>&nbsp;&nbsp;&nbsp;动态检索</h3>
+            <div class="row">
+                <div class="col-md-4">
+                    <select class="dynamicSearch form-control"></select>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>
+<div th:include="include/footer_js :: footer"></div>
+</body>
+<script type="text/javascript">
+    new Vue({
+        el : '#dpLTE'
+    });
+
+    <!-- 系统参数下拉框 -->
+    // 初始化系统参数
+    $('.userState').selectBindEx({
+        url: '../../sys/macro/value?value=userStatus',
+        placeholder: '请选择用户状态',
+        value: 'value',
+        text: 'name',
+    });
+
+    $('.clientType').selectBindEx({
+        url: '../../sys/macro/value?value=clientManage',
+        placeholder: '请选择客户关系',
+        value: 'value',
+        text: 'name',
+        search: false
+    });
+
+    $('.userStateWithDefault').selectBindEx({
+        url: '../../sys/macro/value?value=userStatus',
+        placeholder: '请选择用户状态',
+        value: 'value',
+        text: 'name',
+        selected: '0',
+        search: false
+    });
+
+    <!-- 省市区级联选择 -->
+    // 初始化省份选择,及级联函数
+    $('.province').selectBindEx({
+        url: '../../sys/area/select?areaCode=0',
+        placeholder: '请选择省份',
+        value: 'areaCode',
+        text: 'name',
+        change: function(data) {
+            $('.city').selectBindEx({
+                url: '../../sys/area/select?areaCode=' + data,
+                placeholder: '请选择地市',
+                value: 'areaCode',
+                text: 'name',
+                change: function(data) {
+                    $('.district').selectBindEx({
+                        url: '../../sys/area/select?areaCode=' + data,
+                        placeholder: '请选择区县',
+                        value: 'areaCode',
+                        text: 'name'
+                    });
+                }
+            });
+            // 选择省份后,清空地址选择
+            $('.city').val(null).trigger('change');
+        }
+    });
+    // 初始化地市选择
+    $('.city').selectInitEx('请选择地市');
+    // 初始化区县选择
+    $('.district').selectInitEx('请选择区县');
+
+    <!-- 带默认值的省市区级联选择,江苏省320000-南京市320100-玄武区320102 -->
+    $('.provinceWithValue').selectBindEx({
+        url: '../../sys/area/select?areaCode=0',
+        async: false,
+        placeholder: '请选择省份',
+        value: 'areaCode',
+        text: 'name',
+        change: function(data) {
+            $('.cityWithValue').selectBindEx({
+                url: '../../sys/area/select?areaCode=' + data,
+                async: false,
+                placeholder: '请选择地市',
+                value: 'areaCode',
+                text: 'name',
+                change: function(data) {
+                    $('.districtWithValue').selectBindEx({
+                        url: '../../sys/area/select?areaCode=' + data,
+                        async: false,
+                        placeholder: '请选择区县',
+                        value: 'areaCode',
+                        text: 'name'
+                    });
+                }
+            });
+            $('.cityWithValue').val(null).trigger('change');
+        }
+    });
+    $('.provinceWithValue').val('320000').trigger('change');
+    $('.cityWithValue').val('320100').trigger('change');
+    $('.districtWithValue').val('320102');
+
+    <!-- 多选 -->
+    $('.provinceMuti').selectBindEx({
+        url: '../../sys/area/select?areaCode=0',
+        placeholder: '请选择省份',
+        value: 'areaCode',
+        text: 'name',
+        selected: ['320000','120000','110000']
+    });
+
+    $('.cityMuti').selectBindEx({
+        url: '../../sys/area/select?areaCode=320000',
+        async: false,
+        placeholder: '请选择地市',
+        value: 'areaCode',
+        text: 'name'
+    });
+    $('.cityMuti').val(['320100','320400','320700']);
+
+    <!-- 动态检索 -->
+    $('.dynamicSearch').select2({
+        theme: "bootstrap",
+        language: "zh-CN",
+        width: 'off',
+        placeholder: '请输入行政编码',
+        ajax: {
+            url: '../../sys/area/select',
+            dataType: 'json',
+            delay: 250,
+            data: function(params){
+                return {
+                    areaCode: params.term
+                }
+            },
+            processResults: function(r) {
+                var itemList = [];
+                $.each(r, function(idx, item) {
+                    itemList.push({id: item.areaCode, text: item.name});
+                });
+                return {
+                    results: itemList
+                }
+            },
+            cache: false
+        },
+        minimumInputLength: 1
+    });
+
+</script>
+</html>

+ 98 - 0
src/main/resources/templates/base/component/switchery.html

@@ -0,0 +1,98 @@
+<!DOCTYPE html>
+<html xmlns:th="http://www.thymeleaf.org">
+<head th:include="include/header_css :: header('switchery组件')"></head>
+<body>
+<div id="dpLTE" class="container-fluid" v-cloak>
+    <div class="panel panel-default" style="padding-bottom: 10px;margin-top:10px;">
+        <div class="panel-heading">switchery示例</div>
+        <div>
+            <h3>&nbsp;&nbsp;&nbsp;官方文档</h3>
+            <div class="row">
+                <div class="col-md-12">
+                    <a href="http://abpetkov.github.io/switchery/" target="_blank">http://abpetkov.github.io/switchery/</a>
+                </div>
+            </div>
+            <h3>&nbsp;&nbsp;&nbsp;基础示例</h3>
+            <div class="row">
+                <div class="col-md-2">
+                   <input type="checkbox" class="switcheryDemo js-switch" checked>
+                </div>
+            </div>
+            <div class="row">
+                <div class="col-md-3">
+                    <div class="btn-group">
+                        <a class="btn btn-default" @click="switchOn">设置:开</a>
+                        <a class="btn btn-default" @click="switchOff">设置:关</a>
+                        <a class="btn btn-default" @click="switchDisabled">禁用</a>
+                        <a class="btn btn-default" @click="switchEnabled">启用</a>
+                        <a class="btn btn-default" @click="getState">获取状态</a>
+                    </div>
+                </div>
+                <div class="col-md-9">
+                    选择状态:【{{singleState}}】
+                </div>
+            </div>
+            <h3>&nbsp;&nbsp;&nbsp;多个开关</h3>
+            <div class="row">
+                <div class="col-md-2">
+                    <input type="checkbox" class="switcheryGroup js-switch" data-id="1">
+                    <input type="checkbox" class="switcheryGroup js-switch" data-id="2">
+                    <input type="checkbox" class="switcheryGroup js-switch" data-id="3">
+                    <input type="checkbox" class="switcheryGroup js-switch" data-id="4">
+                    <input type="checkbox" class="switcheryGroup js-switch" data-id="5">
+                    <input type="checkbox" class="switcheryGroup js-switch" data-id="6">
+                </div>
+                <div class="col-md-10">
+                    当前选择id为:【{{idx}}】,选择状态:【{{state}}】
+                </div>
+            </div>
+        </div>
+    </div>
+</div>
+<div th:include="include/footer_js :: footer"></div>
+</body>
+<script type="text/javascript">
+    var vm = new Vue({
+        el : '#dpLTE',
+        data : {
+            singleState: '',
+            idx: '',
+            state: ''
+        },
+        methods: {
+            switchOn: function() {
+                switchUtils.on(switcheryDemo);
+            },
+            switchOff: function() {
+                switchUtils.off(switcheryDemo);
+            },
+            switchDisabled: function() {
+                switchUtils.disable(switcheryDemo);
+            },
+            switchEnabled: function() {
+                switchUtils.enable(switcheryDemo);
+            },
+            getState: function() {
+                vm.singleState = switchUtils.checked(switcheryDemo);
+            }
+        }
+    });
+
+    var switcheryDemo = switchUtils.init({
+        selector: '.switcheryDemo',
+        change: function(switchContainer) {
+            vm.singleState = switchUtils.checked(switchContainer);
+        }
+    });
+
+    switchUtils.init({
+        selector: '.switcheryGroup',
+        single: false,
+        change: function(switchContainer) {
+            vm.state = switchUtils.checked(switchContainer);
+            vm.idx = switchUtils.data(switchContainer, "id");
+        }
+    });
+
+</script>
+</html>

+ 22 - 17
src/main/resources/templates/base/user/add.html

@@ -9,41 +9,46 @@
 	            <td class="formValue">
 					<input type="text" class="form-control" placeholder="用户名" v-model="user.username" isvalid="yes" checkexpession="NotNull">
 	            </td>
-	            <td class="formTitle">所属机构<font face="宋体">*</font></td>
-	            <td class="formValue">
-					<input type="text" class="form-control pointer" placeholder="所属机构" v-model="user.orgName" @click="orgTree" isvalid="yes" checkexpession="NotNull" readonly="readonly">
-	            </td>
         	</tr>
+			<tr>
+				<td class="formTitle">所属机构<font face="宋体">*</font></td>
+				<td class="formValue">
+					<input type="text" class="form-control pointer" placeholder="所属机构" v-model="user.orgName" @click="orgTree" isvalid="yes" checkexpession="NotNull" readonly="readonly">
+				</td>
+			</tr>
         	<tr>
 	            <td class="formTitle">密码<font face="宋体">*</font></td>
 	            <td class="formValue">
 					<input type="text" class="form-control" placeholder="密码" v-model="user.password" isvalid="yes" checkexpession="NotNull">
 	            </td>
-        		<td class="formTitle">邮箱</td>
-	            <td class="formValue">
-					<input type="text" class="form-control" placeholder="邮箱" v-model="user.email">
-	            </td>
         	</tr>
+			<tr>
+				<td class="formTitle">邮箱</td>
+				<td class="formValue">
+					<input type="text" class="form-control" placeholder="邮箱" v-model="user.email">
+				</td>
+			</tr>
         	<tr>
 	            <td class="formTitle">手机号</td>
 	            <td class="formValue">
 					<input type="text" class="form-control" placeholder="手机号" v-model="user.mobile">
 	            </td>
-	            <td class="formTitle">备注</td>
-	            <td class="formValue">
-					<input type="text" class="form-control" placeholder="备注" v-model="user.remark">
-	            </td>
-        		
         	</tr>
 			<tr>
-				<td class="formTitle">角色</td>
-				<td class="formValue" colspan="3">
-					<select multiple="multiple" size="10" name="doublebox" class="rolebox"></select>
+				<td class="formTitle">备注</td>
+				<td class="formValue">
+					<input type="text" class="form-control" placeholder="备注" v-model="user.remark">
+				</td>
+			</tr>
+			<tr>
+				<td class="formTitle">角色<font face="宋体">*</font></td>
+				<td class="formValue">
+					<select style="width:370px;" class="form-control roleSelect" isvalid="yes" checkexpession="NotNull" multiple></select>
 				</td>
 			</tr>
 			<tr>
 				<td class="formTitle">状态</td>
-				<td class="formValue" colspan="3">
+				<td class="formValue">
 					<label class="radio-inline">
 						<input type="radio" name="status" value="0" v-model="user.status"/> 禁用
 					</label>

+ 22 - 17
src/main/resources/templates/base/user/edit.html

@@ -9,41 +9,46 @@
 	            <td class="formValue">
 					<input type="text" class="form-control" placeholder="用户名" v-model="user.username" isvalid="yes" checkexpession="NotNull">
 	            </td>
-	            <td class="formTitle">所属机构<font face="宋体">*</font></td>
-	            <td class="formValue">
-					<input type="text" class="form-control pointer" placeholder="所属机构" v-model="user.orgName" @click="orgTree" isvalid="yes" checkexpession="NotNull" readonly="readonly">
-	            </td>
         	</tr>
+			<tr>
+				<td class="formTitle">所属机构<font face="宋体">*</font></td>
+				<td class="formValue">
+					<input type="text" class="form-control pointer" placeholder="所属机构" v-model="user.orgName" @click="orgTree" isvalid="yes" checkexpession="NotNull" readonly="readonly">
+				</td>
+			</tr>
         	<tr>
 	            <td class="formTitle">密码<font face="宋体">*</font></td>
 	            <td class="formValue">
 					<input type="text" class="form-control" placeholder="密码" value="******" readonly="readonly">
 	            </td>
-        		<td class="formTitle">邮箱</td>
-	            <td class="formValue">
-					<input type="text" class="form-control" placeholder="邮箱" v-model="user.email">
-	            </td>
         	</tr>
+			<tr>
+				<td class="formTitle">邮箱</td>
+				<td class="formValue">
+					<input type="text" class="form-control" placeholder="邮箱" v-model="user.email">
+				</td>
+			</tr>
         	<tr>
 	            <td class="formTitle">手机号</td>
 	            <td class="formValue">
 					<input type="text" class="form-control" placeholder="手机号" v-model="user.mobile">
 	            </td>
-	            <td class="formTitle">备注</td>
-	            <td class="formValue">
-					<input type="text" class="form-control" placeholder="备注" v-model="user.remark">
-	            </td>
-        		
         	</tr>
 			<tr>
-				<td class="formTitle">角色</td>
-				<td class="formValue" colspan="3">
-					<select multiple="multiple" size="10" name="doublebox" class="rolebox"></select>
+				<td class="formTitle">备注</td>
+				<td class="formValue">
+					<input type="text" class="form-control" placeholder="备注" v-model="user.remark">
+				</td>
+			</tr>
+			<tr>
+				<td class="formTitle">角色<font face="宋体">*</font></td>
+				<td class="formValue">
+					<select style="width:370px;" class="form-control roleSelect" isvalid="yes" checkexpession="NotNull" multiple></select>
 				</td>
 			</tr>
 			<tr>
 				<td class="formTitle">状态</td>
-				<td class="formValue" colspan="3">
+				<td class="formValue">
 					<label class="radio-inline">
 						<input type="radio" name="status" value="0" v-model="user.status"/> 禁用
 					</label>

+ 6 - 1
src/main/resources/templates/include/footer_js.html

@@ -11,9 +11,14 @@
 		<script th:src="@{../../plugins/bootstrap-table/locale/bootstrap-table-zh-CN.min.js}"></script>
 		<script th:src="@{../../plugins/bootstrap-table/treegrid/bootstrap-table-treegrid.js}"></script>
 		<script th:src="@{../../plugins/bootstrap-table/treegrid/jquery-treegrid.min.js}"></script>
+		<script th:src="@{../../plugins/bootstrap-table/pagejump/bootstrap-table-pagejump.js}"></script>
 		<script th:src="@{../../plugins/validator/validator.js}"></script>
 		<script th:src="@{../../plugins/laydate/laydate.js}"></script>
-		<script th:src="@{../../plugins/double-box/doublebox-bootstrap.js}"></script>
+		<script th:src="@{../../plugins/select2/select2.min.js}"></script>
+		<script th:src="@{../../plugins/select2/i18n/zh-CN.min.js}"></script>
+		<script th:src="@{../../plugins/switchery/switchery.min.js}"></script>
+		<script th:src="@{../../plugins/editor/editor.min.js}"></script>
+		<script th:src="@{../../plugins/laydate/laydate.js}"></script>
 		<script th:src="@{../../js/common.js}"></script>
 		<script th:src="@{../../js/form.js}"></script>
 	</div>

+ 3 - 1
src/main/resources/templates/include/header_css.html

@@ -9,8 +9,10 @@
 	<link th:href="@{../../css/font-awesome.min.css}" rel="stylesheet"/>
 	<link th:href="@{../../plugins/bootstrap-table/bootstrap-table.min.css}" rel="stylesheet"/>
 	<link th:href="@{../../plugins/bootstrap-table/treegrid/jquery-treegird.min.css}" rel="stylesheet"/>
+	<link th:href="@{../../plugins/bootstrap-table/pagejump/bootstrap-table-pagejump.css}" rel="stylesheet"/>
 	<link th:href="@{../../plugins/ztree/css/metroStyle/metroStyle.css}" rel="stylesheet"/>
-	<link th:href="@{../../plugins/double-box/doublebox-bootstrap.css}" rel="stylesheet"/>
+	<link th:href="@{../../plugins/select2/select2.min.css}" rel="stylesheet"/>
+	<link th:href="@{../../plugins/switchery/switchery.min.css}" rel="stylesheet"/>
 	<link th:href="@{../../css/style.min.css}" rel="stylesheet"/>
 	<link th:href="@{../../css/common.min.css}" rel="stylesheet"/>
 </head>

+ 7 - 0
src/main/resources/templates/system/index/main.html

@@ -32,6 +32,13 @@
             <li>兴趣交流群: 553461392</li>
             <li>如需关注项目最新动态,请Watch、Star项目,同时也是对项目最好的支持</li>
         </ul>
+
+        <h3>&nbsp;&nbsp;&nbsp;开发组件</h3>
+        <ul>
+            <li><a href="/base/component/select2.html" target="_blank">select2(下拉选择组件)</a></li>
+            <li><a href="/base/component/switchery.html" target="_blank">switchery(开关组件)</a></li>
+            <li><a href="/base/component/editor.html" target="_blank">editor(富文本编辑器)</a></li>
+        </ul>
         
     </div>
 </div>

Some files were not shown because too many files changed in this diff