diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 0000000..4a1bf99
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/admin/pom.xml b/admin/pom.xml
new file mode 100644
index 0000000..c5a64c4
--- /dev/null
+++ b/admin/pom.xml
@@ -0,0 +1,159 @@
+
+
+ 4.0.0
+
+
+ xyz.wbsite
+ nginx-admin
+ 1.0-SNAPSHOT
+
+
+ xyz.wbsite
+ admin
+ 1.0-SNAPSHOT
+ jar
+
+
+ UTF-8
+ UTF-8
+ 1.8
+ true
+
+
+
+
+ spring-milestones
+ Spring Milestones
+ https://repo.spring.io/milestone
+
+
+
+
+
+ xyz.wbsite
+ wsqlite
+
+
+
+ org.mybatis.spring.boot
+ mybatis-spring-boot-starter
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+ commons-io
+ commons-io
+
+
+
+
+ com.github.pagehelper
+ pagehelper-spring-boot-starter
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-freemarker
+
+
+
+
+ org.springframework.boot
+ spring-boot-devtools
+ provided
+ true
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+ org.springframework.boot
+ spring-boot-starter-security
+
+
+
+ net.sf.dozer
+ dozer
+
+
+
+ mysql
+ mysql-connector-java
+ runtime
+
+
+
+
+
+ ${artifactId}-${version}
+
+ src/main/java
+
+ src/test/java
+
+
+ src/main/resources
+
+
+
+ src/main/java
+
+ **/mpr/*.xml
+
+
+
+
+ ${basedir}/src/main/resources/lib
+ BOOT-INF/lib/
+
+ *.jar
+
+
+
+
+ ${basedir}/src/main/resources
+
+ *.bat
+
+ ${basedir}/target
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+
+
+ org.apache.maven.plugins
+ maven-war-plugin
+
+
+
+ ${project.basedir}/src/main/resources/lib
+ WEB-INF/lib
+
+ *.jar
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/admin/src/main/java/com/example/Application.java b/admin/src/main/java/com/example/Application.java
new file mode 100644
index 0000000..a223156
--- /dev/null
+++ b/admin/src/main/java/com/example/Application.java
@@ -0,0 +1,21 @@
+package com.example;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
+
+@SpringBootApplication
+@EnableAutoConfiguration
+public class Application extends SpringBootServletInitializer {
+
+ @Override
+ protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
+ return application.sources(Application.class);
+ }
+
+ public static void main(String[] args) {
+ SpringApplication.run(Application.class, args);
+ }
+}
\ No newline at end of file
diff --git a/admin/src/main/java/com/example/action/AjaxController.java b/admin/src/main/java/com/example/action/AjaxController.java
new file mode 100644
index 0000000..fda84d9
--- /dev/null
+++ b/admin/src/main/java/com/example/action/AjaxController.java
@@ -0,0 +1,124 @@
+package com.example.action;
+
+import com.example.module.admin.mgr.MappingManager;
+import com.example.module.admin.req.*;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+
+import com.example.frame.utils.LocalData;
+import com.example.frame.utils.MapperUtil;
+import com.example.frame.utils.Message;
+import com.example.frame.base.BaseResponse;
+import com.example.frame.base.ErrorType;
+import com.example.frame.base.Token;
+import com.example.frame.utils.LogUtil;
+import com.example.frame.base.Error;
+
+@Controller
+public class AjaxController {
+
+ @Autowired
+ private MappingManager mappingManager;
+
+ @RequestMapping("/ajax")
+ @ResponseBody
+ public BaseResponse ajax(@RequestParam("method") String method, HttpServletRequest request, HttpServletResponse response) {
+
+ BaseResponse baseResponse = new BaseResponse();
+ String jsonString = null;
+ try {
+ if (method == null) {
+ baseResponse.addError(new Error(ErrorType.BUSINESS_ERROR, "请求方法不能为空!"));
+ return baseResponse;
+ }
+ Token token = LocalData.getToken();
+ if (token == null) {
+ token = LocalData.getTempToken();
+ }
+ if (!token.hasResource(method)) {
+ baseResponse.addError(new Error(ErrorType.BUSINESS_ERROR, "无权调用该接口!"));
+ return baseResponse;
+ }
+
+ InputStreamReader isr = new InputStreamReader(request.getInputStream(), "UTF-8");
+ BufferedReader in = new BufferedReader(isr);
+ jsonString = in.readLine();
+
+ switch (method) {
+ // 示例
+ case "ajax.example.example":
+ break;
+ // 创建映射
+ case "ajax.admin.mapping.create":
+ baseResponse = createMapping(jsonString, token);
+ break;
+ // 删除映射
+ case "ajax.admin.mapping.delete":
+ baseResponse = deleteMapping(jsonString, token);
+ break;
+ // 修改映射
+ case "ajax.admin.mapping.update":
+ baseResponse = updateMapping(jsonString, token);
+ break;
+ // 查询映射
+ case "ajax.admin.mapping.find":
+ baseResponse = findMapping(jsonString, token);
+ break;
+ default:
+ baseResponse.addError(ErrorType.INVALID_PARAMETER, Message.NOT_EXIST_METHOD);
+ break;
+ }
+
+ } catch (Exception ex) {
+ baseResponse.addError(ErrorType.SYSTEM_ERROR, Message.ERROR_500);
+ LogUtil.dumpException(ex);
+ } finally {
+ if (baseResponse.hasError()) {
+ LogUtil.e("请求方法" + method + ", 请求参数:" + jsonString);
+ LogUtil.e("返回结果包含异常" + MapperUtil.toJson(baseResponse));
+ }
+ }
+ return baseResponse;
+ }
+
+ /**
+ * 创建映射
+ */
+ private BaseResponse createMapping(String jsonString, Token token) {
+ MappingCreateRequest request = MapperUtil.toJava(jsonString, MappingCreateRequest.class);
+ return mappingManager.create(request, token);
+ }
+
+ /**
+ * 删除映射
+ */
+ private BaseResponse deleteMapping(String jsonString, Token token) {
+ MappingDeleteRequest request = MapperUtil.toJava(jsonString, MappingDeleteRequest.class);
+ return mappingManager.delete(request, token);
+ }
+
+ /**
+ * 修改映射
+ */
+ private BaseResponse updateMapping(String jsonString, Token token) {
+ MappingUpdateRequest request = MapperUtil.toJava(jsonString, MappingUpdateRequest.class);
+ return mappingManager.update(request, token);
+ }
+
+ /**
+ * 查询映射
+ */
+ private BaseResponse findMapping(String jsonString, Token token) {
+ MappingFindRequest request = MapperUtil.toJava(jsonString, MappingFindRequest.class);
+ return mappingManager.find(request, token);
+ }
+
+}
diff --git a/admin/src/main/java/com/example/action/GlobalController.java b/admin/src/main/java/com/example/action/GlobalController.java
new file mode 100644
index 0000000..4ccd7ed
--- /dev/null
+++ b/admin/src/main/java/com/example/action/GlobalController.java
@@ -0,0 +1,181 @@
+package com.example.action;
+
+import com.example.frame.base.FileUploadResponse;
+import com.example.frame.base.BaseResponse;
+import com.example.frame.base.ErrorType;
+import com.example.frame.base.Screen;
+import com.example.frame.utils.LocalData;
+import com.example.config.ActionConfig;
+import org.springframework.beans.BeansException;
+import org.apache.commons.io.FileUtils;
+import org.springframework.boot.web.servlet.error.ErrorController;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.multipart.MultipartHttpServletRequest;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.File;
+import java.io.IOException;
+import org.springframework.beans.factory.annotation.Value;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * 全局请求Controller,如果无特殊请求,则不需再增加其他Controller
+ * 全局htm后缀入口{@link GlobalController#hold}
+ * 全局异常捕捉{@link GlobalController#excepitonHandler}
+ * 全局上传接口{@link GlobalController#upload}
+ * 全局下载接口{@link GlobalController#download}
+ *
+ * 说明Request命名规则,驼峰式命名
+ * Api#Example#Request ==> 目标#动作#Request
+ *
+ * @author author
+ * @version 0.0.1
+ * @since 2019-06-16
+ */
+@Controller
+@ControllerAdvice
+public class GlobalController implements ErrorController {
+
+ @Value("${web.welcome.page}")
+ private String homePage;
+
+ /**
+ * 全局异常捕捉
+ *
+ * @param request
+ * @param response
+ * @param exception 要捕获的异常
+ * @return
+ */
+ @ExceptionHandler(Exception.class)
+ public String excepitonHandler(HttpServletRequest request, HttpServletResponse response, Model model, Exception exception) {
+ StringBuffer msg = new StringBuffer("");
+ if (exception != null) {
+ msg = new StringBuffer("");
+ String message = exception.toString();
+ int length = exception.getStackTrace().length;
+ if (length > 0) {
+ msg.append("").append(message).append(" ");
+ for (int i = 0; i < length; i++) {
+ msg.append("").append(exception.getStackTrace()[i]).append(" ");
+ }
+ } else {
+ msg.append(message);
+ }
+ }
+ response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+ model.addAttribute("msg", msg.toString());
+ return "500";
+ }
+
+ private final static String ERROR_PATH = "/error";
+
+ @Override
+ public String getErrorPath() {
+ return ERROR_PATH;
+ }
+
+ @RequestMapping(value = ERROR_PATH)
+ public String error(HttpServletRequest request) {
+ Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code");
+
+ switch (statusCode) {
+ case 404:
+ return "404";
+ case 403:
+ return "403";
+ case 500:
+ return "500";
+ default:
+ return "403";
+ }
+ }
+
+ @RequestMapping("/")
+ public String home() {
+ return "forward:" + homePage;
+ }
+
+ /**
+ * 当未明确指定控制器时,走该请求,默认返回对应的layout布局和screen视图
+ * 当需要使用layout时,不需要返回值,ViewNameTranslator会处理对应关系
+ * @param model
+ * @param request
+ */
+ @RequestMapping({"/**/*.htm"})
+ public void hold(HttpServletRequest request, Model model) {
+ HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
+
+ // 尝试执行Target Screen执行器(服务器渲染),不存在则直接返回视图模板(Ajax渲染)
+ Screen screenExec = null;
+ try {
+ String target = LocalData.getTarget();
+ target = target.replaceAll("/", ".").toLowerCase();
+ screenExec = LocalData.getApplicationContext().getBean(ActionConfig.SCREEN_PREFIX + target, Screen.class);
+ screenExec.exec(model, request, response);
+ } catch (BeansException e) {
+
+ }
+
+ //todo 可在此获取共性数据(也可以在全局拦截器GlobalHandlerInterceptor、拦截器作用域比此更高),
+ //todo 例如用户信息等。其他业务数据在页面渲染后通过Ajax请求
+ }
+
+ @RequestMapping("/upload")
+ @ResponseBody
+ public BaseResponse upload(HttpServletRequest request) {
+ FileUploadResponse fileUploadResponse = new FileUploadResponse();
+ MultipartHttpServletRequest multipartHttpServletRequest = (MultipartHttpServletRequest) request;
+ MultipartFile target = multipartHttpServletRequest.getFile("file");
+
+ String fileName = target.getOriginalFilename();
+
+ //========
+ //处理文件
+ //========
+ fileUploadResponse.setId(1L);
+ fileUploadResponse.setUrl("example.com\\img\\1.jpg");
+ fileUploadResponse.setDownloadUrl("example.com\\img\\1.jpg");
+
+
+ if (target != null) {
+ fileUploadResponse.addError(ErrorType.BUSINESS_ERROR, "文件上传成功,但未处理文件[" + fileName + "]!");
+ } else {
+ fileUploadResponse.addError(ErrorType.BUSINESS_ERROR, "文件上传失败!");
+ }
+
+ return fileUploadResponse;
+ }
+
+ @RequestMapping("/download")
+ @ResponseBody
+ public ResponseEntity download(@RequestParam(value = "file", required = false) String file) throws IOException {
+
+ HttpHeaders headers = new HttpHeaders();
+ headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
+
+ //========
+ //下载DEMO
+ //========
+ if (file == null) {
+ file = "test.txt";
+ headers.setContentDispositionFormData("attachment", new String(file.getBytes("UTF-8"), "iso-8859-1"));
+ return new ResponseEntity("test".getBytes(),
+ headers, HttpStatus.CREATED);
+ }
+
+ return new ResponseEntity(FileUtils.readFileToByteArray(new File(file)),
+ headers, HttpStatus.CREATED);
+ }
+}
diff --git a/admin/src/main/java/com/example/action/control/Footer.java b/admin/src/main/java/com/example/action/control/Footer.java
new file mode 100644
index 0000000..a53ce95
--- /dev/null
+++ b/admin/src/main/java/com/example/action/control/Footer.java
@@ -0,0 +1,15 @@
+package com.example.action.control;
+
+import com.example.frame.base.Control;
+import org.springframework.ui.Model;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+public class Footer extends Control {
+
+ @Override
+ public void exec(Model model, HttpServletRequest request, HttpServletResponse response) {
+
+ }
+}
diff --git a/admin/src/main/java/com/example/action/control/Header.java b/admin/src/main/java/com/example/action/control/Header.java
new file mode 100644
index 0000000..32e8be5
--- /dev/null
+++ b/admin/src/main/java/com/example/action/control/Header.java
@@ -0,0 +1,15 @@
+package com.example.action.control;
+
+import com.example.frame.base.Control;
+import org.springframework.ui.Model;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+public class Header extends Control {
+
+ @Override
+ public void exec(Model model, HttpServletRequest request, HttpServletResponse response) {
+
+ }
+}
diff --git a/admin/src/main/java/com/example/action/screen/Index.java b/admin/src/main/java/com/example/action/screen/Index.java
new file mode 100644
index 0000000..b06dd67
--- /dev/null
+++ b/admin/src/main/java/com/example/action/screen/Index.java
@@ -0,0 +1,23 @@
+package com.example.action.screen;
+
+import com.example.frame.base.Screen;
+import org.springframework.ui.Model;
+import java.util.ArrayList;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+public class Index extends Screen {
+
+ @Override
+ public void exec(Model model, HttpServletRequest request, HttpServletResponse response) {
+
+ model.addAttribute("hello", "Hello world!!!");
+ model.addAttribute("status", 0);
+
+ ArrayList citys = new ArrayList();
+ citys.add("北京");
+ citys.add("上海");
+ citys.add("深圳");
+ model.addAttribute("citys", citys);
+ }
+}
diff --git a/admin/src/main/java/com/example/config/ActionConfig.java b/admin/src/main/java/com/example/config/ActionConfig.java
new file mode 100644
index 0000000..e087d8d
--- /dev/null
+++ b/admin/src/main/java/com/example/config/ActionConfig.java
@@ -0,0 +1,90 @@
+package com.example.config;
+
+import com.example.frame.base.Control;
+import com.example.frame.base.Screen;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
+import org.springframework.beans.factory.support.BeanDefinitionRegistry;
+import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
+import org.springframework.beans.factory.support.BeanNameGenerator;
+import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.type.classreading.MetadataReader;
+import org.springframework.core.type.classreading.MetadataReaderFactory;
+import org.springframework.core.type.filter.TypeFilter;
+
+import java.io.IOException;
+
+/**
+ * 请求处理器配置类,Screen及Control
+ *
+ * 注册扫描Screen处理器 {@link ActionConfig#registryScreen}
+ * 注册扫描Control处理器 {@link ActionConfig#registryControl}
+ *
+ * @author wangbing
+ * @version 0.0.1
+ * @since 2017-01-01
+ */
+@Configuration
+public class ActionConfig implements BeanDefinitionRegistryPostProcessor {
+ public static final String SCREEN_PREFIX = "screen";
+ public static final String CONTROL_PREFIX = "control";
+
+ @Override
+ public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
+ String aPackage = this.getClass().getPackage().getName();
+ int i = registryScreen("com.example.action.screen", beanDefinitionRegistry);
+ int i1 = registryControl("com.example.action.control", beanDefinitionRegistry);
+ System.out.println();
+ }
+
+ @Override
+ public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
+
+ }
+
+ private int registryScreen(String basePackage, BeanDefinitionRegistry beanDefinitionRegistry) {
+ ClassPathBeanDefinitionScanner classPathBeanDefinitionScanner = new ClassPathBeanDefinitionScanner(beanDefinitionRegistry);
+ classPathBeanDefinitionScanner.addIncludeFilter(new TypeFilter() {
+ @Override
+ public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
+ if (metadataReader.getClassMetadata().getSuperClassName().equals(Screen.class.getName())) {
+ return true;
+ }
+ return false;
+ }
+ });
+ classPathBeanDefinitionScanner.setBeanNameGenerator(new BeanNameGenerator() {
+ @Override
+ public String generateBeanName(BeanDefinition beanDefinition, BeanDefinitionRegistry beanDefinitionRegistry) {
+ String beanClassName = beanDefinition.getBeanClassName();
+ String s = beanClassName.replaceAll(basePackage, SCREEN_PREFIX);
+ return s.toLowerCase();
+ }
+ });
+ return classPathBeanDefinitionScanner.scan(basePackage);
+ }
+
+ private int registryControl(String basePackage, BeanDefinitionRegistry beanDefinitionRegistry) {
+ ClassPathBeanDefinitionScanner classPathBeanDefinitionScanner = new ClassPathBeanDefinitionScanner(beanDefinitionRegistry);
+ classPathBeanDefinitionScanner.addIncludeFilter(new TypeFilter() {
+ @Override
+ public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
+ if (metadataReader.getClassMetadata().getSuperClassName().equals(Control.class.getName())) {
+ return true;
+ }
+ return false;
+ }
+ });
+ classPathBeanDefinitionScanner.setBeanNameGenerator(new BeanNameGenerator() {
+ @Override
+ public String generateBeanName(BeanDefinition beanDefinition, BeanDefinitionRegistry beanDefinitionRegistry) {
+ String beanClassName = beanDefinition.getBeanClassName();
+ String s = beanClassName.replaceAll(basePackage, CONTROL_PREFIX);
+ return s.toLowerCase();
+ }
+ });
+ return classPathBeanDefinitionScanner.scan(basePackage);
+ }
+}
diff --git a/admin/src/main/java/com/example/config/SecurityConfig.java b/admin/src/main/java/com/example/config/SecurityConfig.java
new file mode 100644
index 0000000..744c219
--- /dev/null
+++ b/admin/src/main/java/com/example/config/SecurityConfig.java
@@ -0,0 +1,88 @@
+package com.example.config;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.config.http.SessionCreationPolicy;
+import org.springframework.security.core.Authentication;
+import com.example.frame.base.Token;
+import com.example.frame.utils.CookieUtil;
+import com.example.frame.utils.LocalData;
+import javax.servlet.http.HttpServletRequest;
+
+@Configuration
+@EnableGlobalMethodSecurity(securedEnabled = true)
+public class SecurityConfig extends WebSecurityConfigurerAdapter {
+
+ @Value("${web.url.auth.excluded}")
+ private String[] excluded;
+ @Value("${web.url.auth.included}")
+ private String[] included;
+
+ @Override
+ protected void configure(HttpSecurity http) throws Exception {
+ http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
+ .and()
+ .authorizeRequests()
+ .antMatchers(excluded).permitAll()
+ .antMatchers(included).access("@Authorization.hasPermission(request,authentication)")
+ .and().cors()
+ .and().headers().frameOptions().disable()
+ .and().csrf().disable();
+ }
+
+ /**
+ * 此方法不要删除 用于屏蔽默认用户密码生成
+ *
+ * 例如 Using generated security password: f6b42a66-71b1-4c31-b6a8-942838c81408
+ *
+ * @return
+ * @throws Exception
+ */
+ @Bean
+ public AuthenticationManager authenticationManagerBean() throws Exception {
+ return super.authenticationManagerBean();
+ }
+
+ @Bean("Authorization")
+ public Object getAuthorization() {
+ return new Object() {
+ public boolean hasPermission(HttpServletRequest request, Authentication authentication) {
+
+ // 获取Token
+ String token = request.getParameter("token");
+ if (token == null || token.isEmpty()){
+ token = CookieUtil.getCookieValue(request.getCookies(), "token");
+ }
+
+ if (token == null) {
+ LocalData.setToken(LocalData.getTempToken());
+ }else {
+ // 组装Token ~ 这边根据实际的业务组装Token
+ Token token1 = new Token();
+ token1.setId(1L);
+ token1.setUserId(1L);
+ token1.setUserName("admin");
+ //继承临时Token
+ token1.addResourceSet(LocalData.getTempToken());
+ //管理员特有资源(这边请用正则表达式)
+ token1.putResource("/admin/.*\\.htm");
+ LocalData.setToken(token1);
+ }
+
+ // 授权
+ Token token_ = LocalData.getToken();
+ if (token_.hasResource(request.getServletPath())) {
+ return true;
+ }
+
+ return false;
+ }
+ };
+ }
+
+}
diff --git a/admin/src/main/java/com/example/config/TaskConfig.java b/admin/src/main/java/com/example/config/TaskConfig.java
new file mode 100644
index 0000000..7be44f2
--- /dev/null
+++ b/admin/src/main/java/com/example/config/TaskConfig.java
@@ -0,0 +1,38 @@
+package com.example.config;
+
+import com.example.frame.utils.LogUtil;
+import com.example.frame.utils.ProcessUtil;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Profile;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.scheduling.annotation.SchedulingConfigurer;
+import org.springframework.scheduling.config.ScheduledTaskRegistrar;
+
+import java.util.concurrent.Executors;
+
+/**
+ * Task配置,默认只在开发环境生效,根据实际情况是否需要Task选择开启
+ * 开启方法:将@Profile("dev") 删除(所有环境生效) 或改为 @Profile("prod")(只对生产环境生效)
+ */
+@Configuration
+@EnableScheduling
+@Profile("prod")
+public class TaskConfig implements SchedulingConfigurer {
+
+ @Scheduled(cron="0/30 * * * * ? ")
+ public void task(){
+ LogUtil.i("--------------------Task--------------------");
+ }
+
+ /**
+ * Spring的 Schedule 默认是单线程执行
+ * 若要多线程并行运行任务 需实现SchedulingConfigurer并重写configureTasks方法
+ *
+ * @param scheduledTaskRegistrar
+ */
+ @Override
+ public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
+ scheduledTaskRegistrar.setScheduler(Executors.newScheduledThreadPool(3));
+ }
+}
diff --git a/admin/src/main/java/com/example/config/ThreadPoolConfig.java b/admin/src/main/java/com/example/config/ThreadPoolConfig.java
new file mode 100644
index 0000000..764e30d
--- /dev/null
+++ b/admin/src/main/java/com/example/config/ThreadPoolConfig.java
@@ -0,0 +1,56 @@
+package com.example.config;
+
+import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.lang.Nullable;
+import org.springframework.scheduling.annotation.AsyncConfigurer;
+import org.springframework.scheduling.annotation.EnableAsync;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+
+import java.lang.reflect.Method;
+import java.util.concurrent.Executor;
+import java.util.concurrent.ThreadPoolExecutor;
+
+@Configuration
+@EnableAsync
+public class ThreadPoolConfig implements AsyncConfigurer {
+ private ThreadPoolTaskExecutor executor;
+
+ private int corePoolSize = 10;//线程池维护线程的最少数量
+
+ private int maxPoolSize = 30;//线程池维护线程的最大数量
+
+ private int queueCapacity = 8; //缓存队列
+
+ private int keepAlive = 60;//允许的空闲时间
+
+ @Nullable
+ @Override
+ public Executor getAsyncExecutor() {
+ executor = new ThreadPoolTaskExecutor();
+ executor.setCorePoolSize(corePoolSize);
+ executor.setMaxPoolSize(maxPoolSize);
+ executor.setQueueCapacity(queueCapacity);
+ executor.setThreadNamePrefix("mqExecutor-");
+ // rejection-policy:当pool已经达到max size的时候,如何处理新任务
+ // CALLER_RUNS:不在新线程中执行任务,而是由调用者所在的线程来执行
+ executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); //对拒绝task的处理策略
+ executor.setKeepAliveSeconds(keepAlive);
+ executor.initialize();
+ return executor;
+ }
+
+
+ @Nullable
+ @Override
+ public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
+ return new AsyncUncaughtExceptionHandler() {
+
+ @Override
+ public void handleUncaughtException(Throwable throwable, Method method, Object... objects) {
+ System.out.println("-------------》》》捕获线程异常信息");
+ }
+ };
+ }
+
+}
diff --git a/admin/src/main/java/com/example/config/WebMvcConfig.java b/admin/src/main/java/com/example/config/WebMvcConfig.java
new file mode 100644
index 0000000..96f12b5
--- /dev/null
+++ b/admin/src/main/java/com/example/config/WebMvcConfig.java
@@ -0,0 +1,161 @@
+package com.example.config;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.module.SimpleModule;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import com.example.frame.base.Token;
+import com.example.frame.utils.LocalData;
+import com.example.frame.utils.LogUtil;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.converter.HttpMessageConverter;
+import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
+import org.springframework.web.servlet.ModelAndView;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import java.util.List;
+
+@Configuration
+public class WebMvcConfig implements WebMvcConfigurer {
+
+ @Value("${web.welcome.page}")
+ private String homePage;
+
+ /**
+ * 增加全局拦截器,可用于
+ *
+ * @param registry
+ */
+ @Override
+ public void addInterceptors(InterceptorRegistry registry) {
+ registry.addInterceptor(new HandlerInterceptorAdapter() {
+ @Override
+ public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
+ // 处理根Url
+ String servletPath = request.getServletPath();
+ if (servletPath.matches("(.+)\\.htm")) {
+ Pattern compile = Pattern.compile("(.+)\\.htm");
+ Matcher matcher = compile.matcher(servletPath);
+ if (matcher.find()) {
+ servletPath = matcher.group(1);
+ }
+ }
+ LocalData.setTarget(servletPath);
+ return super.preHandle(request, response, handler);
+ }
+
+ @Override
+ public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
+ super.postHandle(request, response, handler, modelAndView);
+
+ //当请求为@ResponseBody,modelAndView为null,不处理
+ if (modelAndView == null) {
+ return;
+ }
+
+ //获取当前用户信息
+ Token token = LocalData.getToken();
+ modelAndView.addObject("token", token);
+
+ //主页
+ modelAndView.addObject("homePath", homePage);
+
+ //获取项目路径,在项目非根路径下用于拼接URL
+ String contextPath = request.getContextPath();
+ modelAndView.addObject("contextPath", contextPath);
+ }
+
+ @Override
+ public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
+ super.afterCompletion(request, response, handler, ex);
+
+ if (ex != null) {
+ LogUtil.dumpException(ex);
+ }
+ }
+
+ }).addPathPatterns("/**/*.htm").order(-1);
+ }
+
+ /**
+ * Jackson序列化时的转化规则配置
+ *
+ * 1、Long或long类型在序列化时转String,防止出现javascript中Number精度丢失的情况。
+ *
+ * @param converters
+ */
+ @Override
+ public void extendMessageConverters(List> converters) {
+ for (HttpMessageConverter> converter : converters) {
+ if (converter instanceof MappingJackson2HttpMessageConverter){
+ ObjectMapper objectMapper = ((MappingJackson2HttpMessageConverter)converter).getObjectMapper();
+ SimpleModule simpleModule = new SimpleModule();
+ simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
+ simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);
+ objectMapper.registerModule(simpleModule);
+ }
+ }
+ }
+
+// @Bean
+// @Profile("prod")
+// public ServletWebServerFactory servletContainer() {
+// TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory();
+//
+// // 基本参数
+// String keyStore = "1754557_www.wbsite.xyz.pfx";
+// String keyStorePassword = "s98n7CLd";
+// String keyStoreType = "PKCS12";
+// int httpsPort = 443;
+//
+// File keystore = null;
+// // 正常开发可以通过getFile()获取,打包jar后无法直接获取File对象,需将文件考出
+// try {
+// keystore = new ClassPathResource(keyStore).getFile();
+// } catch (IOException ex) {
+// try {
+// ApplicationHome home = new ApplicationHome(getClass());
+// // 当前运行jar文件
+// File jarFile = home.getSource();
+// //jar同目录
+// keystore = new File(jarFile.getParent(), keyStore);
+//
+// InputStream inputStream = new ClassPathResource(keyStore).getInputStream();
+// byte[] bytes = new byte[inputStream.available()];
+//
+// inputStream.read(bytes);
+//
+// inputStream.close();
+//
+// FileOutputStream fileOutputStream = new FileOutputStream(keystore);
+// fileOutputStream.write(bytes);
+// fileOutputStream.close();
+// } catch (IOException e) {
+// e.printStackTrace();
+// }
+// }
+//
+// // 创建Connector
+// Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
+// Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler();
+// connector.setScheme("https");
+// connector.setSecure(true);
+// connector.setPort(httpsPort);
+// protocol.setSSLEnabled(true);
+// protocol.setKeystoreFile(keystore.getAbsolutePath());
+// protocol.setKeystorePass(keyStorePassword);
+// protocol.setKeystoreType(keyStoreType);
+//
+// // 添加
+// tomcat.addAdditionalTomcatConnectors(connector);
+// return tomcat;
+// }
+}
\ No newline at end of file
diff --git a/admin/src/main/java/com/example/frame/base/BaseEntity.java b/admin/src/main/java/com/example/frame/base/BaseEntity.java
new file mode 100644
index 0000000..9e2afd9
--- /dev/null
+++ b/admin/src/main/java/com/example/frame/base/BaseEntity.java
@@ -0,0 +1,99 @@
+package com.example.frame.base;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * Base - 基类
+ *
+ * @author wangbing
+ * @version 0.0.1
+ * @since 2017-01-01
+ */
+
+public class BaseEntity implements Serializable {
+
+ /**
+ * 行版本
+ */
+ private long rowVersion;
+
+ /**
+ * 创建用户
+ */
+ @JsonIgnore
+ private long createBy;
+
+ /**
+ * 创建时间
+ */
+ @JsonIgnore
+ private Date createTime;
+
+ /**
+ * 最后更新用户
+ */
+ @JsonIgnore
+ private long lastUpdateBy;
+
+ /**
+ * 最后更新时间
+ */
+ @JsonIgnore
+ private Date lastUpdateTime;
+
+ /**
+ * 是否删除
+ */
+ @JsonIgnore
+ private boolean isDeleted;
+
+ public boolean getIsDeleted() {
+ return isDeleted;
+ }
+
+ public void setIsDeleted(boolean isDeleted) {
+ this.isDeleted = isDeleted;
+ }
+
+ public long getRowVersion() {
+ return rowVersion;
+ }
+
+ public void setRowVersion(long rowVersion) {
+ this.rowVersion = rowVersion;
+ }
+
+ public long getCreateBy() {
+ return createBy;
+ }
+
+ public void setCreateBy(long createBy) {
+ this.createBy = createBy;
+ }
+
+ public long getLastUpdateBy() {
+ return lastUpdateBy;
+ }
+
+ public void setLastUpdateBy(long lastUpdateBy) {
+ this.lastUpdateBy = lastUpdateBy;
+ }
+
+ public Date getCreateTime() {
+ return createTime;
+ }
+
+ public void setCreateTime(Date createTime) {
+ this.createTime = createTime;
+ }
+
+ public Date getLastUpdateTime() {
+ return lastUpdateTime;
+ }
+
+ public void setLastUpdateTime(Date lastUpdateTime) {
+ this.lastUpdateTime = lastUpdateTime;
+ }
+}
diff --git a/admin/src/main/java/com/example/frame/base/BaseFindRequest.java b/admin/src/main/java/com/example/frame/base/BaseFindRequest.java
new file mode 100644
index 0000000..834c624
--- /dev/null
+++ b/admin/src/main/java/com/example/frame/base/BaseFindRequest.java
@@ -0,0 +1,29 @@
+package com.example.frame.base;
+
+/**
+ * BaseFindRequest - 基类
+ *
+ * @author wangbing
+ * @version 0.0.1
+ * @since 2017-01-01
+ */
+public class BaseFindRequest extends BaseGetAllRequest {
+ private int pageNumber = 1;
+ private int pageSize = 10;
+
+ public int getPageNumber() {
+ return pageNumber;
+ }
+
+ public void setPageNumber(int pageNumber) {
+ this.pageNumber = pageNumber;
+ }
+
+ public int getPageSize() {
+ return pageSize;
+ }
+
+ public void setPageSize(int pageSize) {
+ this.pageSize = pageSize;
+ }
+}
diff --git a/admin/src/main/java/com/example/frame/base/BaseFindResponse.java b/admin/src/main/java/com/example/frame/base/BaseFindResponse.java
new file mode 100644
index 0000000..ce3b0aa
--- /dev/null
+++ b/admin/src/main/java/com/example/frame/base/BaseFindResponse.java
@@ -0,0 +1,33 @@
+package com.example.frame.base;
+
+import java.util.List;
+
+/**
+ * BaseFindResponse - 基类
+ *
+ * @author wangbing
+ * @version 0.0.1
+ * @since 2017-01-01
+ */
+public class BaseFindResponse extends BaseResponse{
+
+ private List result;
+
+ private Long totalCount;
+
+ public List getResult() {
+ return result;
+ }
+
+ public void setResult(List result) {
+ this.result = result;
+ }
+
+ public Long getTotalCount() {
+ return totalCount;
+ }
+
+ public void setTotalCount(Long totalCount) {
+ this.totalCount = totalCount;
+ }
+}
diff --git a/admin/src/main/java/com/example/frame/base/BaseGetAllRequest.java b/admin/src/main/java/com/example/frame/base/BaseGetAllRequest.java
new file mode 100644
index 0000000..7fd7162
--- /dev/null
+++ b/admin/src/main/java/com/example/frame/base/BaseGetAllRequest.java
@@ -0,0 +1,32 @@
+package com.example.frame.base;
+
+/**
+ * BaseFindRequest - 基类
+ *
+ * @author wangbing
+ * @version 0.0.1
+ * @since 2017-01-01
+ */
+public class BaseGetAllRequest extends BaseRequest {
+
+ private String sortKey;
+
+ private SortType sortType;
+
+ public String getSortKey() {
+ return sortKey;
+ }
+
+ public void setSortKey(String sortKey) {
+ this.sortKey = sortKey;
+ }
+
+ public SortType getSortType() {
+ return sortType;
+ }
+
+ public void setSortType(SortType sortType) {
+ this.sortType = sortType;
+ }
+
+}
diff --git a/admin/src/main/java/com/example/frame/base/BaseRequest.java b/admin/src/main/java/com/example/frame/base/BaseRequest.java
new file mode 100644
index 0000000..848e47a
--- /dev/null
+++ b/admin/src/main/java/com/example/frame/base/BaseRequest.java
@@ -0,0 +1,12 @@
+package com.example.frame.base;
+
+/**
+ * BaseRequest - 基类
+ *
+ * @author wangbing
+ * @version 0.0.1
+ * @since 2017-01-01
+ */
+public class BaseRequest {
+
+}
diff --git a/admin/src/main/java/com/example/frame/base/BaseResponse.java b/admin/src/main/java/com/example/frame/base/BaseResponse.java
new file mode 100644
index 0000000..cbcbe9d
--- /dev/null
+++ b/admin/src/main/java/com/example/frame/base/BaseResponse.java
@@ -0,0 +1,38 @@
+package com.example.frame.base;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * BaseResponse - 基类
+ *
+ * @author wangbing
+ * @version 0.0.1
+ * @since 2017-01-01
+ */
+public class BaseResponse {
+ private List errors = new ArrayList();
+
+ public void addError(Error error){
+ this.errors.add(error);
+ }
+
+ public void addError(ErrorType type,String message){
+ this.errors.add(new Error(type,message));
+ }
+
+ public void addErrors(List errors){
+ this.errors.addAll(errors);
+ }
+
+ public boolean hasError(){
+ return this.errors.size() > 0;
+ }
+
+ /**
+ * 获取全部的错误信息,返回的是副本
+ */
+ public List getErrors() {
+ return new ArrayList(errors);
+ }
+}
diff --git a/admin/src/main/java/com/example/frame/base/BaseSearchRequest.java b/admin/src/main/java/com/example/frame/base/BaseSearchRequest.java
new file mode 100644
index 0000000..94ea40c
--- /dev/null
+++ b/admin/src/main/java/com/example/frame/base/BaseSearchRequest.java
@@ -0,0 +1,24 @@
+package com.example.frame.base;
+
+/**
+ * BaseSearchRequest - 基类
+ *
+ * @author wangbing
+ * @version 0.0.1
+ * @since 2017-01-01
+ */
+public class BaseSearchRequest extends BaseFindRequest {
+
+ /**
+ * 模糊查询的关键字。
+ */
+ private String keyword;
+
+ public String getKeyword() {
+ return keyword;
+ }
+
+ public void setKeyword(String keyword) {
+ this.keyword = keyword;
+ }
+}
diff --git a/admin/src/main/java/com/example/frame/base/BaseUpdateRequest.java b/admin/src/main/java/com/example/frame/base/BaseUpdateRequest.java
new file mode 100644
index 0000000..eebc3ab
--- /dev/null
+++ b/admin/src/main/java/com/example/frame/base/BaseUpdateRequest.java
@@ -0,0 +1,24 @@
+package com.example.frame.base;
+
+/**
+ * BaseUpdateRequest - 基类
+ *
+ * @author wangbing
+ * @version 0.0.1
+ * @since 2017-01-01
+ */
+public class BaseUpdateRequest extends BaseRequest{
+
+ /**
+ * 版本戳
+ */
+ private long rowVersion;
+
+ public long getRowVersion() {
+ return rowVersion;
+ }
+
+ public void setRowVersion(long rowVersion) {
+ this.rowVersion = rowVersion;
+ }
+}
\ No newline at end of file
diff --git a/admin/src/main/java/com/example/frame/base/Control.java b/admin/src/main/java/com/example/frame/base/Control.java
new file mode 100644
index 0000000..2f862af
--- /dev/null
+++ b/admin/src/main/java/com/example/frame/base/Control.java
@@ -0,0 +1,10 @@
+package com.example.frame.base;
+
+import org.springframework.ui.Model;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+public abstract class Control {
+ public abstract void exec(Model model, HttpServletRequest request, HttpServletResponse response);
+}
\ No newline at end of file
diff --git a/admin/src/main/java/com/example/frame/base/Error.java b/admin/src/main/java/com/example/frame/base/Error.java
new file mode 100644
index 0000000..06fd8e0
--- /dev/null
+++ b/admin/src/main/java/com/example/frame/base/Error.java
@@ -0,0 +1,41 @@
+package com.example.frame.base;
+
+/**
+ * Error - 错误基类
+ *
+ * @author wangbing
+ * @version 0.0.1
+ * @since 2017-01-01
+ */
+public class Error {
+
+ /*错误类型*/
+ private ErrorType type;
+
+ /*错误内容*/
+ private String message;
+
+ public Error() {
+ }
+
+ public Error(ErrorType type, String message) {
+ this.type = type;
+ this.message = message;
+ }
+
+ public ErrorType getType() {
+ return type;
+ }
+
+ public void setType(ErrorType type) {
+ this.type = type;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+}
diff --git a/admin/src/main/java/com/example/frame/base/ErrorType.java b/admin/src/main/java/com/example/frame/base/ErrorType.java
new file mode 100644
index 0000000..c99e7da
--- /dev/null
+++ b/admin/src/main/java/com/example/frame/base/ErrorType.java
@@ -0,0 +1,17 @@
+package com.example.frame.base;
+
+/**
+ * ErrorType - 错误类型
+ *
+ * @author wangbing
+ * @version 0.0.1
+ * @since 2017-01-01
+ */
+public enum ErrorType {
+ BUSINESS_ERROR,
+ SYSTEM_ERROR,
+ UNKNOWN_ERROR,
+ UNIQUENESS_ERROR,
+ EXPECTATION_NULL,
+ INVALID_PARAMETER
+}
diff --git a/admin/src/main/java/com/example/frame/base/FileUploadResponse.java b/admin/src/main/java/com/example/frame/base/FileUploadResponse.java
new file mode 100644
index 0000000..74fe555
--- /dev/null
+++ b/admin/src/main/java/com/example/frame/base/FileUploadResponse.java
@@ -0,0 +1,34 @@
+package com.example.frame.base;
+
+public class FileUploadResponse extends BaseResponse {
+
+ private Long id;
+
+ private String url;
+
+ private String downloadUrl;
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getUrl() {
+ return url;
+ }
+
+ public void setUrl(String url) {
+ this.url = url;
+ }
+
+ public String getDownloadUrl() {
+ return downloadUrl;
+ }
+
+ public void setDownloadUrl(String downloadUrl) {
+ this.downloadUrl = downloadUrl;
+ }
+}
diff --git a/admin/src/main/java/com/example/frame/base/Screen.java b/admin/src/main/java/com/example/frame/base/Screen.java
new file mode 100644
index 0000000..41c10e8
--- /dev/null
+++ b/admin/src/main/java/com/example/frame/base/Screen.java
@@ -0,0 +1,10 @@
+package com.example.frame.base;
+
+import org.springframework.ui.Model;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+public abstract class Screen {
+ public abstract void exec(Model model, HttpServletRequest request, HttpServletResponse response);
+}
diff --git a/admin/src/main/java/com/example/frame/base/SortType.java b/admin/src/main/java/com/example/frame/base/SortType.java
new file mode 100644
index 0000000..3670757
--- /dev/null
+++ b/admin/src/main/java/com/example/frame/base/SortType.java
@@ -0,0 +1,17 @@
+package com.example.frame.base;
+
+/**
+ * SortTypeEnum - 排序方式
+ *
+ * @author wangbing
+ * @version 0.0.1
+ * @since 2017-01-01
+ */
+public enum SortType {
+
+ //升序
+ ASC,
+
+ //降序
+ DESC
+}
\ No newline at end of file
diff --git a/admin/src/main/java/com/example/frame/base/Token.java b/admin/src/main/java/com/example/frame/base/Token.java
new file mode 100644
index 0000000..88d79a5
--- /dev/null
+++ b/admin/src/main/java/com/example/frame/base/Token.java
@@ -0,0 +1,74 @@
+package com.example.frame.base;
+
+import java.io.Serializable;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Token - 通行证类
+ *
+ * @author wangbing
+ * @version 0.0.1
+ * @since 2017-01-01
+ */
+public class Token implements Serializable {
+ private static final Long serialVersionUID = 1L;
+ /** ID */
+ private long id;
+ /** 用户ID */
+ private long userId;
+ /** 用户名称 */
+ private String userName;
+
+ private Set resourceSet = new HashSet();
+
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public long getUserId() {
+ return userId;
+ }
+
+ public void setUserId(long userId) {
+ this.userId = userId;
+ }
+
+ public String getUserName() {
+ return userName;
+ }
+
+ public void setUserName(String userName) {
+ this.userName = userName;
+ }
+
+ public boolean hasResource(String resource){
+ for (String s : resourceSet) {
+ if (resource.matches(s)){
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public void putResource(String resource){
+ resourceSet.add(resource);
+ }
+
+ public Set getResourceSet() {
+ return resourceSet;
+ }
+
+ public void addResourceSet(Set resourceSet){
+ this.resourceSet.addAll(resourceSet);
+ }
+
+ public void addResourceSet(Token token){
+ addResourceSet(token.getResourceSet());
+ }
+}
diff --git a/admin/src/main/java/com/example/frame/freemarker/Layout.java b/admin/src/main/java/com/example/frame/freemarker/Layout.java
new file mode 100644
index 0000000..ea35850
--- /dev/null
+++ b/admin/src/main/java/com/example/frame/freemarker/Layout.java
@@ -0,0 +1,95 @@
+package com.example.frame.freemarker;
+
+import java.io.File;
+import com.example.config.ActionConfig;
+import freemarker.template.TemplateModelException;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.validation.support.BindingAwareModelMap;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+import org.springframework.web.servlet.DispatcherServlet;
+import org.springframework.web.servlet.LocaleResolver;
+import org.springframework.web.servlet.View;
+import org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.Locale;
+import com.example.frame.base.Control;
+import com.example.frame.utils.LocalData;
+
+/**
+ * 布局帮助类
+ *
+ * @author wangbing
+ * @version 0.0.1
+ * @since 2017-01-01
+ */
+@Component
+public class Layout {
+
+ @Autowired
+ private FreeMarkerViewResolver viewResolver;
+
+ private String screenPrefix = "/screen/";
+ private String controlPrefix = "/control/";
+ private String suffix = ".ftl";
+
+ public String setScreen() throws TemplateModelException {
+ try {
+ HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
+ LocaleResolver localeResolver = (LocaleResolver) request.getAttribute(DispatcherServlet.LOCALE_RESOLVER_ATTRIBUTE);
+ String servletPath = LocalData.getTarget();
+ servletPath = servletPath.replaceAll("^/", "");
+
+ String[] split = servletPath.split("/");
+ StringBuilder sb = new StringBuilder("");
+
+ // 分割组装路径
+ for (int i = 0; i < split.length; i++) {
+ sb.append(split[i]);
+ if (i != split.length - 1) {
+ sb.append(File.separator);
+ }
+ }
+
+ Locale locale = localeResolver.resolveLocale(request);
+ String viewName = "screen" + File.separator + sb.toString();
+ View view = viewResolver.resolveViewName(viewName, locale);
+ //无法找到对应screen
+ if (view == null) {
+ return "";
+ } else {
+ return screenPrefix + servletPath + suffix;
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return "";
+ }
+
+ public String setControl(String control) {
+
+ // 查找是否存在对应控制面板执行器
+ Control controlExec = null;
+ try {
+ controlExec = LocalData.getApplicationContext().getBean(ActionConfig.CONTROL_PREFIX + "." + control, Control.class);
+
+ HttpServletRequest request = LocalData.getRequest();
+ HttpServletResponse response = LocalData.getResponse();
+
+ BindingAwareModelMap modelMap = new BindingAwareModelMap();
+ controlExec.exec(modelMap, request, response);
+
+ for (String key : modelMap.keySet()) {
+ request.setAttribute(key, modelMap.get(key));
+ }
+ } catch (BeansException e) {
+
+ }
+
+ control = control.replaceAll("/", File.separator);
+ return controlPrefix + control + suffix;
+ }
+}
diff --git a/admin/src/main/java/com/example/frame/freemarker/Uri.java b/admin/src/main/java/com/example/frame/freemarker/Uri.java
new file mode 100644
index 0000000..7489a53
--- /dev/null
+++ b/admin/src/main/java/com/example/frame/freemarker/Uri.java
@@ -0,0 +1,41 @@
+package com.example.frame.freemarker;
+
+import freemarker.template.TemplateModelException;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+import javax.servlet.http.HttpServletRequest;
+import java.util.Locale;
+
+/**
+ * Url帮助类
+ *
+ * @author wangbing
+ * @version 0.0.1
+ * @since 2017-01-01
+ */
+@Component
+public class Uri {
+
+ public String getUrl(String path) throws TemplateModelException {
+ if (path == null) {
+ return "";
+ }
+
+ if (!path.startsWith("/")) {
+ return "/" + path;
+ }
+
+ HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
+ // 协议
+ String scheme = request.getScheme();
+ // 域名
+ String serverName = request.getServerName();
+ // 端口
+ int serverPort = request.getServerPort();
+ // 上下文路径
+ String contextPath = request.getContextPath();
+
+ return String.format(Locale.CHINA, "%s://%s:%d%s%s", scheme, serverName, serverPort, contextPath, path);
+ }
+}
diff --git a/admin/src/main/java/com/example/frame/freemarker/ViewNameTranslator.java b/admin/src/main/java/com/example/frame/freemarker/ViewNameTranslator.java
new file mode 100644
index 0000000..d1f33d3
--- /dev/null
+++ b/admin/src/main/java/com/example/frame/freemarker/ViewNameTranslator.java
@@ -0,0 +1,106 @@
+package com.example.frame.freemarker;
+
+import com.example.frame.utils.LocalData;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.web.servlet.DispatcherServlet;
+import org.springframework.web.servlet.LocaleResolver;
+import org.springframework.web.servlet.View;
+import org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator;
+import org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver;
+import javax.annotation.PostConstruct;
+import javax.servlet.http.HttpServletRequest;
+import java.io.File;
+import java.util.Locale;
+import java.util.Map;
+
+/**
+ * FreemarkerViewName解析器
+ *
+ * @author wangbing
+ * @version 0.0.1
+ * @since 2017-01-01
+ */
+@Component("viewNameTranslator")
+public class ViewNameTranslator extends DefaultRequestToViewNameTranslator {
+
+ @Autowired
+ private FreeMarkerViewResolver viewResolver;
+ @Autowired
+ private Layout layout;
+ @Autowired
+ private Uri uri;
+
+ @PostConstruct
+ public void setSharedVariable() {
+ //设置基本工具类
+ Map attributesMap = viewResolver.getAttributesMap();
+ attributesMap.put("Layout", layout);
+ attributesMap.put("Uri", uri);
+ }
+
+ @Override
+ public String getViewName(HttpServletRequest request) {
+ String viewName = "";
+ try {
+ LocaleResolver localeResolver = (LocaleResolver) request.getAttribute(DispatcherServlet.LOCALE_RESOLVER_ATTRIBUTE);
+ String servletPath = LocalData.getTarget();
+ servletPath = servletPath.replaceAll("^/", "");
+ Locale locale = localeResolver.resolveLocale(request);
+
+ {//查询screen
+ String[] split = servletPath.split("/");
+ StringBuilder sb = new StringBuilder("");
+ sb.append("screen");
+ for (int i = 0; i < split.length; i++) {
+ sb.append(File.separator);
+ sb.append(split[i]);
+ }
+ viewName = sb.toString();
+ View view = viewResolver.resolveViewName(viewName, locale);
+ if (view == null) {
+// LogUtil.e("can not find screen.");
+// HttpServletResponse response = LocalData.getResponse();
+// response.setStatus(HttpStatus.NOT_FOUND.value());
+ }
+ }
+
+ {//查找layout
+ String[] split = servletPath.split("/");
+
+ int lt = split.length;
+ while (lt > 0) {
+
+ StringBuilder sb = new StringBuilder("");
+ sb.append("layout");
+ for (int i = 0; i < lt - 1; i++) {
+ sb.append(File.separator);
+ sb.append(split[i]);
+ }
+
+ viewName = sb.toString() + File.separator + split[split.length - 1];
+
+ View view = viewResolver.resolveViewName(viewName, locale);
+ //无法找到对应layout,使用默认layout
+ if (view == null) {
+ viewName = sb.toString() + File.separator + "default";
+ View defaultView = viewResolver.resolveViewName(viewName, locale);
+ if (null == defaultView && lt == 1) {
+ System.err.println("can not find layout/default.ftl");
+ } else if (null == defaultView) {
+ lt--;
+ } else {
+ break;
+ }
+ } else {
+ break;
+ }
+ }
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return viewName;
+ }
+}
diff --git a/admin/src/main/java/com/example/frame/utils/AESUtil.java b/admin/src/main/java/com/example/frame/utils/AESUtil.java
new file mode 100644
index 0000000..44d5106
--- /dev/null
+++ b/admin/src/main/java/com/example/frame/utils/AESUtil.java
@@ -0,0 +1,110 @@
+package com.example.frame.utils;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.spec.SecretKeySpec;
+import java.io.UnsupportedEncodingException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+
+/**
+ * AESUtil 对称加密和解密工具类
+ *
+ * @author wangbing
+ * @version 0.0.1
+ * @since 2017-01-01
+ */
+public class AESUtil {
+
+ private static final String ALGORITHM = "AES";
+ private static final String ALGORITHM_STR = "AES/ECB/PKCS5Padding";
+
+ /**
+ * 加密
+ *
+ * @param data 待加密字节数组
+ * @param secret 密钥
+ * @return base64字符串
+ */
+ public static byte[] encrypt(byte[] data, String secret) {
+ try {
+ if (secret.length() != 16) {
+ throw new IllegalArgumentException("secret's length is not 16");
+ }
+ SecretKeySpec key = new SecretKeySpec(secret.getBytes(), ALGORITHM);
+ Cipher cipher = Cipher.getInstance(ALGORITHM_STR); // 创建密码器
+ cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化
+ return cipher.doFinal(data);// 加密
+ } catch (NoSuchPaddingException e) {
+ e.printStackTrace();
+ } catch (NoSuchAlgorithmException e) {
+ e.printStackTrace();
+ } catch (InvalidKeyException e) {
+ e.printStackTrace();
+ } catch (IllegalBlockSizeException e) {
+ e.printStackTrace();
+ } catch (BadPaddingException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ /**
+ * 加密
+ *
+ * @param data 待加密字节数组
+ * @param secret 密钥
+ * @return base64字符串
+ */
+ public static String encrypt2Base64(byte[] data, String secret) {
+ byte[] encrypt = encrypt(data, secret);
+ return Base64Util.encodeToString(encrypt, false);
+ }
+
+ /**
+ * 解密
+ *
+ * @param data 待解密字节数组
+ * @param secret 密钥
+ * @return
+ */
+ public static byte[] decrypt(byte[] data, String secret) {
+ try {
+ if (secret.length() != 16) {
+ throw new IllegalArgumentException("secret's length is not 16");
+ }
+ SecretKeySpec key = new SecretKeySpec(secret.getBytes(), ALGORITHM);
+ Cipher cipher = Cipher.getInstance(ALGORITHM_STR);
+ cipher.init(Cipher.DECRYPT_MODE, key);
+ return cipher.doFinal(data);
+ } catch (NoSuchAlgorithmException e) {
+ e.printStackTrace();
+ } catch (NoSuchPaddingException e) {
+ e.printStackTrace();
+ } catch (InvalidKeyException e) {
+ e.printStackTrace();
+ } catch (IllegalBlockSizeException e) {
+ e.printStackTrace();
+ } catch (BadPaddingException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ public static byte[] decryptBase64(String base64Data, String secret) {
+ byte[] decode = Base64Util.decode(base64Data);
+ return decrypt(decode, secret);
+ }
+
+ public static String decrypt2String(String base64Data, String secret) {
+ byte[] bytes = decryptBase64(base64Data, secret);
+ try {
+ return new String(bytes, "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+}
\ No newline at end of file
diff --git a/admin/src/main/java/com/example/frame/utils/Base64Util.java b/admin/src/main/java/com/example/frame/utils/Base64Util.java
new file mode 100644
index 0000000..253fddb
--- /dev/null
+++ b/admin/src/main/java/com/example/frame/utils/Base64Util.java
@@ -0,0 +1,497 @@
+package com.example.frame.utils;
+
+import java.util.Arrays;
+
+/**
+ * Base64Util
+ *
+ * @author wangbing
+ * @version 0.0.1
+ * @since 2017-01-01
+ */
+public class Base64Util {
+ private static final char[] CA = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray();
+ private static final int[] IA = new int[256];
+
+ static {
+ Arrays.fill(IA, -1);
+ for (int i = 0, iS = CA.length; i < iS; i++)
+ IA[CA[i]] = i;
+ IA['='] = 0;
+ }
+
+ public final static String encodeToString(byte[] sArr) {
+ return new String(encodeToChar(sArr, false));
+ }
+
+ public final static char[] encodeToChar(byte[] sArr, boolean lineSep) {
+ // Check special case
+ int sLen = sArr != null ? sArr.length : 0;
+ if (sLen == 0)
+ return new char[0];
+
+ int eLen = (sLen / 3) * 3; // Length of even 24-bits.
+ int cCnt = ((sLen - 1) / 3 + 1) << 2; // Returned character count
+ int dLen = cCnt + (lineSep ? (cCnt - 1) / 76 << 1 : 0); // Length of returned array
+ char[] dArr = new char[dLen];
+
+ // Encode even 24-bits
+ for (int s = 0, d = 0, cc = 0; s < eLen; ) {
+ // Copy next three bytes into lower 24 bits of int, paying attension to sign.
+ int i = (sArr[s++] & 0xff) << 16 | (sArr[s++] & 0xff) << 8 | (sArr[s++] & 0xff);
+
+ // Encode the int into four chars
+ dArr[d++] = CA[(i >>> 18) & 0x3f];
+ dArr[d++] = CA[(i >>> 12) & 0x3f];
+ dArr[d++] = CA[(i >>> 6) & 0x3f];
+ dArr[d++] = CA[i & 0x3f];
+
+ // Add optional line separator
+ if (lineSep && ++cc == 19 && d < dLen - 2) {
+ dArr[d++] = '\r';
+ dArr[d++] = '\n';
+ cc = 0;
+ }
+ }
+
+ // Pad and encode last bits if source isn't even 24 bits.
+ int left = sLen - eLen; // 0 - 2.
+ if (left > 0) {
+ // Prepare the int
+ int i = ((sArr[eLen] & 0xff) << 10) | (left == 2 ? ((sArr[sLen - 1] & 0xff) << 2) : 0);
+
+ // Set last four chars
+ dArr[dLen - 4] = CA[i >> 12];
+ dArr[dLen - 3] = CA[(i >>> 6) & 0x3f];
+ dArr[dLen - 2] = left == 2 ? CA[i & 0x3f] : '=';
+ dArr[dLen - 1] = '=';
+ }
+ return dArr;
+ }
+
+ /**
+ * Encodes a raw byte array into a BASE64 String
representation i accordance with RFC 2045.
+ *
+ * @param sArr The bytes to convert. If null
or length 0 an empty array will be returned.
+ * @param lineSep Optional "\r\n" after 76 characters, unless end of file.
+ * No line separator will be in breach of RFC 2045 which specifies max 76 per line but will be a
+ * little faster.
+ * @return A BASE64 encoded array. Never null
.
+ */
+ public final static String encodeToString(byte[] sArr, boolean lineSep) {
+ // Reuse char[] since we can't create a String incrementally anyway and StringBuffer/Builder would be slower.
+ return new String(encodeToChar(sArr, lineSep));
+ }
+
+ /**
+ * Encodes a raw byte array into a BASE64 byte[]
representation i accordance with RFC 2045.
+ *
+ * @param sArr The bytes to convert. If null
or length 0 an empty array will be returned.
+ * @param lineSep Optional "\r\n" after 76 characters, unless end of file.
+ * No line separator will be in breach of RFC 2045 which specifies max 76 per line but will be a
+ * little faster.
+ * @return A BASE64 encoded array. Never null
.
+ */
+ public final static byte[] encodeToByte(byte[] sArr, boolean lineSep) {
+ // Check special case
+ int sLen = sArr != null ? sArr.length : 0;
+ if (sLen == 0)
+ return new byte[0];
+
+ int eLen = (sLen / 3) * 3; // Length of even 24-bits.
+ int cCnt = ((sLen - 1) / 3 + 1) << 2; // Returned character count
+ int dLen = cCnt + (lineSep ? (cCnt - 1) / 76 << 1 : 0); // Length of returned array
+ byte[] dArr = new byte[dLen];
+
+ // Encode even 24-bits
+ for (int s = 0, d = 0, cc = 0; s < eLen; ) {
+ // Copy next three bytes into lower 24 bits of int, paying attension to sign.
+ int i = (sArr[s++] & 0xff) << 16 | (sArr[s++] & 0xff) << 8 | (sArr[s++] & 0xff);
+
+ // Encode the int into four chars
+ dArr[d++] = (byte) CA[(i >>> 18) & 0x3f];
+ dArr[d++] = (byte) CA[(i >>> 12) & 0x3f];
+ dArr[d++] = (byte) CA[(i >>> 6) & 0x3f];
+ dArr[d++] = (byte) CA[i & 0x3f];
+
+ // Add optional line separator
+ if (lineSep && ++cc == 19 && d < dLen - 2) {
+ dArr[d++] = '\r';
+ dArr[d++] = '\n';
+ cc = 0;
+ }
+ }
+
+ // Pad and encode last bits if source isn't an even 24 bits.
+ int left = sLen - eLen; // 0 - 2.
+ if (left > 0) {
+ // Prepare the int
+ int i = ((sArr[eLen] & 0xff) << 10) | (left == 2 ? ((sArr[sLen - 1] & 0xff) << 2) : 0);
+
+ // Set last four chars
+ dArr[dLen - 4] = (byte) CA[i >> 12];
+ dArr[dLen - 3] = (byte) CA[(i >>> 6) & 0x3f];
+ dArr[dLen - 2] = left == 2 ? (byte) CA[i & 0x3f] : (byte) '=';
+ dArr[dLen - 1] = '=';
+ }
+ return dArr;
+ }
+
+ public final static byte[] decode(char[] sArr) {
+ // Check special case
+ int sLen = sArr != null ? sArr.length : 0;
+ if (sLen == 0)
+ return new byte[0];
+
+ // Count illegal characters (including '\r', '\n') to know what size the returned array will be,
+ // so we don't have to reallocate & copy it later.
+ int sepCnt = 0; // Number of separator characters. (Actually illegal characters, but that's a bonus...)
+ for (int i = 0; i < sLen; i++) // If input is "pure" (I.e. no line separators or illegal chars) base64 this loop can be commented out.
+ if (IA[sArr[i]] < 0)
+ sepCnt++;
+
+ // Check so that legal chars (including '=') are evenly divideable by 4 as specified in RFC 2045.
+ if ((sLen - sepCnt) % 4 != 0)
+ return null;
+
+ int pad = 0;
+ for (int i = sLen; i > 1 && IA[sArr[--i]] <= 0; )
+ if (sArr[i] == '=')
+ pad++;
+
+ int len = ((sLen - sepCnt) * 6 >> 3) - pad;
+
+ byte[] dArr = new byte[len]; // Preallocate byte[] of exact length
+
+ for (int s = 0, d = 0; d < len; ) {
+ // Assemble three bytes into an int from four "valid" characters.
+ int i = 0;
+ for (int j = 0; j < 4; j++) { // j only increased if a valid char was found.
+ int c = IA[sArr[s++]];
+ if (c >= 0)
+ i |= c << (18 - j * 6);
+ else
+ j--;
+ }
+ // Add the bytes
+ dArr[d++] = (byte) (i >> 16);
+ if (d < len) {
+ dArr[d++] = (byte) (i >> 8);
+ if (d < len)
+ dArr[d++] = (byte) i;
+ }
+ }
+ return dArr;
+ }
+
+ /**
+ * Decodes a BASE64 encoded byte array. All illegal characters will be ignored and can handle both arrays with
+ * and without line separators.
+ *
+ * @param sArr The source array. Length 0 will return an empty array. null
will throw an exception.
+ * @return The decoded array of bytes. May be of length 0. Will be null
if the legal characters
+ * (including '=') isn't divideable by 4. (I.e. definitely corrupted).
+ */
+ public final static byte[] decode(byte[] sArr) {
+ // Check special case
+ int sLen = sArr.length;
+
+ // Count illegal characters (including '\r', '\n') to know what size the returned array will be,
+ // so we don't have to reallocate & copy it later.
+ int sepCnt = 0; // Number of separator characters. (Actually illegal characters, but that's a bonus...)
+ for (int i = 0; i < sLen; i++) // If input is "pure" (I.e. no line separators or illegal chars) base64 this loop can be commented out.
+ if (IA[sArr[i] & 0xff] < 0)
+ sepCnt++;
+
+ // Check so that legal chars (including '=') are evenly divideable by 4 as specified in RFC 2045.
+ if ((sLen - sepCnt) % 4 != 0)
+ return null;
+
+ int pad = 0;
+ for (int i = sLen; i > 1 && IA[sArr[--i] & 0xff] <= 0; )
+ if (sArr[i] == '=')
+ pad++;
+
+ int len = ((sLen - sepCnt) * 6 >> 3) - pad;
+
+ byte[] dArr = new byte[len]; // Preallocate byte[] of exact length
+
+ for (int s = 0, d = 0; d < len; ) {
+ // Assemble three bytes into an int from four "valid" characters.
+ int i = 0;
+ for (int j = 0; j < 4; j++) { // j only increased if a valid char was found.
+ int c = IA[sArr[s++] & 0xff];
+ if (c >= 0)
+ i |= c << (18 - j * 6);
+ else
+ j--;
+ }
+
+ // Add the bytes
+ dArr[d++] = (byte) (i >> 16);
+ if (d < len) {
+ dArr[d++] = (byte) (i >> 8);
+ if (d < len)
+ dArr[d++] = (byte) i;
+ }
+ }
+
+ return dArr;
+ }
+
+ /**
+ * Decodes a BASE64 encoded byte array that is known to be resonably well formatted. The method is about twice as
+ * fast as {@link =#=decode(byte[])}. The preconditions are:
+ * + The array must have a line length of 76 chars OR no line separators at all (one line).
+ * + Line separator must be "\r\n", as specified in RFC 2045
+ * + The array must not contain illegal characters within the encoded string
+ * + The array CAN have illegal characters at the beginning and end, those will be dealt with appropriately.
+ *
+ * @param sArr The source array. Length 0 will return an empty array. null
will throw an exception.
+ * @return The decoded array of bytes. May be of length 0.
+ */
+ public final static byte[] decodeFast(byte[] sArr) {
+ // Check special case
+ int sLen = sArr.length;
+ if (sLen == 0)
+ return new byte[0];
+
+ int sIx = 0, eIx = sLen - 1; // Start and end index after trimming.
+
+ // Trim illegal chars from start
+ while (sIx < eIx && IA[sArr[sIx] & 0xff] < 0)
+ sIx++;
+
+ // Trim illegal chars from end
+ while (eIx > 0 && IA[sArr[eIx] & 0xff] < 0)
+ eIx--;
+
+ // get the padding count (=) (0, 1 or 2)
+ int pad = sArr[eIx] == '=' ? (sArr[eIx - 1] == '=' ? 2 : 1) : 0; // Count '=' at end.
+ int cCnt = eIx - sIx + 1; // Content count including possible separators
+ int sepCnt = sLen > 76 ? (sArr[76] == '\r' ? cCnt / 78 : 0) << 1 : 0;
+
+ int len = ((cCnt - sepCnt) * 6 >> 3) - pad; // The number of decoded bytes
+ byte[] dArr = new byte[len]; // Preallocate byte[] of exact length
+
+ // Decode all but the last 0 - 2 bytes.
+ int d = 0;
+ for (int cc = 0, eLen = (len / 3) * 3; d < eLen; ) {
+ // Assemble three bytes into an int from four "valid" characters.
+ int i = IA[sArr[sIx++]] << 18 | IA[sArr[sIx++]] << 12 | IA[sArr[sIx++]] << 6 | IA[sArr[sIx++]];
+
+ // Add the bytes
+ dArr[d++] = (byte) (i >> 16);
+ dArr[d++] = (byte) (i >> 8);
+ dArr[d++] = (byte) i;
+
+ // If line separator, jump over it.
+ if (sepCnt > 0 && ++cc == 19) {
+ sIx += 2;
+ cc = 0;
+ }
+ }
+
+ if (d < len) {
+ // Decode last 1-3 bytes (incl '=') into 1-3 bytes
+ int i = 0;
+ for (int j = 0; sIx <= eIx - pad; j++)
+ i |= IA[sArr[sIx++]] << (18 - j * 6);
+
+ for (int r = 16; d < len; r -= 8)
+ dArr[d++] = (byte) (i >> r);
+ }
+
+ return dArr;
+ }
+
+ /**
+ * Decodes a BASE64 encoded char array that is known to be resonably well formatted. The method is about twice as
+ * fast as {@link =#=decode(char[])}. The preconditions are:
+ * + The array must have a line length of 76 chars OR no line separators at all (one line).
+ * + Line separator must be "\r\n", as specified in RFC 2045
+ * + The array must not contain illegal characters within the encoded string
+ * + The array CAN have illegal characters at the beginning and end, those will be dealt with appropriately.
+ *
+ * @param sArr The source array. Length 0 will return an empty array. null
will throw an exception.
+ * @return The decoded array of bytes. May be of length 0.
+ */
+ public final static byte[] decodeFast(char[] sArr) {
+ // Check special case
+ int sLen = sArr.length;
+ if (sLen == 0)
+ return new byte[0];
+
+ int sIx = 0, eIx = sLen - 1; // Start and end index after trimming.
+
+ // Trim illegal chars from start
+ while (sIx < eIx && IA[sArr[sIx]] < 0)
+ sIx++;
+
+ // Trim illegal chars from end
+ while (eIx > 0 && IA[sArr[eIx]] < 0)
+ eIx--;
+
+ // get the padding count (=) (0, 1 or 2)
+ int pad = sArr[eIx] == '=' ? (sArr[eIx - 1] == '=' ? 2 : 1) : 0; // Count '=' at end.
+ int cCnt = eIx - sIx + 1; // Content count including possible separators
+ int sepCnt = sLen > 76 ? (sArr[76] == '\r' ? cCnt / 78 : 0) << 1 : 0;
+
+ int len = ((cCnt - sepCnt) * 6 >> 3) - pad; // The number of decoded bytes
+ byte[] dArr = new byte[len]; // Preallocate byte[] of exact length
+
+ // Decode all but the last 0 - 2 bytes.
+ int d = 0;
+ for (int cc = 0, eLen = (len / 3) * 3; d < eLen; ) {
+ // Assemble three bytes into an int from four "valid" characters.
+ int i = IA[sArr[sIx++]] << 18 | IA[sArr[sIx++]] << 12 | IA[sArr[sIx++]] << 6 | IA[sArr[sIx++]];
+
+ // Add the bytes
+ dArr[d++] = (byte) (i >> 16);
+ dArr[d++] = (byte) (i >> 8);
+ dArr[d++] = (byte) i;
+
+ // If line separator, jump over it.
+ if (sepCnt > 0 && ++cc == 19) {
+ sIx += 2;
+ cc = 0;
+ }
+ }
+
+ if (d < len) {
+ // Decode last 1-3 bytes (incl '=') into 1-3 bytes
+ int i = 0;
+ for (int j = 0; sIx <= eIx - pad; j++)
+ i |= IA[sArr[sIx++]] << (18 - j * 6);
+
+ for (int r = 16; d < len; r -= 8)
+ dArr[d++] = (byte) (i >> r);
+ }
+
+ return dArr;
+ }
+
+ /**
+ * Decodes a BASE64 encoded String
. All illegal characters will be ignored and can handle both strings with
+ * and without line separators.
+ * Note! It can be up to about 2x the speed to call decode(str.toCharArray())
instead. That
+ * will create a temporary array though. This version will use str.charAt(i)
to iterate the string.
+ *
+ * @param str The source string. null
or length 0 will return an empty array.
+ * @return The decoded array of bytes. May be of length 0. Will be null
if the legal characters
+ * (including '=') isn't divideable by 4. (I.e. definitely corrupted).
+ */
+ public final static byte[] decode(String str) {
+ // Check special case
+ int sLen = str != null ? str.length() : 0;
+ if (sLen == 0)
+ return new byte[0];
+
+ // Count illegal characters (including '\r', '\n') to know what size the returned array will be,
+ // so we don't have to reallocate & copy it later.
+ int sepCnt = 0; // Number of separator characters. (Actually illegal characters, but that's a bonus...)
+ for (int i = 0; i < sLen; i++) // If input is "pure" (I.e. no line separators or illegal chars) base64 this loop can be commented out.
+ if (IA[str.charAt(i)] < 0)
+ sepCnt++;
+
+ // Check so that legal chars (including '=') are evenly divideable by 4 as specified in RFC 2045.
+ if ((sLen - sepCnt) % 4 != 0)
+ return null;
+
+ // Count '=' at end
+ int pad = 0;
+ for (int i = sLen; i > 1 && IA[str.charAt(--i)] <= 0; )
+ if (str.charAt(i) == '=')
+ pad++;
+
+ int len = ((sLen - sepCnt) * 6 >> 3) - pad;
+
+ byte[] dArr = new byte[len]; // Preallocate byte[] of exact length
+
+ for (int s = 0, d = 0; d < len; ) {
+ // Assemble three bytes into an int from four "valid" characters.
+ int i = 0;
+ for (int j = 0; j < 4; j++) { // j only increased if a valid char was found.
+ int c = IA[str.charAt(s++)];
+ if (c >= 0)
+ i |= c << (18 - j * 6);
+ else
+ j--;
+ }
+ // Add the bytes
+ dArr[d++] = (byte) (i >> 16);
+ if (d < len) {
+ dArr[d++] = (byte) (i >> 8);
+ if (d < len)
+ dArr[d++] = (byte) i;
+ }
+ }
+ return dArr;
+ }
+
+ /**
+ * Decodes a BASE64 encoded string that is known to be resonably well formatted. The method is about twice as
+ * fast as {@link =#=decode(String)}. The preconditions are:
+ * + The array must have a line length of 76 chars OR no line separators at all (one line).
+ * + Line separator must be "\r\n", as specified in RFC 2045
+ * + The array must not contain illegal characters within the encoded string
+ * + The array CAN have illegal characters at the beginning and end, those will be dealt with appropriately.
+ *
+ * @param str The source string. Length 0 will return an empty array. null
will throw an exception.
+ * @return The decoded array of bytes. May be of length 0.
+ */
+ public final static byte[] decodeFast(String str) {
+ // Check special case
+ int sLen = str.length();
+ if (sLen == 0)
+ return new byte[0];
+
+ int sIx = 0, eIx = sLen - 1; // Start and end index after trimming.
+
+ // Trim illegal chars from start
+ while (sIx < eIx && IA[str.charAt(sIx) & 0xff] < 0)
+ sIx++;
+
+ // Trim illegal chars from end
+ while (eIx > 0 && IA[str.charAt(eIx) & 0xff] < 0)
+ eIx--;
+
+ // get the padding count (=) (0, 1 or 2)
+ int pad = str.charAt(eIx) == '=' ? (str.charAt(eIx - 1) == '=' ? 2 : 1) : 0; // Count '=' at end.
+ int cCnt = eIx - sIx + 1; // Content count including possible separators
+ int sepCnt = sLen > 76 ? (str.charAt(76) == '\r' ? cCnt / 78 : 0) << 1 : 0;
+
+ int len = ((cCnt - sepCnt) * 6 >> 3) - pad; // The number of decoded bytes
+ byte[] dArr = new byte[len]; // Preallocate byte[] of exact length
+
+ // Decode all but the last 0 - 2 bytes.
+ int d = 0;
+ for (int cc = 0, eLen = (len / 3) * 3; d < eLen; ) {
+ // Assemble three bytes into an int from four "valid" characters.
+ int i = IA[str.charAt(sIx++)] << 18 | IA[str.charAt(sIx++)] << 12 | IA[str.charAt(sIx++)] << 6 | IA[str.charAt(sIx++)];
+
+ // Add the bytes
+ dArr[d++] = (byte) (i >> 16);
+ dArr[d++] = (byte) (i >> 8);
+ dArr[d++] = (byte) i;
+
+ // If line separator, jump over it.
+ if (sepCnt > 0 && ++cc == 19) {
+ sIx += 2;
+ cc = 0;
+ }
+ }
+
+ if (d < len) {
+ // Decode last 1-3 bytes (incl '=') into 1-3 bytes
+ int i = 0;
+ for (int j = 0; sIx <= eIx - pad; j++)
+ i |= IA[str.charAt(sIx++)] << (18 - j * 6);
+
+ for (int r = 16; d < len; r -= 8)
+ dArr[d++] = (byte) (i >> r);
+ }
+
+ return dArr;
+ }
+}
diff --git a/admin/src/main/java/com/example/frame/utils/CookieUtil.java b/admin/src/main/java/com/example/frame/utils/CookieUtil.java
new file mode 100644
index 0000000..3f2f512
--- /dev/null
+++ b/admin/src/main/java/com/example/frame/utils/CookieUtil.java
@@ -0,0 +1,34 @@
+package com.example.frame.utils;
+
+import javax.servlet.http.Cookie;
+
+/**
+ * CookieUtil
+ *
+ * @author wangbing
+ * @version 0.0.1
+ * @since 2017-01-01
+ */
+public class CookieUtil {
+
+ /**
+ * 通过Cookies获取内容
+ *
+ * @param cookies Cookies
+ * @return passportID
+ */
+ public static String getCookieValue(Cookie[] cookies, String key) {
+ if (cookies != null) {
+ for (Cookie cookie : cookies) {
+ // Cookie中存放的为passport的id ,Cookie名称通过ConfigToolObject获取
+ if (cookie != null && cookie.getName().equals(key)) {
+ try {
+ return cookie.getValue();
+ } catch (Exception ignored) {
+ }
+ }
+ }
+ }
+ return null;
+ }
+}
diff --git a/admin/src/main/java/com/example/frame/utils/IDgenerator.java b/admin/src/main/java/com/example/frame/utils/IDgenerator.java
new file mode 100644
index 0000000..390ae19
--- /dev/null
+++ b/admin/src/main/java/com/example/frame/utils/IDgenerator.java
@@ -0,0 +1,73 @@
+package com.example.frame.utils;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+
+/**
+ * IDgenerator - ID生成器
+ *
+ * @author wangbing
+ * @version 0.0.1
+ * @since 2017-01-01
+ */
+public class IDgenerator {
+
+ private static long workerId = 1L;
+ private static long datacenterId = 1L;
+ private static long sequence = 0L;
+ // 时间起始标记点,作为基准,一般取系统的最近时间(一旦确定不能变动)
+ private static long twepoch = 1531130104852L;
+ // 机器标识位数
+ private static long workerIdBits = 2L;//分布应用可设置为5,这里减少占位增加可支持时间
+ // 数据中心标识位数
+ private static long datacenterIdBits = 2L;//分布应用可设置为5,这里减少占位增加可支持时间
+ // 机器ID最大值
+ private static long maxWorkerId = -1L ^ (-1L << workerIdBits);
+ // 数据中心ID最大值
+ private static long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);
+ // 毫秒内自增位
+ private static long sequenceBits = 12L;
+ // 机器ID偏左移12位
+ private static long workerIdShift = sequenceBits;
+ // 数据中心ID左移17位
+ private static long datacenterIdShift = sequenceBits + workerIdBits;
+ // 时间毫秒左移22位
+ private static long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;
+ private static long sequenceMask = -1L ^ (-1L << sequenceBits);
+ // 上次生产id时间戳
+ private static long lastTimestamp = -1L;
+
+ public static synchronized long nextId() {
+ long timestamp = timeGen();
+
+ if (timestamp < lastTimestamp) {
+ throw new RuntimeException(String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));
+ }
+
+ if (lastTimestamp == timestamp) {
+ sequence = (sequence + 1) & sequenceMask;
+ if (sequence == 0) {
+ timestamp = tilNextMillis(lastTimestamp);
+ }
+ } else {
+ sequence = 0L;
+ }
+
+ lastTimestamp = timestamp;
+
+ return ((timestamp - twepoch) << timestampLeftShift) | (datacenterId << datacenterIdShift) | (workerId << workerIdShift) | sequence;
+ }
+
+ protected static long tilNextMillis(long lastTimestamp) {
+ long timestamp = timeGen();
+ while (timestamp <= lastTimestamp) {
+ timestamp = timeGen();
+ }
+ return timestamp;
+ }
+
+ protected static long timeGen() {
+ return System.currentTimeMillis();
+ }
+}
diff --git a/admin/src/main/java/com/example/frame/utils/LocalData.java b/admin/src/main/java/com/example/frame/utils/LocalData.java
new file mode 100644
index 0000000..ff1d2c4
--- /dev/null
+++ b/admin/src/main/java/com/example/frame/utils/LocalData.java
@@ -0,0 +1,90 @@
+package com.example.frame.utils;
+
+import com.example.frame.base.Token;
+import org.springframework.context.ApplicationContext;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+import org.springframework.web.context.support.WebApplicationContextUtils;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * LocalData - 本地数据存放类
+ *
+ * @author wangbing
+ * @version 0.0.1
+ * @since 2017-01-01
+ */
+public class LocalData {
+
+ private static Token temp = null;
+
+ private static Token system = null;
+
+ static {
+ // 组装临时Token和系统Token
+ temp = new Token();
+ temp.setId(-1);
+ temp.setUserId(-1);
+ temp.setUserName("游客");
+ temp.putResource("/");
+ temp.putResource("/ajax");
+ temp.putResource("/upload");
+ temp.putResource("/index.htm");
+ temp.putResource("/home.htm");
+ temp.putResource("/app.htm");
+ temp.putResource("ajax.example.example");
+ system = new Token();
+ system.setId(0);
+ system.setUserId(0);
+ system.setUserName("system");
+ system.putResource(".*");
+ }
+
+ public static Token getTempToken(){
+ return temp;
+ }
+
+ public static Token getSysToken() {
+ return system;
+ }
+
+ /**
+ * 当请求目标 target = '/aa/bb'
+ */
+ private static final ThreadLocal targetHolder = new ThreadLocal();
+
+ public static String getTarget() {
+ return targetHolder.get();
+ }
+
+ public static void setTarget(String target) {
+ targetHolder.set(target);
+ }
+
+ /**
+ * 当前用户的通行证
+ */
+ private static final ThreadLocal tokenHolder = new ThreadLocal();
+
+ public static Token getToken() {
+ return tokenHolder.get();
+ }
+
+ public static void setToken(Token token) {
+ tokenHolder.set(token);
+ }
+
+ public static HttpServletRequest getRequest() {
+ return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
+ }
+
+ public static HttpServletResponse getResponse() {
+ return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
+ }
+
+ public static ApplicationContext getApplicationContext() {
+ return WebApplicationContextUtils.getWebApplicationContext(getRequest().getServletContext());
+ }
+}
diff --git a/admin/src/main/java/com/example/frame/utils/LogUtil.java b/admin/src/main/java/com/example/frame/utils/LogUtil.java
new file mode 100644
index 0000000..ea9bc7f
--- /dev/null
+++ b/admin/src/main/java/com/example/frame/utils/LogUtil.java
@@ -0,0 +1,70 @@
+package com.example.frame.utils;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * LogUtil - 日志记录工具类
+ *
+ * @author wangbing
+ * @version 0.0.1
+ * @since 2017-01-01
+ */
+public class LogUtil {
+
+ //定义一个全局的记录器,通过LoggerFactory获取
+ private final static Logger logger = LoggerFactory.getLogger(LogUtil.class);
+
+ /**
+ * 输出info日志
+ * @param context 日志内容
+ */
+ public static void i(String context){
+ logger.info(context);
+ }
+
+ /**
+ * 输出debug日志
+ * @param context 日志内容
+ */
+ public static void d(String context){
+ logger.debug(context);
+ }
+
+ /**
+ * 输出warn日志
+ * @param context 日志内容
+ */
+ public static void w(String context){
+ logger.warn(context);
+ }
+
+ /**
+ * 输出error日志
+ * @param context 日志内容
+ */
+ public static void e(String context){
+ logger.error(context);
+ }
+
+ /**
+ * 获取异常详细堆栈信息
+ */
+ public static void dumpException(Throwable e){
+ StringBuffer msg = new StringBuffer("null");
+ if (e != null) {
+ msg = new StringBuffer("");
+ String message = e.toString();
+ int length = e.getStackTrace().length;
+ if (length > 0) {
+ msg.append(message).append("\n");
+ for (int i = 0; i < length; i++) {
+ msg.append("\t").append(e.getStackTrace()[i]).append("\n");
+ }
+ } else {
+ msg.append(message);
+ }
+ }
+ logger.error(msg.toString());
+ }
+}
diff --git a/admin/src/main/java/com/example/frame/utils/MD5Util.java b/admin/src/main/java/com/example/frame/utils/MD5Util.java
new file mode 100644
index 0000000..b5b4d23
--- /dev/null
+++ b/admin/src/main/java/com/example/frame/utils/MD5Util.java
@@ -0,0 +1,58 @@
+package com.example.frame.utils;
+
+import com.fasterxml.jackson.core.TreeNode;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Iterator;
+
+/**
+ * MD5Util - MD5工具类
+ *
+ * @author wangbing
+ * @version 0.0.1
+ * @since 2017-01-01
+ */
+public class MD5Util {
+
+ /**
+ * 加密
+ *
+ * @param value
+ * @return
+ */
+ public static String encode(String value) {
+ try {
+ MessageDigest md = MessageDigest.getInstance("md5");
+ byte[] e = md.digest(value.getBytes());
+ return toHexString(e);
+ } catch (NoSuchAlgorithmException e) {
+ e.printStackTrace();
+ return value;
+ }
+ }
+
+ public static String encode(byte[] bytes) {
+ try {
+ MessageDigest md = MessageDigest.getInstance("md5");
+ byte[] e = md.digest(bytes);
+ return toHexString(e);
+ } catch (NoSuchAlgorithmException e) {
+ e.printStackTrace();
+ return "";
+ }
+ }
+
+ private static String toHexString(byte bytes[]) {
+ StringBuilder hs = new StringBuilder();
+ String stmp = "";
+ for (int n = 0; n < bytes.length; n++) {
+ stmp = Integer.toHexString(bytes[n] & 0xff);
+ if (stmp.length() == 1)
+ hs.append("0").append(stmp);
+ else
+ hs.append(stmp);
+ }
+
+ return hs.toString();
+ }
+}
diff --git a/admin/src/main/java/com/example/frame/utils/MapperUtil.java b/admin/src/main/java/com/example/frame/utils/MapperUtil.java
new file mode 100644
index 0000000..2746acd
--- /dev/null
+++ b/admin/src/main/java/com/example/frame/utils/MapperUtil.java
@@ -0,0 +1,133 @@
+package com.example.frame.utils;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.TreeNode;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.*;
+import org.dozer.DozerBeanMapper;
+import org.dozer.Mapper;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+
+/**
+ * MapUtil - 映射转化工具类
+ *
+ * @author wangbing
+ * @version 0.0.1
+ * @since 2017-01-01
+ */
+public class MapperUtil {
+ private static ObjectMapper om;
+ private static Mapper mapper;
+
+ static {
+ //初始化
+ om = new ObjectMapper();
+ //序列化时忽略null属性
+ om.setSerializationInclusion(JsonInclude.Include.NON_NULL);
+ //序列化时排序
+ om.configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, true);
+ //反序列化是忽略多余字段
+ om.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+ //支持空类序列化时出错InvalidDefinitionException
+ om.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS,false);
+
+ mapper = new DozerBeanMapper();
+ }
+
+ public static TreeNode toTree(String json) {
+ try {
+ return om.readTree(json);
+ } catch (IOException e) {
+ e.printStackTrace();
+ return om.createObjectNode();
+ }
+ }
+
+ public static TreeNode toTree(Object json) {
+ return om.valueToTree(json);
+ }
+
+ public static String toJson(Object object) {
+ return toJson(object, false);
+ }
+
+ public static String toJson(Object object, boolean pretty) {
+ try {
+ if (pretty) {
+ return om.writerWithDefaultPrettyPrinter().writeValueAsString(object);
+ } else {
+ return om.writeValueAsString(object);
+ }
+ } catch (JsonProcessingException e) {
+ e.printStackTrace();
+ return "{}";
+ }
+ }
+
+ public static String toJson(JsonNode jsonNode) {
+ return jsonNode.asText();
+ }
+
+ public static T toJava(String json, Class cls) {
+ try {
+ if (json == null || "".equals(json)) {
+ return cls.newInstance();
+ }
+ return om.readValue(json, cls);
+ } catch (IOException e) {
+ e.printStackTrace();
+ } catch (IllegalAccessException e) {
+ e.printStackTrace();
+ } catch (InstantiationException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ public static T toJava(TreeNode treeNode, Class cls) {
+ try {
+ return om.treeToValue(treeNode, cls);
+ } catch (JsonProcessingException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ public static T toJava(String json, TypeReference valueTypeRef) {
+ try {
+ return om.readValue(json, valueTypeRef);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ public static List toJavaList(String json, TypeReference> reference) {
+ try {
+ return om.readValue(json, reference);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ public static List toJavaList(InputStream json, TypeReference> reference) {
+ try {
+ return om.readValue(json, reference);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ public static T map(Object o, Class aClass) {
+ return mapper.map(o, aClass);
+ }
+
+ public static void map(Object o, Object o1) {
+ mapper.map(o, o1);
+ }
+}
diff --git a/admin/src/main/java/com/example/frame/utils/Message.java b/admin/src/main/java/com/example/frame/utils/Message.java
new file mode 100644
index 0000000..d788d93
--- /dev/null
+++ b/admin/src/main/java/com/example/frame/utils/Message.java
@@ -0,0 +1,21 @@
+package com.example.frame.utils;
+
+
+/**
+ * Message - 基本消息类
+ *
+ * @author wangbing
+ * @version 0.0.1
+ * @since 2017-01-01
+ */
+public class Message {
+ public static final String ERROR_500 = "服务器走了下神,稍后再试一次";
+ public static final String NOT_EXIST_METHOD = "调用的方法不存在";
+
+ public static String CREATE_FAILURE = "创建失败,请刷新后重新尝试";
+ public static String DELETE_FAILURE = "删除失败,请刷新后重新尝试";
+ public static String UPDATE_FAILURE = "更新失败,请刷新后重新尝试";
+ public static String FIND_FAILURE = "查询失败,请刷新后重新尝试";
+ public static String GET_FAILURE = "未获取相应内容";
+ public static String INSERT_DUPLICATE = "已经存在相同数据,返回列表页面确认";
+}
diff --git a/admin/src/main/java/com/example/frame/utils/ProcessUtil.java b/admin/src/main/java/com/example/frame/utils/ProcessUtil.java
new file mode 100644
index 0000000..c82562a
--- /dev/null
+++ b/admin/src/main/java/com/example/frame/utils/ProcessUtil.java
@@ -0,0 +1,117 @@
+package com.example.frame.utils;
+
+import java.awt.*;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+
+/**
+ * 程序操作工具
+ *
+ * @author wangbing
+ * @version 0.0.1
+ * @since 2017-01-01
+ */
+public class ProcessUtil {
+ /**
+ * 启动windows系统下的exe文件
+ * @param path 可执行exe文件路径
+ */
+ public static void execExe(String path) {
+ Runtime rn = Runtime.getRuntime();
+ Process p = null;
+ try {
+ p = rn.exec(path);
+ } catch (Exception e) {
+ System.out.println("Error exec!");
+ }
+ }
+
+ /**
+ * 执行windows批处理文件路
+ * @param path 可执行批处理文件路径
+ */
+ public static void execBat(String path) {
+ Runtime rn = Runtime.getRuntime();
+ Process p = null;
+ try {
+ p = rn.exec(path);
+ } catch (Exception e) {
+ System.out.println("Error exec!");
+ }
+ }
+
+ /**
+ * 执行windows cmd命令
+ * @param command cmd命令
+ */
+ public static String execCmd(String command) {
+ return exec("cmd /c " + command);
+ }
+
+
+ /**
+ * 执行运行环境命令
+ * @param command cmd命令
+ */
+ public static String exec(String command) {
+ StringBuilder build = new StringBuilder();
+ Runtime runtime = Runtime.getRuntime();
+ Process process = null;
+ try {
+ process = runtime.exec(command);
+ BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream(), "UTF-8"));
+ String line = null;
+ while ((line = br.readLine()) != null) {
+ build.append(line);
+ }
+ process.destroy();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return build.toString();
+ }
+
+ /**
+ * @throws IOException
+ * @desc 杀死进程
+ * @author zp
+ * @date 2018-3-29
+ */
+ public static void killProc(String processName) throws IOException {
+ if (processName != null && !"".equals(processName)) {
+ execCmd("taskkill /F /IM " + processName);
+ }
+ }
+
+ /**
+ * @desc 判断进程是否开启
+ * @author zp
+ * @date 2018-3-29
+ */
+ public static boolean findProcess(String processName) {
+ BufferedReader bufferedReader = null;
+ try {
+ Process proc = Runtime.getRuntime().exec("tasklist -fi " + '"' + "imagename eq " + processName + '"');
+ bufferedReader = new BufferedReader(new InputStreamReader(proc.getInputStream()));
+ String line = null;
+ while ((line = bufferedReader.readLine()) != null) {
+ if (line.contains(processName)) {
+ return true;
+ }
+ }
+ return false;
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ return false;
+ } finally {
+ if (bufferedReader != null) {
+ try {
+ bufferedReader.close();
+ } catch (Exception ex) {
+ }
+ }
+ }
+ }
+}
diff --git a/admin/src/main/java/com/example/frame/utils/RSAUtil.java b/admin/src/main/java/com/example/frame/utils/RSAUtil.java
new file mode 100644
index 0000000..9e4e207
--- /dev/null
+++ b/admin/src/main/java/com/example/frame/utils/RSAUtil.java
@@ -0,0 +1,308 @@
+package com.example.frame.utils;
+
+import javax.crypto.Cipher;
+import java.io.ByteArrayOutputStream;
+import java.io.UnsupportedEncodingException;
+import java.security.*;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPublicKey;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+import java.util.Arrays;
+
+/**
+ * RSAUtil - RSA工具类
+ *
+ * @author wangbing
+ * @version 0.0.1
+ * @since 2017-01-01
+ */
+public class RSAUtil {
+
+ private static String cryptPublicKeyBase64 = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCTrwfsrJjCF+pP4S3A/wrD4U1txg53EuBC1mPt" +
+ "3vGXvSK2U0YNRVR3Q65ooHnPKmk4LwI8v+7+ATTxUg3qkuRiDuzBa5zLkYKM50LOgEWSdOKzbnbx" +
+ "a5FnE7IXawNt1p8+MVN1TTI7J/fZy6g1x0WBy1odE5Osru4WfZNOqQtjHwIDAQAB";
+ private static String cryptPrivateKeyBase64 = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAJOvB+ysmMIX6k/hLcD/CsPhTW3G" +
+ "DncS4ELWY+3e8Ze9IrZTRg1FVHdDrmigec8qaTgvAjy/7v4BNPFSDeqS5GIO7MFrnMuRgoznQs6A" +
+ "RZJ04rNudvFrkWcTshdrA23Wnz4xU3VNMjsn99nLqDXHRYHLWh0Tk6yu7hZ9k06pC2MfAgMBAAEC" +
+ "gYBjLRjKRMI1HfBZgmPChsPI9YWU4XuXVVLLL8Rd2uktOHOWM2gIw3VMvmPimVoT2GxesZr0BwTN" +
+ "CSxvnuX/kHPTqtsIu1r5Iup3mGbvlj3sn8RvG0yvUDglDN7QVDqqN7XWvHJSBVfBzDXeExA/WGnE" +
+ "6BOocNT9qkqA/UWNbCXGKQJBAN0Fd/P2D6EvCd2RztHhzVE6V8s/LwOTDnGn/YhdMpddy9TwZpBi" +
+ "r7I6lzcLWQ1HfDUive3t+DGXqPqr/4FfkG0CQQCrDlZKf216QrXOmJ70LQSbflgvGYU+b6kLFyEh" +
+ "+15HcIBfKUQCU+XUK4UzLMQDYxdngTNMNyq4AQ9Sh0tUTUI7AkEAtkq9XayzxWhLhcCtyTOoqPcq" +
+ "1Aqf1x3iCuHYXTEo+ek1pcJFhY6vhJuIfrDQWQB9tEGcTvI4A4cnquBTkzvjnQJAYid58ImqYmuB" +
+ "M6l0HJzwdeFL7MryIF+mWozNIFjDQq8VmoVtVwCZcuP+LN1VJLRpq6UBsIw/YRKKnkqwORGUHQJA" +
+ "UuR0G/3Hai+vKDA14tIYIH6C4zNmbULxAEuQVh9thfafWNmiDcifApvkxQ2ewXwEGeJtz44zv6iY" +
+ "3f3yq+a2OQ==";
+
+ private static String signPublicKeyBase64 = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCTrwfsrJjCF+pP4S3A/wrD4U1txg53EuBC1mPt" +
+ "3vGXvSK2U0YNRVR3Q65ooHnPKmk4LwI8v+7+ATTxUg3qkuRiDuzBa5zLkYKM50LOgEWSdOKzbnbx" +
+ "a5FnE7IXawNt1p8+MVN1TTI7J/fZy6g1x0WBy1odE5Osru4WfZNOqQtjHwIDAQAB";
+ private static String signPrivateKeyBase64 = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAJOvB+ysmMIX6k/hLcD/CsPhTW3G" +
+ "DncS4ELWY+3e8Ze9IrZTRg1FVHdDrmigec8qaTgvAjy/7v4BNPFSDeqS5GIO7MFrnMuRgoznQs6A" +
+ "RZJ04rNudvFrkWcTshdrA23Wnz4xU3VNMjsn99nLqDXHRYHLWh0Tk6yu7hZ9k06pC2MfAgMBAAEC" +
+ "gYBjLRjKRMI1HfBZgmPChsPI9YWU4XuXVVLLL8Rd2uktOHOWM2gIw3VMvmPimVoT2GxesZr0BwTN" +
+ "CSxvnuX/kHPTqtsIu1r5Iup3mGbvlj3sn8RvG0yvUDglDN7QVDqqN7XWvHJSBVfBzDXeExA/WGnE" +
+ "6BOocNT9qkqA/UWNbCXGKQJBAN0Fd/P2D6EvCd2RztHhzVE6V8s/LwOTDnGn/YhdMpddy9TwZpBi" +
+ "r7I6lzcLWQ1HfDUive3t+DGXqPqr/4FfkG0CQQCrDlZKf216QrXOmJ70LQSbflgvGYU+b6kLFyEh" +
+ "+15HcIBfKUQCU+XUK4UzLMQDYxdngTNMNyq4AQ9Sh0tUTUI7AkEAtkq9XayzxWhLhcCtyTOoqPcq" +
+ "1Aqf1x3iCuHYXTEo+ek1pcJFhY6vhJuIfrDQWQB9tEGcTvI4A4cnquBTkzvjnQJAYid58ImqYmuB" +
+ "M6l0HJzwdeFL7MryIF+mWozNIFjDQq8VmoVtVwCZcuP+LN1VJLRpq6UBsIw/YRKKnkqwORGUHQJA" +
+ "UuR0G/3Hai+vKDA14tIYIH6C4zNmbULxAEuQVh9thfafWNmiDcifApvkxQ2ewXwEGeJtz44zv6iY" +
+ "3f3yq+a2OQ==";
+
+ /**
+ * 创建密钥和私钥
+ */
+ public static void createKey() {
+ try {
+ KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
+ keyPairGenerator.initialize(1024);
+ KeyPair keyPair = keyPairGenerator.generateKeyPair();
+
+ //公钥
+ RSAPublicKey aPublic = (RSAPublicKey) keyPair.getPublic();
+ //私钥
+ RSAPrivateKey aPrivate = (RSAPrivateKey) keyPair.getPrivate();
+ //把密钥对象对应的字节转为Base64字符存储
+ System.err.println("publicKeyBase64-->" + Base64Util.encodeToString(aPublic.getEncoded()));
+ System.err.println("privateKeyBase64-->" + Base64Util.encodeToString(aPrivate.getEncoded()));
+ } catch (NoSuchAlgorithmException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public static String encrypt2Base64(byte[] data) {
+ byte[] encrypt = encrypt(data);
+ return Base64Util.encodeToString(encrypt);
+ }
+
+ public static byte[] encrypt(String data) {
+ return encrypt(data.getBytes());
+ }
+
+ /**
+ * 加密
+ *
+ * @param data 待加密数据
+ */
+ public static byte[] encrypt(byte[] data) {
+ try {
+ //生成公钥对象
+ KeyFactory keyFactory = KeyFactory.getInstance("RSA");
+ X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(Base64Util.decode(cryptPublicKeyBase64));
+ PublicKey aPublic = keyFactory.generatePublic(x509EncodedKeySpec);
+
+ //分段加密开始
+ ByteArrayOutputStream bs = new ByteArrayOutputStream();
+ Cipher rsa = Cipher.getInstance("RSA");
+ rsa.init(Cipher.ENCRYPT_MODE, aPublic);
+ int offset = 0;
+ while (offset < data.length) {
+ byte[] bytes = rsa.doFinal(Arrays.copyOfRange(data, offset, Math.min(offset + 117, data.length)));
+ bs.write(bytes);
+ offset += 117;
+ }
+ return bs.toByteArray();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ /**
+ * 加密
+ *
+ * @param data 待加密明文
+ */
+ public static byte[] encrypt(String data, PublicKey aPublic) {
+ try {
+ if (aPublic == null) {
+ System.err.println("PublicKey can not be null");
+ return null;
+ }
+
+ //分段加密开始
+ ByteArrayOutputStream bs = new ByteArrayOutputStream();
+ Cipher rsa = Cipher.getInstance("RSA");
+ rsa.init(Cipher.ENCRYPT_MODE, aPublic);
+ int offset = 0;
+ byte[] b = data.getBytes();
+ while (offset < b.length) {
+ byte[] bytes = rsa.doFinal(Arrays.copyOfRange(b, offset, Math.min(offset + 117, b.length)));
+ bs.write(bytes);
+ offset += 117;
+ }
+ return bs.toByteArray();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ /**
+ * @param base64String base64编码字符串
+ * @return
+ */
+ public static byte[] decrypt(String base64String) {
+ return decrypt(Base64Util.decode(base64String));
+ }
+
+ public static String decrypt2String(String base64String) {
+ byte[] decrypt = decrypt(Base64Util.decode(base64String));
+ try {
+ return new String(decrypt, "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ /**
+ * 解密
+ *
+ * @param data 已加密字节
+ */
+ public static byte[] decrypt(byte[] data) {
+ try {
+ //生成私钥对象
+ KeyFactory keyFactory = KeyFactory.getInstance("RSA");
+ PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64Util.decode(cryptPrivateKeyBase64));
+ PrivateKey aPrivate = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
+
+ Cipher rsa = Cipher.getInstance("RSA");
+ rsa.init(Cipher.DECRYPT_MODE, aPrivate);
+ //获得密文字节
+ ByteArrayOutputStream bs = new ByteArrayOutputStream();
+ int offset = 0;
+ while (offset < data.length) {
+ byte[] bytes = rsa.doFinal(Arrays.copyOfRange(data, offset, Math.min(offset + 128, data.length)));
+ bs.write(bytes);
+ offset += 128;
+ }
+ return bs.toByteArray();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ /**
+ * 解密
+ *
+ * @param data 已加密字节
+ * @param aPrivate 公钥
+ * @return 解密后的字节
+ */
+ public static byte[] decrypt(byte[] data, PublicKey aPrivate) {
+ try {
+ if (aPrivate == null) {
+ System.err.println("PublicKey can not be null");
+ return null;
+ }
+
+ Cipher rsa = Cipher.getInstance("RSA");
+ rsa.init(Cipher.DECRYPT_MODE, aPrivate);
+ //获得密文字节
+ ByteArrayOutputStream bs = new ByteArrayOutputStream();
+ int offset = 0;
+ while (offset < data.length) {
+ byte[] bytes = rsa.doFinal(Arrays.copyOfRange(data, offset, Math.min(offset + 128, data.length)));
+ bs.write(bytes);
+ offset += 128;
+ }
+ return bs.toByteArray();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ public static String sign2Base64(byte[] data) {
+ return sign2Base64(data, signPrivateKeyBase64);
+ }
+
+ public static String sign2Base64(byte[] data, String privateKey) {
+ byte[] sign = sign(data, privateKey);
+ return Base64Util.encodeToString(sign);
+ }
+
+ /**
+ * RSA签名
+ *
+ * @param data 待签名数据
+ * @param privateKey 私钥
+ * @return 签名字节数组
+ */
+ public static byte[] sign(byte[] data, String privateKey) {
+ try {
+ KeyFactory keyFactory = KeyFactory.getInstance("RSA");
+ PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(Base64Util.decode(privateKey));
+ PrivateKey aPrivate = keyFactory.generatePrivate(priPKCS8);
+
+ Signature signature = Signature.getInstance("SHA1WithRSA");
+
+ signature.initSign(aPrivate);
+ signature.update(data);
+ return signature.sign();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ return null;
+ }
+
+ /**
+ * RSA验签名检查
+ *
+ * @param data 待签名数据
+ * @param sign base64 签名字符串
+ * @param publicKey 公钥
+ * @return 布尔值
+ */
+ public static boolean doCheck(byte[] data, String sign, String publicKey) {
+ try {
+ KeyFactory keyFactory = KeyFactory.getInstance("RSA");
+ byte[] encodedKey = Base64Util.decode(publicKey);
+ PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
+ Signature signature = Signature.getInstance("SHA1WithRSA");
+ signature.initVerify(pubKey);
+ signature.update(data);
+ return signature.verify(Base64Util.decode(sign));
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return false;
+ }
+
+ public static boolean doCheck(byte[] data, String sign) {
+ return doCheck(data, sign, signPublicKeyBase64);
+ }
+
+ public static PublicKey parsePublicKey(String cryptPublicKeyBase64) {
+ try {
+ KeyFactory keyFactory = KeyFactory.getInstance("RSA");
+ X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(Base64Util.decode(cryptPublicKeyBase64));
+ return keyFactory.generatePublic(x509EncodedKeySpec);
+ } catch (NoSuchAlgorithmException e) {
+ e.printStackTrace();
+ } catch (InvalidKeySpecException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ public static PrivateKey parsePrivateKey(String cryptPrivateKeyBase64) {
+ try {
+ KeyFactory keyFactory = KeyFactory.getInstance("RSA");
+ PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(Base64Util.decode(cryptPrivateKeyBase64));
+ return keyFactory.generatePrivate(priPKCS8);
+ } catch (NoSuchAlgorithmException e) {
+ e.printStackTrace();
+ } catch (InvalidKeySpecException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+}
diff --git a/admin/src/main/java/com/example/frame/utils/ValidationUtil.java b/admin/src/main/java/com/example/frame/utils/ValidationUtil.java
new file mode 100644
index 0000000..8f0cc6e
--- /dev/null
+++ b/admin/src/main/java/com/example/frame/utils/ValidationUtil.java
@@ -0,0 +1,54 @@
+package com.example.frame.utils;
+
+import com.example.frame.base.BaseRequest;
+import com.example.frame.base.BaseResponse;
+import com.example.frame.base.ErrorType;
+import javax.validation.ConstraintViolation;
+import javax.validation.Validation;
+import javax.validation.Validator;
+import javax.validation.ValidatorFactory;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * 验证工具类。提供一些通用简单的数据验证功能
+ *
+ * @author wangbing
+ * @version 0.0.1
+ * @since 2017-01-01
+ */
+public class ValidationUtil {
+
+ private static ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
+
+ public static T validate(BaseRequest req, T response) {
+
+ if (req == null) {
+ response.addError(ErrorType.EXPECTATION_NULL, "请求对象不能为空");
+ return response;
+ }
+
+ try {
+ Validator validator = factory.getValidator();
+
+ Set> constraintViolations = validator.validate(req);
+
+ if (constraintViolations.size() > 0) {
+ for (ConstraintViolation violation : constraintViolations) {
+ response.addError(ErrorType.INVALID_PARAMETER, violation.getMessage());
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ LogUtil.dumpException(e);
+ response.addError(ErrorType.BUSINESS_ERROR, e.getMessage());
+ }
+ return response;
+ }
+}
diff --git a/admin/src/main/java/com/example/frame/utils/WebUtils.java b/admin/src/main/java/com/example/frame/utils/WebUtils.java
new file mode 100644
index 0000000..bf7da8f
--- /dev/null
+++ b/admin/src/main/java/com/example/frame/utils/WebUtils.java
@@ -0,0 +1,459 @@
+package com.example.frame.utils;
+
+import javax.net.ssl.*;
+import java.io.*;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.URLDecoder;
+import java.net.URLEncoder;
+import java.security.SecureRandom;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * WebUtils - 模拟http访问工具类
+ *
+ * @author wangbing
+ * @version 0.0.1
+ * @since 2017-01-01
+ */
+public class WebUtils {
+ private static final String DEFAULT_CHARSET = "UTF-8";
+ private static final String METHOD_POST = "POST";
+ private static final String METHOD_GET = "GET";
+ //private static final Certificate verisign; //
+ private static boolean ignoreSSLCheck; // 忽略SSL检查
+
+ private static class TrustAllTrustManager implements X509TrustManager {
+ public X509Certificate[] getAcceptedIssuers() {
+ return null;
+ }
+
+ public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
+ }
+
+ public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
+ }
+ }
+
+ private WebUtils() {
+ }
+
+ public static void setIgnoreSSLCheck(boolean ignoreSSLCheck) {
+ WebUtils.ignoreSSLCheck = ignoreSSLCheck;
+ }
+
+ /**
+ * 执行HTTP POST请求。
+ *
+ * @param url 请求地址
+ * @param params 请求参数
+ * @return 响应字符串
+ */
+ public static String doPost(String url, Map params, int connectTimeout, int readTimeout) throws IOException {
+ return doPost(url, params, DEFAULT_CHARSET, connectTimeout, readTimeout);
+ }
+
+ /**
+ * 执行HTTP POST请求。
+ *
+ * @param url 请求地址
+ * @param params 请求参数
+ * @param charset 字符集,如UTF-8, GBK, GB2312
+ * @return 响应字符串
+ */
+ public static String doPost(String url, Map params, String charset, int connectTimeout, int readTimeout) throws IOException {
+ return doPost(url, params, charset, connectTimeout, readTimeout, null);
+ }
+
+ public static String doPost(String url, Map params, String charset, int connectTimeout, int readTimeout, Map headerMap) throws IOException {
+ String ctype = "application/x-www-form-urlencoded;charset=" + charset;
+ String query = buildQuery(params, charset);
+ byte[] content = {};
+ if (query != null) {
+ content = query.getBytes(charset);
+ }
+ return _doPost(url, ctype, content, connectTimeout, readTimeout, headerMap);
+ }
+
+ /**
+ * 执行HTTP POST请求。
+ *
+ * @param url 请求地址
+ * @param ctype 请求类型
+ * @param content 请求字节数组
+ * @return 响应字符串
+ */
+ public static String doPost(String url, String ctype, byte[] content, int connectTimeout, int readTimeout) throws IOException {
+ return _doPost(url, ctype, content, connectTimeout, readTimeout, null);
+ }
+
+ private static String _doPost(String url, String ctype, byte[] content, int connectTimeout, int readTimeout, Map headerMap) throws IOException {
+ HttpURLConnection conn = null;
+ OutputStream out = null;
+ String rsp = null;
+ try {
+ try {
+ conn = getConnection(new URL(url), METHOD_POST, ctype, headerMap);
+ conn.setConnectTimeout(connectTimeout);
+ conn.setReadTimeout(readTimeout);
+ } catch (IOException e) {
+ throw e;
+ }
+ try {
+ out = conn.getOutputStream();
+ out.write(content);
+ rsp = getResponseAsString(conn);
+ } catch (IOException e) {
+ throw e;
+ }
+ } finally {
+ if (out != null) {
+ out.close();
+ }
+ if (conn != null) {
+ conn.disconnect();
+ }
+ }
+
+ return rsp;
+ }
+
+ private static byte[] getTextEntry(String fieldName, String fieldValue, String charset) throws IOException {
+ StringBuilder entry = new StringBuilder();
+ entry.append("Content-Disposition:form-data;name=\"");
+ entry.append(fieldName);
+ entry.append("\"\r\nContent-Type:text/plain\r\n\r\n");
+ entry.append(fieldValue);
+ return entry.toString().getBytes(charset);
+ }
+
+ private static byte[] getFileEntry(String fieldName, String fileName, String mimeType, String charset) throws IOException {
+ StringBuilder entry = new StringBuilder();
+ entry.append("Content-Disposition:form-data;name=\"");
+ entry.append(fieldName);
+ entry.append("\";filename=\"");
+ entry.append(fileName);
+ entry.append("\"\r\nContent-Type:");
+ entry.append(mimeType);
+ entry.append("\r\n\r\n");
+ return entry.toString().getBytes(charset);
+ }
+
+ /**
+ * 执行HTTP GET请求。
+ *
+ * @param url 请求地址
+ * @param params 请求参数
+ * @return 响应字符串
+ */
+ public static String doGet(String url, Map params) throws IOException {
+ return doGet(url, params, DEFAULT_CHARSET);
+ }
+
+ /**
+ * 执行HTTP GET请求。
+ *
+ * @param url 请求地址
+ * @param params 请求参数
+ * @param charset 字符集,如UTF-8, GBK, GB2312
+ * @return 响应字符串
+ */
+ public static String doGet(String url, Map params, String charset) throws IOException {
+ HttpURLConnection conn = null;
+ String rsp = null;
+
+ try {
+ String ctype = "application/x-www-form-urlencoded;charset=" + charset;
+ String query = buildQuery(params, charset);
+ try {
+ conn = getConnection(buildGetUrl(url, query), METHOD_GET, ctype, null);
+ } catch (IOException e) {
+ throw e;
+ }
+
+ try {
+ rsp = getResponseAsString(conn);
+ } catch (IOException e) {
+ throw e;
+ }
+ } finally {
+ if (conn != null) {
+ conn.disconnect();
+ }
+ }
+
+ return rsp;
+ }
+
+ private static HttpURLConnection getConnection(URL url, String method, String ctype, Map headerMap) throws IOException {
+ HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+ if (conn instanceof HttpsURLConnection) {
+ HttpsURLConnection connHttps = (HttpsURLConnection) conn;
+ if (ignoreSSLCheck) {
+ try {
+ SSLContext ctx = SSLContext.getInstance("TLS");
+ ctx.init(null, new TrustManager[]{new TrustAllTrustManager()}, new SecureRandom());
+ connHttps.setSSLSocketFactory(ctx.getSocketFactory());
+ connHttps.setHostnameVerifier(new HostnameVerifier() {
+ public boolean verify(String hostname, SSLSession session) {
+ return true;
+ }
+ });
+ } catch (Exception e) {
+ throw new IOException(e);
+ }
+ } else {
+ try {
+ //SSLContext ctx = SSLContext.getInstance("TLS");
+ //ctx.init(null, new TrustManager[] { new VerisignTrustManager() }, new SecureRandom());
+ //connHttps.setSSLSocketFactory(ctx.getSocketFactory());
+ } catch (Exception e) {
+ throw new IOException(e);
+ }
+ }
+ conn = connHttps;
+ }
+
+ conn.setRequestMethod(method);
+ conn.setDoInput(true);
+ conn.setDoOutput(true);
+ conn.setRequestProperty("Accept", "text/xml,text/javascript");
+ conn.setRequestProperty("User-Agent", "top-sdk-java");
+ conn.setRequestProperty("Content-Type", ctype);
+ if (headerMap != null) {
+ for (Map.Entry entry : headerMap.entrySet()) {
+ conn.setRequestProperty(entry.getKey(), entry.getValue());
+ }
+ }
+ return conn;
+ }
+
+ private static URL buildGetUrl(String strUrl, String query) throws IOException {
+ URL url = new URL(strUrl);
+ if (isEmpty(query)) {
+ return url;
+ }
+
+ if (isEmpty(url.getQuery())) {
+ if (strUrl.endsWith("?")) {
+ strUrl = strUrl + query;
+ } else {
+ strUrl = strUrl + "?" + query;
+ }
+ } else {
+ if (strUrl.endsWith("&")) {
+ strUrl = strUrl + query;
+ } else {
+ strUrl = strUrl + "&" + query;
+ }
+ }
+
+ return new URL(strUrl);
+ }
+
+ public static String buildQuery(Map params, String charset) throws IOException {
+ if (params == null || params.isEmpty()) {
+ return null;
+ }
+
+ StringBuilder query = new StringBuilder();
+ Set> entries = params.entrySet();
+ boolean hasParam = false;
+
+ for (Map.Entry entry : entries) {
+ String name = entry.getKey();
+ String value = entry.getValue();
+ // 忽略参数名或参数值为空的参数
+ if (areNotEmpty(name, value)) {
+ if (hasParam) {
+ query.append("&");
+ } else {
+ hasParam = true;
+ }
+
+ query.append(name).append("=").append(URLEncoder.encode(value, charset));
+ }
+ }
+
+ return query.toString();
+ }
+
+ public static boolean isEmpty(String value) {
+ int strLen;
+ if (value == null || (strLen = value.length()) == 0) {
+ return true;
+ }
+ for (int i = 0; i < strLen; i++) {
+ if ((Character.isWhitespace(value.charAt(i)) == false)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * 检查指定的字符串列表是否不为空。
+ */
+ public static boolean areNotEmpty(String... values) {
+ boolean result = true;
+ if (values == null || values.length == 0) {
+ result = false;
+ } else {
+ for (String value : values) {
+ result &= !isEmpty(value);
+ }
+ }
+ return result;
+ }
+
+ protected static String getResponseAsString(HttpURLConnection conn) throws IOException {
+ String charset = getResponseCharset(conn.getContentType());
+ InputStream es = conn.getErrorStream();
+ if (es == null) {
+ return getStreamAsString(conn.getInputStream(), charset);
+ } else {
+ String msg = getStreamAsString(es, charset);
+ if (isEmpty(msg)) {
+ throw new IOException(conn.getResponseCode() + ":" + conn.getResponseMessage());
+ } else {
+ throw new IOException(msg);
+ }
+ }
+ }
+
+ private static String getStreamAsString(InputStream stream, String charset) throws IOException {
+ try {
+ Reader reader = new InputStreamReader(stream, charset);
+ StringBuilder response = new StringBuilder();
+
+ final char[] buff = new char[1024];
+ int read = 0;
+ while ((read = reader.read(buff)) > 0) {
+ response.append(buff, 0, read);
+ }
+
+ return response.toString();
+ } finally {
+ if (stream != null) {
+ stream.close();
+ }
+ }
+ }
+
+ private static String getResponseCharset(String ctype) {
+ String charset = DEFAULT_CHARSET;
+
+ if (!isEmpty(ctype)) {
+ String[] params = ctype.split(";");
+ for (String param : params) {
+ param = param.trim();
+ if (param.startsWith("charset")) {
+ String[] pair = param.split("=", 2);
+ if (pair.length == 2) {
+ if (!isEmpty(pair[1])) {
+ charset = pair[1].trim();
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ return charset;
+ }
+
+ /**
+ * 使用默认的UTF-8字符集反编码请求参数值。
+ *
+ * @param value 参数值
+ * @return 反编码后的参数值
+ */
+ public static String decode(String value) {
+ return decode(value, DEFAULT_CHARSET);
+ }
+
+ /**
+ * 使用默认的UTF-8字符集编码请求参数值。
+ *
+ * @param value 参数值
+ * @return 编码后的参数值
+ */
+ public static String encode(String value) {
+ return encode(value, DEFAULT_CHARSET);
+ }
+
+ /**
+ * 使用指定的字符集反编码请求参数值。
+ *
+ * @param value 参数值
+ * @param charset 字符集
+ * @return 反编码后的参数值
+ */
+ public static String decode(String value, String charset) {
+ String result = null;
+ if (!isEmpty(value)) {
+ try {
+ result = URLDecoder.decode(value, charset);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * 使用指定的字符集编码请求参数值。
+ *
+ * @param value 参数值
+ * @param charset 字符集
+ * @return 编码后的参数值
+ */
+ public static String encode(String value, String charset) {
+ String result = null;
+ if (!isEmpty(value)) {
+ try {
+ result = URLEncoder.encode(value, charset);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ return result;
+ }
+
+ private static Map getParamsFromUrl(String url) {
+ Map map = null;
+ if (url != null && url.indexOf('?') != -1) {
+ map = splitUrlQuery(url.substring(url.indexOf('?') + 1));
+ }
+ if (map == null) {
+ map = new HashMap();
+ }
+ return map;
+ }
+
+ /**
+ * 从URL中提取所有的参数。
+ *
+ * @param query URL地址
+ * @return 参数映射
+ */
+ public static Map splitUrlQuery(String query) {
+ Map result = new HashMap();
+
+ String[] pairs = query.split("&");
+ if (pairs != null && pairs.length > 0) {
+ for (String pair : pairs) {
+ String[] param = pair.split("=", 2);
+ if (param != null && param.length == 2) {
+ result.put(param[0], param[1]);
+ }
+ }
+ }
+
+ return result;
+ }
+}
diff --git a/admin/src/main/java/com/example/frame/validation/Dict.java b/admin/src/main/java/com/example/frame/validation/Dict.java
new file mode 100644
index 0000000..f96f392
--- /dev/null
+++ b/admin/src/main/java/com/example/frame/validation/Dict.java
@@ -0,0 +1,18 @@
+package com.example.frame.validation;
+
+import javax.validation.Constraint;
+import javax.validation.Payload;
+import java.lang.annotation.*;
+
+@Target({ElementType.FIELD})
+@Retention(RetentionPolicy.RUNTIME)
+@Constraint(validatedBy = DictValidator.class)
+public @interface Dict {
+ String message() default "字典项错误";
+
+ String name() default "";
+
+ Class>[] groups() default {};
+
+ Class extends Payload>[] payload() default {};
+}
diff --git a/admin/src/main/java/com/example/frame/validation/DictValidator.java b/admin/src/main/java/com/example/frame/validation/DictValidator.java
new file mode 100644
index 0000000..10fa99a
--- /dev/null
+++ b/admin/src/main/java/com/example/frame/validation/DictValidator.java
@@ -0,0 +1,36 @@
+package com.example.frame.validation;
+
+import javax.validation.ConstraintValidator;
+import javax.validation.ConstraintValidatorContext;
+import java.util.HashSet;
+
+public class DictValidator implements ConstraintValidator {
+
+ private String name;
+
+ @Override
+ public void initialize(Dict constraint) {
+ name = constraint.name();
+ }
+
+ @Override
+ public boolean isValid(String o, ConstraintValidatorContext constraintValidatorContext) {
+ if (null == o) {
+ return true;
+ } else if (name == null) {
+ constraintValidatorContext.disableDefaultConstraintViolation();
+ constraintValidatorContext.buildConstraintViolationWithTemplate("字典名称为空").addConstraintViolation();
+ return false;
+ } else {
+ // name 字典名称
+ HashSet codeSet = new HashSet();
+ if (codeSet.contains(o)) {
+ return true;
+ } else {
+ constraintValidatorContext.disableDefaultConstraintViolation();
+ constraintValidatorContext.buildConstraintViolationWithTemplate("非法的字典[" + name + "]值").addConstraintViolation();
+ return false;
+ }
+ }
+ }
+}
diff --git a/admin/src/main/java/com/example/module/admin/ent/Mapping.java b/admin/src/main/java/com/example/module/admin/ent/Mapping.java
new file mode 100644
index 0000000..27b0643
--- /dev/null
+++ b/admin/src/main/java/com/example/module/admin/ent/Mapping.java
@@ -0,0 +1,50 @@
+package com.example.module.admin.ent;
+
+import com.example.frame.base.BaseEntity;
+
+/**
+ * MAPPING - 映射
+ *
+ * @author author
+ * @version 0.0.1
+ * @since 2019-09-28
+ */
+public class Mapping extends BaseEntity {
+
+ /**
+ * ID - 主键
+ */
+ private Long id;
+ /**
+ * USERNAME - 用户名
+ */
+ private String username;
+ /**
+ * PASSWORD - 用户密码
+ */
+ private String password;
+
+ public Long getId() {
+ return this.id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getUsername() {
+ return this.username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getPassword() {
+ return this.password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+}
\ No newline at end of file
diff --git a/admin/src/main/java/com/example/module/admin/mgr/MappingManager.java b/admin/src/main/java/com/example/module/admin/mgr/MappingManager.java
new file mode 100644
index 0000000..b9d657e
--- /dev/null
+++ b/admin/src/main/java/com/example/module/admin/mgr/MappingManager.java
@@ -0,0 +1,52 @@
+package com.example.module.admin.mgr;
+
+import com.example.module.admin.req.*;
+import com.example.module.admin.rsp.*;
+import com.example.frame.base.Token;
+
+/**
+ * 映射
+ *
+ * @author author
+ * @version 0.0.1
+ * @since 2019-09-28
+ */
+public interface MappingManager {
+
+ /**
+ * 插入
+ *
+ * @param request 请求对象
+ * @param token 令牌
+ * @return
+ */
+ MappingCreateResponse create(MappingCreateRequest request, Token token);
+
+ /**
+ * 逻辑删除
+ *
+ * @param request 请求对象
+ * @param token 令牌
+ * @return
+ */
+ MappingDeleteResponse delete(MappingDeleteRequest request, Token token);
+
+ /**
+ * 更新
+ *
+ * @param request 请求对象
+ * @param token 令牌
+ * @return
+ */
+ MappingUpdateResponse update(MappingUpdateRequest request, Token token);
+
+ /**
+ * 查询
+ *
+ * @param request 请求对象
+ * @param token 令牌
+ * @return
+ */
+ MappingFindResponse find(MappingFindRequest request, Token token);
+
+}
diff --git a/admin/src/main/java/com/example/module/admin/mgr/MappingManagerImpl.java b/admin/src/main/java/com/example/module/admin/mgr/MappingManagerImpl.java
new file mode 100644
index 0000000..58c95e4
--- /dev/null
+++ b/admin/src/main/java/com/example/module/admin/mgr/MappingManagerImpl.java
@@ -0,0 +1,113 @@
+package com.example.module.admin.mgr;
+
+import com.example.frame.utils.IDgenerator;
+import com.example.frame.utils.Message;
+import com.example.frame.base.ErrorType;
+import com.example.frame.base.Token;
+import com.example.frame.utils.MapperUtil;
+import com.example.frame.utils.ValidationUtil;
+import com.example.module.admin.ent.Mapping;
+import com.example.module.admin.req.MappingCreateRequest;
+import com.example.module.admin.req.MappingDeleteRequest;
+import com.example.module.admin.req.MappingFindRequest;
+import com.example.module.admin.req.MappingUpdateRequest;
+import com.example.module.admin.rsp.MappingCreateResponse;
+import com.example.module.admin.rsp.MappingDeleteResponse;
+import com.example.module.admin.rsp.MappingFindResponse;
+import com.example.module.admin.rsp.MappingUpdateResponse;
+import com.github.pagehelper.PageHelper;
+import com.github.pagehelper.PageInfo;
+import com.github.pagehelper.util.StringUtil;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+/**
+ * MAPPING - 映射
+ *
+ * @author author
+ * @version 0.0.1
+ * @since 2019-09-28
+ */
+@Service
+public class MappingManagerImpl implements MappingManager {
+
+ /**
+ * 插入
+ *
+ * @param request 请求对象
+ * @param token 令牌
+ * @return 响应
+ */
+ public MappingCreateResponse create(MappingCreateRequest request, Token token) {
+ MappingCreateResponse response = new MappingCreateResponse();
+
+ ValidationUtil.validate(request, response);
+ if (response.hasError()) {
+ return response;
+ }
+
+ long id = IDgenerator.nextId();
+ Mapping entity = MapperUtil.map(request, Mapping.class);
+ entity.setId(id);
+
+
+ return response;
+ }
+
+ /**
+ * 逻辑删除
+ *
+ * @param request 请求对象
+ * @param token 令牌
+ * @return 响应
+ */
+ public MappingDeleteResponse delete(MappingDeleteRequest request, Token token) {
+ MappingDeleteResponse response = new MappingDeleteResponse();
+
+ ValidationUtil.validate(request, response);
+ if (response.hasError()) {
+ return response;
+ }
+
+
+ return response;
+ }
+
+ /**
+ * 更新
+ *
+ * @param request 请求对象
+ * @param token 令牌
+ * @return 响应
+ */
+ public MappingUpdateResponse update(MappingUpdateRequest request, Token token) {
+ MappingUpdateResponse response = new MappingUpdateResponse();
+
+ ValidationUtil.validate(request, response);
+ if (response.hasError()) {
+ return response;
+ }
+
+
+ return response;
+ }
+
+ /**
+ * 查询
+ *
+ * @param request 请求对象
+ * @param token 令牌
+ * @return 响应
+ */
+ @Transactional(readOnly = true)
+ public MappingFindResponse find(MappingFindRequest request, Token token) {
+ MappingFindResponse response = new MappingFindResponse();
+
+ ValidationUtil.validate(request, response);
+ if (response.hasError()) {
+ return response;
+ }
+
+ return response;
+ }
+}
diff --git a/admin/src/main/java/com/example/module/admin/req/MappingCreateRequest.java b/admin/src/main/java/com/example/module/admin/req/MappingCreateRequest.java
new file mode 100644
index 0000000..41b9148
--- /dev/null
+++ b/admin/src/main/java/com/example/module/admin/req/MappingCreateRequest.java
@@ -0,0 +1,44 @@
+package com.example.module.admin.req;
+
+import com.example.frame.base.BaseRequest;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.NotEmpty;
+import org.hibernate.validator.constraints.Length;
+
+/**
+ * MappingCreateRequest - 映射新增
+ *
+ * @author author
+ * @version 0.0.1
+ * @since 2019-09-28
+ */
+public class MappingCreateRequest extends BaseRequest {
+
+ /**
+ * 用户名
+ */
+ @Length(min = 0, max = 100, message = "用户名长度不合法(0-100)")
+ private String username;
+
+ /**
+ * 用户密码
+ */
+ @Length(min = 0, max = 100, message = "用户密码长度不合法(0-100)")
+ private String password;
+
+ public String getUsername() {
+ return this.username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getPassword() {
+ return this.password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+}
diff --git a/admin/src/main/java/com/example/module/admin/req/MappingDeleteRequest.java b/admin/src/main/java/com/example/module/admin/req/MappingDeleteRequest.java
new file mode 100644
index 0000000..6c65a34
--- /dev/null
+++ b/admin/src/main/java/com/example/module/admin/req/MappingDeleteRequest.java
@@ -0,0 +1,28 @@
+package com.example.module.admin.req;
+
+import com.example.frame.base.BaseUpdateRequest;
+import javax.validation.constraints.NotNull;
+
+/**
+ * MappingDeleteRequest - 映射删除
+ *
+ * @author author
+ * @version 0.0.1
+ * @since 2019-09-28
+ */
+public class MappingDeleteRequest extends BaseUpdateRequest {
+
+ /**
+ * 主键
+ */
+ @NotNull(message = "主键不能为空")
+ private long id;
+
+ public long getId() {
+ return this.id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+}
diff --git a/admin/src/main/java/com/example/module/admin/req/MappingFindRequest.java b/admin/src/main/java/com/example/module/admin/req/MappingFindRequest.java
new file mode 100644
index 0000000..9c13159
--- /dev/null
+++ b/admin/src/main/java/com/example/module/admin/req/MappingFindRequest.java
@@ -0,0 +1,39 @@
+package com.example.module.admin.req;
+
+import com.example.frame.base.BaseFindRequest;
+
+/**
+ * MappingRequest - 映射查询
+ *
+ * @author author
+ * @version 0.0.1
+ * @since 2019-09-28
+ */
+public class MappingFindRequest extends BaseFindRequest {
+
+ /**
+ * 用户名
+ */
+ private String username;
+
+ /**
+ * 用户密码
+ */
+ private String password;
+
+ public String getUsername() {
+ return this.username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getPassword() {
+ return this.password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+}
diff --git a/admin/src/main/java/com/example/module/admin/req/MappingUpdateRequest.java b/admin/src/main/java/com/example/module/admin/req/MappingUpdateRequest.java
new file mode 100644
index 0000000..cd58649
--- /dev/null
+++ b/admin/src/main/java/com/example/module/admin/req/MappingUpdateRequest.java
@@ -0,0 +1,58 @@
+package com.example.module.admin.req;
+
+import com.example.frame.base.BaseUpdateRequest;
+import javax.validation.constraints.NotNull;
+import org.hibernate.validator.constraints.Length;
+import javax.validation.constraints.NotEmpty;
+
+/**
+ * MappingUpdateRequest - 映射更新
+ *
+ * @author author
+ * @version 0.0.1
+ * @since 2019-09-28
+ */
+public class MappingUpdateRequest extends BaseUpdateRequest {
+
+ /**
+ * 主键
+ */
+ @NotNull(message = "主键不能为NULL")
+ private Long id;
+
+ /**
+ * 用户名
+ */
+ @Length(min = 0, max = 100, message = "用户名长度不合法(0-100)")
+ private String username;
+
+ /**
+ * 用户密码
+ */
+ @Length(min = 0, max = 100, message = "用户密码长度不合法(0-100)")
+ private String password;
+
+ public Long getId() {
+ return this.id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getUsername() {
+ return this.username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getPassword() {
+ return this.password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+}
diff --git a/admin/src/main/java/com/example/module/admin/rsp/MappingCreateResponse.java b/admin/src/main/java/com/example/module/admin/rsp/MappingCreateResponse.java
new file mode 100644
index 0000000..bf966c1
--- /dev/null
+++ b/admin/src/main/java/com/example/module/admin/rsp/MappingCreateResponse.java
@@ -0,0 +1,26 @@
+package com.example.module.admin.rsp;
+
+import com.example.frame.base.BaseResponse;
+
+/**
+ * MappingCreateResponse - 映射
+ *
+ * @author author
+ * @version 0.0.1
+ * @since 2019-09-28
+ */
+public class MappingCreateResponse extends BaseResponse {
+
+ /**
+ * ID
+ */
+ private Long id;
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+}
diff --git a/admin/src/main/java/com/example/module/admin/rsp/MappingDeleteResponse.java b/admin/src/main/java/com/example/module/admin/rsp/MappingDeleteResponse.java
new file mode 100644
index 0000000..5d6687c
--- /dev/null
+++ b/admin/src/main/java/com/example/module/admin/rsp/MappingDeleteResponse.java
@@ -0,0 +1,26 @@
+package com.example.module.admin.rsp;
+
+import com.example.frame.base.BaseResponse;
+
+/**
+ * MappingDeleteResponse - 映射
+ *
+ * @author author
+ * @version 0.0.1
+ * @since 2019-09-28
+ */
+public class MappingDeleteResponse extends BaseResponse {
+
+ /**
+ * 删除数目
+ */
+ private Long result;
+
+ public Long getResult() {
+ return this.result;
+ }
+
+ public void setResult(Long result) {
+ this.result = result;
+ }
+}
diff --git a/admin/src/main/java/com/example/module/admin/rsp/MappingFindResponse.java b/admin/src/main/java/com/example/module/admin/rsp/MappingFindResponse.java
new file mode 100644
index 0000000..93e074b
--- /dev/null
+++ b/admin/src/main/java/com/example/module/admin/rsp/MappingFindResponse.java
@@ -0,0 +1,15 @@
+package com.example.module.admin.rsp;
+
+
+import com.example.frame.base.BaseFindResponse;
+import com.example.module.admin.ent.Mapping;
+
+/**
+ * MappingFindResponse - 映射
+ *
+ * @author author
+ * @version 0.0.1
+ * @since 2019-09-28
+ */
+public class MappingFindResponse extends BaseFindResponse {
+}
\ No newline at end of file
diff --git a/admin/src/main/java/com/example/module/admin/rsp/MappingUpdateResponse.java b/admin/src/main/java/com/example/module/admin/rsp/MappingUpdateResponse.java
new file mode 100644
index 0000000..7aaa0eb
--- /dev/null
+++ b/admin/src/main/java/com/example/module/admin/rsp/MappingUpdateResponse.java
@@ -0,0 +1,26 @@
+package com.example.module.admin.rsp;
+
+import com.example.frame.base.BaseResponse;
+
+/**
+ * MappingUpdateResponse - 映射
+ *
+ * @author author
+ * @version 0.0.1
+ * @since 2019-09-28
+ */
+public class MappingUpdateResponse extends BaseResponse {
+
+ /**
+ * 更新数目
+ */
+ private Long result;
+
+ public Long getResult() {
+ return this.result;
+ }
+
+ public void setResult(Long result) {
+ this.result = result;
+ }
+}
diff --git a/admin/src/main/resources/application-dev.properties b/admin/src/main/resources/application-dev.properties
new file mode 100644
index 0000000..d66df1f
--- /dev/null
+++ b/admin/src/main/resources/application-dev.properties
@@ -0,0 +1,63 @@
+# 开发环境
+server.port=8080
+server.servlet.context-path=/
+spring.mvc.static-path-pattern=/static/**
+spring.resources.static-locations=classpath:static/
+spring.application.name=EXAMPLE-WEB
+spring.main.banner-mode=CONSOLE
+spring.devtools.restart.enabled=true
+# 编码配置
+spring.http.encoding.force=true
+spring.http.encoding.charset=UTF-8
+spring.http.encoding.enabled=true
+server.tomcat.uri-encoding=UTF-8
+# 根路径、欢迎页
+web.welcome.page=/index.htm
+# 需要验证授权, 既访问时组装Token
+web.url.auth.included=/**
+# 不需要验证授权, 或该请求有自己的验证机制
+web.url.auth.excluded=/favicon.ico,/static/**,/api,/login.htm
+# 日志配置
+logging.path=D://
+logging.levels=DEBUG
+logging.config=classpath:logback-config.xml
+# mysql
+spring.datasource.driver-class-name=com.mysql.jdbc.Driver
+spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false
+spring.datasource.username=test
+spring.datasource.password=123456
+# mybatis
+mybatis.mapper-locations=classpath:**/mpr/*.xml
+# pagehelper
+pagehelper.autoRuntimeDialect=true
+pagehelper.reasonable=false
+pagehelper.supportMethodsArguments=true
+pagehelper.params=count=countSql
+# jackson 相关配置
+spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
+spring.jackson.time-zone=GMT+8
+spring.jackson.default-property-inclusion=use_defaults
+spring.jackson.mapper.sort-properties-alphabetically=true
+spring.jackson.deserialization.fail-on-unknown-properties=false
+# freemarker
+spring.freemarker.enabled=true
+spring.freemarker.allow-request-override=false
+spring.freemarker.cache=true
+spring.freemarker.check-template-location=true
+spring.freemarker.charset=UTF-8
+spring.freemarker.content-type=text/html
+spring.freemarker.expose-request-attributes=false
+spring.freemarker.expose-session-attributes=false
+spring.freemarker.expose-spring-macro-helpers=false
+spring.freemarker.settings.template_update_delay=1
+spring.freemarker.settings.locale=zh_CN
+spring.freemarker.settings.datetime_format=yyyy-MM-dd
+spring.freemarker.settings.date_format=yyyy-MM-dd
+spring.freemarker.settings.number_format=#.##
+spring.freemarker.settings.classic_compatible=true
+spring.freemarker.settings.whitespace_stripping=true
+spring.freemarker.settings.url_escaping_charset=utf-8
+# 文件上传配置
+spring.servlet.multipart.resolveLazily=false
+spring.servlet.multipart.max-file-size=100MB
+spring.servlet.multipart.max-request-size=100MB
\ No newline at end of file
diff --git a/admin/src/main/resources/application-prod.properties b/admin/src/main/resources/application-prod.properties
new file mode 100644
index 0000000..7d37eb4
--- /dev/null
+++ b/admin/src/main/resources/application-prod.properties
@@ -0,0 +1,63 @@
+# 生产环境
+server.port=80
+server.servlet.context-path=/
+spring.mvc.static-path-pattern=/static/**
+spring.resources.static-locations=classpath:static/
+spring.application.name=EXAMPLE-WEB
+spring.main.banner-mode=off
+spring.devtools.restart.enabled=false
+# 编码配置
+spring.http.encoding.force=true
+spring.http.encoding.charset=UTF-8
+spring.http.encoding.enabled=true
+server.tomcat.uri-encoding=UTF-8
+# 根路径、欢迎页
+web.welcome.page=/index.htm
+# 需要验证授权, 既访问时组装Token
+web.url.auth.included=/**
+# 不需要验证授权, 或该请求有自己的验证机制
+web.url.auth.excluded=/favicon.ico,/static/**,/api,/login.htm
+# 日志配置
+logging.path=/root/
+logging.levels=INFO
+logging.config=classpath:logback-config.xml
+# mysql
+spring.datasource.driver-class-name=com.mysql.jdbc.Driver
+spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false
+spring.datasource.username=test
+spring.datasource.password=123456
+# mybatis
+mybatis.mapper-locations=classpath:**/mpr/*.xml
+# pagehelper
+pagehelper.autoRuntimeDialect=true
+pagehelper.reasonable=false
+pagehelper.supportMethodsArguments=true
+pagehelper.params=count=countSql
+# jackson 相关配置
+spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
+spring.jackson.time-zone=GMT+8
+spring.jackson.default-property-inclusion=use_defaults
+spring.jackson.mapper.sort-properties-alphabetically=true
+spring.jackson.deserialization.fail-on-unknown-properties=false
+# freemarker
+spring.freemarker.enabled=true
+spring.freemarker.allow-request-override=false
+spring.freemarker.cache=true
+spring.freemarker.check-template-location=true
+spring.freemarker.charset=UTF-8
+spring.freemarker.content-type=text/html
+spring.freemarker.expose-request-attributes=false
+spring.freemarker.expose-session-attributes=false
+spring.freemarker.expose-spring-macro-helpers=false
+spring.freemarker.settings.template_update_delay=1
+spring.freemarker.settings.locale=zh_CN
+spring.freemarker.settings.datetime_format=yyyy-MM-dd
+spring.freemarker.settings.date_format=yyyy-MM-dd
+spring.freemarker.settings.number_format=#.##
+spring.freemarker.settings.classic_compatible=true
+spring.freemarker.settings.whitespace_stripping=true
+spring.freemarker.settings.url_escaping_charset=utf-8
+# 文件上传配置
+spring.servlet.multipart.resolveLazily=false
+spring.servlet.multipart.max-file-size=100MB
+spring.servlet.multipart.max-request-size=100MB
\ No newline at end of file
diff --git a/admin/src/main/resources/banner.txt b/admin/src/main/resources/banner.txt
new file mode 100644
index 0000000..a5a86e7
--- /dev/null
+++ b/admin/src/main/resources/banner.txt
@@ -0,0 +1,26 @@
+${AnsiColor.BRIGHT_YELLOW}
+ /////////////////////////////////////////////////////////
+ // _ooOoo_ //
+ // o8888888o //
+ // 88" . "88 //
+ // (| ^_^ |) //
+ // O\ = /O //
+ // ____/`---'\____ //
+ // .' \\| |// `. //
+ // / \\||| : |||// \ //
+ // / _||||| -:- |||||- \ //
+ // | | \\\ - /// | | //
+ // | \_| ''\---/'' | | //
+ // \ .-\__ `-` ___/-. / //
+ // ___`. .' /--.--\ `. . ___ //
+ // ."" '< `.___\_<|>_/___.' >'"". //
+ // | | : `- \`.;`\ _ /`;.`/ - ` : | | //
+ // \ \ `-. \_ __\ /__ _/ .-` / / //
+ // ========`-.____`-.___\_____/___.-`____.-'======== //
+ // `=---=' //
+ // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ //
+ /////////////////////////////////////////////////////////
+
+ 佛祖保佑 永无BUG
+ :: Spring Boot :: ${spring-boot.formatted-version} (${spring.profiles.active})
+
diff --git a/admin/src/main/resources/dbtool/EXAMPLE-WEB.xml b/admin/src/main/resources/dbtool/EXAMPLE-WEB.xml
new file mode 100644
index 0000000..9f24040
--- /dev/null
+++ b/admin/src/main/resources/dbtool/EXAMPLE-WEB.xml
@@ -0,0 +1,29 @@
+
+
+EXAMPLE-WEB
+com.example
+author
+
+
+用户
+SYS
+usermodel
+true
+
+
+
+
+
+
diff --git a/admin/src/main/resources/dbtool/usermodel_table/ALL_TABLE.sql b/admin/src/main/resources/dbtool/usermodel_table/ALL_TABLE.sql
new file mode 100644
index 0000000..98204c2
--- /dev/null
+++ b/admin/src/main/resources/dbtool/usermodel_table/ALL_TABLE.sql
@@ -0,0 +1,17 @@
+
+-- ----------------------------
+-- Table structure for MAPPING - 映射
+-- ----------------------------
+CREATE TABLE `SYSMAPPING` (
+ `ID` BIGINT(20) NOT NULL COMMENT '主键',
+ `USERNAME` VARCHAR(100) COMMENT '用户名',
+ `PASSWORD` VARCHAR(100) COMMENT '用户密码',
+ `ROW_VERSION` BIGINT(20) NOT NULL DEFAULT 0 COMMENT '行版本',
+ `IS_DELETED` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否已删除',
+ `CREATE_BY` BIGINT(20) NOT NULL COMMENT '创建用户',
+ `CREATE_TIME` DATETIME NOT NULL COMMENT '创建时间',
+ `LAST_UPDATE_BY` BIGINT(20) DEFAULT NULL COMMENT '最后更新用户',
+ `LAST_UPDATE_TIME` DATETIME DEFAULT NULL COMMENT '最后更新时间',
+PRIMARY KEY (`ID`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='映射';
+
diff --git a/admin/src/main/resources/dbtool/usermodel_table/USER.sql b/admin/src/main/resources/dbtool/usermodel_table/USER.sql
new file mode 100644
index 0000000..0b9ab82
--- /dev/null
+++ b/admin/src/main/resources/dbtool/usermodel_table/USER.sql
@@ -0,0 +1,22 @@
+/*
+Target : MYSQL
+Author
+Date: 2019-08-14
+*/
+
+-- ----------------------------
+-- Table structure for USER - 用户
+-- ----------------------------
+
+CREATE TABLE `SYSUSER` (
+ `ID` BIGINT(20) NOT NULL COMMENT '主键',
+ `USERNAME` VARCHAR(100) COMMENT '用户名',
+ `PASSWORD` VARCHAR(100) COMMENT '用户密码',
+ `ROW_VERSION` BIGINT(20) NOT NULL DEFAULT 0 COMMENT '行版本',
+ `IS_DELETED` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否已删除',
+ `CREATE_BY` BIGINT(20) NOT NULL COMMENT '创建用户',
+ `CREATE_TIME` DATETIME NOT NULL COMMENT '创建时间',
+ `LAST_UPDATE_BY` BIGINT(20) DEFAULT NULL COMMENT '最后更新用户',
+ `LAST_UPDATE_TIME` DATETIME DEFAULT NULL COMMENT '最后更新时间',
+PRIMARY KEY (`ID`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户';
diff --git a/admin/src/main/resources/lib/ojdbc7-12.1.0.2.jar b/admin/src/main/resources/lib/ojdbc7-12.1.0.2.jar
new file mode 100644
index 0000000..d72b9eb
Binary files /dev/null and b/admin/src/main/resources/lib/ojdbc7-12.1.0.2.jar differ
diff --git a/admin/src/main/resources/logback-config.xml b/admin/src/main/resources/logback-config.xml
new file mode 100644
index 0000000..39f7b30
--- /dev/null
+++ b/admin/src/main/resources/logback-config.xml
@@ -0,0 +1,109 @@
+
+
+
+
+
+
+
+
+
+
+ ${root}log/all/all.log
+
+ ${root}log/all/all-%d{yyyy-MM-dd}-%i.log
+ 30
+
+ 10MB
+
+
+
+ [%-4level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%logger{36}-%method] %msg%n
+
+
+ INFO
+
+
+
+
+
+ ${root}log/error/error.log
+
+ ${root}log/error/error-%d{yyyy-MM-dd}-%i.log
+ 30
+
+ 10MB
+
+
+
+ [%-4level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%logger{36}-%method] %msg%n
+
+
+ ERROR
+ ACCEPT
+ DENY
+
+
+
+
+
+ ${root}log/warn/warn.log
+
+ ${root}log/warn/warn-%d{yyyy-MM-dd}-%i.log
+ 30
+
+ 10MB
+
+
+
+ [%-4level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%logger{36}-%method] %msg%n
+
+
+ WARN
+ ACCEPT
+ DENY
+
+
+
+
+
+ ${root}log/info/info.log
+
+ ${root}log/info/info-%d{yyyy-MM-dd}-%i.log
+ 30
+
+ 10MB
+
+
+
+ [%-4level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%logger{36}-%method] %msg%n
+
+
+ INFO
+ ACCEPT
+ DENY
+
+
+
+
+
+ debug级别及以上
+
+ DEBUG
+
+
+ %highlight(%d{yyyy-MM-dd HH:mm:ss.SSS} [%-4level] [%thread] [%logger{36}-%method] %ex %msg%n)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/admin/src/main/resources/nginx-1.14.2.zip b/admin/src/main/resources/nginx-1.14.2.zip
new file mode 100644
index 0000000..a403aee
Binary files /dev/null and b/admin/src/main/resources/nginx-1.14.2.zip differ
diff --git a/admin/src/main/resources/start-dev.bat b/admin/src/main/resources/start-dev.bat
new file mode 100644
index 0000000..3fd26b3
--- /dev/null
+++ b/admin/src/main/resources/start-dev.bat
@@ -0,0 +1,3 @@
+@echo off
+cd %cd%
+start java -Dfile.encoding=UTF-8 -jar EXAMPLE-WEB-0.0.1-SNAPSHOT.jar --spring.profiles.active=dev
\ No newline at end of file
diff --git a/admin/src/main/resources/start-prod.bat b/admin/src/main/resources/start-prod.bat
new file mode 100644
index 0000000..4fd1945
--- /dev/null
+++ b/admin/src/main/resources/start-prod.bat
@@ -0,0 +1,3 @@
+@echo off
+cd %cd%
+start java -Dfile.encoding=UTF-8 -jar EXAMPLE-WEB-0.0.1-SNAPSHOT.jar --spring.profiles.active=prod
\ No newline at end of file
diff --git a/admin/src/main/resources/static/css/base.css b/admin/src/main/resources/static/css/base.css
new file mode 100644
index 0000000..0d33d76
--- /dev/null
+++ b/admin/src/main/resources/static/css/base.css
@@ -0,0 +1,687 @@
+* {
+ -webkit-box-sizing: border-box;
+ box-sizing: border-box;
+ -webkit-tap-highlight-color: transparent;
+ margin: 0;
+ padding: 0;
+ font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "微软雅黑", Arial, sans-serif;
+}
+
+html {
+ line-height: 1.15;
+ -ms-text-size-adjust: 100%;
+ -webkit-text-size-adjust: 100%
+}
+
+body {
+ margin: 0;
+ font-size: 12px;
+ line-height: 1.5;
+ color: #515a6e;
+ background-color: #fff;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale
+}
+
+html, body {
+ width: 100%;
+ height: 100%;
+}
+
+article, aside, footer, header, nav, section {
+ display: block
+}
+
+h1 {
+ font-size: 2em;
+ margin: .67em 0
+}
+
+pre {
+ font-family: monospace, monospace;
+ font-size: 1em
+}
+
+button, input, optgroup, select, textarea {
+ font-family: sans-serif;
+ font-size: 100%;
+ line-height: 1.15;
+ margin: 0
+}
+
+button, select {
+ text-transform: none
+}
+
+[type=reset], [type=submit], button, html [type=button] {
+ -webkit-appearance: button
+}
+
+[type=button]::-moz-focus-inner, [type=reset]::-moz-focus-inner, [type=submit]::-moz-focus-inner, button::-moz-focus-inner {
+ border-style: none;
+ padding: 0
+}
+
+[type=button]:-moz-focusring, [type=reset]:-moz-focusring, [type=submit]:-moz-focusring, button:-moz-focusring {
+ outline: 1px dotted ButtonText
+}
+
+fieldset {
+ border: 1px solid silver;
+ margin: 0 2px;
+ padding: .35em .625em .75em
+}
+
+legend {
+ -webkit-box-sizing: border-box;
+ box-sizing: border-box;
+ color: inherit;
+ display: table;
+ max-width: 100%;
+ padding: 0;
+ white-space: normal
+}
+
+progress {
+ display: inline-block;
+ vertical-align: baseline
+}
+
+textarea {
+ overflow: auto;
+ resize: vertical
+}
+
+[type=checkbox], [type=radio] {
+ -webkit-box-sizing: border-box;
+ box-sizing: border-box;
+ padding: 0
+}
+
+[type=number]::-webkit-inner-spin-button, [type=number]::-webkit-outer-spin-button {
+ height: auto
+}
+
+[type=search] {
+ -webkit-appearance: textfield;
+ outline-offset: -2px
+}
+
+[type=search]::-webkit-search-cancel-button, [type=search]::-webkit-search-decoration {
+ -webkit-appearance: none
+}
+
+::-webkit-file-upload-button {
+ -webkit-appearance: button;
+ font: inherit
+}
+
+details, menu {
+ display: block
+}
+
+summary {
+ display: list-item
+}
+
+canvas {
+ display: inline-block
+}
+
+template {
+ display: none
+}
+
+[hidden] {
+ display: none
+}
+
+:after, :before {
+ -webkit-box-sizing: border-box;
+ box-sizing: border-box
+}
+
+a {
+ text-decoration: none;
+ outline: 0;
+ cursor: pointer;
+ -webkit-transition: color .2s ease;
+ transition: color .2s ease;
+ -webkit-text-decoration-skip: objects;
+ color: #757575;
+}
+
+a:active, a:hover {
+ outline-width: 0
+}
+
+a:hover {
+ opacity: 0.7;
+}
+
+a:active {
+ opacity: 0.9;
+}
+
+a:active, a:hover {
+ outline: 0;
+ text-decoration: none
+}
+
+a[disabled] {
+ color: #ccc;
+ cursor: not-allowed;
+ pointer-events: none
+}
+
+code, kbd, pre, samp {
+ font-family: Consolas, Menlo, Courier, monospace
+}
+
+a {
+ text-decoration: none;
+}
+
+/*主标题*/
+h1 {
+ font-size: 20px;
+ padding: 10px 0px;
+ margin: 20px 0px 10px 0px;
+}
+
+/*标题*/
+h2 {
+ font-size: 18px;
+ padding: 9px 0px;
+ margin: 18px 0px 8px 0px;
+}
+
+/*小标题*/
+h3 {
+ font-size: 16px;
+ padding: 8px 0px;
+ margin: 16px 0px 6px 0px;
+}
+
+/*次要标题*/
+h4 {
+ font-size: 14px;
+ padding: 4px 0px;
+ margin: 4px 0px 4px 0px;
+}
+
+p {
+ font-size: 14px;
+ padding: 7px 0px;
+ color: #545C64;;
+}
+
+p.text-indent {
+ text-indent: 2em
+}
+
+/*正文*/
+.text-regular {
+ font-size: 14px;
+}
+
+/*正文(小)*/
+.text-small {
+ font-size: 13px
+}
+
+/*辅助文字*/
+.text-smaller {
+ font-size: 12px
+}
+
+/*中文字体*/
+.typo-PingFang {
+ font-family: PingFang SC
+}
+
+.typo-Hiragino {
+ font-family: Hiragino Sans GB
+}
+
+.typo-Microsoft {
+ font-family: Microsoft YaHei
+}
+
+/*英文/数字字体*/
+.typo-Helvetica-Neue {
+ font-family: Helvetica Neue
+}
+
+.typo-Helvetica {
+ font-family: Helvetica
+}
+
+.typo-Arial {
+ font-family: Arial
+}
+
+.bg-blue {
+ background-color: #409eff
+}
+
+.bg-success {
+ background-color: #67c23a
+}
+
+.bg-warning {
+ background-color: #e6a23c
+}
+
+.bg-danger {
+ background-color: #f56c6c
+}
+
+.bg-info {
+ background-color: #909399
+}
+
+.text-color-primary {
+ color: #303133
+}
+
+.text-color-regular {
+ color: #606266
+}
+
+.text-color-secondary {
+ color: #909399
+}
+
+.text-color-placeholder {
+ color: #c0c4cc
+}
+
+.bg-border-base {
+ background-color: #dcdfe6
+}
+
+.bg-border-light {
+ background-color: #e4e7ed
+}
+
+.bg-border-lighter {
+ background-color: #ebeef5
+}
+
+.bg-border-extra-light {
+ background-color: #f2f6fc
+}
+
+[class*="bg-border-"] {
+ color: #303133
+}
+
+code {
+ background-color: #f9fafc;
+ padding: 0 4px;
+ border: 1px solid #eaeefb;
+ border-radius: 4px;
+ display: inline-block;
+}
+
+.remarks {
+ font-size: 12px;
+ color: #909399
+}
+
+.table {
+ display: table;
+}
+
+.table-cell {
+ display: table-cell;
+}
+
+.table-cell.center {
+ text-align: center;
+ vertical-align: middle;
+}
+
+.table-cell.v-center {
+ vertical-align: middle;
+}
+
+.table-cell.h-center {
+ text-align: center;
+}
+
+.table-cell.right {
+ text-align: right;
+}
+
+.table-cell.left {
+ text-align: left;
+}
+
+.table-cell.top {
+ vertical-align: top;
+}
+
+.table-cell.bottom {
+ vertical-align: bottom;
+}
+
+.m-t-10 {
+ margin-top: 10px;
+}
+
+.m-t-20 {
+ margin-top: 20px;
+}
+
+.m-t-30 {
+ margin-top: 30px;
+}
+
+.m-t-40 {
+ margin-top: 40px;
+}
+
+.m-t-50 {
+ margin-top: 50px;
+}
+.center{
+ text-align: center;
+}
+.full {
+ width: 100%;
+ height: 100%;
+}
+
+.nowrap {
+ white-space: nowrap;
+ overflow: hidden;
+ word-break: keep-all;
+}
+
+[v-cloak] {
+ display: none;
+}
+
+/* 可以设置不同的进入和离开动画 */
+/* 设置持续时间和动画函数 */
+.left-in-right-out-enter-active, .left-in-right-out-leave-active {
+ transition: all 0.3s linear;
+ position: absolute;
+}
+
+.left-in-right-out-enter
+ /* .slide-fade-leave-active for below version 2.1.8 */
+{
+ transform: translateX(-100%);
+ opacity: 0;
+}
+
+.left-in-right-out-leave-to
+ /* .slide-fade-leave-active for below version 2.1.8 */
+{
+ transform: translateX(100%);
+ opacity: 0;
+}
+
+.right-in-left-out-enter-active, .right-in-left-out-leave-active {
+ transition: all .3s linear;
+ position: absolute;
+}
+
+.right-in-left-out-enter {
+ transform: translateX(100%);
+}
+
+.right-in-left-out-leave-to {
+ transform: translateX(-100%);
+}
+
+.el-switch__input:focus ~ .el-switch__core {
+ position: relative;
+ box-sizing: border-box;
+ outline: none !important;
+}
+
+.row {
+ position: relative;
+ box-sizing: border-box;
+}
+
+[class*=col-] {
+ float: left;
+ box-sizing: border-box;
+}
+
+.col-1 {
+ width: 4.16667%;
+}
+
+.col-2 {
+ width: 8.33333%;
+}
+
+.col-3 {
+ width: 12.5%;
+}
+
+.col-4 {
+ width: 16.66667%;
+}
+
+.col-5 {
+ width: 20.83333%;
+}
+
+.col-6 {
+ width: 25%;
+}
+
+.col-7 {
+ width: 29.16667%;
+}
+
+.col-8 {
+ width: 33.33333%;
+}
+
+.col-9 {
+ width: 37.5%;
+}
+
+.col-10 {
+ width: 41.66667%;
+}
+
+.col-11 {
+ width: 45.83333%;
+}
+
+.col-12 {
+ width: 50%;
+}
+
+.col-13 {
+ width: 54.16667%;
+}
+
+.col-14 {
+ width: 58.33333%;
+}
+
+.col-15 {
+ width: 62.5%;
+}
+
+.col-16 {
+ width: 66.66667%;
+}
+
+.col-17 {
+ width: 70.83333%;
+}
+
+.col-18 {
+ width: 75%;
+}
+
+.col-19 {
+ width: 79.16667%;
+}
+
+.col-20 {
+ width: 83.33333%;
+}
+
+.col-21 {
+ width: 87.5%;
+}
+
+.col-22 {
+ width: 91.66667%;
+}
+
+.col-23 {
+ width: 95.83333%;
+}
+
+.col-24 {
+ width: 100%;
+}
+
+.page_list {
+ display: flex;
+}
+
+.page_list a {
+ display: inline-block;
+ height: 35px;
+ width: 35px;
+ line-height: 35px;
+ text-align: center;
+ cursor: pointer;
+ background-color: #2a2a2a;
+ color: #ffffff;
+}
+
+.page_list a.disabled {
+ opacity: 0.7;
+}
+
+.page_list a.current {
+ background-color: #16C0F8;
+ color: #ffffff;
+}
+
+.page_list a:hover {
+ background-color: #16C0F8;
+ color: #ffffff;
+}
+
+.page_list a.disabled:hover {
+ background-color: #373737;
+ color: #ffffff;
+}
+
+.page_list a.top_page,
+.page_list a.page_prev,
+.page_list a.page_next,
+.page_list a.end_page {
+ width: 55px;
+ padding: 0px 5px;
+}
+.page_list p{
+ padding: 0px 20px;
+ line-height: 35px;
+}
+::-webkit-scrollbar {
+ width: 7px;
+ height: 7px;
+ background-color: #ffffff;
+}
+::-webkit-scrollbar-thumb {
+ background-color: #16C0F8;
+}
+::-webkit-scrollbar-track {
+ background-color: #ffffff;
+}
+
+.el-scrollbar.hidden_x > .el-scrollbar__wrap {
+ overflow-x: hidden !important;
+}
+
+.el-scrollbar.hidden_x > .el-scrollbar__wrap > .el-scrollbar__view {
+ height: 100%;
+}
+
+.el-menu--horizontal {
+ border-bottom: solid 0px #e6e6e6 !important;
+}
+
+.el-message {
+ min-width: 100px;
+ padding: 10px 60px 10px 20px;
+ background-color: #ffffff;
+ box-shadow: 0 1px 6px rgba(0, 0, 0, .2);
+}
+
+.loading-bar {
+ width: 100%;
+ padding: 0px;
+ top: 0px;
+ box-shadow: 0px 0px 0px 0px;
+ border: 0px;
+}
+
+.loading-bar .el-message__content {
+ display: block;
+ width: 100%;
+ height: 2px;
+}
+
+.loading-bar .el-message__content .bar {
+ display: block;
+ height: 2px;
+ background-color: #2d8cf0;
+}
+
+.loading-bar .el-message__content .bar.error {
+ background-color: #ff1a0e;
+}
+
+/* 带有固定title布局,title保持固定*/
+.wb-layout-title-fix {
+ width: 100%;
+ height: 100%;
+ overflow: hidden;
+}
+
+.wb-layout-title-fix > .wb-head {
+ height: 60px;
+ overflow: hidden;
+}
+
+.wb-layout-title-fix > .wb-body {
+ height: calc(100% - 60px);
+}
+
+/* 保持页脚绝对底部,当内容足够或高于屏幕,会自动将页面撑开,底部依旧保持在底部*/
+.wb-layout-foot-absolute {
+ position: relative;
+ width: 100%;
+ height: auto;
+ min-height: 100%;
+}
+
+.wb-layout-foot-absolute > .wb-body {
+ padding-bottom: 50px;
+}
+
+.wb-layout-foot-absolute > .wb-foot {
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ height: 50px;
+ width: 100%;
+}
diff --git a/admin/src/main/resources/static/dist/fonts/element-icons.woff b/admin/src/main/resources/static/dist/fonts/element-icons.woff
new file mode 100644
index 0000000..02b9a25
Binary files /dev/null and b/admin/src/main/resources/static/dist/fonts/element-icons.woff differ
diff --git a/admin/src/main/resources/static/dist/fonts/w-e-icon.woff b/admin/src/main/resources/static/dist/fonts/w-e-icon.woff
new file mode 100644
index 0000000..6dc5b5a
Binary files /dev/null and b/admin/src/main/resources/static/dist/fonts/w-e-icon.woff differ
diff --git a/admin/src/main/resources/static/dist/index.min.css b/admin/src/main/resources/static/dist/index.min.css
new file mode 100644
index 0000000..afe4505
--- /dev/null
+++ b/admin/src/main/resources/static/dist/index.min.css
@@ -0,0 +1 @@
+@charset "UTF-8";.el-pagination--small .arrow.disabled,.el-table .hidden-columns,.el-table td.is-hidden>*,.el-table th.is-hidden>*,.el-table--hidden{visibility:hidden}.el-dropdown .el-dropdown-selfdefine:focus:active,.el-dropdown .el-dropdown-selfdefine:focus:not(.focusing),.el-message__closeBtn:focus,.el-message__content:focus,.el-popover:focus,.el-popover:focus:active,.el-popover__reference:focus:hover,.el-popover__reference:focus:not(.focusing),.el-rate:active,.el-rate:focus,.el-tooltip:focus:hover,.el-tooltip:focus:not(.focusing),.el-upload-list__item.is-success:active,.el-upload-list__item.is-success:not(.focusing):focus{outline-width:0}.el-input__suffix,.el-tree.is-dragging .el-tree-node__content *{pointer-events:none}@font-face{font-family:element-icons;src:url(fonts/element-icons.woff) format("woff"),url(fonts/element-icons.ttf) format("truetype");font-weight:400;font-style:normal}[class*=" el-icon-"],[class^=el-icon-]{font-family:element-icons!important;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;vertical-align:baseline;display:inline-block;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.el-icon-ice-cream-round:before{content:"\e6a0"}.el-icon-ice-cream-square:before{content:"\e6a3"}.el-icon-lollipop:before{content:"\e6a4"}.el-icon-potato-strips:before{content:"\e6a5"}.el-icon-milk-tea:before{content:"\e6a6"}.el-icon-ice-drink:before{content:"\e6a7"}.el-icon-ice-tea:before{content:"\e6a9"}.el-icon-coffee:before{content:"\e6aa"}.el-icon-orange:before{content:"\e6ab"}.el-icon-pear:before{content:"\e6ac"}.el-icon-apple:before{content:"\e6ad"}.el-icon-cherry:before{content:"\e6ae"}.el-icon-watermelon:before{content:"\e6af"}.el-icon-grape:before{content:"\e6b0"}.el-icon-refrigerator:before{content:"\e6b1"}.el-icon-goblet-square-full:before{content:"\e6b2"}.el-icon-goblet-square:before{content:"\e6b3"}.el-icon-goblet-full:before{content:"\e6b4"}.el-icon-goblet:before{content:"\e6b5"}.el-icon-cold-drink:before{content:"\e6b6"}.el-icon-coffee-cup:before{content:"\e6b8"}.el-icon-water-cup:before{content:"\e6b9"}.el-icon-hot-water:before{content:"\e6ba"}.el-icon-ice-cream:before{content:"\e6bb"}.el-icon-dessert:before{content:"\e6bc"}.el-icon-sugar:before{content:"\e6bd"}.el-icon-tableware:before{content:"\e6be"}.el-icon-burger:before{content:"\e6bf"}.el-icon-knife-fork:before{content:"\e6c1"}.el-icon-fork-spoon:before{content:"\e6c2"}.el-icon-chicken:before{content:"\e6c3"}.el-icon-food:before{content:"\e6c4"}.el-icon-dish-1:before{content:"\e6c5"}.el-icon-dish:before{content:"\e6c6"}.el-icon-refresh-left:before{content:"\e6c7"}.el-icon-refresh-right:before{content:"\e6c8"}.el-icon-warning-outline:before{content:"\e6c9"}.el-icon-setting:before{content:"\e6ca"}.el-icon-phone-outline:before{content:"\e6cb"}.el-icon-more-outline:before{content:"\e6cc"}.el-icon-finished:before{content:"\e6cd"}.el-icon-view:before{content:"\e6ce"}.el-icon-loading:before{content:"\e6cf"}.el-icon-refresh:before{content:"\e6d0"}.el-icon-rank:before{content:"\e6d1"}.el-icon-sort:before{content:"\e6d2"}.el-icon-mobile-phone:before{content:"\e6d3"}.el-icon-service:before{content:"\e6d4"}.el-icon-sell:before{content:"\e6d5"}.el-icon-sold-out:before{content:"\e6d6"}.el-icon-delete:before{content:"\e6d7"}.el-icon-minus:before{content:"\e6d8"}.el-icon-plus:before{content:"\e6d9"}.el-icon-check:before{content:"\e6da"}.el-icon-close:before{content:"\e6db"}.el-icon-d-arrow-right:before{content:"\e6dc"}.el-icon-d-arrow-left:before{content:"\e6dd"}.el-icon-arrow-left:before{content:"\e6de"}.el-icon-arrow-down:before{content:"\e6df"}.el-icon-arrow-right:before{content:"\e6e0"}.el-icon-arrow-up:before{content:"\e6e1"}.el-icon-key:before{content:"\e6e2"}.el-icon-user:before{content:"\e6e3"}.el-icon-unlock:before{content:"\e6e4"}.el-icon-lock:before{content:"\e6e5"}.el-icon-top:before{content:"\e6e6"}.el-icon-top-right:before{content:"\e6e7"}.el-icon-top-left:before{content:"\e6e8"}.el-icon-right:before{content:"\e6e9"}.el-icon-back:before{content:"\e6ea"}.el-icon-bottom:before{content:"\e6eb"}.el-icon-bottom-right:before{content:"\e6ec"}.el-icon-bottom-left:before{content:"\e6ed"}.el-icon-moon-night:before{content:"\e6ee"}.el-icon-moon:before{content:"\e6f0"}.el-icon-cloudy-and-sunny:before{content:"\e6f1"}.el-icon-partly-cloudy:before{content:"\e6f2"}.el-icon-cloudy:before{content:"\e6f3"}.el-icon-sunny:before{content:"\e6f6"}.el-icon-sunset:before{content:"\e6f7"}.el-icon-sunrise-1:before{content:"\e6f8"}.el-icon-sunrise:before{content:"\e6f9"}.el-icon-heavy-rain:before{content:"\e6fa"}.el-icon-lightning:before{content:"\e6fb"}.el-icon-light-rain:before{content:"\e6fc"}.el-icon-wind-power:before{content:"\e6fd"}.el-icon-watch:before{content:"\e6fe"}.el-icon-watch-1:before{content:"\e6ff"}.el-icon-timer:before{content:"\e702"}.el-icon-alarm-clock:before{content:"\e703"}.el-icon-map-location:before{content:"\e704"}.el-icon-delete-location:before{content:"\e705"}.el-icon-add-location:before{content:"\e706"}.el-icon-location-information:before{content:"\e707"}.el-icon-location-outline:before{content:"\e708"}.el-icon-place:before{content:"\e709"}.el-icon-discover:before{content:"\e70a"}.el-icon-first-aid-kit:before{content:"\e70b"}.el-icon-trophy-1:before{content:"\e70c"}.el-icon-trophy:before{content:"\e70d"}.el-icon-medal:before{content:"\e70e"}.el-icon-medal-1:before{content:"\e70f"}.el-icon-stopwatch:before{content:"\e710"}.el-icon-mic:before{content:"\e711"}.el-icon-baseball:before{content:"\e712"}.el-icon-soccer:before{content:"\e713"}.el-icon-football:before{content:"\e715"}.el-icon-basketball:before{content:"\e716"}.el-icon-star-off:before{content:"\e717"}.el-icon-copy-document:before{content:"\e718"}.el-icon-full-screen:before{content:"\e719"}.el-icon-switch-button:before{content:"\e71b"}.el-icon-aim:before{content:"\e71c"}.el-icon-crop:before{content:"\e71d"}.el-icon-odometer:before{content:"\e71e"}.el-icon-time:before{content:"\e71f"}.el-icon-circle-check:before{content:"\e720"}.el-icon-remove-outline:before{content:"\e722"}.el-icon-circle-plus-outline:before{content:"\e723"}.el-icon-bangzhu:before{content:"\e724"}.el-icon-bell:before{content:"\e725"}.el-icon-close-notification:before{content:"\e726"}.el-icon-microphone:before{content:"\e727"}.el-icon-turn-off-microphone:before{content:"\e728"}.el-icon-position:before{content:"\e729"}.el-icon-postcard:before{content:"\e72a"}.el-icon-message:before{content:"\e72b"}.el-icon-chat-line-square:before{content:"\e72d"}.el-icon-chat-dot-square:before{content:"\e72e"}.el-icon-chat-dot-round:before{content:"\e72f"}.el-icon-chat-square:before{content:"\e730"}.el-icon-chat-line-round:before{content:"\e731"}.el-icon-chat-round:before{content:"\e732"}.el-icon-set-up:before{content:"\e733"}.el-icon-turn-off:before{content:"\e734"}.el-icon-open:before{content:"\e735"}.el-icon-connection:before{content:"\e736"}.el-icon-link:before{content:"\e737"}.el-icon-cpu:before{content:"\e738"}.el-icon-thumb:before{content:"\e739"}.el-icon-female:before{content:"\e73a"}.el-icon-male:before{content:"\e73b"}.el-icon-guide:before{content:"\e73c"}.el-icon-help:before{content:"\e73d"}.el-icon-news:before{content:"\e73e"}.el-icon-ship:before{content:"\e73f"}.el-icon-truck:before{content:"\e740"}.el-icon-bicycle:before{content:"\e741"}.el-icon-price-tag:before{content:"\e744"}.el-icon-discount:before{content:"\e745"}.el-icon-wallet:before{content:"\e747"}.el-icon-coin:before{content:"\e748"}.el-icon-money:before{content:"\e749"}.el-icon-bank-card:before{content:"\e74a"}.el-icon-box:before{content:"\e74b"}.el-icon-present:before{content:"\e74c"}.el-icon-shopping-bag-2:before{content:"\e74d"}.el-icon-shopping-bag-1:before{content:"\e74e"}.el-icon-shopping-cart-2:before{content:"\e74f"}.el-icon-shopping-cart-1:before{content:"\e750"}.el-icon-shopping-cart-full:before{content:"\e751"}.el-icon-smoking:before{content:"\e752"}.el-icon-no-smoking:before{content:"\e753"}.el-icon-house:before{content:"\e754"}.el-icon-table-lamp:before{content:"\e755"}.el-icon-school:before{content:"\e756"}.el-icon-office-building:before{content:"\e757"}.el-icon-toilet-paper:before{content:"\e758"}.el-icon-notebook-2:before{content:"\e759"}.el-icon-notebook-1:before{content:"\e75a"}.el-icon-files:before{content:"\e75b"}.el-icon-collection:before{content:"\e75c"}.el-icon-receiving:before{content:"\e75d"}.el-icon-picture-outline:before{content:"\e75e"}.el-icon-picture-outline-round:before{content:"\e75f"}.el-icon-suitcase-1:before{content:"\e760"}.el-icon-suitcase:before{content:"\e761"}.el-icon-film:before{content:"\e763"}.el-icon-edit-outline:before{content:"\e764"}.el-icon-collection-tag:before{content:"\e765"}.el-icon-data-analysis:before{content:"\e766"}.el-icon-pie-chart:before{content:"\e767"}.el-icon-data-board:before{content:"\e768"}.el-icon-reading:before{content:"\e769"}.el-icon-magic-stick:before{content:"\e76a"}.el-icon-coordinate:before{content:"\e76b"}.el-icon-mouse:before{content:"\e76c"}.el-icon-data-line:before{content:"\e76d"}.el-icon-brush:before{content:"\e76e"}.el-icon-headset:before{content:"\e76f"}.el-icon-umbrella:before{content:"\e770"}.el-icon-scissors:before{content:"\e771"}.el-icon-video-camera:before{content:"\e772"}.el-icon-mobile:before{content:"\e773"}.el-icon-attract:before{content:"\e774"}.el-icon-monitor:before{content:"\e775"}.el-icon-zoom-out:before{content:"\e776"}.el-icon-zoom-in:before{content:"\e777"}.el-icon-search:before{content:"\e778"}.el-icon-camera:before{content:"\e779"}.el-icon-takeaway-box:before{content:"\e77a"}.el-icon-upload2:before{content:"\e77b"}.el-icon-download:before{content:"\e77c"}.el-icon-paperclip:before{content:"\e77d"}.el-icon-printer:before{content:"\e77e"}.el-icon-document-add:before{content:"\e782"}.el-icon-document:before{content:"\e785"}.el-icon-document-checked:before{content:"\e786"}.el-icon-document-copy:before{content:"\e787"}.el-icon-document-delete:before{content:"\e788"}.el-icon-document-remove:before{content:"\e789"}.el-icon-tickets:before{content:"\e78b"}.el-icon-folder-checked:before{content:"\e77f"}.el-icon-folder-delete:before{content:"\e780"}.el-icon-folder-remove:before{content:"\e781"}.el-icon-folder-add:before{content:"\e783"}.el-icon-folder-opened:before{content:"\e784"}.el-icon-folder:before{content:"\e78a"}.el-icon-edit:before{content:"\e78c"}.el-icon-circle-close:before{content:"\e78d"}.el-icon-date:before{content:"\e78e"}.el-icon-caret-top:before{content:"\e78f"}.el-icon-caret-bottom:before{content:"\e790"}.el-icon-caret-right:before{content:"\e791"}.el-icon-caret-left:before{content:"\e792"}.el-icon-share:before{content:"\e793"}.el-icon-more:before{content:"\e794"}.el-icon-phone:before{content:"\e795"}.el-icon-video-camera-solid:before{content:"\e796"}.el-icon-star-on:before{content:"\e797"}.el-icon-menu:before{content:"\e798"}.el-icon-message-solid:before{content:"\e799"}.el-icon-d-caret:before{content:"\e79a"}.el-icon-camera-solid:before{content:"\e79b"}.el-icon-success:before{content:"\e79c"}.el-icon-error:before{content:"\e79d"}.el-icon-location:before{content:"\e79e"}.el-icon-picture:before{content:"\e79f"}.el-icon-circle-plus:before{content:"\e7a0"}.el-icon-info:before{content:"\e7a1"}.el-icon-remove:before{content:"\e7a2"}.el-icon-warning:before{content:"\e7a3"}.el-icon-question:before{content:"\e7a4"}.el-icon-user-solid:before{content:"\e7a5"}.el-icon-s-grid:before{content:"\e7a6"}.el-icon-s-check:before{content:"\e7a7"}.el-icon-s-data:before{content:"\e7a8"}.el-icon-s-fold:before{content:"\e7a9"}.el-icon-s-opportunity:before{content:"\e7aa"}.el-icon-s-custom:before{content:"\e7ab"}.el-icon-s-tools:before{content:"\e7ac"}.el-icon-s-claim:before{content:"\e7ad"}.el-icon-s-finance:before{content:"\e7ae"}.el-icon-s-comment:before{content:"\e7af"}.el-icon-s-flag:before{content:"\e7b0"}.el-icon-s-marketing:before{content:"\e7b1"}.el-icon-s-goods:before{content:"\e7b2"}.el-icon-s-help:before{content:"\e7b3"}.el-icon-s-shop:before{content:"\e7b4"}.el-icon-s-open:before{content:"\e7b5"}.el-icon-s-management:before{content:"\e7b6"}.el-icon-s-ticket:before{content:"\e7b7"}.el-icon-s-release:before{content:"\e7b8"}.el-icon-s-home:before{content:"\e7b9"}.el-icon-s-promotion:before{content:"\e7ba"}.el-icon-s-operation:before{content:"\e7bb"}.el-icon-s-unfold:before{content:"\e7bc"}.el-icon-s-platform:before{content:"\e7bd"}.el-icon-s-order:before{content:"\e7be"}.el-icon-s-cooperation:before{content:"\e7bf"}.el-icon-video-play:before{content:"\e7c0"}.el-icon-video-pause:before{content:"\e7c1"}.el-icon-goods:before{content:"\e7c2"}.el-icon-upload:before{content:"\e7c3"}.el-icon-sort-down:before{content:"\e7c4"}.el-icon-sort-up:before{content:"\e7c5"}.el-icon-c-scale-to-original:before{content:"\e7c6"}.el-icon-eleme:before{content:"\e7c7"}.el-icon-delete-solid:before{content:"\e7c9"}.el-icon-platform-eleme:before{content:"\e7ca"}.el-icon-loading{-webkit-animation:rotating 2s linear infinite;animation:rotating 2s linear infinite}.el-icon--right{margin-left:5px}.el-icon--left{margin-right:5px}@-webkit-keyframes rotating{0%{-webkit-transform:rotateZ(0);transform:rotateZ(0)}100%{-webkit-transform:rotateZ(360deg);transform:rotateZ(360deg)}}@keyframes rotating{0%{-webkit-transform:rotateZ(0);transform:rotateZ(0)}100%{-webkit-transform:rotateZ(360deg);transform:rotateZ(360deg)}}.el-pagination{white-space:nowrap;padding:2px 5px;color:#303133;font-weight:700}.el-pagination::after,.el-pagination::before{display:table;content:""}.el-pagination::after{clear:both}.el-pagination button,.el-pagination span:not([class*=suffix]){display:inline-block;font-size:13px;min-width:35.5px;height:28px;line-height:28px;vertical-align:top;-webkit-box-sizing:border-box;box-sizing:border-box}.el-pagination .el-input__inner{text-align:center;-moz-appearance:textfield;line-height:normal}.el-pagination .el-input__suffix{right:0;-webkit-transform:scale(.8);transform:scale(.8)}.el-pagination .el-select .el-input{width:100px;margin:0 5px}.el-pagination .el-select .el-input .el-input__inner{padding-right:25px;border-radius:3px}.el-pagination button{border:none;padding:0 6px;background:0 0}.el-pagination button:focus{outline:0}.el-pagination button:hover{color:#409EFF}.el-pagination button:disabled{color:#C0C4CC;background-color:#FFF;cursor:not-allowed}.el-pagination .btn-next,.el-pagination .btn-prev{background:center center no-repeat #FFF;background-size:16px;cursor:pointer;margin:0;color:#303133}.el-pagination .btn-next .el-icon,.el-pagination .btn-prev .el-icon{display:block;font-size:12px;font-weight:700}.el-pagination .btn-prev{padding-right:12px}.el-pagination .btn-next{padding-left:12px}.el-pagination .el-pager li.disabled{color:#C0C4CC;cursor:not-allowed}.el-pager li,.el-pager li.btn-quicknext:hover,.el-pager li.btn-quickprev:hover{cursor:pointer}.el-pagination--small .btn-next,.el-pagination--small .btn-prev,.el-pagination--small .el-pager li,.el-pagination--small .el-pager li.btn-quicknext,.el-pagination--small .el-pager li.btn-quickprev,.el-pagination--small .el-pager li:last-child{border-color:transparent;font-size:12px;line-height:22px;height:22px;min-width:22px}.el-pagination--small .more::before,.el-pagination--small li.more::before{line-height:24px}.el-pagination--small button,.el-pagination--small span:not([class*=suffix]){height:22px;line-height:22px}.el-pagination--small .el-pagination__editor,.el-pagination--small .el-pagination__editor.el-input .el-input__inner{height:22px}.el-pagination__sizes{margin:0 10px 0 0;font-weight:400;color:#606266}.el-pagination__sizes .el-input .el-input__inner{font-size:13px;padding-left:8px}.el-pagination__sizes .el-input .el-input__inner:hover{border-color:#409EFF}.el-pagination__total{margin-right:10px;font-weight:400;color:#606266}.el-pagination__jump{margin-left:24px;font-weight:400;color:#606266}.el-pagination__jump .el-input__inner{padding:0 3px}.el-pagination__rightwrapper{float:right}.el-pagination__editor{line-height:18px;padding:0 2px;height:28px;text-align:center;margin:0 2px;-webkit-box-sizing:border-box;box-sizing:border-box;border-radius:3px}.el-pager,.el-pagination.is-background .btn-next,.el-pagination.is-background .btn-prev{padding:0}.el-pagination__editor.el-input{width:50px}.el-pagination__editor.el-input .el-input__inner{height:28px}.el-pagination__editor .el-input__inner::-webkit-inner-spin-button,.el-pagination__editor .el-input__inner::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.el-pagination.is-background .btn-next,.el-pagination.is-background .btn-prev,.el-pagination.is-background .el-pager li{margin:0 5px;background-color:#f4f4f5;color:#606266;min-width:30px;border-radius:2px}.el-pagination.is-background .btn-next.disabled,.el-pagination.is-background .btn-next:disabled,.el-pagination.is-background .btn-prev.disabled,.el-pagination.is-background .btn-prev:disabled,.el-pagination.is-background .el-pager li.disabled{color:#C0C4CC}.el-pagination.is-background .el-pager li:not(.disabled):hover{color:#409EFF}.el-pagination.is-background .el-pager li:not(.disabled).active{background-color:#409EFF;color:#FFF}.el-dialog,.el-pager li{background:#FFF;-webkit-box-sizing:border-box}.el-pagination.is-background.el-pagination--small .btn-next,.el-pagination.is-background.el-pagination--small .btn-prev,.el-pagination.is-background.el-pagination--small .el-pager li{margin:0 3px;min-width:22px}.el-pager,.el-pager li{vertical-align:top;margin:0;display:inline-block}.el-pager{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;list-style:none;font-size:0}.el-radio,.el-table th{-webkit-user-select:none;-moz-user-select:none}.el-date-table,.el-radio,.el-table th{-ms-user-select:none}.el-pager .more::before{line-height:30px}.el-pager li{padding:0 4px;font-size:13px;min-width:35.5px;height:28px;line-height:28px;box-sizing:border-box;text-align:center}.el-menu--collapse .el-menu .el-submenu,.el-menu--popup{min-width:200px}.el-pager li.btn-quicknext,.el-pager li.btn-quickprev{line-height:28px;color:#303133}.el-pager li.btn-quicknext.disabled,.el-pager li.btn-quickprev.disabled{color:#C0C4CC}.el-pager li.active+li{border-left:0}.el-pager li:hover{color:#409EFF}.el-pager li.active{color:#409EFF;cursor:default}@-webkit-keyframes v-modal-in{0%{opacity:0}}@-webkit-keyframes v-modal-out{100%{opacity:0}}.el-dialog{position:relative;margin:0 auto 50px;border-radius:2px;-webkit-box-shadow:0 1px 3px rgba(0,0,0,.3);box-shadow:0 1px 3px rgba(0,0,0,.3);box-sizing:border-box;width:50%}.el-dialog.is-fullscreen{width:100%;margin-top:0;margin-bottom:0;height:100%;overflow:auto}.el-dialog__wrapper{position:fixed;top:0;right:0;bottom:0;left:0;overflow:auto;margin:0}.el-dialog__header{padding:20px 20px 10px}.el-dialog__headerbtn{position:absolute;top:20px;right:20px;padding:0;background:0 0;border:none;outline:0;cursor:pointer;font-size:16px}.el-dialog__headerbtn .el-dialog__close{color:#909399}.el-dialog__headerbtn:focus .el-dialog__close,.el-dialog__headerbtn:hover .el-dialog__close{color:#409EFF}.el-dialog__title{line-height:24px;font-size:18px;color:#303133}.el-dialog__body{padding:30px 20px;color:#606266;font-size:14px;word-break:break-all}.el-dialog__footer{padding:10px 20px 20px;text-align:right;-webkit-box-sizing:border-box;box-sizing:border-box}.el-dialog--center{text-align:center}.el-dialog--center .el-dialog__body{text-align:initial;padding:25px 25px 30px}.el-dialog--center .el-dialog__footer{text-align:inherit}.dialog-fade-enter-active{-webkit-animation:dialog-fade-in .3s;animation:dialog-fade-in .3s}.dialog-fade-leave-active{-webkit-animation:dialog-fade-out .3s;animation:dialog-fade-out .3s}@-webkit-keyframes dialog-fade-in{0%{-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0);opacity:0}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);opacity:1}}@keyframes dialog-fade-in{0%{-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0);opacity:0}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);opacity:1}}@-webkit-keyframes dialog-fade-out{0%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);opacity:1}100%{-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0);opacity:0}}@keyframes dialog-fade-out{0%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);opacity:1}100%{-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0);opacity:0}}.el-autocomplete{position:relative;display:inline-block}.el-autocomplete-suggestion{margin:5px 0;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);box-shadow:0 2px 12px 0 rgba(0,0,0,.1);border-radius:4px;border:1px solid #E4E7ED;-webkit-box-sizing:border-box;box-sizing:border-box;background-color:#FFF}.el-dropdown-menu,.el-menu--collapse .el-submenu .el-menu{z-index:10;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1)}.el-autocomplete-suggestion__wrap{max-height:280px;padding:10px 0;-webkit-box-sizing:border-box;box-sizing:border-box}.el-autocomplete-suggestion__list{margin:0;padding:0}.el-autocomplete-suggestion li{padding:0 20px;margin:0;line-height:34px;cursor:pointer;color:#606266;font-size:14px;list-style:none;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.el-autocomplete-suggestion li.highlighted,.el-autocomplete-suggestion li:hover{background-color:#F5F7FA}.el-autocomplete-suggestion li.divider{margin-top:6px;border-top:1px solid #000}.el-autocomplete-suggestion li.divider:last-child{margin-bottom:-6px}.el-autocomplete-suggestion.is-loading li{text-align:center;height:100px;line-height:100px;font-size:20px;color:#999}.el-autocomplete-suggestion.is-loading li::after{display:inline-block;content:"";height:100%;vertical-align:middle}.el-autocomplete-suggestion.is-loading li:hover{background-color:#FFF}.el-autocomplete-suggestion.is-loading .el-icon-loading{vertical-align:middle}.el-dropdown{display:inline-block;position:relative;color:#606266;font-size:14px}.el-dropdown .el-button-group{display:block}.el-dropdown .el-button-group .el-button{float:none}.el-dropdown .el-dropdown__caret-button{padding-left:5px;padding-right:5px;position:relative;border-left:none}.el-dropdown .el-dropdown__caret-button::before{content:'';position:absolute;display:block;width:1px;top:5px;bottom:5px;left:0;background:rgba(255,255,255,.5)}.el-dropdown .el-dropdown__caret-button:hover::before{top:0;bottom:0}.el-dropdown .el-dropdown__caret-button .el-dropdown__icon{padding-left:0}.el-dropdown__icon{font-size:12px;margin:0 3px}.el-dropdown-menu{position:absolute;top:0;left:0;padding:10px 0;margin:5px 0;background-color:#FFF;border:1px solid #EBEEF5;border-radius:4px;box-shadow:0 2px 12px 0 rgba(0,0,0,.1)}.el-dropdown-menu__item{list-style:none;line-height:36px;padding:0 20px;margin:0;font-size:14px;color:#606266;cursor:pointer;outline:0}.el-dropdown-menu__item:focus,.el-dropdown-menu__item:not(.is-disabled):hover{background-color:#ecf5ff;color:#66b1ff}.el-dropdown-menu__item i{margin-right:5px}.el-dropdown-menu__item--divided{position:relative;margin-top:6px;border-top:1px solid #EBEEF5}.el-dropdown-menu__item--divided:before{content:'';height:6px;display:block;margin:0 -20px;background-color:#FFF}.el-menu::after,.el-menu::before,.el-radio__inner::after,.el-switch__core:after{content:""}.el-dropdown-menu__item.is-disabled{cursor:default;color:#bbb;pointer-events:none}.el-dropdown-menu--medium{padding:6px 0}.el-dropdown-menu--medium .el-dropdown-menu__item{line-height:30px;padding:0 17px;font-size:14px}.el-dropdown-menu--medium .el-dropdown-menu__item.el-dropdown-menu__item--divided{margin-top:6px}.el-dropdown-menu--medium .el-dropdown-menu__item.el-dropdown-menu__item--divided:before{height:6px;margin:0 -17px}.el-dropdown-menu--small{padding:6px 0}.el-dropdown-menu--small .el-dropdown-menu__item{line-height:27px;padding:0 15px;font-size:13px}.el-dropdown-menu--small .el-dropdown-menu__item.el-dropdown-menu__item--divided{margin-top:4px}.el-dropdown-menu--small .el-dropdown-menu__item.el-dropdown-menu__item--divided:before{height:4px;margin:0 -15px}.el-dropdown-menu--mini{padding:3px 0}.el-dropdown-menu--mini .el-dropdown-menu__item{line-height:24px;padding:0 10px;font-size:12px}.el-dropdown-menu--mini .el-dropdown-menu__item.el-dropdown-menu__item--divided{margin-top:3px}.el-dropdown-menu--mini .el-dropdown-menu__item.el-dropdown-menu__item--divided:before{height:3px;margin:0 -10px}.el-menu{border-right:solid 1px #e6e6e6;list-style:none;position:relative;margin:0;padding-left:0;background-color:#FFF}.el-menu--horizontal>.el-menu-item:not(.is-disabled):focus,.el-menu--horizontal>.el-menu-item:not(.is-disabled):hover,.el-menu--horizontal>.el-submenu .el-submenu__title:hover{background-color:#fff}.el-menu::after,.el-menu::before{display:table}.el-menu::after{clear:both}.el-menu.el-menu--horizontal{border-bottom:solid 1px #e6e6e6}.el-menu--horizontal{border-right:none}.el-menu--horizontal>.el-menu-item{float:left;height:60px;line-height:60px;margin:0;border-bottom:2px solid transparent;color:#909399}.el-menu--horizontal>.el-menu-item a,.el-menu--horizontal>.el-menu-item a:hover{color:inherit}.el-menu--horizontal>.el-submenu{float:left}.el-menu--horizontal>.el-submenu:focus,.el-menu--horizontal>.el-submenu:hover{outline:0}.el-menu--horizontal>.el-submenu:focus .el-submenu__title,.el-menu--horizontal>.el-submenu:hover .el-submenu__title{color:#303133}.el-menu--horizontal>.el-submenu.is-active .el-submenu__title{border-bottom:2px solid #409EFF;color:#303133}.el-menu--horizontal>.el-submenu .el-submenu__title{height:60px;line-height:60px;border-bottom:2px solid transparent;color:#909399}.el-menu--horizontal>.el-submenu .el-submenu__icon-arrow{position:static;vertical-align:middle;margin-left:8px;margin-top:-3px}.el-menu--horizontal .el-menu .el-menu-item,.el-menu--horizontal .el-menu .el-submenu__title{background-color:#FFF;float:none;height:36px;line-height:36px;padding:0 10px;color:#909399}.el-menu--horizontal .el-menu .el-menu-item.is-active,.el-menu--horizontal .el-menu .el-submenu.is-active>.el-submenu__title{color:#303133}.el-menu--horizontal .el-menu-item:not(.is-disabled):focus,.el-menu--horizontal .el-menu-item:not(.is-disabled):hover{outline:0;color:#303133}.el-menu--horizontal>.el-menu-item.is-active{border-bottom:2px solid #409EFF;color:#303133}.el-menu--collapse{width:64px}.el-menu--collapse>.el-menu-item [class^=el-icon-],.el-menu--collapse>.el-submenu>.el-submenu__title [class^=el-icon-]{margin:0;vertical-align:middle;width:24px;text-align:center}.el-menu--collapse>.el-menu-item .el-submenu__icon-arrow,.el-menu--collapse>.el-submenu>.el-submenu__title .el-submenu__icon-arrow{display:none}.el-menu--collapse>.el-menu-item span,.el-menu--collapse>.el-submenu>.el-submenu__title span{height:0;width:0;overflow:hidden;visibility:hidden;display:inline-block}.el-menu--collapse>.el-menu-item.is-active i{color:inherit}.el-menu--collapse .el-submenu{position:relative}.el-menu--collapse .el-submenu .el-menu{position:absolute;margin-left:5px;top:0;left:100%;border:1px solid #E4E7ED;border-radius:2px;box-shadow:0 2px 12px 0 rgba(0,0,0,.1)}.el-menu-item,.el-submenu__title{height:56px;line-height:56px;position:relative;-webkit-box-sizing:border-box;white-space:nowrap;list-style:none}.el-menu--collapse .el-submenu.is-opened>.el-submenu__title .el-submenu__icon-arrow{-webkit-transform:none;transform:none}.el-menu--popup{z-index:100;border:none;padding:5px 0;border-radius:2px;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);box-shadow:0 2px 12px 0 rgba(0,0,0,.1)}.el-menu--popup-bottom-start{margin-top:5px}.el-menu--popup-right-start{margin-left:5px;margin-right:5px}.el-menu-item{font-size:14px;color:#303133;padding:0 20px;cursor:pointer;-webkit-transition:border-color .3s,background-color .3s,color .3s;transition:border-color .3s,background-color .3s,color .3s;box-sizing:border-box}.el-menu-item *{vertical-align:middle}.el-menu-item i{color:#909399}.el-menu-item:focus,.el-menu-item:hover{outline:0;background-color:#ecf5ff}.el-menu-item.is-disabled{opacity:.25;cursor:not-allowed;background:0 0!important}.el-menu-item [class^=el-icon-]{margin-right:5px;width:24px;text-align:center;font-size:18px;vertical-align:middle}.el-menu-item.is-active{color:#409EFF}.el-menu-item.is-active i{color:inherit}.el-submenu{list-style:none;margin:0;padding-left:0}.el-submenu__title{font-size:14px;color:#303133;padding:0 20px;cursor:pointer;-webkit-transition:border-color .3s,background-color .3s,color .3s;transition:border-color .3s,background-color .3s,color .3s;box-sizing:border-box}.el-submenu__title *{vertical-align:middle}.el-submenu__title i{color:#909399}.el-submenu__title:focus,.el-submenu__title:hover{outline:0;background-color:#ecf5ff}.el-submenu__title.is-disabled{opacity:.25;cursor:not-allowed;background:0 0!important}.el-submenu__title:hover{background-color:#ecf5ff}.el-submenu .el-menu{border:none}.el-submenu .el-menu-item{height:50px;line-height:50px;padding:0 45px;min-width:200px}.el-submenu__icon-arrow{position:absolute;top:50%;right:20px;margin-top:-7px;-webkit-transition:-webkit-transform .3s;transition:-webkit-transform .3s;transition:transform .3s;transition:transform .3s,-webkit-transform .3s;font-size:12px}.el-radio,.el-radio__inner,.el-radio__input{position:relative;display:inline-block}.el-submenu.is-active .el-submenu__title{border-bottom-color:#409EFF}.el-submenu.is-opened>.el-submenu__title .el-submenu__icon-arrow{-webkit-transform:rotateZ(180deg);transform:rotateZ(180deg)}.el-submenu.is-disabled .el-menu-item,.el-submenu.is-disabled .el-submenu__title{opacity:.25;cursor:not-allowed;background:0 0!important}.el-submenu [class^=el-icon-]{vertical-align:middle;margin-right:5px;width:24px;text-align:center;font-size:18px}.el-menu-item-group>ul{padding:0}.el-menu-item-group__title{padding:7px 0 7px 20px;line-height:normal;font-size:12px;color:#909399}.el-radio,.el-radio--medium.is-bordered .el-radio__label{font-size:14px}.horizontal-collapse-transition .el-submenu__title .el-submenu__icon-arrow{-webkit-transition:.2s;transition:.2s;opacity:0}.el-radio{color:#606266;font-weight:500;line-height:1;cursor:pointer;white-space:nowrap;outline:0;margin-right:30px}.el-radio.is-bordered{padding:12px 20px 0 10px;border-radius:4px;border:1px solid #DCDFE6;-webkit-box-sizing:border-box;box-sizing:border-box;height:40px}.el-radio.is-bordered.is-checked{border-color:#409EFF}.el-radio.is-bordered.is-disabled{cursor:not-allowed;border-color:#EBEEF5}.el-radio__input.is-disabled .el-radio__inner,.el-radio__input.is-disabled.is-checked .el-radio__inner{background-color:#F5F7FA;border-color:#E4E7ED}.el-radio.is-bordered+.el-radio.is-bordered{margin-left:10px}.el-radio--medium.is-bordered{padding:10px 20px 0 10px;border-radius:4px;height:36px}.el-radio--mini.is-bordered .el-radio__label,.el-radio--small.is-bordered .el-radio__label{font-size:12px}.el-radio--medium.is-bordered .el-radio__inner{height:14px;width:14px}.el-radio--small.is-bordered{padding:8px 15px 0 10px;border-radius:3px;height:32px}.el-radio--small.is-bordered .el-radio__inner{height:12px;width:12px}.el-radio--mini.is-bordered{padding:6px 15px 0 10px;border-radius:3px;height:28px}.el-radio--mini.is-bordered .el-radio__inner{height:12px;width:12px}.el-radio:last-child{margin-right:0}.el-radio__input{white-space:nowrap;cursor:pointer;outline:0;line-height:1;vertical-align:middle}.el-radio__input.is-disabled .el-radio__inner{cursor:not-allowed}.el-radio__input.is-disabled .el-radio__inner::after{cursor:not-allowed;background-color:#F5F7FA}.el-radio__input.is-disabled .el-radio__inner+.el-radio__label{cursor:not-allowed}.el-radio__input.is-disabled.is-checked .el-radio__inner::after{background-color:#C0C4CC}.el-radio__input.is-disabled+span.el-radio__label{color:#C0C4CC;cursor:not-allowed}.el-radio__input.is-checked .el-radio__inner{border-color:#409EFF;background:#409EFF}.el-radio__input.is-checked .el-radio__inner::after{-webkit-transform:translate(-50%,-50%) scale(1);transform:translate(-50%,-50%) scale(1)}.el-radio__input.is-checked+.el-radio__label{color:#409EFF}.el-radio__input.is-focus .el-radio__inner{border-color:#409EFF}.el-radio__inner{border:1px solid #DCDFE6;border-radius:100%;width:14px;height:14px;background-color:#FFF;cursor:pointer;-webkit-box-sizing:border-box;box-sizing:border-box}.el-radio__inner:hover{border-color:#409EFF}.el-radio__inner::after{width:4px;height:4px;border-radius:100%;background-color:#FFF;position:absolute;left:50%;top:50%;-webkit-transform:translate(-50%,-50%) scale(0);transform:translate(-50%,-50%) scale(0);-webkit-transition:-webkit-transform .15s ease-in;transition:-webkit-transform .15s ease-in;transition:transform .15s ease-in;transition:transform .15s ease-in,-webkit-transform .15s ease-in}.el-radio__original{opacity:0;outline:0;position:absolute;z-index:-1;top:0;left:0;right:0;bottom:0;margin:0}.el-radio-button,.el-radio-button__inner{display:inline-block;position:relative;outline:0}.el-radio:focus:not(.is-focus):not(:active):not(.is-disabled) .el-radio__inner{-webkit-box-shadow:0 0 2px 2px #409EFF;box-shadow:0 0 2px 2px #409EFF}.el-radio__label{font-size:14px;padding-left:10px}.el-radio-group{display:inline-block;line-height:1;vertical-align:middle;font-size:0}.el-radio-button__inner{line-height:1;white-space:nowrap;vertical-align:middle;background:#FFF;border:1px solid #DCDFE6;font-weight:500;border-left:0;color:#606266;-webkit-appearance:none;text-align:center;-webkit-box-sizing:border-box;box-sizing:border-box;margin:0;cursor:pointer;-webkit-transition:all .3s cubic-bezier(.645,.045,.355,1);transition:all .3s cubic-bezier(.645,.045,.355,1);padding:12px 20px;font-size:14px;border-radius:0}.el-radio-button__inner.is-round{padding:12px 20px}.el-radio-button__inner:hover{color:#409EFF}.el-radio-button__inner [class*=el-icon-]{line-height:.9}.el-radio-button__inner [class*=el-icon-]+span{margin-left:5px}.el-radio-button:first-child .el-radio-button__inner{border-left:1px solid #DCDFE6;border-radius:4px 0 0 4px;-webkit-box-shadow:none!important;box-shadow:none!important}.el-radio-button__orig-radio{opacity:0;outline:0;position:absolute;z-index:-1}.el-radio-button__orig-radio:checked+.el-radio-button__inner{color:#FFF;background-color:#409EFF;border-color:#409EFF;-webkit-box-shadow:-1px 0 0 0 #409EFF;box-shadow:-1px 0 0 0 #409EFF}.el-radio-button__orig-radio:disabled+.el-radio-button__inner{color:#C0C4CC;cursor:not-allowed;background-image:none;background-color:#FFF;border-color:#EBEEF5;-webkit-box-shadow:none;box-shadow:none}.el-radio-button__orig-radio:disabled:checked+.el-radio-button__inner{background-color:#F2F6FC}.el-radio-button:last-child .el-radio-button__inner{border-radius:0 4px 4px 0}.el-popover,.el-radio-button:first-child:last-child .el-radio-button__inner{border-radius:4px}.el-radio-button--medium .el-radio-button__inner{padding:10px 20px;font-size:14px;border-radius:0}.el-radio-button--medium .el-radio-button__inner.is-round{padding:10px 20px}.el-radio-button--small .el-radio-button__inner{padding:9px 15px;font-size:12px;border-radius:0}.el-radio-button--small .el-radio-button__inner.is-round{padding:9px 15px}.el-radio-button--mini .el-radio-button__inner{padding:7px 15px;font-size:12px;border-radius:0}.el-radio-button--mini .el-radio-button__inner.is-round{padding:7px 15px}.el-radio-button:focus:not(.is-focus):not(:active):not(.is-disabled){-webkit-box-shadow:0 0 2px 2px #409EFF;box-shadow:0 0 2px 2px #409EFF}.el-switch{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;position:relative;font-size:14px;line-height:20px;height:20px;vertical-align:middle}.el-switch__core,.el-switch__label{display:inline-block;cursor:pointer}.el-switch.is-disabled .el-switch__core,.el-switch.is-disabled .el-switch__label{cursor:not-allowed}.el-switch__label{-webkit-transition:.2s;transition:.2s;height:20px;font-size:14px;font-weight:500;vertical-align:middle;color:#303133}.el-switch__label.is-active{color:#409EFF}.el-switch__label--left{margin-right:10px}.el-switch__label--right{margin-left:10px}.el-switch__label *{line-height:1;font-size:14px;display:inline-block}.el-switch__input{position:absolute;width:0;height:0;opacity:0;margin:0}.el-switch__core{margin:0;position:relative;width:40px;height:20px;border:1px solid #DCDFE6;outline:0;border-radius:10px;-webkit-box-sizing:border-box;box-sizing:border-box;background:#DCDFE6;-webkit-transition:border-color .3s,background-color .3s;transition:border-color .3s,background-color .3s;vertical-align:middle}.el-switch__core:after{position:absolute;top:1px;left:1px;border-radius:100%;-webkit-transition:all .3s;transition:all .3s;width:16px;height:16px;background-color:#FFF}.el-switch.is-checked .el-switch__core{border-color:#409EFF;background-color:#409EFF}.el-switch.is-checked .el-switch__core::after{left:100%;margin-left:-17px}.el-switch.is-disabled{opacity:.6}.el-switch--wide .el-switch__label.el-switch__label--left span{left:10px}.el-switch--wide .el-switch__label.el-switch__label--right span{right:10px}.el-switch .label-fade-enter,.el-switch .label-fade-leave-active{opacity:0}.el-select-dropdown{position:absolute;z-index:1001;border:1px solid #E4E7ED;border-radius:4px;background-color:#FFF;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);box-shadow:0 2px 12px 0 rgba(0,0,0,.1);-webkit-box-sizing:border-box;box-sizing:border-box;margin:5px 0}.el-select-dropdown.is-multiple .el-select-dropdown__item.selected{color:#409EFF;background-color:#FFF}.el-select-dropdown.is-multiple .el-select-dropdown__item.selected.hover{background-color:#F5F7FA}.el-select-dropdown.is-multiple .el-select-dropdown__item.selected::after{position:absolute;right:20px;font-family:element-icons;content:"\e6da";font-size:12px;font-weight:700;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.el-select-dropdown .el-scrollbar.is-empty .el-select-dropdown__list{padding:0}.el-select-dropdown__empty{padding:10px 0;margin:0;text-align:center;color:#999;font-size:14px}.el-select-dropdown__wrap{max-height:274px}.el-select-dropdown__list{list-style:none;padding:6px 0;margin:0;-webkit-box-sizing:border-box;box-sizing:border-box}.el-select-dropdown__item{font-size:14px;padding:0 20px;position:relative;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:#606266;height:34px;line-height:34px;-webkit-box-sizing:border-box;box-sizing:border-box;cursor:pointer}.el-select .el-tag,.el-table{-webkit-box-sizing:border-box}.el-select-dropdown__item.is-disabled{color:#C0C4CC;cursor:not-allowed}.el-select-dropdown__item.is-disabled:hover{background-color:#FFF}.el-select-dropdown__item.hover,.el-select-dropdown__item:hover{background-color:#F5F7FA}.el-select-dropdown__item.selected{color:#409EFF;font-weight:700}.el-select-group{margin:0;padding:0}.el-select-group__wrap{position:relative;list-style:none;margin:0;padding:0}.el-select-group__wrap:not(:last-of-type){padding-bottom:24px}.el-select-group__wrap:not(:last-of-type)::after{content:'';position:absolute;display:block;left:20px;right:20px;bottom:12px;height:1px;background:#E4E7ED}.el-select-group__title{padding-left:20px;font-size:12px;color:#909399;line-height:30px}.el-select-group .el-select-dropdown__item{padding-left:20px}.el-select{display:inline-block;position:relative}.el-select .el-select__tags>span{display:contents}.el-select:hover .el-input__inner{border-color:#C0C4CC}.el-select .el-input__inner{cursor:pointer;padding-right:35px}.el-select .el-input__inner:focus{border-color:#409EFF}.el-select .el-input .el-select__caret{color:#C0C4CC;font-size:14px;-webkit-transition:-webkit-transform .3s;transition:-webkit-transform .3s;transition:transform .3s;transition:transform .3s,-webkit-transform .3s;-webkit-transform:rotateZ(180deg);transform:rotateZ(180deg);cursor:pointer}.el-select .el-input .el-select__caret.is-reverse{-webkit-transform:rotateZ(0);transform:rotateZ(0)}.el-select .el-input .el-select__caret.is-show-close{font-size:14px;text-align:center;-webkit-transform:rotateZ(180deg);transform:rotateZ(180deg);border-radius:100%;color:#C0C4CC;-webkit-transition:color .2s cubic-bezier(.645,.045,.355,1);transition:color .2s cubic-bezier(.645,.045,.355,1)}.el-select .el-input .el-select__caret.is-show-close:hover{color:#909399}.el-select .el-input.is-disabled .el-input__inner{cursor:not-allowed}.el-select .el-input.is-disabled .el-input__inner:hover{border-color:#E4E7ED}.el-select .el-input.is-focus .el-input__inner{border-color:#409EFF}.el-select>.el-input{display:block}.el-select__input{border:none;outline:0;padding:0;margin-left:15px;color:#666;font-size:14px;-webkit-appearance:none;-moz-appearance:none;appearance:none;height:28px;background-color:transparent}.el-select__input.is-mini{height:14px}.el-select__close{cursor:pointer;position:absolute;top:8px;z-index:1000;right:25px;color:#C0C4CC;line-height:18px;font-size:14px}.el-select__close:hover{color:#909399}.el-select__tags{position:absolute;line-height:normal;white-space:normal;z-index:1;top:50%;-webkit-transform:translateY(-50%);transform:translateY(-50%);display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-ms-flex-wrap:wrap;flex-wrap:wrap}.el-select .el-tag__close{margin-top:-2px}.el-select .el-tag{box-sizing:border-box;border-color:transparent;margin:2px 0 2px 6px;background-color:#f0f2f5}.el-select .el-tag__close.el-icon-close{background-color:#C0C4CC;right:-7px;top:0;color:#FFF}.el-select .el-tag__close.el-icon-close:hover{background-color:#909399}.el-table,.el-table__expanded-cell{background-color:#FFF}.el-select .el-tag__close.el-icon-close::before{display:block;-webkit-transform:translate(0,.5px);transform:translate(0,.5px)}.el-table{position:relative;overflow:hidden;box-sizing:border-box;-webkit-box-flex:1;-ms-flex:1;flex:1;width:100%;max-width:100%;font-size:14px;color:#606266}.el-table--mini,.el-table--small,.el-table__expand-icon{font-size:12px}.el-table__empty-block{min-height:60px;text-align:center;width:100%;height:100%;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.el-table__empty-text{line-height:60px;width:50%;color:#909399}.el-table__expand-column .cell{padding:0;text-align:center}.el-table__expand-icon{position:relative;cursor:pointer;color:#666;-webkit-transition:-webkit-transform .2s ease-in-out;transition:-webkit-transform .2s ease-in-out;transition:transform .2s ease-in-out;transition:transform .2s ease-in-out,-webkit-transform .2s ease-in-out;height:20px}.el-table__expand-icon--expanded{-webkit-transform:rotate(90deg);transform:rotate(90deg)}.el-table__expand-icon>.el-icon{position:absolute;left:50%;top:50%;margin-left:-5px;margin-top:-5px}.el-table__expanded-cell[class*=cell]{padding:20px 50px}.el-table__expanded-cell:hover{background-color:transparent!important}.el-table__placeholder{display:inline-block;width:20px}.el-table--fit{border-right:0;border-bottom:0}.el-table--fit td.gutter,.el-table--fit th.gutter{border-right-width:1px}.el-table--scrollable-x .el-table__body-wrapper{overflow-x:auto}.el-table--scrollable-y .el-table__body-wrapper{overflow-y:auto}.el-table thead{color:#909399;font-weight:500}.el-table thead.is-group th{background:#F5F7FA}.el-table th,.el-table tr{background-color:#FFF}.el-table td,.el-table th{padding:12px 0;min-width:0;-webkit-box-sizing:border-box;box-sizing:border-box;text-overflow:ellipsis;vertical-align:middle;position:relative;text-align:left}.el-table td.is-center,.el-table th.is-center{text-align:center}.el-table td.is-right,.el-table th.is-right{text-align:right}.el-table td.gutter,.el-table th.gutter{width:15px;border-right-width:0;border-bottom-width:0;padding:0}.el-table--medium td,.el-table--medium th{padding:10px 0}.el-table--small td,.el-table--small th{padding:8px 0}.el-table--mini td,.el-table--mini th{padding:6px 0}.el-table .cell,.el-table th div{padding-right:10px;overflow:hidden;text-overflow:ellipsis}.el-table .cell,.el-table th div,.el-table--border td:first-child .cell,.el-table--border th:first-child .cell{padding-left:10px}.el-table tr input[type=checkbox]{margin:0}.el-table td,.el-table th.is-leaf{border-bottom:1px solid #EBEEF5}.el-table th.is-sortable{cursor:pointer}.el-table th{white-space:nowrap;overflow:hidden;user-select:none}.el-date-table,.el-time-panel{-webkit-user-select:none;-moz-user-select:none}.el-table th div{display:inline-block;line-height:40px;-webkit-box-sizing:border-box;box-sizing:border-box;white-space:nowrap}.el-table th>.cell{position:relative;word-wrap:normal;text-overflow:ellipsis;display:inline-block;vertical-align:middle;width:100%;-webkit-box-sizing:border-box;box-sizing:border-box}.el-table th>.cell.highlight{color:#409EFF}.el-table th.required>div::before{display:inline-block;content:"";width:8px;height:8px;border-radius:50%;background:#ff4d51;margin-right:5px;vertical-align:middle}.el-table td div{-webkit-box-sizing:border-box;box-sizing:border-box}.el-table td.gutter{width:0}.el-table .cell{-webkit-box-sizing:border-box;box-sizing:border-box;white-space:normal;word-break:break-all;line-height:23px}.el-table .cell.el-tooltip{white-space:nowrap;min-width:50px}.el-table--border,.el-table--group{border:1px solid #EBEEF5}.el-table--border::after,.el-table--group::after,.el-table::before{content:'';position:absolute;background-color:#EBEEF5;z-index:1}.el-table--border::after,.el-table--group::after{top:0;right:0;width:1px;height:100%}.el-table::before{left:0;bottom:0;width:100%;height:1px}.el-table--border{border-right:none;border-bottom:none}.el-table--border.el-loading-parent--relative{border-color:transparent}.el-table--border td,.el-table--border th,.el-table__body-wrapper .el-table--border.is-scrolling-left~.el-table__fixed{border-right:1px solid #EBEEF5}.el-table--border th.gutter:last-of-type{border-bottom:1px solid #EBEEF5;border-bottom-width:1px}.el-table--border th,.el-table__fixed-right-patch{border-bottom:1px solid #EBEEF5}.el-table__fixed,.el-table__fixed-right{position:absolute;top:0;left:0;overflow-x:hidden;overflow-y:hidden;-webkit-box-shadow:0 0 10px rgba(0,0,0,.12);box-shadow:0 0 10px rgba(0,0,0,.12)}.el-table__fixed-right::before,.el-table__fixed::before{content:'';position:absolute;left:0;bottom:0;width:100%;height:1px;background-color:#EBEEF5;z-index:4}.el-table__fixed-right-patch{position:absolute;top:-1px;right:0;background-color:#FFF}.el-table__fixed-right{top:0;left:auto;right:0}.el-table__fixed-right .el-table__fixed-body-wrapper,.el-table__fixed-right .el-table__fixed-footer-wrapper,.el-table__fixed-right .el-table__fixed-header-wrapper{left:auto;right:0}.el-table__fixed-header-wrapper{position:absolute;left:0;top:0;z-index:3}.el-table__fixed-footer-wrapper{position:absolute;left:0;bottom:0;z-index:3}.el-table__fixed-footer-wrapper tbody td{border-top:1px solid #EBEEF5;background-color:#F5F7FA;color:#606266}.el-table__fixed-body-wrapper{position:absolute;left:0;top:37px;overflow:hidden;z-index:3}.el-table__body-wrapper,.el-table__footer-wrapper,.el-table__header-wrapper{width:100%}.el-table__footer-wrapper{margin-top:-1px}.el-table__footer-wrapper td{border-top:1px solid #EBEEF5}.el-table__body,.el-table__footer,.el-table__header{table-layout:fixed;border-collapse:separate}.el-table__footer-wrapper,.el-table__header-wrapper{overflow:hidden}.el-table__footer-wrapper tbody td,.el-table__header-wrapper tbody td{background-color:#F5F7FA;color:#606266}.el-table__body-wrapper{overflow:hidden;position:relative}.el-table__body-wrapper.is-scrolling-left~.el-table__fixed,.el-table__body-wrapper.is-scrolling-none~.el-table__fixed,.el-table__body-wrapper.is-scrolling-none~.el-table__fixed-right,.el-table__body-wrapper.is-scrolling-right~.el-table__fixed-right{-webkit-box-shadow:none;box-shadow:none}.el-picker-panel,.el-table-filter{-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1)}.el-table__body-wrapper .el-table--border.is-scrolling-right~.el-table__fixed-right{border-left:1px solid #EBEEF5}.el-table .caret-wrapper{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-webkit-box-align:center;-ms-flex-align:center;align-items:center;height:34px;width:24px;vertical-align:middle;cursor:pointer;overflow:initial;position:relative}.el-table .sort-caret{width:0;height:0;border:5px solid transparent;position:absolute;left:7px}.el-table .sort-caret.ascending{border-bottom-color:#C0C4CC;top:5px}.el-table .sort-caret.descending{border-top-color:#C0C4CC;bottom:7px}.el-table .ascending .sort-caret.ascending{border-bottom-color:#409EFF}.el-table .descending .sort-caret.descending{border-top-color:#409EFF}.el-table .hidden-columns{position:absolute;z-index:-1}.el-table--striped .el-table__body tr.el-table__row--striped td{background:#FAFAFA}.el-table--striped .el-table__body tr.el-table__row--striped.current-row td,.el-table__body tr.current-row>td,.el-table__body tr.hover-row.current-row>td,.el-table__body tr.hover-row.el-table__row--striped.current-row>td,.el-table__body tr.hover-row.el-table__row--striped>td,.el-table__body tr.hover-row>td{background-color:#ecf5ff}.el-table__column-resize-proxy{position:absolute;left:200px;top:0;bottom:0;width:0;border-left:1px solid #EBEEF5;z-index:10}.el-table__column-filter-trigger{display:inline-block;line-height:34px;cursor:pointer}.el-table__column-filter-trigger i{color:#909399;font-size:12px;-webkit-transform:scale(.75);transform:scale(.75)}.el-table--enable-row-transition .el-table__body td{-webkit-transition:background-color .25s ease;transition:background-color .25s ease}.el-table--enable-row-hover .el-table__body tr:hover>td{background-color:#F5F7FA}.el-table--fluid-height .el-table__fixed,.el-table--fluid-height .el-table__fixed-right{bottom:0;overflow:hidden}.el-table [class*=el-table__row--level] .el-table__expand-icon{display:inline-block;width:14px;vertical-align:middle;margin-right:5px}.el-table-column--selection .cell{padding-left:14px;padding-right:14px}.el-table-filter{border:1px solid #EBEEF5;border-radius:2px;background-color:#FFF;box-shadow:0 2px 12px 0 rgba(0,0,0,.1);-webkit-box-sizing:border-box;box-sizing:border-box;margin:2px 0}.el-date-table td,.el-date-table td div{height:30px;-webkit-box-sizing:border-box}.el-table-filter__list{padding:5px 0;margin:0;list-style:none;min-width:100px}.el-table-filter__list-item{line-height:36px;padding:0 10px;cursor:pointer;font-size:14px}.el-table-filter__list-item:hover{background-color:#ecf5ff;color:#66b1ff}.el-table-filter__list-item.is-active{background-color:#409EFF;color:#FFF}.el-table-filter__content{min-width:100px}.el-table-filter__bottom{border-top:1px solid #EBEEF5;padding:8px}.el-table-filter__bottom button{background:0 0;border:none;color:#606266;cursor:pointer;font-size:13px;padding:0 3px}.el-date-table td.in-range div,.el-date-table td.in-range div:hover,.el-date-table.is-week-mode .el-date-table__row.current div,.el-date-table.is-week-mode .el-date-table__row:hover div{background-color:#F2F6FC}.el-table-filter__bottom button:hover{color:#409EFF}.el-table-filter__bottom button:focus{outline:0}.el-table-filter__bottom button.is-disabled{color:#C0C4CC;cursor:not-allowed}.el-table-filter__wrap{max-height:280px}.el-table-filter__checkbox-group{padding:10px}.el-table-filter__checkbox-group label.el-checkbox{display:block;margin-right:5px;margin-bottom:8px;margin-left:5px}.el-table-filter__checkbox-group .el-checkbox:last-child{margin-bottom:0}.el-date-table{font-size:12px;user-select:none}.el-date-table.is-week-mode .el-date-table__row:hover td.available:hover{color:#606266}.el-date-table.is-week-mode .el-date-table__row:hover td:first-child div{margin-left:5px;border-top-left-radius:15px;border-bottom-left-radius:15px}.el-date-table.is-week-mode .el-date-table__row:hover td:last-child div{margin-right:5px;border-top-right-radius:15px;border-bottom-right-radius:15px}.el-date-table td{width:32px;padding:4px 0;box-sizing:border-box;text-align:center;cursor:pointer;position:relative}.el-date-table td div{padding:3px 0;box-sizing:border-box}.el-date-table td span{width:24px;height:24px;display:block;margin:0 auto;line-height:24px;position:absolute;left:50%;-webkit-transform:translateX(-50%);transform:translateX(-50%);border-radius:50%}.el-date-table td.next-month,.el-date-table td.prev-month{color:#C0C4CC}.el-date-table td.today{position:relative}.el-date-table td.today span{color:#409EFF;font-weight:700}.el-date-table td.today.end-date span,.el-date-table td.today.start-date span{color:#FFF}.el-date-table td.available:hover{color:#409EFF}.el-date-table td.current:not(.disabled) span{color:#FFF;background-color:#409EFF}.el-date-table td.end-date div,.el-date-table td.start-date div{color:#FFF}.el-date-table td.end-date span,.el-date-table td.start-date span{background-color:#409EFF}.el-date-table td.start-date div{margin-left:5px;border-top-left-radius:15px;border-bottom-left-radius:15px}.el-date-table td.end-date div{margin-right:5px;border-top-right-radius:15px;border-bottom-right-radius:15px}.el-date-table td.disabled div{background-color:#F5F7FA;opacity:1;cursor:not-allowed;color:#C0C4CC}.el-date-table td.selected div{margin-left:5px;margin-right:5px;background-color:#F2F6FC;border-radius:15px}.el-date-table td.selected div:hover{background-color:#F2F6FC}.el-date-table td.selected span{background-color:#409EFF;color:#FFF;border-radius:15px}.el-date-table td.week{font-size:80%;color:#606266}.el-month-table,.el-year-table{font-size:12px;border-collapse:collapse}.el-date-table th{padding:5px;color:#606266;font-weight:400;border-bottom:solid 1px #EBEEF5}.el-month-table{margin:-1px}.el-month-table td{text-align:center;padding:8px 0;cursor:pointer}.el-month-table td div{height:48px;padding:6px 0;-webkit-box-sizing:border-box;box-sizing:border-box}.el-month-table td.today .cell{color:#409EFF;font-weight:700}.el-month-table td.today.end-date .cell,.el-month-table td.today.start-date .cell{color:#FFF}.el-month-table td.disabled .cell{background-color:#F5F7FA;cursor:not-allowed;color:#C0C4CC}.el-month-table td.disabled .cell:hover{color:#C0C4CC}.el-month-table td .cell{width:60px;height:36px;display:block;line-height:36px;color:#606266;margin:0 auto;border-radius:18px}.el-month-table td .cell:hover{color:#409EFF}.el-month-table td.in-range div,.el-month-table td.in-range div:hover{background-color:#F2F6FC}.el-month-table td.end-date div,.el-month-table td.start-date div{color:#FFF}.el-month-table td.end-date .cell,.el-month-table td.start-date .cell{color:#FFF;background-color:#409EFF}.el-month-table td.start-date div{border-top-left-radius:24px;border-bottom-left-radius:24px}.el-month-table td.end-date div{border-top-right-radius:24px;border-bottom-right-radius:24px}.el-month-table td.current:not(.disabled) .cell{color:#409EFF}.el-year-table{margin:-1px}.el-year-table .el-icon{color:#303133}.el-year-table td{text-align:center;padding:20px 3px;cursor:pointer}.el-year-table td.today .cell{color:#409EFF;font-weight:700}.el-year-table td.disabled .cell{background-color:#F5F7FA;cursor:not-allowed;color:#C0C4CC}.el-year-table td.disabled .cell:hover{color:#C0C4CC}.el-year-table td .cell{width:48px;height:32px;display:block;line-height:32px;color:#606266;margin:0 auto}.el-year-table td .cell:hover,.el-year-table td.current:not(.disabled) .cell{color:#409EFF}.el-date-range-picker{width:646px}.el-date-range-picker.has-sidebar{width:756px}.el-date-range-picker table{table-layout:fixed;width:100%}.el-date-range-picker .el-picker-panel__body{min-width:513px}.el-date-range-picker .el-picker-panel__content{margin:0}.el-date-range-picker__header{position:relative;text-align:center;height:28px}.el-date-range-picker__header [class*=arrow-left]{float:left}.el-date-range-picker__header [class*=arrow-right]{float:right}.el-date-range-picker__header div{font-size:16px;font-weight:500;margin-right:50px}.el-date-range-picker__content{float:left;width:50%;-webkit-box-sizing:border-box;box-sizing:border-box;margin:0;padding:16px}.el-date-range-picker__content.is-left{border-right:1px solid #e4e4e4}.el-date-range-picker__content .el-date-range-picker__header div{margin-left:50px;margin-right:50px}.el-date-range-picker__editors-wrap{-webkit-box-sizing:border-box;box-sizing:border-box;display:table-cell}.el-date-range-picker__editors-wrap.is-right{text-align:right}.el-date-range-picker__time-header{position:relative;border-bottom:1px solid #e4e4e4;font-size:12px;padding:8px 5px 5px;display:table;width:100%;-webkit-box-sizing:border-box;box-sizing:border-box}.el-date-range-picker__time-header>.el-icon-arrow-right{font-size:20px;vertical-align:middle;display:table-cell;color:#303133}.el-date-range-picker__time-picker-wrap{position:relative;display:table-cell;padding:0 5px}.el-date-range-picker__time-picker-wrap .el-picker-panel{position:absolute;top:13px;right:0;z-index:1;background:#FFF}.el-date-picker{width:322px}.el-date-picker.has-sidebar.has-time{width:434px}.el-date-picker.has-sidebar{width:438px}.el-date-picker.has-time .el-picker-panel__body-wrapper{position:relative}.el-date-picker .el-picker-panel__content{width:292px}.el-date-picker table{table-layout:fixed;width:100%}.el-date-picker__editor-wrap{position:relative;display:table-cell;padding:0 5px}.el-date-picker__time-header{position:relative;border-bottom:1px solid #e4e4e4;font-size:12px;padding:8px 5px 5px;display:table;width:100%;-webkit-box-sizing:border-box;box-sizing:border-box}.el-date-picker__header{margin:12px;text-align:center}.el-date-picker__header--bordered{margin-bottom:0;padding-bottom:12px;border-bottom:solid 1px #EBEEF5}.el-date-picker__header--bordered+.el-picker-panel__content{margin-top:0}.el-date-picker__header-label{font-size:16px;font-weight:500;padding:0 5px;line-height:22px;text-align:center;cursor:pointer;color:#606266}.el-date-picker__header-label.active,.el-date-picker__header-label:hover{color:#409EFF}.el-date-picker__prev-btn{float:left}.el-date-picker__next-btn{float:right}.el-date-picker__time-wrap{padding:10px;text-align:center}.el-date-picker__time-label{float:left;cursor:pointer;line-height:30px;margin-left:10px}.time-select{margin:5px 0;min-width:0}.time-select .el-picker-panel__content{max-height:200px;margin:0}.time-select-item{padding:8px 10px;font-size:14px;line-height:20px}.time-select-item.selected:not(.disabled){color:#409EFF;font-weight:700}.time-select-item.disabled{color:#E4E7ED;cursor:not-allowed}.time-select-item:hover{background-color:#F5F7FA;font-weight:700;cursor:pointer}.el-date-editor{position:relative;display:inline-block;text-align:left}.el-date-editor.el-input,.el-date-editor.el-input__inner{width:220px}.el-date-editor--monthrange.el-input,.el-date-editor--monthrange.el-input__inner{width:300px}.el-date-editor--daterange.el-input,.el-date-editor--daterange.el-input__inner,.el-date-editor--timerange.el-input,.el-date-editor--timerange.el-input__inner{width:350px}.el-date-editor--datetimerange.el-input,.el-date-editor--datetimerange.el-input__inner{width:400px}.el-date-editor--dates .el-input__inner{text-overflow:ellipsis;white-space:nowrap}.el-date-editor .el-icon-circle-close{cursor:pointer}.el-date-editor .el-range__icon{font-size:14px;margin-left:-5px;color:#C0C4CC;float:left;line-height:32px}.el-date-editor .el-range-input,.el-date-editor .el-range-separator{height:100%;margin:0;text-align:center;display:inline-block;font-size:14px}.el-date-editor .el-range-input{-webkit-appearance:none;-moz-appearance:none;appearance:none;border:none;outline:0;padding:0;width:39%;color:#606266}.el-date-editor .el-range-input::-webkit-input-placeholder{color:#C0C4CC}.el-date-editor .el-range-input:-ms-input-placeholder{color:#C0C4CC}.el-date-editor .el-range-input::-ms-input-placeholder{color:#C0C4CC}.el-date-editor .el-range-input::placeholder{color:#C0C4CC}.el-date-editor .el-range-separator{padding:0 5px;line-height:32px;width:5%;color:#303133}.el-date-editor .el-range__close-icon{font-size:14px;color:#C0C4CC;width:25px;display:inline-block;float:right;line-height:32px}.el-range-editor.el-input__inner{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:3px 10px}.el-range-editor .el-range-input{line-height:1}.el-range-editor.is-active,.el-range-editor.is-active:hover{border-color:#409EFF}.el-range-editor--medium.el-input__inner{height:36px}.el-range-editor--medium .el-range-separator{line-height:28px;font-size:14px}.el-range-editor--medium .el-range-input{font-size:14px}.el-range-editor--medium .el-range__close-icon,.el-range-editor--medium .el-range__icon{line-height:28px}.el-range-editor--small.el-input__inner{height:32px}.el-range-editor--small .el-range-separator{line-height:24px;font-size:13px}.el-range-editor--small .el-range-input{font-size:13px}.el-range-editor--small .el-range__close-icon,.el-range-editor--small .el-range__icon{line-height:24px}.el-range-editor--mini.el-input__inner{height:28px}.el-range-editor--mini .el-range-separator{line-height:20px;font-size:12px}.el-range-editor--mini .el-range-input{font-size:12px}.el-range-editor--mini .el-range__close-icon,.el-range-editor--mini .el-range__icon{line-height:20px}.el-range-editor.is-disabled{background-color:#F5F7FA;border-color:#E4E7ED;color:#C0C4CC;cursor:not-allowed}.el-range-editor.is-disabled:focus,.el-range-editor.is-disabled:hover{border-color:#E4E7ED}.el-range-editor.is-disabled input{background-color:#F5F7FA;color:#C0C4CC;cursor:not-allowed}.el-range-editor.is-disabled input::-webkit-input-placeholder{color:#C0C4CC}.el-range-editor.is-disabled input:-ms-input-placeholder{color:#C0C4CC}.el-range-editor.is-disabled input::-ms-input-placeholder{color:#C0C4CC}.el-range-editor.is-disabled input::placeholder{color:#C0C4CC}.el-range-editor.is-disabled .el-range-separator{color:#C0C4CC}.el-picker-panel{color:#606266;border:1px solid #E4E7ED;box-shadow:0 2px 12px 0 rgba(0,0,0,.1);background:#FFF;border-radius:4px;line-height:30px;margin:5px 0}.el-popover,.el-time-panel{-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1)}.el-picker-panel__body-wrapper::after,.el-picker-panel__body::after{content:"";display:table;clear:both}.el-picker-panel__content{position:relative;margin:15px}.el-picker-panel__footer{border-top:1px solid #e4e4e4;padding:4px;text-align:right;background-color:#FFF;position:relative;font-size:0}.el-picker-panel__shortcut{display:block;width:100%;border:0;background-color:transparent;line-height:28px;font-size:14px;color:#606266;padding-left:12px;text-align:left;outline:0;cursor:pointer}.el-picker-panel__shortcut:hover{color:#409EFF}.el-picker-panel__shortcut.active{background-color:#e6f1fe;color:#409EFF}.el-picker-panel__btn{border:1px solid #dcdcdc;color:#333;line-height:24px;border-radius:2px;padding:0 20px;cursor:pointer;background-color:transparent;outline:0;font-size:12px}.el-picker-panel__btn[disabled]{color:#ccc;cursor:not-allowed}.el-picker-panel__icon-btn{font-size:12px;color:#303133;border:0;background:0 0;cursor:pointer;outline:0;margin-top:8px}.el-picker-panel__icon-btn:hover{color:#409EFF}.el-picker-panel__icon-btn.is-disabled{color:#bbb}.el-picker-panel__icon-btn.is-disabled:hover{cursor:not-allowed}.el-picker-panel__link-btn{vertical-align:middle}.el-picker-panel [slot=sidebar],.el-picker-panel__sidebar{position:absolute;top:0;bottom:0;width:110px;border-right:1px solid #e4e4e4;-webkit-box-sizing:border-box;box-sizing:border-box;padding-top:6px;background-color:#FFF;overflow:auto}.el-picker-panel [slot=sidebar]+.el-picker-panel__body,.el-picker-panel__sidebar+.el-picker-panel__body{margin-left:110px}.el-time-spinner.has-seconds .el-time-spinner__wrapper{width:33.3%}.el-time-spinner__wrapper{max-height:190px;overflow:auto;display:inline-block;width:50%;vertical-align:top;position:relative}.el-time-spinner__wrapper .el-scrollbar__wrap:not(.el-scrollbar__wrap--hidden-default){padding-bottom:15px}.el-time-spinner__input.el-input .el-input__inner,.el-time-spinner__list{padding:0;text-align:center}.el-time-spinner__wrapper.is-arrow{-webkit-box-sizing:border-box;box-sizing:border-box;text-align:center;overflow:hidden}.el-time-spinner__wrapper.is-arrow .el-time-spinner__list{-webkit-transform:translateY(-32px);transform:translateY(-32px)}.el-time-spinner__wrapper.is-arrow .el-time-spinner__item:hover:not(.disabled):not(.active){background:#FFF;cursor:default}.el-time-spinner__arrow{font-size:12px;color:#909399;position:absolute;left:0;width:100%;z-index:1;text-align:center;height:30px;line-height:30px;cursor:pointer}.el-time-spinner__arrow:hover{color:#409EFF}.el-time-spinner__arrow.el-icon-arrow-up{top:10px}.el-time-spinner__arrow.el-icon-arrow-down{bottom:10px}.el-time-spinner__input.el-input{width:70%}.el-time-spinner__list{margin:0;list-style:none}.el-time-spinner__list::after,.el-time-spinner__list::before{content:'';display:block;width:100%;height:80px}.el-time-spinner__item{height:32px;line-height:32px;font-size:12px;color:#606266}.el-time-spinner__item:hover:not(.disabled):not(.active){background:#F5F7FA;cursor:pointer}.el-time-spinner__item.active:not(.disabled){color:#303133;font-weight:700}.el-time-spinner__item.disabled{color:#C0C4CC;cursor:not-allowed}.el-time-panel{margin:5px 0;border:1px solid #E4E7ED;background-color:#FFF;box-shadow:0 2px 12px 0 rgba(0,0,0,.1);border-radius:2px;position:absolute;width:180px;left:0;z-index:1000;-ms-user-select:none;user-select:none;-webkit-box-sizing:content-box;box-sizing:content-box}.el-slider__button,.el-slider__button-wrapper{-webkit-user-select:none;-moz-user-select:none}.el-time-panel__content{font-size:0;position:relative;overflow:hidden}.el-time-panel__content::after,.el-time-panel__content::before{content:"";top:50%;position:absolute;margin-top:-15px;height:32px;z-index:-1;left:0;right:0;-webkit-box-sizing:border-box;box-sizing:border-box;padding-top:6px;text-align:left;border-top:1px solid #E4E7ED;border-bottom:1px solid #E4E7ED}.el-time-panel__content::after{left:50%;margin-left:12%;margin-right:12%}.el-time-panel__content::before{padding-left:50%;margin-right:12%;margin-left:12%}.el-time-panel__content.has-seconds::after{left:calc(100% / 3 * 2)}.el-time-panel__content.has-seconds::before{padding-left:calc(100% / 3)}.el-time-panel__footer{border-top:1px solid #e4e4e4;padding:4px;height:36px;line-height:25px;text-align:right;-webkit-box-sizing:border-box;box-sizing:border-box}.el-time-panel__btn{border:none;line-height:28px;padding:0 5px;margin:0 5px;cursor:pointer;background-color:transparent;outline:0;font-size:12px;color:#303133}.el-time-panel__btn.confirm{font-weight:800;color:#409EFF}.el-time-range-picker{width:354px;overflow:visible}.el-time-range-picker__content{position:relative;text-align:center;padding:10px}.el-time-range-picker__cell{-webkit-box-sizing:border-box;box-sizing:border-box;margin:0;padding:4px 7px 7px;width:50%;display:inline-block}.el-time-range-picker__header{margin-bottom:5px;text-align:center;font-size:14px}.el-time-range-picker__body{border-radius:2px;border:1px solid #E4E7ED}.el-popover{position:absolute;background:#FFF;min-width:150px;border:1px solid #EBEEF5;padding:12px;z-index:2000;color:#606266;line-height:1.4;text-align:justify;font-size:14px;box-shadow:0 2px 12px 0 rgba(0,0,0,.1);word-break:break-all}.el-popover--plain{padding:18px 20px}.el-popover__title{color:#303133;font-size:16px;line-height:1;margin-bottom:12px}.v-modal-enter{-webkit-animation:v-modal-in .2s ease;animation:v-modal-in .2s ease}.v-modal-leave{-webkit-animation:v-modal-out .2s ease forwards;animation:v-modal-out .2s ease forwards}@keyframes v-modal-in{0%{opacity:0}}@keyframes v-modal-out{100%{opacity:0}}.v-modal{position:fixed;left:0;top:0;width:100%;height:100%;opacity:.5;background:#000}.el-popup-parent--hidden{overflow:hidden}.el-message-box{display:inline-block;width:420px;padding-bottom:10px;vertical-align:middle;background-color:#FFF;border-radius:4px;border:1px solid #EBEEF5;font-size:18px;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);box-shadow:0 2px 12px 0 rgba(0,0,0,.1);text-align:left;overflow:hidden;-webkit-backface-visibility:hidden;backface-visibility:hidden}.el-message-box__wrapper{position:fixed;top:0;bottom:0;left:0;right:0;text-align:center}.el-message-box__wrapper::after{content:"";display:inline-block;height:100%;width:0;vertical-align:middle}.el-message-box__header{position:relative;padding:15px 15px 10px}.el-message-box__title{padding-left:0;margin-bottom:0;font-size:18px;line-height:1;color:#303133}.el-message-box__headerbtn{position:absolute;top:15px;right:15px;padding:0;border:none;outline:0;background:0 0;font-size:16px;cursor:pointer}.el-form-item.is-error .el-input__inner,.el-form-item.is-error .el-input__inner:focus,.el-form-item.is-error .el-textarea__inner,.el-form-item.is-error .el-textarea__inner:focus,.el-message-box__input input.invalid,.el-message-box__input input.invalid:focus{border-color:#F56C6C}.el-message-box__headerbtn .el-message-box__close{color:#909399}.el-message-box__headerbtn:focus .el-message-box__close,.el-message-box__headerbtn:hover .el-message-box__close{color:#409EFF}.el-message-box__content{position:relative;padding:10px 15px;color:#606266;font-size:14px}.el-message-box__input{padding-top:15px}.el-message-box__status{position:absolute;top:50%;-webkit-transform:translateY(-50%);transform:translateY(-50%);font-size:24px!important}.el-message-box__status::before{padding-left:1px}.el-message-box__status+.el-message-box__message{padding-left:36px;padding-right:12px}.el-message-box__status.el-icon-success{color:#67C23A}.el-message-box__status.el-icon-info{color:#909399}.el-message-box__status.el-icon-warning{color:#E6A23C}.el-message-box__status.el-icon-error{color:#F56C6C}.el-message-box__message{margin:0}.el-message-box__message p{margin:0;line-height:24px}.el-message-box__errormsg{color:#F56C6C;font-size:12px;min-height:18px;margin-top:2px}.el-message-box__btns{padding:5px 15px 0;text-align:right}.el-message-box__btns button:nth-child(2){margin-left:10px}.el-message-box__btns-reverse{-webkit-box-orient:horizontal;-webkit-box-direction:reverse;-ms-flex-direction:row-reverse;flex-direction:row-reverse}.el-container,.el-container.is-vertical,.el-link,.el-steps--vertical{-webkit-box-direction:normal}.el-message-box--center{padding-bottom:30px}.el-message-box--center .el-message-box__header{padding-top:30px}.el-message-box--center .el-message-box__title{position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.el-message-box--center .el-message-box__status{position:relative;top:auto;padding-right:5px;text-align:center;-webkit-transform:translateY(-1px);transform:translateY(-1px)}.el-message-box--center .el-message-box__message{margin-left:0}.el-message-box--center .el-message-box__btns,.el-message-box--center .el-message-box__content{text-align:center}.el-message-box--center .el-message-box__content{padding-left:27px;padding-right:27px}.msgbox-fade-enter-active{-webkit-animation:msgbox-fade-in .3s;animation:msgbox-fade-in .3s}.msgbox-fade-leave-active{-webkit-animation:msgbox-fade-out .3s;animation:msgbox-fade-out .3s}@-webkit-keyframes msgbox-fade-in{0%{-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0);opacity:0}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);opacity:1}}@keyframes msgbox-fade-in{0%{-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0);opacity:0}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);opacity:1}}@-webkit-keyframes msgbox-fade-out{0%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);opacity:1}100%{-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0);opacity:0}}@keyframes msgbox-fade-out{0%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);opacity:1}100%{-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0);opacity:0}}.el-breadcrumb{font-size:14px;line-height:1}.el-breadcrumb::after,.el-breadcrumb::before{display:table;content:""}.el-breadcrumb::after{clear:both}.el-breadcrumb__separator{margin:0 9px;font-weight:700;color:#C0C4CC}.el-breadcrumb__separator[class*=icon]{margin:0 6px;font-weight:400}.el-breadcrumb__item{float:left}.el-breadcrumb__inner{color:#606266}.el-breadcrumb__inner a,.el-breadcrumb__inner.is-link{font-weight:700;text-decoration:none;-webkit-transition:color .2s cubic-bezier(.645,.045,.355,1);transition:color .2s cubic-bezier(.645,.045,.355,1);color:#303133}.el-breadcrumb__inner a:hover,.el-breadcrumb__inner.is-link:hover{color:#409EFF;cursor:pointer}.el-breadcrumb__item:last-child .el-breadcrumb__inner,.el-breadcrumb__item:last-child .el-breadcrumb__inner a,.el-breadcrumb__item:last-child .el-breadcrumb__inner a:hover,.el-breadcrumb__item:last-child .el-breadcrumb__inner:hover{font-weight:400;color:#606266;cursor:text}.el-breadcrumb__item:last-child .el-breadcrumb__separator{display:none}.el-form--label-left .el-form-item__label{text-align:left}.el-form--label-top .el-form-item__label{float:none;display:inline-block;text-align:left;padding:0 0 10px}.el-form--inline .el-form-item{display:inline-block;margin-right:10px;vertical-align:top}.el-form--inline .el-form-item__label{float:none;display:inline-block}.el-form--inline .el-form-item__content{display:inline-block;vertical-align:top}.el-form-item__content .el-input-group,.el-form-item__label,.el-tag .el-icon-close{vertical-align:middle}.el-form--inline.el-form--label-top .el-form-item__content{display:block}.el-form-item{margin-bottom:22px}.el-form-item::after,.el-form-item::before{display:table;content:""}.el-form-item::after{clear:both}.el-form-item .el-form-item{margin-bottom:0}.el-form-item--mini.el-form-item,.el-form-item--small.el-form-item{margin-bottom:18px}.el-form-item .el-input__validateIcon{display:none}.el-form-item--medium .el-form-item__content,.el-form-item--medium .el-form-item__label{line-height:36px}.el-form-item--small .el-form-item__content,.el-form-item--small .el-form-item__label{line-height:32px}.el-form-item--small .el-form-item__error{padding-top:2px}.el-form-item--mini .el-form-item__content,.el-form-item--mini .el-form-item__label{line-height:28px}.el-form-item--mini .el-form-item__error{padding-top:1px}.el-form-item__label-wrap{float:left}.el-form-item__label-wrap .el-form-item__label{display:inline-block;float:none}.el-form-item__label{text-align:right;float:left;font-size:14px;color:#606266;line-height:40px;padding:0 12px 0 0;-webkit-box-sizing:border-box;box-sizing:border-box}.el-form-item__content{line-height:40px;position:relative;font-size:14px}.el-form-item__content::after,.el-form-item__content::before{display:table;content:""}.el-form-item__content::after{clear:both}.el-form-item__error{color:#F56C6C;font-size:12px;line-height:1;padding-top:4px;position:absolute;top:100%;left:0}.el-form-item__error--inline{position:relative;top:auto;left:auto;display:inline-block;margin-left:10px}.el-form-item.is-required:not(.is-no-asterisk) .el-form-item__label-wrap>.el-form-item__label:before,.el-form-item.is-required:not(.is-no-asterisk)>.el-form-item__label:before{content:'*';color:#F56C6C;margin-right:4px}.el-form-item.is-error .el-input-group__append .el-input__inner,.el-form-item.is-error .el-input-group__prepend .el-input__inner{border-color:transparent}.el-form-item.is-error .el-input__validateIcon{color:#F56C6C}.el-form-item.is-success .el-input__inner,.el-form-item.is-success .el-input__inner:focus,.el-form-item.is-success .el-textarea__inner,.el-form-item.is-success .el-textarea__inner:focus{border-color:#67C23A}.el-form-item.is-success .el-input-group__append .el-input__inner,.el-form-item.is-success .el-input-group__prepend .el-input__inner{border-color:transparent}.el-form-item.is-success .el-input__validateIcon{color:#67C23A}.el-form-item--feedback .el-input__validateIcon{display:inline-block}.el-tabs__header{padding:0;position:relative;margin:0 0 15px}.el-tabs__active-bar{position:absolute;bottom:0;left:0;height:2px;background-color:#409EFF;z-index:1;-webkit-transition:-webkit-transform .3s cubic-bezier(.645,.045,.355,1);transition:-webkit-transform .3s cubic-bezier(.645,.045,.355,1);transition:transform .3s cubic-bezier(.645,.045,.355,1);transition:transform .3s cubic-bezier(.645,.045,.355,1),-webkit-transform .3s cubic-bezier(.645,.045,.355,1);list-style:none}.el-tabs__new-tab{float:right;border:1px solid #d3dce6;height:18px;width:18px;line-height:18px;margin:12px 0 9px 10px;border-radius:3px;text-align:center;font-size:12px;color:#d3dce6;cursor:pointer;-webkit-transition:all .15s;transition:all .15s}.el-tabs__new-tab .el-icon-plus{-webkit-transform:scale(.8,.8);transform:scale(.8,.8)}.el-tabs__new-tab:hover{color:#409EFF}.el-tabs__nav-wrap{overflow:hidden;margin-bottom:-1px;position:relative}.el-tabs__nav-wrap::after{content:"";position:absolute;left:0;bottom:0;width:100%;height:2px;background-color:#E4E7ED;z-index:1}.el-tabs--border-card>.el-tabs__header .el-tabs__nav-wrap::after,.el-tabs--card>.el-tabs__header .el-tabs__nav-wrap::after{content:none}.el-tabs__nav-wrap.is-scrollable{padding:0 20px;-webkit-box-sizing:border-box;box-sizing:border-box}.el-tabs__nav-scroll{overflow:hidden}.el-tabs__nav-next,.el-tabs__nav-prev{position:absolute;cursor:pointer;line-height:44px;font-size:12px;color:#909399}.el-tabs__nav-next{right:0}.el-tabs__nav-prev{left:0}.el-tabs__nav{white-space:nowrap;position:relative;-webkit-transition:-webkit-transform .3s;transition:-webkit-transform .3s;transition:transform .3s;transition:transform .3s,-webkit-transform .3s;float:left;z-index:2}.el-tabs__nav.is-stretch{min-width:100%;display:-webkit-box;display:-ms-flexbox;display:flex}.el-tabs__nav.is-stretch>*{-webkit-box-flex:1;-ms-flex:1;flex:1;text-align:center}.el-tabs__item{padding:0 20px;height:40px;-webkit-box-sizing:border-box;box-sizing:border-box;line-height:40px;display:inline-block;list-style:none;font-size:14px;font-weight:500;color:#303133;position:relative}.el-tabs__item:focus,.el-tabs__item:focus:active{outline:0}.el-tabs__item:focus.is-active.is-focus:not(:active){-webkit-box-shadow:0 0 2px 2px #409EFF inset;box-shadow:0 0 2px 2px #409EFF inset;border-radius:3px}.el-tabs__item .el-icon-close{border-radius:50%;text-align:center;-webkit-transition:all .3s cubic-bezier(.645,.045,.355,1);transition:all .3s cubic-bezier(.645,.045,.355,1);margin-left:5px}.el-tabs__item .el-icon-close:before{-webkit-transform:scale(.9);transform:scale(.9);display:inline-block}.el-tabs__item .el-icon-close:hover{background-color:#C0C4CC;color:#FFF}.el-tabs__item.is-active{color:#409EFF}.el-tabs__item:hover{color:#409EFF;cursor:pointer}.el-tabs__item.is-disabled{color:#C0C4CC;cursor:default}.el-tabs__content{overflow:hidden;position:relative}.el-tabs--card>.el-tabs__header{border-bottom:1px solid #E4E7ED}.el-tabs--card>.el-tabs__header .el-tabs__nav{border:1px solid #E4E7ED;border-bottom:none;border-radius:4px 4px 0 0;-webkit-box-sizing:border-box;box-sizing:border-box}.el-alert,.el-tag{-webkit-box-sizing:border-box}.el-tabs--card>.el-tabs__header .el-tabs__active-bar{display:none}.el-tabs--card>.el-tabs__header .el-tabs__item .el-icon-close{position:relative;font-size:12px;width:0;height:14px;vertical-align:middle;line-height:15px;overflow:hidden;top:-1px;right:-2px;-webkit-transform-origin:100% 50%;transform-origin:100% 50%}.el-tabs--card>.el-tabs__header .el-tabs__item.is-active.is-closable .el-icon-close,.el-tabs--card>.el-tabs__header .el-tabs__item.is-closable:hover .el-icon-close{width:14px}.el-tabs--card>.el-tabs__header .el-tabs__item{border-bottom:1px solid transparent;border-left:1px solid #E4E7ED;-webkit-transition:color .3s cubic-bezier(.645,.045,.355,1),padding .3s cubic-bezier(.645,.045,.355,1);transition:color .3s cubic-bezier(.645,.045,.355,1),padding .3s cubic-bezier(.645,.045,.355,1)}.el-tabs--card>.el-tabs__header .el-tabs__item:first-child{border-left:none}.el-tabs--card>.el-tabs__header .el-tabs__item.is-closable:hover{padding-left:13px;padding-right:13px}.el-tabs--card>.el-tabs__header .el-tabs__item.is-active{border-bottom-color:#FFF}.el-tabs--card>.el-tabs__header .el-tabs__item.is-active.is-closable{padding-left:20px;padding-right:20px}.el-tabs--border-card{background:#FFF;border:1px solid #DCDFE6;-webkit-box-shadow:0 2px 4px 0 rgba(0,0,0,.12),0 0 6px 0 rgba(0,0,0,.04);box-shadow:0 2px 4px 0 rgba(0,0,0,.12),0 0 6px 0 rgba(0,0,0,.04)}.el-tabs--border-card>.el-tabs__content{padding:15px}.el-tabs--border-card>.el-tabs__header{background-color:#F5F7FA;border-bottom:1px solid #E4E7ED;margin:0}.el-tabs--border-card>.el-tabs__header .el-tabs__item{-webkit-transition:all .3s cubic-bezier(.645,.045,.355,1);transition:all .3s cubic-bezier(.645,.045,.355,1);border:1px solid transparent;margin-top:-1px;color:#909399}.el-tabs--border-card>.el-tabs__header .el-tabs__item+.el-tabs__item,.el-tabs--border-card>.el-tabs__header .el-tabs__item:first-child{margin-left:-1px}.el-tabs--border-card>.el-tabs__header .el-tabs__item.is-active{color:#409EFF;background-color:#FFF;border-right-color:#DCDFE6;border-left-color:#DCDFE6}.el-tabs--border-card>.el-tabs__header .el-tabs__item:not(.is-disabled):hover{color:#409EFF}.el-tabs--border-card>.el-tabs__header .el-tabs__item.is-disabled{color:#C0C4CC}.el-tabs--border-card>.el-tabs__header .is-scrollable .el-tabs__item:first-child{margin-left:0}.el-tabs--bottom .el-tabs__item.is-bottom:nth-child(2),.el-tabs--bottom .el-tabs__item.is-top:nth-child(2),.el-tabs--top .el-tabs__item.is-bottom:nth-child(2),.el-tabs--top .el-tabs__item.is-top:nth-child(2){padding-left:0}.el-tabs--bottom .el-tabs__item.is-bottom:last-child,.el-tabs--bottom .el-tabs__item.is-top:last-child,.el-tabs--top .el-tabs__item.is-bottom:last-child,.el-tabs--top .el-tabs__item.is-top:last-child{padding-right:0}.el-tabs--bottom .el-tabs--left .el-tabs__item:nth-child(2),.el-tabs--bottom .el-tabs--right .el-tabs__item:nth-child(2),.el-tabs--bottom.el-tabs--border-card .el-tabs__item:nth-child(2),.el-tabs--bottom.el-tabs--card .el-tabs__item:nth-child(2),.el-tabs--top .el-tabs--left .el-tabs__item:nth-child(2),.el-tabs--top .el-tabs--right .el-tabs__item:nth-child(2),.el-tabs--top.el-tabs--border-card .el-tabs__item:nth-child(2),.el-tabs--top.el-tabs--card .el-tabs__item:nth-child(2){padding-left:20px}.el-tabs--bottom .el-tabs--left .el-tabs__item:last-child,.el-tabs--bottom .el-tabs--right .el-tabs__item:last-child,.el-tabs--bottom.el-tabs--border-card .el-tabs__item:last-child,.el-tabs--bottom.el-tabs--card .el-tabs__item:last-child,.el-tabs--top .el-tabs--left .el-tabs__item:last-child,.el-tabs--top .el-tabs--right .el-tabs__item:last-child,.el-tabs--top.el-tabs--border-card .el-tabs__item:last-child,.el-tabs--top.el-tabs--card .el-tabs__item:last-child{padding-right:20px}.el-tabs--bottom .el-tabs__header.is-bottom{margin-bottom:0;margin-top:10px}.el-tabs--bottom.el-tabs--border-card .el-tabs__header.is-bottom{border-bottom:0;border-top:1px solid #DCDFE6}.el-tabs--bottom.el-tabs--border-card .el-tabs__nav-wrap.is-bottom{margin-top:-1px;margin-bottom:0}.el-tabs--bottom.el-tabs--border-card .el-tabs__item.is-bottom:not(.is-active){border:1px solid transparent}.el-tabs--bottom.el-tabs--border-card .el-tabs__item.is-bottom{margin:0 -1px -1px}.el-tabs--left,.el-tabs--right{overflow:hidden}.el-tabs--left .el-tabs__header.is-left,.el-tabs--left .el-tabs__header.is-right,.el-tabs--left .el-tabs__nav-scroll,.el-tabs--left .el-tabs__nav-wrap.is-left,.el-tabs--left .el-tabs__nav-wrap.is-right,.el-tabs--right .el-tabs__header.is-left,.el-tabs--right .el-tabs__header.is-right,.el-tabs--right .el-tabs__nav-scroll,.el-tabs--right .el-tabs__nav-wrap.is-left,.el-tabs--right .el-tabs__nav-wrap.is-right{height:100%}.el-tabs--left .el-tabs__active-bar.is-left,.el-tabs--left .el-tabs__active-bar.is-right,.el-tabs--right .el-tabs__active-bar.is-left,.el-tabs--right .el-tabs__active-bar.is-right{top:0;bottom:auto;width:2px;height:auto}.el-tabs--left .el-tabs__nav-wrap.is-left,.el-tabs--left .el-tabs__nav-wrap.is-right,.el-tabs--right .el-tabs__nav-wrap.is-left,.el-tabs--right .el-tabs__nav-wrap.is-right{margin-bottom:0}.el-tabs--left .el-tabs__nav-wrap.is-left>.el-tabs__nav-next,.el-tabs--left .el-tabs__nav-wrap.is-left>.el-tabs__nav-prev,.el-tabs--left .el-tabs__nav-wrap.is-right>.el-tabs__nav-next,.el-tabs--left .el-tabs__nav-wrap.is-right>.el-tabs__nav-prev,.el-tabs--right .el-tabs__nav-wrap.is-left>.el-tabs__nav-next,.el-tabs--right .el-tabs__nav-wrap.is-left>.el-tabs__nav-prev,.el-tabs--right .el-tabs__nav-wrap.is-right>.el-tabs__nav-next,.el-tabs--right .el-tabs__nav-wrap.is-right>.el-tabs__nav-prev{height:30px;line-height:30px;width:100%;text-align:center;cursor:pointer}.el-tabs--left .el-tabs__nav-wrap.is-left>.el-tabs__nav-next i,.el-tabs--left .el-tabs__nav-wrap.is-left>.el-tabs__nav-prev i,.el-tabs--left .el-tabs__nav-wrap.is-right>.el-tabs__nav-next i,.el-tabs--left .el-tabs__nav-wrap.is-right>.el-tabs__nav-prev i,.el-tabs--right .el-tabs__nav-wrap.is-left>.el-tabs__nav-next i,.el-tabs--right .el-tabs__nav-wrap.is-left>.el-tabs__nav-prev i,.el-tabs--right .el-tabs__nav-wrap.is-right>.el-tabs__nav-next i,.el-tabs--right .el-tabs__nav-wrap.is-right>.el-tabs__nav-prev i{-webkit-transform:rotateZ(90deg);transform:rotateZ(90deg)}.el-tabs--left .el-tabs__nav-wrap.is-left>.el-tabs__nav-prev,.el-tabs--left .el-tabs__nav-wrap.is-right>.el-tabs__nav-prev,.el-tabs--right .el-tabs__nav-wrap.is-left>.el-tabs__nav-prev,.el-tabs--right .el-tabs__nav-wrap.is-right>.el-tabs__nav-prev{left:auto;top:0}.el-tabs--left .el-tabs__nav-wrap.is-left>.el-tabs__nav-next,.el-tabs--left .el-tabs__nav-wrap.is-right>.el-tabs__nav-next,.el-tabs--right .el-tabs__nav-wrap.is-left>.el-tabs__nav-next,.el-tabs--right .el-tabs__nav-wrap.is-right>.el-tabs__nav-next{right:auto;bottom:0}.el-tabs--left .el-tabs__active-bar.is-left,.el-tabs--left .el-tabs__nav-wrap.is-left::after{right:0;left:auto}.el-tabs--left .el-tabs__nav-wrap.is-left.is-scrollable,.el-tabs--left .el-tabs__nav-wrap.is-right.is-scrollable,.el-tabs--right .el-tabs__nav-wrap.is-left.is-scrollable,.el-tabs--right .el-tabs__nav-wrap.is-right.is-scrollable{padding:30px 0}.el-tabs--left .el-tabs__nav-wrap.is-left::after,.el-tabs--left .el-tabs__nav-wrap.is-right::after,.el-tabs--right .el-tabs__nav-wrap.is-left::after,.el-tabs--right .el-tabs__nav-wrap.is-right::after{height:100%;width:2px;bottom:auto;top:0}.el-tabs--left .el-tabs__nav.is-left,.el-tabs--left .el-tabs__nav.is-right,.el-tabs--right .el-tabs__nav.is-left,.el-tabs--right .el-tabs__nav.is-right{float:none}.el-tabs--left .el-tabs__item.is-left,.el-tabs--left .el-tabs__item.is-right,.el-tabs--right .el-tabs__item.is-left,.el-tabs--right .el-tabs__item.is-right{display:block}.el-tabs--left.el-tabs--card .el-tabs__active-bar.is-left,.el-tabs--right.el-tabs--card .el-tabs__active-bar.is-right{display:none}.el-tabs--left .el-tabs__header.is-left{float:left;margin-bottom:0;margin-right:10px}.el-tabs--left .el-tabs__nav-wrap.is-left{margin-right:-1px}.el-tabs--left .el-tabs__item.is-left{text-align:right}.el-tabs--left.el-tabs--card .el-tabs__item.is-left{border-left:none;border-right:1px solid #E4E7ED;border-bottom:none;border-top:1px solid #E4E7ED}.el-tabs--left.el-tabs--card .el-tabs__item.is-left:first-child{border-right:1px solid #E4E7ED;border-top:none}.el-tabs--left.el-tabs--card .el-tabs__item.is-left.is-active{border:1px solid #E4E7ED;border-right-color:#fff;border-left:none;border-bottom:none}.el-tabs--left.el-tabs--card .el-tabs__item.is-left.is-active:first-child{border-top:none}.el-tabs--left.el-tabs--card .el-tabs__item.is-left.is-active:last-child{border-bottom:none}.el-tabs--left.el-tabs--card .el-tabs__nav{border-radius:4px 0 0 4px;border-bottom:1px solid #E4E7ED;border-right:none}.el-tabs--left.el-tabs--card .el-tabs__new-tab{float:none}.el-tabs--left.el-tabs--border-card .el-tabs__header.is-left{border-right:1px solid #dfe4ed}.el-tabs--left.el-tabs--border-card .el-tabs__item.is-left{border:1px solid transparent;margin:-1px 0 -1px -1px}.el-tabs--left.el-tabs--border-card .el-tabs__item.is-left.is-active{border-color:#d1dbe5 transparent}.el-tabs--right .el-tabs__header.is-right{float:right;margin-bottom:0;margin-left:10px}.el-tabs--right .el-tabs__nav-wrap.is-right{margin-left:-1px}.el-tabs--right .el-tabs__nav-wrap.is-right::after{left:0;right:auto}.el-tabs--right .el-tabs__active-bar.is-right{left:0}.el-tag,.slideInLeft-transition,.slideInRight-transition{display:inline-block}.el-tabs--right.el-tabs--card .el-tabs__item.is-right{border-bottom:none;border-top:1px solid #E4E7ED}.el-tabs--right.el-tabs--card .el-tabs__item.is-right:first-child{border-left:1px solid #E4E7ED;border-top:none}.el-tabs--right.el-tabs--card .el-tabs__item.is-right.is-active{border:1px solid #E4E7ED;border-left-color:#fff;border-right:none;border-bottom:none}.el-tabs--right.el-tabs--card .el-tabs__item.is-right.is-active:first-child{border-top:none}.el-tabs--right.el-tabs--card .el-tabs__item.is-right.is-active:last-child{border-bottom:none}.el-tabs--right.el-tabs--card .el-tabs__nav{border-radius:0 4px 4px 0;border-bottom:1px solid #E4E7ED;border-left:none}.el-tabs--right.el-tabs--border-card .el-tabs__header.is-right{border-left:1px solid #dfe4ed}.el-tabs--right.el-tabs--border-card .el-tabs__item.is-right{border:1px solid transparent;margin:-1px -1px -1px 0}.el-tabs--right.el-tabs--border-card .el-tabs__item.is-right.is-active{border-color:#d1dbe5 transparent}.slideInRight-enter{-webkit-animation:slideInRight-enter .3s;animation:slideInRight-enter .3s}.slideInRight-leave{position:absolute;left:0;right:0;-webkit-animation:slideInRight-leave .3s;animation:slideInRight-leave .3s}.slideInLeft-enter{-webkit-animation:slideInLeft-enter .3s;animation:slideInLeft-enter .3s}.slideInLeft-leave{position:absolute;left:0;right:0;-webkit-animation:slideInLeft-leave .3s;animation:slideInLeft-leave .3s}@-webkit-keyframes slideInRight-enter{0%{opacity:0;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(100%);transform:translateX(100%)}to{opacity:1;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(0);transform:translateX(0)}}@keyframes slideInRight-enter{0%{opacity:0;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(100%);transform:translateX(100%)}to{opacity:1;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(0);transform:translateX(0)}}@-webkit-keyframes slideInRight-leave{0%{-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(0);transform:translateX(0);opacity:1}100%{-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(100%);transform:translateX(100%);opacity:0}}@keyframes slideInRight-leave{0%{-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(0);transform:translateX(0);opacity:1}100%{-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(100%);transform:translateX(100%);opacity:0}}@-webkit-keyframes slideInLeft-enter{0%{opacity:0;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(-100%);transform:translateX(-100%)}to{opacity:1;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(0);transform:translateX(0)}}@keyframes slideInLeft-enter{0%{opacity:0;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(-100%);transform:translateX(-100%)}to{opacity:1;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(0);transform:translateX(0)}}@-webkit-keyframes slideInLeft-leave{0%{-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(0);transform:translateX(0);opacity:1}100%{-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(-100%);transform:translateX(-100%);opacity:0}}@keyframes slideInLeft-leave{0%{-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(0);transform:translateX(0);opacity:1}100%{-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(-100%);transform:translateX(-100%);opacity:0}}.el-tag{background-color:rgba(64,158,255,.1);padding:0 10px;height:32px;line-height:30px;font-size:12px;color:#409EFF;border-radius:4px;box-sizing:border-box;border:1px solid rgba(64,158,255,.2);white-space:nowrap}.el-tag .el-icon-close{border-radius:50%;text-align:center;position:relative;cursor:pointer;font-size:12px;height:16px;width:16px;line-height:16px;top:-1px;right:-5px;color:#409EFF}.el-tag .el-icon-close::before{display:block}.el-tag .el-icon-close:hover{background-color:#409EFF;color:#FFF}.el-tag--info,.el-tag--info .el-tag__close{color:#909399}.el-tag--info{background-color:rgba(144,147,153,.1);border-color:rgba(144,147,153,.2)}.el-tag--info.is-hit{border-color:#909399}.el-tag--info .el-tag__close:hover{background-color:#909399;color:#FFF}.el-tag--success{background-color:rgba(103,194,58,.1);border-color:rgba(103,194,58,.2);color:#67C23A}.el-tag--success.is-hit{border-color:#67C23A}.el-tag--success .el-tag__close{color:#67C23A}.el-tag--success .el-tag__close:hover{background-color:#67C23A;color:#FFF}.el-tag--warning{background-color:rgba(230,162,60,.1);border-color:rgba(230,162,60,.2);color:#E6A23C}.el-tag--warning.is-hit{border-color:#E6A23C}.el-tag--warning .el-tag__close{color:#E6A23C}.el-tag--warning .el-tag__close:hover{background-color:#E6A23C;color:#FFF}.el-tag--danger{background-color:rgba(245,108,108,.1);border-color:rgba(245,108,108,.2);color:#F56C6C}.el-tag--danger.is-hit{border-color:#F56C6C}.el-tag--danger .el-tag__close{color:#F56C6C}.el-tag--danger .el-tag__close:hover{background-color:#F56C6C;color:#FFF}.el-tag--medium{height:28px;line-height:26px}.el-tag--medium .el-icon-close{-webkit-transform:scale(.8);transform:scale(.8)}.el-tag--small{height:24px;padding:0 8px;line-height:22px}.el-tag--small .el-icon-close{-webkit-transform:scale(.8);transform:scale(.8)}.el-tag--mini{height:20px;padding:0 5px;line-height:19px}.el-tag--mini .el-icon-close{margin-left:-3px;-webkit-transform:scale(.7);transform:scale(.7)}.el-tree{position:relative;cursor:default;background:#FFF;color:#606266}.el-tree__empty-block{position:relative;min-height:60px;text-align:center;width:100%;height:100%}.el-tree__empty-text{position:absolute;left:50%;top:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);color:#909399}.el-tree__drop-indicator{position:absolute;left:0;right:0;height:1px;background-color:#409EFF}.el-tree-node{white-space:nowrap;outline:0}.el-tree-node:focus>.el-tree-node__content{background-color:#F5F7FA}.el-tree-node.is-drop-inner>.el-tree-node__content .el-tree-node__label{background-color:#409EFF;color:#fff}.el-tree-node__content{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;height:26px;cursor:pointer}.el-tree-node__content>.el-tree-node__expand-icon{padding:6px}.el-tree-node__content>.el-checkbox{margin-right:8px}.el-tree-node__content:hover{background-color:#F5F7FA}.el-tree.is-dragging .el-tree-node__content{cursor:move}.el-tree.is-dragging.is-drop-not-allow .el-tree-node__content{cursor:not-allowed}.el-tree-node__expand-icon{cursor:pointer;color:#C0C4CC;font-size:12px;-webkit-transform:rotate(0);transform:rotate(0);-webkit-transition:-webkit-transform .3s ease-in-out;transition:-webkit-transform .3s ease-in-out;transition:transform .3s ease-in-out;transition:transform .3s ease-in-out,-webkit-transform .3s ease-in-out}.el-tree-node__expand-icon.expanded{-webkit-transform:rotate(90deg);transform:rotate(90deg)}.el-tree-node__expand-icon.is-leaf{color:transparent;cursor:default}.el-tree-node__label{font-size:14px}.el-tree-node__loading-icon{margin-right:8px;font-size:14px;color:#C0C4CC}.el-tree-node>.el-tree-node__children{overflow:hidden;background-color:transparent}.el-tree-node.is-expanded>.el-tree-node__children{display:block}.el-tree--highlight-current .el-tree-node.is-current>.el-tree-node__content{background-color:#f0f7ff}.el-alert{width:100%;padding:8px 16px;margin:0;box-sizing:border-box;border-radius:4px;position:relative;background-color:#FFF;overflow:hidden;opacity:1;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-transition:opacity .2s;transition:opacity .2s}.el-alert.is-light .el-alert__closebtn{color:#C0C4CC}.el-alert.is-dark .el-alert__closebtn,.el-alert.is-dark .el-alert__description{color:#FFF}.el-alert.is-center{-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.el-alert--success.is-light{background-color:#f0f9eb;color:#67C23A}.el-alert--success.is-light .el-alert__description{color:#67C23A}.el-alert--success.is-dark{background-color:#67C23A;color:#FFF}.el-alert--info.is-light{background-color:#f4f4f5;color:#909399}.el-alert--info.is-dark{background-color:#909399;color:#FFF}.el-alert--info .el-alert__description{color:#909399}.el-alert--warning.is-light{background-color:#fdf6ec;color:#E6A23C}.el-alert--warning.is-light .el-alert__description{color:#E6A23C}.el-alert--warning.is-dark{background-color:#E6A23C;color:#FFF}.el-alert--error.is-light{background-color:#fef0f0;color:#F56C6C}.el-alert--error.is-light .el-alert__description{color:#F56C6C}.el-alert--error.is-dark{background-color:#F56C6C;color:#FFF}.el-alert__content{display:table-cell;padding:0 8px}.el-alert__icon{font-size:16px;width:16px}.el-alert__icon.is-big{font-size:28px;width:28px}.el-alert__title{font-size:13px;line-height:18px}.el-alert__title.is-bold{font-weight:700}.el-alert .el-alert__description{font-size:12px;margin:5px 0 0}.el-alert__closebtn{font-size:12px;opacity:1;position:absolute;top:12px;right:15px;cursor:pointer}.el-alert-fade-enter,.el-alert-fade-leave-active,.el-loading-fade-enter,.el-loading-fade-leave-active,.el-notification-fade-leave-active{opacity:0}.el-alert__closebtn.is-customed{font-style:normal;font-size:13px;top:9px}.el-notification{display:-webkit-box;display:-ms-flexbox;display:flex;width:330px;padding:14px 26px 14px 13px;border-radius:8px;-webkit-box-sizing:border-box;box-sizing:border-box;border:1px solid #EBEEF5;position:fixed;background-color:#FFF;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);box-shadow:0 2px 12px 0 rgba(0,0,0,.1);-webkit-transition:opacity .3s,left .3s,right .3s,top .4s,bottom .3s,-webkit-transform .3s;transition:opacity .3s,left .3s,right .3s,top .4s,bottom .3s,-webkit-transform .3s;transition:opacity .3s,transform .3s,left .3s,right .3s,top .4s,bottom .3s;transition:opacity .3s,transform .3s,left .3s,right .3s,top .4s,bottom .3s,-webkit-transform .3s;overflow:hidden}.el-notification.right{right:16px}.el-notification.left{left:16px}.el-notification__group{margin-left:13px;margin-right:8px}.el-notification__title{font-weight:700;font-size:16px;color:#303133;margin:0}.el-notification__content{font-size:14px;line-height:21px;margin:6px 0 0;color:#606266;text-align:justify}.el-notification__content p{margin:0}.el-notification__icon{height:24px;width:24px;font-size:24px}.el-notification__closeBtn{position:absolute;top:18px;right:15px;cursor:pointer;color:#909399;font-size:16px}.el-notification__closeBtn:hover{color:#606266}.el-notification .el-icon-success{color:#67C23A}.el-notification .el-icon-error{color:#F56C6C}.el-notification .el-icon-info{color:#909399}.el-notification .el-icon-warning{color:#E6A23C}.el-notification-fade-enter.right{right:0;-webkit-transform:translateX(100%);transform:translateX(100%)}.el-notification-fade-enter.left{left:0;-webkit-transform:translateX(-100%);transform:translateX(-100%)}.el-input-number{position:relative;display:inline-block;width:180px;line-height:38px}.el-input-number .el-input{display:block}.el-input-number .el-input__inner{-webkit-appearance:none;padding-left:50px;padding-right:50px;text-align:center}.el-input-number__decrease,.el-input-number__increase{position:absolute;z-index:1;top:1px;width:40px;height:auto;text-align:center;background:#F5F7FA;color:#606266;cursor:pointer;font-size:13px}.el-input-number__decrease:hover,.el-input-number__increase:hover{color:#409EFF}.el-input-number__decrease:hover:not(.is-disabled)~.el-input .el-input__inner:not(.is-disabled),.el-input-number__increase:hover:not(.is-disabled)~.el-input .el-input__inner:not(.is-disabled){border-color:#409EFF}.el-input-number__decrease.is-disabled,.el-input-number__increase.is-disabled{color:#C0C4CC;cursor:not-allowed}.el-input-number__increase{right:1px;border-radius:0 4px 4px 0;border-left:1px solid #DCDFE6}.el-input-number__decrease{left:1px;border-radius:4px 0 0 4px;border-right:1px solid #DCDFE6}.el-input-number.is-disabled .el-input-number__decrease,.el-input-number.is-disabled .el-input-number__increase{border-color:#E4E7ED;color:#E4E7ED}.el-input-number.is-disabled .el-input-number__decrease:hover,.el-input-number.is-disabled .el-input-number__increase:hover{color:#E4E7ED;cursor:not-allowed}.el-input-number--medium{width:200px;line-height:34px}.el-input-number--medium .el-input-number__decrease,.el-input-number--medium .el-input-number__increase{width:36px;font-size:14px}.el-input-number--medium .el-input__inner{padding-left:43px;padding-right:43px}.el-input-number--small{width:130px;line-height:30px}.el-input-number--small .el-input-number__decrease,.el-input-number--small .el-input-number__increase{width:32px;font-size:13px}.el-input-number--small .el-input-number__decrease [class*=el-icon],.el-input-number--small .el-input-number__increase [class*=el-icon]{-webkit-transform:scale(.9);transform:scale(.9)}.el-input-number--small .el-input__inner{padding-left:39px;padding-right:39px}.el-input-number--mini{width:130px;line-height:26px}.el-input-number--mini .el-input-number__decrease,.el-input-number--mini .el-input-number__increase{width:28px;font-size:12px}.el-input-number--mini .el-input-number__decrease [class*=el-icon],.el-input-number--mini .el-input-number__increase [class*=el-icon]{-webkit-transform:scale(.8);transform:scale(.8)}.el-input-number--mini .el-input__inner{padding-left:35px;padding-right:35px}.el-input-number.is-without-controls .el-input__inner{padding-left:15px;padding-right:15px}.el-input-number.is-controls-right .el-input__inner{padding-left:15px;padding-right:50px}.el-input-number.is-controls-right .el-input-number__decrease,.el-input-number.is-controls-right .el-input-number__increase{height:auto;line-height:19px}.el-input-number.is-controls-right .el-input-number__decrease [class*=el-icon],.el-input-number.is-controls-right .el-input-number__increase [class*=el-icon]{-webkit-transform:scale(.8);transform:scale(.8)}.el-input-number.is-controls-right .el-input-number__increase{border-radius:0 4px 0 0;border-bottom:1px solid #DCDFE6}.el-input-number.is-controls-right .el-input-number__decrease{right:1px;bottom:1px;top:auto;left:auto;border-right:none;border-left:1px solid #DCDFE6;border-radius:0 0 4px}.el-input-number.is-controls-right[class*=medium] [class*=decrease],.el-input-number.is-controls-right[class*=medium] [class*=increase]{line-height:17px}.el-input-number.is-controls-right[class*=small] [class*=decrease],.el-input-number.is-controls-right[class*=small] [class*=increase]{line-height:15px}.el-input-number.is-controls-right[class*=mini] [class*=decrease],.el-input-number.is-controls-right[class*=mini] [class*=increase]{line-height:13px}.el-tooltip__popper{position:absolute;border-radius:4px;padding:10px;z-index:2000;font-size:12px;line-height:1.2;min-width:10px;word-wrap:break-word}.el-tooltip__popper .popper__arrow,.el-tooltip__popper .popper__arrow::after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.el-tooltip__popper .popper__arrow{border-width:6px}.el-tooltip__popper .popper__arrow::after{content:" ";border-width:5px}.el-progress-bar__inner::after,.el-row::after,.el-row::before,.el-slider::after,.el-slider::before,.el-slider__button-wrapper::after,.el-upload-cover::after{content:""}.el-tooltip__popper[x-placement^=top]{margin-bottom:12px}.el-tooltip__popper[x-placement^=top] .popper__arrow{bottom:-6px;border-top-color:#303133;border-bottom-width:0}.el-tooltip__popper[x-placement^=top] .popper__arrow::after{bottom:1px;margin-left:-5px;border-top-color:#303133;border-bottom-width:0}.el-tooltip__popper[x-placement^=bottom]{margin-top:12px}.el-tooltip__popper[x-placement^=bottom] .popper__arrow{top:-6px;border-top-width:0;border-bottom-color:#303133}.el-tooltip__popper[x-placement^=bottom] .popper__arrow::after{top:1px;margin-left:-5px;border-top-width:0;border-bottom-color:#303133}.el-tooltip__popper[x-placement^=right]{margin-left:12px}.el-tooltip__popper[x-placement^=right] .popper__arrow{left:-6px;border-right-color:#303133;border-left-width:0}.el-tooltip__popper[x-placement^=right] .popper__arrow::after{bottom:-5px;left:1px;border-right-color:#303133;border-left-width:0}.el-tooltip__popper[x-placement^=left]{margin-right:12px}.el-tooltip__popper[x-placement^=left] .popper__arrow{right:-6px;border-right-width:0;border-left-color:#303133}.el-tooltip__popper[x-placement^=left] .popper__arrow::after{right:1px;bottom:-5px;margin-left:-5px;border-right-width:0;border-left-color:#303133}.el-tooltip__popper.is-dark{background:#303133;color:#FFF}.el-tooltip__popper.is-light{background:#FFF;border:1px solid #303133}.el-tooltip__popper.is-light[x-placement^=top] .popper__arrow{border-top-color:#303133}.el-tooltip__popper.is-light[x-placement^=top] .popper__arrow::after{border-top-color:#FFF}.el-tooltip__popper.is-light[x-placement^=bottom] .popper__arrow{border-bottom-color:#303133}.el-tooltip__popper.is-light[x-placement^=bottom] .popper__arrow::after{border-bottom-color:#FFF}.el-tooltip__popper.is-light[x-placement^=left] .popper__arrow{border-left-color:#303133}.el-tooltip__popper.is-light[x-placement^=left] .popper__arrow::after{border-left-color:#FFF}.el-tooltip__popper.is-light[x-placement^=right] .popper__arrow{border-right-color:#303133}.el-tooltip__popper.is-light[x-placement^=right] .popper__arrow::after{border-right-color:#FFF}.el-slider::after,.el-slider::before{display:table}.el-slider__button-wrapper .el-tooltip,.el-slider__button-wrapper::after{vertical-align:middle;display:inline-block}.el-slider::after{clear:both}.el-slider__runway{width:100%;height:6px;margin:16px 0;background-color:#E4E7ED;border-radius:3px;position:relative;cursor:pointer;vertical-align:middle}.el-slider__runway.show-input{margin-right:160px;width:auto}.el-slider__runway.disabled{cursor:default}.el-slider__runway.disabled .el-slider__bar{background-color:#C0C4CC}.el-slider__runway.disabled .el-slider__button{border-color:#C0C4CC}.el-slider__runway.disabled .el-slider__button-wrapper.dragging,.el-slider__runway.disabled .el-slider__button-wrapper.hover,.el-slider__runway.disabled .el-slider__button-wrapper:hover{cursor:not-allowed}.el-slider__runway.disabled .el-slider__button.dragging,.el-slider__runway.disabled .el-slider__button.hover,.el-slider__runway.disabled .el-slider__button:hover{-webkit-transform:scale(1);transform:scale(1);cursor:not-allowed}.el-slider__button-wrapper,.el-slider__stop{-webkit-transform:translateX(-50%);position:absolute}.el-slider__input{float:right;margin-top:3px;width:130px}.el-slider__input.el-input-number--mini{margin-top:5px}.el-slider__input.el-input-number--medium{margin-top:0}.el-slider__input.el-input-number--large{margin-top:-2px}.el-slider__bar{height:6px;background-color:#409EFF;border-top-left-radius:3px;border-bottom-left-radius:3px;position:absolute}.el-slider__button-wrapper{height:36px;width:36px;z-index:1001;top:-15px;transform:translateX(-50%);background-color:transparent;text-align:center;-ms-user-select:none;user-select:none;line-height:normal}.el-slider__button-wrapper::after{height:100%}.el-slider__button-wrapper.hover,.el-slider__button-wrapper:hover{cursor:-webkit-grab;cursor:grab}.el-slider__button-wrapper.dragging{cursor:-webkit-grabbing;cursor:grabbing}.el-slider__button{width:16px;height:16px;border:2px solid #409EFF;background-color:#FFF;border-radius:50%;-webkit-transition:.2s;transition:.2s;-ms-user-select:none;user-select:none}.el-button,.el-step__icon-inner{-moz-user-select:none;-webkit-user-select:none}.el-slider__button.dragging,.el-slider__button.hover,.el-slider__button:hover{-webkit-transform:scale(1.2);transform:scale(1.2)}.el-slider__button.hover,.el-slider__button:hover{cursor:-webkit-grab;cursor:grab}.el-slider__button.dragging{cursor:-webkit-grabbing;cursor:grabbing}.el-slider__stop{height:6px;width:6px;border-radius:100%;background-color:#FFF;transform:translateX(-50%)}.el-slider__marks{top:0;left:12px;width:18px;height:100%}.el-slider__marks-text{position:absolute;-webkit-transform:translateX(-50%);transform:translateX(-50%);font-size:14px;color:#909399;margin-top:15px}.el-slider.is-vertical{position:relative}.el-slider.is-vertical .el-slider__runway{width:6px;height:100%;margin:0 16px}.el-slider.is-vertical .el-slider__bar{width:6px;height:auto;border-radius:0 0 3px 3px}.el-slider.is-vertical .el-slider__button-wrapper{top:auto;left:-15px;-webkit-transform:translateY(50%);transform:translateY(50%)}.el-slider.is-vertical .el-slider__stop{-webkit-transform:translateY(50%);transform:translateY(50%)}.el-slider.is-vertical.el-slider--with-input{padding-bottom:58px}.el-slider.is-vertical.el-slider--with-input .el-slider__input{overflow:visible;float:none;position:absolute;bottom:22px;width:36px;margin-top:15px}.el-slider.is-vertical.el-slider--with-input .el-slider__input .el-input__inner{text-align:center;padding-left:5px;padding-right:5px}.el-slider.is-vertical.el-slider--with-input .el-slider__input .el-input-number__decrease,.el-slider.is-vertical.el-slider--with-input .el-slider__input .el-input-number__increase{top:32px;margin-top:-1px;border:1px solid #DCDFE6;line-height:20px;-webkit-box-sizing:border-box;box-sizing:border-box;-webkit-transition:border-color .2s cubic-bezier(.645,.045,.355,1);transition:border-color .2s cubic-bezier(.645,.045,.355,1)}.el-slider.is-vertical.el-slider--with-input .el-slider__input .el-input-number__decrease{width:18px;right:18px;border-bottom-left-radius:4px}.el-slider.is-vertical.el-slider--with-input .el-slider__input .el-input-number__increase{width:19px;border-bottom-right-radius:4px}.el-slider.is-vertical.el-slider--with-input .el-slider__input .el-input-number__increase~.el-input .el-input__inner{border-bottom-left-radius:0;border-bottom-right-radius:0}.el-slider.is-vertical.el-slider--with-input .el-slider__input:hover .el-input-number__decrease,.el-slider.is-vertical.el-slider--with-input .el-slider__input:hover .el-input-number__increase{border-color:#C0C4CC}.el-slider.is-vertical.el-slider--with-input .el-slider__input:active .el-input-number__decrease,.el-slider.is-vertical.el-slider--with-input .el-slider__input:active .el-input-number__increase{border-color:#409EFF}.el-slider.is-vertical .el-slider__marks-text{margin-top:0;left:15px;-webkit-transform:translateY(50%);transform:translateY(50%)}.el-loading-parent--relative{position:relative!important}.el-loading-parent--hidden{overflow:hidden!important}.el-loading-mask{position:absolute;z-index:2000;background-color:rgba(255,255,255,.9);margin:0;top:0;right:0;bottom:0;left:0;-webkit-transition:opacity .3s;transition:opacity .3s}.el-loading-mask.is-fullscreen{position:fixed}.el-loading-mask.is-fullscreen .el-loading-spinner{margin-top:-25px}.el-loading-mask.is-fullscreen .el-loading-spinner .circular{height:50px;width:50px}.el-loading-spinner{top:50%;margin-top:-21px;width:100%;text-align:center;position:absolute}.el-col-pull-0,.el-col-pull-1,.el-col-pull-10,.el-col-pull-11,.el-col-pull-13,.el-col-pull-14,.el-col-pull-15,.el-col-pull-16,.el-col-pull-17,.el-col-pull-18,.el-col-pull-19,.el-col-pull-2,.el-col-pull-20,.el-col-pull-21,.el-col-pull-22,.el-col-pull-23,.el-col-pull-24,.el-col-pull-3,.el-col-pull-4,.el-col-pull-5,.el-col-pull-6,.el-col-pull-7,.el-col-pull-8,.el-col-pull-9,.el-col-push-0,.el-col-push-1,.el-col-push-10,.el-col-push-11,.el-col-push-12,.el-col-push-13,.el-col-push-14,.el-col-push-15,.el-col-push-16,.el-col-push-17,.el-col-push-18,.el-col-push-19,.el-col-push-2,.el-col-push-20,.el-col-push-21,.el-col-push-22,.el-col-push-23,.el-col-push-24,.el-col-push-3,.el-col-push-4,.el-col-push-5,.el-col-push-6,.el-col-push-7,.el-col-push-8,.el-col-push-9,.el-row{position:relative}.el-loading-spinner .el-loading-text{color:#409EFF;margin:3px 0;font-size:14px}.el-loading-spinner .circular{height:42px;width:42px;-webkit-animation:loading-rotate 2s linear infinite;animation:loading-rotate 2s linear infinite}.el-loading-spinner .path{-webkit-animation:loading-dash 1.5s ease-in-out infinite;animation:loading-dash 1.5s ease-in-out infinite;stroke-dasharray:90,150;stroke-dashoffset:0;stroke-width:2;stroke:#409EFF;stroke-linecap:round}.el-loading-spinner i{color:#409EFF}@-webkit-keyframes loading-rotate{100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes loading-rotate{100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@-webkit-keyframes loading-dash{0%{stroke-dasharray:1,200;stroke-dashoffset:0}50%{stroke-dasharray:90,150;stroke-dashoffset:-40px}100%{stroke-dasharray:90,150;stroke-dashoffset:-120px}}@keyframes loading-dash{0%{stroke-dasharray:1,200;stroke-dashoffset:0}50%{stroke-dasharray:90,150;stroke-dashoffset:-40px}100%{stroke-dasharray:90,150;stroke-dashoffset:-120px}}.el-row{-webkit-box-sizing:border-box;box-sizing:border-box}.el-row::after,.el-row::before{display:table}.el-row::after{clear:both}.el-row--flex{display:-webkit-box;display:-ms-flexbox;display:flex}.el-col-0,.el-row--flex:after,.el-row--flex:before{display:none}.el-row--flex.is-justify-center{-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.el-row--flex.is-justify-end{-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end}.el-row--flex.is-justify-space-between{-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.el-row--flex.is-justify-space-around{-ms-flex-pack:distribute;justify-content:space-around}.el-row--flex.is-align-middle{-webkit-box-align:center;-ms-flex-align:center;align-items:center}.el-row--flex.is-align-bottom{-webkit-box-align:end;-ms-flex-align:end;align-items:flex-end}[class*=el-col-]{float:left;-webkit-box-sizing:border-box;box-sizing:border-box}.el-upload--picture-card,.el-upload-dragger{-webkit-box-sizing:border-box;cursor:pointer}.el-col-0{width:0%}.el-col-offset-0{margin-left:0}.el-col-pull-0{right:0}.el-col-push-0{left:0}.el-col-1{width:4.16667%}.el-col-offset-1{margin-left:4.16667%}.el-col-pull-1{right:4.16667%}.el-col-push-1{left:4.16667%}.el-col-2{width:8.33333%}.el-col-offset-2{margin-left:8.33333%}.el-col-pull-2{right:8.33333%}.el-col-push-2{left:8.33333%}.el-col-3{width:12.5%}.el-col-offset-3{margin-left:12.5%}.el-col-pull-3{right:12.5%}.el-col-push-3{left:12.5%}.el-col-4{width:16.66667%}.el-col-offset-4{margin-left:16.66667%}.el-col-pull-4{right:16.66667%}.el-col-push-4{left:16.66667%}.el-col-5{width:20.83333%}.el-col-offset-5{margin-left:20.83333%}.el-col-pull-5{right:20.83333%}.el-col-push-5{left:20.83333%}.el-col-6{width:25%}.el-col-offset-6{margin-left:25%}.el-col-pull-6{right:25%}.el-col-push-6{left:25%}.el-col-7{width:29.16667%}.el-col-offset-7{margin-left:29.16667%}.el-col-pull-7{right:29.16667%}.el-col-push-7{left:29.16667%}.el-col-8{width:33.33333%}.el-col-offset-8{margin-left:33.33333%}.el-col-pull-8{right:33.33333%}.el-col-push-8{left:33.33333%}.el-col-9{width:37.5%}.el-col-offset-9{margin-left:37.5%}.el-col-pull-9{right:37.5%}.el-col-push-9{left:37.5%}.el-col-10{width:41.66667%}.el-col-offset-10{margin-left:41.66667%}.el-col-pull-10{right:41.66667%}.el-col-push-10{left:41.66667%}.el-col-11{width:45.83333%}.el-col-offset-11{margin-left:45.83333%}.el-col-pull-11{right:45.83333%}.el-col-push-11{left:45.83333%}.el-col-12{width:50%}.el-col-offset-12{margin-left:50%}.el-col-pull-12{position:relative;right:50%}.el-col-push-12{left:50%}.el-col-13{width:54.16667%}.el-col-offset-13{margin-left:54.16667%}.el-col-pull-13{right:54.16667%}.el-col-push-13{left:54.16667%}.el-col-14{width:58.33333%}.el-col-offset-14{margin-left:58.33333%}.el-col-pull-14{right:58.33333%}.el-col-push-14{left:58.33333%}.el-col-15{width:62.5%}.el-col-offset-15{margin-left:62.5%}.el-col-pull-15{right:62.5%}.el-col-push-15{left:62.5%}.el-col-16{width:66.66667%}.el-col-offset-16{margin-left:66.66667%}.el-col-pull-16{right:66.66667%}.el-col-push-16{left:66.66667%}.el-col-17{width:70.83333%}.el-col-offset-17{margin-left:70.83333%}.el-col-pull-17{right:70.83333%}.el-col-push-17{left:70.83333%}.el-col-18{width:75%}.el-col-offset-18{margin-left:75%}.el-col-pull-18{right:75%}.el-col-push-18{left:75%}.el-col-19{width:79.16667%}.el-col-offset-19{margin-left:79.16667%}.el-col-pull-19{right:79.16667%}.el-col-push-19{left:79.16667%}.el-col-20{width:83.33333%}.el-col-offset-20{margin-left:83.33333%}.el-col-pull-20{right:83.33333%}.el-col-push-20{left:83.33333%}.el-col-21{width:87.5%}.el-col-offset-21{margin-left:87.5%}.el-col-pull-21{right:87.5%}.el-col-push-21{left:87.5%}.el-col-22{width:91.66667%}.el-col-offset-22{margin-left:91.66667%}.el-col-pull-22{right:91.66667%}.el-col-push-22{left:91.66667%}.el-col-23{width:95.83333%}.el-col-offset-23{margin-left:95.83333%}.el-col-pull-23{right:95.83333%}.el-col-push-23{left:95.83333%}.el-col-24{width:100%}.el-col-offset-24{margin-left:100%}.el-col-pull-24{right:100%}.el-col-push-24{left:100%}@media only screen and (max-width:767px){.el-col-xs-0{display:none;width:0%}.el-col-xs-offset-0{margin-left:0}.el-col-xs-pull-0{position:relative;right:0}.el-col-xs-push-0{position:relative;left:0}.el-col-xs-1{width:4.16667%}.el-col-xs-offset-1{margin-left:4.16667%}.el-col-xs-pull-1{position:relative;right:4.16667%}.el-col-xs-push-1{position:relative;left:4.16667%}.el-col-xs-2{width:8.33333%}.el-col-xs-offset-2{margin-left:8.33333%}.el-col-xs-pull-2{position:relative;right:8.33333%}.el-col-xs-push-2{position:relative;left:8.33333%}.el-col-xs-3{width:12.5%}.el-col-xs-offset-3{margin-left:12.5%}.el-col-xs-pull-3{position:relative;right:12.5%}.el-col-xs-push-3{position:relative;left:12.5%}.el-col-xs-4{width:16.66667%}.el-col-xs-offset-4{margin-left:16.66667%}.el-col-xs-pull-4{position:relative;right:16.66667%}.el-col-xs-push-4{position:relative;left:16.66667%}.el-col-xs-5{width:20.83333%}.el-col-xs-offset-5{margin-left:20.83333%}.el-col-xs-pull-5{position:relative;right:20.83333%}.el-col-xs-push-5{position:relative;left:20.83333%}.el-col-xs-6{width:25%}.el-col-xs-offset-6{margin-left:25%}.el-col-xs-pull-6{position:relative;right:25%}.el-col-xs-push-6{position:relative;left:25%}.el-col-xs-7{width:29.16667%}.el-col-xs-offset-7{margin-left:29.16667%}.el-col-xs-pull-7{position:relative;right:29.16667%}.el-col-xs-push-7{position:relative;left:29.16667%}.el-col-xs-8{width:33.33333%}.el-col-xs-offset-8{margin-left:33.33333%}.el-col-xs-pull-8{position:relative;right:33.33333%}.el-col-xs-push-8{position:relative;left:33.33333%}.el-col-xs-9{width:37.5%}.el-col-xs-offset-9{margin-left:37.5%}.el-col-xs-pull-9{position:relative;right:37.5%}.el-col-xs-push-9{position:relative;left:37.5%}.el-col-xs-10{width:41.66667%}.el-col-xs-offset-10{margin-left:41.66667%}.el-col-xs-pull-10{position:relative;right:41.66667%}.el-col-xs-push-10{position:relative;left:41.66667%}.el-col-xs-11{width:45.83333%}.el-col-xs-offset-11{margin-left:45.83333%}.el-col-xs-pull-11{position:relative;right:45.83333%}.el-col-xs-push-11{position:relative;left:45.83333%}.el-col-xs-12{width:50%}.el-col-xs-offset-12{margin-left:50%}.el-col-xs-pull-12{position:relative;right:50%}.el-col-xs-push-12{position:relative;left:50%}.el-col-xs-13{width:54.16667%}.el-col-xs-offset-13{margin-left:54.16667%}.el-col-xs-pull-13{position:relative;right:54.16667%}.el-col-xs-push-13{position:relative;left:54.16667%}.el-col-xs-14{width:58.33333%}.el-col-xs-offset-14{margin-left:58.33333%}.el-col-xs-pull-14{position:relative;right:58.33333%}.el-col-xs-push-14{position:relative;left:58.33333%}.el-col-xs-15{width:62.5%}.el-col-xs-offset-15{margin-left:62.5%}.el-col-xs-pull-15{position:relative;right:62.5%}.el-col-xs-push-15{position:relative;left:62.5%}.el-col-xs-16{width:66.66667%}.el-col-xs-offset-16{margin-left:66.66667%}.el-col-xs-pull-16{position:relative;right:66.66667%}.el-col-xs-push-16{position:relative;left:66.66667%}.el-col-xs-17{width:70.83333%}.el-col-xs-offset-17{margin-left:70.83333%}.el-col-xs-pull-17{position:relative;right:70.83333%}.el-col-xs-push-17{position:relative;left:70.83333%}.el-col-xs-18{width:75%}.el-col-xs-offset-18{margin-left:75%}.el-col-xs-pull-18{position:relative;right:75%}.el-col-xs-push-18{position:relative;left:75%}.el-col-xs-19{width:79.16667%}.el-col-xs-offset-19{margin-left:79.16667%}.el-col-xs-pull-19{position:relative;right:79.16667%}.el-col-xs-push-19{position:relative;left:79.16667%}.el-col-xs-20{width:83.33333%}.el-col-xs-offset-20{margin-left:83.33333%}.el-col-xs-pull-20{position:relative;right:83.33333%}.el-col-xs-push-20{position:relative;left:83.33333%}.el-col-xs-21{width:87.5%}.el-col-xs-offset-21{margin-left:87.5%}.el-col-xs-pull-21{position:relative;right:87.5%}.el-col-xs-push-21{position:relative;left:87.5%}.el-col-xs-22{width:91.66667%}.el-col-xs-offset-22{margin-left:91.66667%}.el-col-xs-pull-22{position:relative;right:91.66667%}.el-col-xs-push-22{position:relative;left:91.66667%}.el-col-xs-23{width:95.83333%}.el-col-xs-offset-23{margin-left:95.83333%}.el-col-xs-pull-23{position:relative;right:95.83333%}.el-col-xs-push-23{position:relative;left:95.83333%}.el-col-xs-24{width:100%}.el-col-xs-offset-24{margin-left:100%}.el-col-xs-pull-24{position:relative;right:100%}.el-col-xs-push-24{position:relative;left:100%}}@media only screen and (min-width:768px){.el-col-sm-0{display:none;width:0%}.el-col-sm-offset-0{margin-left:0}.el-col-sm-pull-0{position:relative;right:0}.el-col-sm-push-0{position:relative;left:0}.el-col-sm-1{width:4.16667%}.el-col-sm-offset-1{margin-left:4.16667%}.el-col-sm-pull-1{position:relative;right:4.16667%}.el-col-sm-push-1{position:relative;left:4.16667%}.el-col-sm-2{width:8.33333%}.el-col-sm-offset-2{margin-left:8.33333%}.el-col-sm-pull-2{position:relative;right:8.33333%}.el-col-sm-push-2{position:relative;left:8.33333%}.el-col-sm-3{width:12.5%}.el-col-sm-offset-3{margin-left:12.5%}.el-col-sm-pull-3{position:relative;right:12.5%}.el-col-sm-push-3{position:relative;left:12.5%}.el-col-sm-4{width:16.66667%}.el-col-sm-offset-4{margin-left:16.66667%}.el-col-sm-pull-4{position:relative;right:16.66667%}.el-col-sm-push-4{position:relative;left:16.66667%}.el-col-sm-5{width:20.83333%}.el-col-sm-offset-5{margin-left:20.83333%}.el-col-sm-pull-5{position:relative;right:20.83333%}.el-col-sm-push-5{position:relative;left:20.83333%}.el-col-sm-6{width:25%}.el-col-sm-offset-6{margin-left:25%}.el-col-sm-pull-6{position:relative;right:25%}.el-col-sm-push-6{position:relative;left:25%}.el-col-sm-7{width:29.16667%}.el-col-sm-offset-7{margin-left:29.16667%}.el-col-sm-pull-7{position:relative;right:29.16667%}.el-col-sm-push-7{position:relative;left:29.16667%}.el-col-sm-8{width:33.33333%}.el-col-sm-offset-8{margin-left:33.33333%}.el-col-sm-pull-8{position:relative;right:33.33333%}.el-col-sm-push-8{position:relative;left:33.33333%}.el-col-sm-9{width:37.5%}.el-col-sm-offset-9{margin-left:37.5%}.el-col-sm-pull-9{position:relative;right:37.5%}.el-col-sm-push-9{position:relative;left:37.5%}.el-col-sm-10{width:41.66667%}.el-col-sm-offset-10{margin-left:41.66667%}.el-col-sm-pull-10{position:relative;right:41.66667%}.el-col-sm-push-10{position:relative;left:41.66667%}.el-col-sm-11{width:45.83333%}.el-col-sm-offset-11{margin-left:45.83333%}.el-col-sm-pull-11{position:relative;right:45.83333%}.el-col-sm-push-11{position:relative;left:45.83333%}.el-col-sm-12{width:50%}.el-col-sm-offset-12{margin-left:50%}.el-col-sm-pull-12{position:relative;right:50%}.el-col-sm-push-12{position:relative;left:50%}.el-col-sm-13{width:54.16667%}.el-col-sm-offset-13{margin-left:54.16667%}.el-col-sm-pull-13{position:relative;right:54.16667%}.el-col-sm-push-13{position:relative;left:54.16667%}.el-col-sm-14{width:58.33333%}.el-col-sm-offset-14{margin-left:58.33333%}.el-col-sm-pull-14{position:relative;right:58.33333%}.el-col-sm-push-14{position:relative;left:58.33333%}.el-col-sm-15{width:62.5%}.el-col-sm-offset-15{margin-left:62.5%}.el-col-sm-pull-15{position:relative;right:62.5%}.el-col-sm-push-15{position:relative;left:62.5%}.el-col-sm-16{width:66.66667%}.el-col-sm-offset-16{margin-left:66.66667%}.el-col-sm-pull-16{position:relative;right:66.66667%}.el-col-sm-push-16{position:relative;left:66.66667%}.el-col-sm-17{width:70.83333%}.el-col-sm-offset-17{margin-left:70.83333%}.el-col-sm-pull-17{position:relative;right:70.83333%}.el-col-sm-push-17{position:relative;left:70.83333%}.el-col-sm-18{width:75%}.el-col-sm-offset-18{margin-left:75%}.el-col-sm-pull-18{position:relative;right:75%}.el-col-sm-push-18{position:relative;left:75%}.el-col-sm-19{width:79.16667%}.el-col-sm-offset-19{margin-left:79.16667%}.el-col-sm-pull-19{position:relative;right:79.16667%}.el-col-sm-push-19{position:relative;left:79.16667%}.el-col-sm-20{width:83.33333%}.el-col-sm-offset-20{margin-left:83.33333%}.el-col-sm-pull-20{position:relative;right:83.33333%}.el-col-sm-push-20{position:relative;left:83.33333%}.el-col-sm-21{width:87.5%}.el-col-sm-offset-21{margin-left:87.5%}.el-col-sm-pull-21{position:relative;right:87.5%}.el-col-sm-push-21{position:relative;left:87.5%}.el-col-sm-22{width:91.66667%}.el-col-sm-offset-22{margin-left:91.66667%}.el-col-sm-pull-22{position:relative;right:91.66667%}.el-col-sm-push-22{position:relative;left:91.66667%}.el-col-sm-23{width:95.83333%}.el-col-sm-offset-23{margin-left:95.83333%}.el-col-sm-pull-23{position:relative;right:95.83333%}.el-col-sm-push-23{position:relative;left:95.83333%}.el-col-sm-24{width:100%}.el-col-sm-offset-24{margin-left:100%}.el-col-sm-pull-24{position:relative;right:100%}.el-col-sm-push-24{position:relative;left:100%}}@media only screen and (min-width:992px){.el-col-md-0{display:none;width:0%}.el-col-md-offset-0{margin-left:0}.el-col-md-pull-0{position:relative;right:0}.el-col-md-push-0{position:relative;left:0}.el-col-md-1{width:4.16667%}.el-col-md-offset-1{margin-left:4.16667%}.el-col-md-pull-1{position:relative;right:4.16667%}.el-col-md-push-1{position:relative;left:4.16667%}.el-col-md-2{width:8.33333%}.el-col-md-offset-2{margin-left:8.33333%}.el-col-md-pull-2{position:relative;right:8.33333%}.el-col-md-push-2{position:relative;left:8.33333%}.el-col-md-3{width:12.5%}.el-col-md-offset-3{margin-left:12.5%}.el-col-md-pull-3{position:relative;right:12.5%}.el-col-md-push-3{position:relative;left:12.5%}.el-col-md-4{width:16.66667%}.el-col-md-offset-4{margin-left:16.66667%}.el-col-md-pull-4{position:relative;right:16.66667%}.el-col-md-push-4{position:relative;left:16.66667%}.el-col-md-5{width:20.83333%}.el-col-md-offset-5{margin-left:20.83333%}.el-col-md-pull-5{position:relative;right:20.83333%}.el-col-md-push-5{position:relative;left:20.83333%}.el-col-md-6{width:25%}.el-col-md-offset-6{margin-left:25%}.el-col-md-pull-6{position:relative;right:25%}.el-col-md-push-6{position:relative;left:25%}.el-col-md-7{width:29.16667%}.el-col-md-offset-7{margin-left:29.16667%}.el-col-md-pull-7{position:relative;right:29.16667%}.el-col-md-push-7{position:relative;left:29.16667%}.el-col-md-8{width:33.33333%}.el-col-md-offset-8{margin-left:33.33333%}.el-col-md-pull-8{position:relative;right:33.33333%}.el-col-md-push-8{position:relative;left:33.33333%}.el-col-md-9{width:37.5%}.el-col-md-offset-9{margin-left:37.5%}.el-col-md-pull-9{position:relative;right:37.5%}.el-col-md-push-9{position:relative;left:37.5%}.el-col-md-10{width:41.66667%}.el-col-md-offset-10{margin-left:41.66667%}.el-col-md-pull-10{position:relative;right:41.66667%}.el-col-md-push-10{position:relative;left:41.66667%}.el-col-md-11{width:45.83333%}.el-col-md-offset-11{margin-left:45.83333%}.el-col-md-pull-11{position:relative;right:45.83333%}.el-col-md-push-11{position:relative;left:45.83333%}.el-col-md-12{width:50%}.el-col-md-offset-12{margin-left:50%}.el-col-md-pull-12{position:relative;right:50%}.el-col-md-push-12{position:relative;left:50%}.el-col-md-13{width:54.16667%}.el-col-md-offset-13{margin-left:54.16667%}.el-col-md-pull-13{position:relative;right:54.16667%}.el-col-md-push-13{position:relative;left:54.16667%}.el-col-md-14{width:58.33333%}.el-col-md-offset-14{margin-left:58.33333%}.el-col-md-pull-14{position:relative;right:58.33333%}.el-col-md-push-14{position:relative;left:58.33333%}.el-col-md-15{width:62.5%}.el-col-md-offset-15{margin-left:62.5%}.el-col-md-pull-15{position:relative;right:62.5%}.el-col-md-push-15{position:relative;left:62.5%}.el-col-md-16{width:66.66667%}.el-col-md-offset-16{margin-left:66.66667%}.el-col-md-pull-16{position:relative;right:66.66667%}.el-col-md-push-16{position:relative;left:66.66667%}.el-col-md-17{width:70.83333%}.el-col-md-offset-17{margin-left:70.83333%}.el-col-md-pull-17{position:relative;right:70.83333%}.el-col-md-push-17{position:relative;left:70.83333%}.el-col-md-18{width:75%}.el-col-md-offset-18{margin-left:75%}.el-col-md-pull-18{position:relative;right:75%}.el-col-md-push-18{position:relative;left:75%}.el-col-md-19{width:79.16667%}.el-col-md-offset-19{margin-left:79.16667%}.el-col-md-pull-19{position:relative;right:79.16667%}.el-col-md-push-19{position:relative;left:79.16667%}.el-col-md-20{width:83.33333%}.el-col-md-offset-20{margin-left:83.33333%}.el-col-md-pull-20{position:relative;right:83.33333%}.el-col-md-push-20{position:relative;left:83.33333%}.el-col-md-21{width:87.5%}.el-col-md-offset-21{margin-left:87.5%}.el-col-md-pull-21{position:relative;right:87.5%}.el-col-md-push-21{position:relative;left:87.5%}.el-col-md-22{width:91.66667%}.el-col-md-offset-22{margin-left:91.66667%}.el-col-md-pull-22{position:relative;right:91.66667%}.el-col-md-push-22{position:relative;left:91.66667%}.el-col-md-23{width:95.83333%}.el-col-md-offset-23{margin-left:95.83333%}.el-col-md-pull-23{position:relative;right:95.83333%}.el-col-md-push-23{position:relative;left:95.83333%}.el-col-md-24{width:100%}.el-col-md-offset-24{margin-left:100%}.el-col-md-pull-24{position:relative;right:100%}.el-col-md-push-24{position:relative;left:100%}}@media only screen and (min-width:1200px){.el-col-lg-0{display:none;width:0%}.el-col-lg-offset-0{margin-left:0}.el-col-lg-pull-0{position:relative;right:0}.el-col-lg-push-0{position:relative;left:0}.el-col-lg-1{width:4.16667%}.el-col-lg-offset-1{margin-left:4.16667%}.el-col-lg-pull-1{position:relative;right:4.16667%}.el-col-lg-push-1{position:relative;left:4.16667%}.el-col-lg-2{width:8.33333%}.el-col-lg-offset-2{margin-left:8.33333%}.el-col-lg-pull-2{position:relative;right:8.33333%}.el-col-lg-push-2{position:relative;left:8.33333%}.el-col-lg-3{width:12.5%}.el-col-lg-offset-3{margin-left:12.5%}.el-col-lg-pull-3{position:relative;right:12.5%}.el-col-lg-push-3{position:relative;left:12.5%}.el-col-lg-4{width:16.66667%}.el-col-lg-offset-4{margin-left:16.66667%}.el-col-lg-pull-4{position:relative;right:16.66667%}.el-col-lg-push-4{position:relative;left:16.66667%}.el-col-lg-5{width:20.83333%}.el-col-lg-offset-5{margin-left:20.83333%}.el-col-lg-pull-5{position:relative;right:20.83333%}.el-col-lg-push-5{position:relative;left:20.83333%}.el-col-lg-6{width:25%}.el-col-lg-offset-6{margin-left:25%}.el-col-lg-pull-6{position:relative;right:25%}.el-col-lg-push-6{position:relative;left:25%}.el-col-lg-7{width:29.16667%}.el-col-lg-offset-7{margin-left:29.16667%}.el-col-lg-pull-7{position:relative;right:29.16667%}.el-col-lg-push-7{position:relative;left:29.16667%}.el-col-lg-8{width:33.33333%}.el-col-lg-offset-8{margin-left:33.33333%}.el-col-lg-pull-8{position:relative;right:33.33333%}.el-col-lg-push-8{position:relative;left:33.33333%}.el-col-lg-9{width:37.5%}.el-col-lg-offset-9{margin-left:37.5%}.el-col-lg-pull-9{position:relative;right:37.5%}.el-col-lg-push-9{position:relative;left:37.5%}.el-col-lg-10{width:41.66667%}.el-col-lg-offset-10{margin-left:41.66667%}.el-col-lg-pull-10{position:relative;right:41.66667%}.el-col-lg-push-10{position:relative;left:41.66667%}.el-col-lg-11{width:45.83333%}.el-col-lg-offset-11{margin-left:45.83333%}.el-col-lg-pull-11{position:relative;right:45.83333%}.el-col-lg-push-11{position:relative;left:45.83333%}.el-col-lg-12{width:50%}.el-col-lg-offset-12{margin-left:50%}.el-col-lg-pull-12{position:relative;right:50%}.el-col-lg-push-12{position:relative;left:50%}.el-col-lg-13{width:54.16667%}.el-col-lg-offset-13{margin-left:54.16667%}.el-col-lg-pull-13{position:relative;right:54.16667%}.el-col-lg-push-13{position:relative;left:54.16667%}.el-col-lg-14{width:58.33333%}.el-col-lg-offset-14{margin-left:58.33333%}.el-col-lg-pull-14{position:relative;right:58.33333%}.el-col-lg-push-14{position:relative;left:58.33333%}.el-col-lg-15{width:62.5%}.el-col-lg-offset-15{margin-left:62.5%}.el-col-lg-pull-15{position:relative;right:62.5%}.el-col-lg-push-15{position:relative;left:62.5%}.el-col-lg-16{width:66.66667%}.el-col-lg-offset-16{margin-left:66.66667%}.el-col-lg-pull-16{position:relative;right:66.66667%}.el-col-lg-push-16{position:relative;left:66.66667%}.el-col-lg-17{width:70.83333%}.el-col-lg-offset-17{margin-left:70.83333%}.el-col-lg-pull-17{position:relative;right:70.83333%}.el-col-lg-push-17{position:relative;left:70.83333%}.el-col-lg-18{width:75%}.el-col-lg-offset-18{margin-left:75%}.el-col-lg-pull-18{position:relative;right:75%}.el-col-lg-push-18{position:relative;left:75%}.el-col-lg-19{width:79.16667%}.el-col-lg-offset-19{margin-left:79.16667%}.el-col-lg-pull-19{position:relative;right:79.16667%}.el-col-lg-push-19{position:relative;left:79.16667%}.el-col-lg-20{width:83.33333%}.el-col-lg-offset-20{margin-left:83.33333%}.el-col-lg-pull-20{position:relative;right:83.33333%}.el-col-lg-push-20{position:relative;left:83.33333%}.el-col-lg-21{width:87.5%}.el-col-lg-offset-21{margin-left:87.5%}.el-col-lg-pull-21{position:relative;right:87.5%}.el-col-lg-push-21{position:relative;left:87.5%}.el-col-lg-22{width:91.66667%}.el-col-lg-offset-22{margin-left:91.66667%}.el-col-lg-pull-22{position:relative;right:91.66667%}.el-col-lg-push-22{position:relative;left:91.66667%}.el-col-lg-23{width:95.83333%}.el-col-lg-offset-23{margin-left:95.83333%}.el-col-lg-pull-23{position:relative;right:95.83333%}.el-col-lg-push-23{position:relative;left:95.83333%}.el-col-lg-24{width:100%}.el-col-lg-offset-24{margin-left:100%}.el-col-lg-pull-24{position:relative;right:100%}.el-col-lg-push-24{position:relative;left:100%}}@media only screen and (min-width:1920px){.el-col-xl-0{display:none;width:0%}.el-col-xl-offset-0{margin-left:0}.el-col-xl-pull-0{position:relative;right:0}.el-col-xl-push-0{position:relative;left:0}.el-col-xl-1{width:4.16667%}.el-col-xl-offset-1{margin-left:4.16667%}.el-col-xl-pull-1{position:relative;right:4.16667%}.el-col-xl-push-1{position:relative;left:4.16667%}.el-col-xl-2{width:8.33333%}.el-col-xl-offset-2{margin-left:8.33333%}.el-col-xl-pull-2{position:relative;right:8.33333%}.el-col-xl-push-2{position:relative;left:8.33333%}.el-col-xl-3{width:12.5%}.el-col-xl-offset-3{margin-left:12.5%}.el-col-xl-pull-3{position:relative;right:12.5%}.el-col-xl-push-3{position:relative;left:12.5%}.el-col-xl-4{width:16.66667%}.el-col-xl-offset-4{margin-left:16.66667%}.el-col-xl-pull-4{position:relative;right:16.66667%}.el-col-xl-push-4{position:relative;left:16.66667%}.el-col-xl-5{width:20.83333%}.el-col-xl-offset-5{margin-left:20.83333%}.el-col-xl-pull-5{position:relative;right:20.83333%}.el-col-xl-push-5{position:relative;left:20.83333%}.el-col-xl-6{width:25%}.el-col-xl-offset-6{margin-left:25%}.el-col-xl-pull-6{position:relative;right:25%}.el-col-xl-push-6{position:relative;left:25%}.el-col-xl-7{width:29.16667%}.el-col-xl-offset-7{margin-left:29.16667%}.el-col-xl-pull-7{position:relative;right:29.16667%}.el-col-xl-push-7{position:relative;left:29.16667%}.el-col-xl-8{width:33.33333%}.el-col-xl-offset-8{margin-left:33.33333%}.el-col-xl-pull-8{position:relative;right:33.33333%}.el-col-xl-push-8{position:relative;left:33.33333%}.el-col-xl-9{width:37.5%}.el-col-xl-offset-9{margin-left:37.5%}.el-col-xl-pull-9{position:relative;right:37.5%}.el-col-xl-push-9{position:relative;left:37.5%}.el-col-xl-10{width:41.66667%}.el-col-xl-offset-10{margin-left:41.66667%}.el-col-xl-pull-10{position:relative;right:41.66667%}.el-col-xl-push-10{position:relative;left:41.66667%}.el-col-xl-11{width:45.83333%}.el-col-xl-offset-11{margin-left:45.83333%}.el-col-xl-pull-11{position:relative;right:45.83333%}.el-col-xl-push-11{position:relative;left:45.83333%}.el-col-xl-12{width:50%}.el-col-xl-offset-12{margin-left:50%}.el-col-xl-pull-12{position:relative;right:50%}.el-col-xl-push-12{position:relative;left:50%}.el-col-xl-13{width:54.16667%}.el-col-xl-offset-13{margin-left:54.16667%}.el-col-xl-pull-13{position:relative;right:54.16667%}.el-col-xl-push-13{position:relative;left:54.16667%}.el-col-xl-14{width:58.33333%}.el-col-xl-offset-14{margin-left:58.33333%}.el-col-xl-pull-14{position:relative;right:58.33333%}.el-col-xl-push-14{position:relative;left:58.33333%}.el-col-xl-15{width:62.5%}.el-col-xl-offset-15{margin-left:62.5%}.el-col-xl-pull-15{position:relative;right:62.5%}.el-col-xl-push-15{position:relative;left:62.5%}.el-col-xl-16{width:66.66667%}.el-col-xl-offset-16{margin-left:66.66667%}.el-col-xl-pull-16{position:relative;right:66.66667%}.el-col-xl-push-16{position:relative;left:66.66667%}.el-col-xl-17{width:70.83333%}.el-col-xl-offset-17{margin-left:70.83333%}.el-col-xl-pull-17{position:relative;right:70.83333%}.el-col-xl-push-17{position:relative;left:70.83333%}.el-col-xl-18{width:75%}.el-col-xl-offset-18{margin-left:75%}.el-col-xl-pull-18{position:relative;right:75%}.el-col-xl-push-18{position:relative;left:75%}.el-col-xl-19{width:79.16667%}.el-col-xl-offset-19{margin-left:79.16667%}.el-col-xl-pull-19{position:relative;right:79.16667%}.el-col-xl-push-19{position:relative;left:79.16667%}.el-col-xl-20{width:83.33333%}.el-col-xl-offset-20{margin-left:83.33333%}.el-col-xl-pull-20{position:relative;right:83.33333%}.el-col-xl-push-20{position:relative;left:83.33333%}.el-col-xl-21{width:87.5%}.el-col-xl-offset-21{margin-left:87.5%}.el-col-xl-pull-21{position:relative;right:87.5%}.el-col-xl-push-21{position:relative;left:87.5%}.el-col-xl-22{width:91.66667%}.el-col-xl-offset-22{margin-left:91.66667%}.el-col-xl-pull-22{position:relative;right:91.66667%}.el-col-xl-push-22{position:relative;left:91.66667%}.el-col-xl-23{width:95.83333%}.el-col-xl-offset-23{margin-left:95.83333%}.el-col-xl-pull-23{position:relative;right:95.83333%}.el-col-xl-push-23{position:relative;left:95.83333%}.el-col-xl-24{width:100%}.el-col-xl-offset-24{margin-left:100%}.el-col-xl-pull-24{position:relative;right:100%}.el-col-xl-push-24{position:relative;left:100%}}@-webkit-keyframes progress{0%{background-position:0 0}100%{background-position:32px 0}}.el-upload{display:inline-block;text-align:center;cursor:pointer;outline:0}.el-upload__input{display:none}.el-upload__tip{font-size:12px;color:#606266;margin-top:7px}.el-upload iframe{position:absolute;z-index:-1;top:0;left:0;opacity:0;filter:alpha(opacity=0)}.el-upload--picture-card{background-color:#fbfdff;border:1px dashed #c0ccda;border-radius:6px;box-sizing:border-box;width:148px;height:148px;line-height:146px;vertical-align:top}.el-upload--picture-card i{font-size:28px;color:#8c939d}.el-upload--picture-card:hover,.el-upload:focus{border-color:#409EFF;color:#409EFF}.el-upload:focus .el-upload-dragger{border-color:#409EFF}.el-upload-dragger{background-color:#fff;border:1px dashed #d9d9d9;border-radius:6px;box-sizing:border-box;width:360px;height:180px;text-align:center;position:relative;overflow:hidden}.el-upload-dragger .el-icon-upload{font-size:67px;color:#C0C4CC;margin:40px 0 16px;line-height:50px}.el-upload-dragger+.el-upload__tip{text-align:center}.el-upload-dragger~.el-upload__files{border-top:1px solid #DCDFE6;margin-top:7px;padding-top:5px}.el-upload-dragger .el-upload__text{color:#606266;font-size:14px;text-align:center}.el-upload-dragger .el-upload__text em{color:#409EFF;font-style:normal}.el-upload-dragger:hover{border-color:#409EFF}.el-upload-dragger.is-dragover{background-color:rgba(32,159,255,.06);border:2px dashed #409EFF}.el-upload-list{margin:0;padding:0;list-style:none}.el-upload-list__item{-webkit-transition:all .5s cubic-bezier(.55,0,.1,1);transition:all .5s cubic-bezier(.55,0,.1,1);font-size:14px;color:#606266;line-height:1.8;margin-top:5px;position:relative;-webkit-box-sizing:border-box;box-sizing:border-box;border-radius:4px;width:100%}.el-upload-list__item .el-progress{position:absolute;top:20px;width:100%}.el-upload-list__item .el-progress__text{position:absolute;right:0;top:-13px}.el-upload-list__item .el-progress-bar{margin-right:0;padding-right:0}.el-upload-list__item:first-child{margin-top:10px}.el-upload-list__item .el-icon-upload-success{color:#67C23A}.el-upload-list__item .el-icon-close{display:none;position:absolute;top:5px;right:5px;cursor:pointer;opacity:.75;color:#606266}.el-upload-list__item .el-icon-close:hover{opacity:1}.el-upload-list__item .el-icon-close-tip{display:none;position:absolute;top:5px;right:5px;font-size:12px;cursor:pointer;opacity:1;color:#409EFF}.el-upload-list__item:hover{background-color:#F5F7FA}.el-upload-list__item:hover .el-icon-close{display:inline-block}.el-upload-list__item:hover .el-progress__text{display:none}.el-upload-list__item.is-success .el-upload-list__item-status-label{display:block}.el-upload-list__item.is-success .el-upload-list__item-name:focus,.el-upload-list__item.is-success .el-upload-list__item-name:hover{color:#409EFF;cursor:pointer}.el-upload-list__item.is-success:focus:not(:hover) .el-icon-close-tip{display:inline-block}.el-upload-list__item.is-success:active .el-icon-close-tip,.el-upload-list__item.is-success:focus .el-upload-list__item-status-label,.el-upload-list__item.is-success:hover .el-upload-list__item-status-label,.el-upload-list__item.is-success:not(.focusing):focus .el-icon-close-tip{display:none}.el-upload-list.is-disabled .el-upload-list__item:hover .el-upload-list__item-status-label{display:block}.el-upload-list__item-name{color:#606266;display:block;margin-right:40px;overflow:hidden;padding-left:4px;text-overflow:ellipsis;-webkit-transition:color .3s;transition:color .3s;white-space:nowrap}.el-upload-list__item-name [class^=el-icon]{height:100%;margin-right:7px;color:#909399;line-height:inherit}.el-upload-list__item-status-label{position:absolute;right:5px;top:0;line-height:inherit;display:none}.el-upload-list__item-delete{position:absolute;right:10px;top:0;font-size:12px;color:#606266;display:none}.el-upload-list__item-delete:hover{color:#409EFF}.el-upload-list--picture-card{margin:0;display:inline;vertical-align:top}.el-upload-list--picture-card .el-upload-list__item{overflow:hidden;background-color:#fff;border:1px solid #c0ccda;border-radius:6px;-webkit-box-sizing:border-box;box-sizing:border-box;width:148px;height:148px;margin:0 8px 8px 0;display:inline-block}.el-upload-list--picture-card .el-upload-list__item .el-icon-check,.el-upload-list--picture-card .el-upload-list__item .el-icon-circle-check{color:#FFF}.el-upload-list--picture-card .el-upload-list__item .el-icon-close,.el-upload-list--picture-card .el-upload-list__item:hover .el-upload-list__item-status-label{display:none}.el-upload-list--picture-card .el-upload-list__item:hover .el-progress__text{display:block}.el-upload-list--picture-card .el-upload-list__item-name{display:none}.el-upload-list--picture-card .el-upload-list__item-thumbnail{width:100%;height:100%}.el-upload-list--picture-card .el-upload-list__item-status-label{position:absolute;right:-15px;top:-6px;width:40px;height:24px;background:#13ce66;text-align:center;-webkit-transform:rotate(45deg);transform:rotate(45deg);-webkit-box-shadow:0 0 1pc 1px rgba(0,0,0,.2);box-shadow:0 0 1pc 1px rgba(0,0,0,.2)}.el-upload-list--picture-card .el-upload-list__item-status-label i{font-size:12px;margin-top:11px;-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}.el-upload-list--picture-card .el-upload-list__item-actions{position:absolute;width:100%;height:100%;left:0;top:0;cursor:default;text-align:center;color:#fff;opacity:0;font-size:20px;background-color:rgba(0,0,0,.5);-webkit-transition:opacity .3s;transition:opacity .3s}.el-upload-list--picture-card .el-upload-list__item-actions::after{display:inline-block;content:"";height:100%;vertical-align:middle}.el-upload-list--picture-card .el-upload-list__item-actions span{display:none;cursor:pointer}.el-upload-list--picture-card .el-upload-list__item-actions span+span{margin-left:15px}.el-upload-list--picture-card .el-upload-list__item-actions .el-upload-list__item-delete{position:static;font-size:inherit;color:inherit}.el-upload-list--picture-card .el-upload-list__item-actions:hover{opacity:1}.el-upload-list--picture-card .el-upload-list__item-actions:hover span{display:inline-block}.el-upload-list--picture-card .el-progress{top:50%;left:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);bottom:auto;width:126px}.el-upload-list--picture-card .el-progress .el-progress__text{top:50%}.el-upload-list--picture .el-upload-list__item{overflow:hidden;z-index:0;background-color:#fff;border:1px solid #c0ccda;border-radius:6px;-webkit-box-sizing:border-box;box-sizing:border-box;margin-top:10px;padding:10px 10px 10px 90px;height:92px}.el-upload-list--picture .el-upload-list__item .el-icon-check,.el-upload-list--picture .el-upload-list__item .el-icon-circle-check{color:#FFF}.el-upload-list--picture .el-upload-list__item:hover .el-upload-list__item-status-label{background:0 0;-webkit-box-shadow:none;box-shadow:none;top:-2px;right:-12px}.el-upload-list--picture .el-upload-list__item:hover .el-progress__text{display:block}.el-upload-list--picture .el-upload-list__item.is-success .el-upload-list__item-name{line-height:70px;margin-top:0}.el-upload-list--picture .el-upload-list__item.is-success .el-upload-list__item-name i{display:none}.el-upload-list--picture .el-upload-list__item-thumbnail{vertical-align:middle;display:inline-block;width:70px;height:70px;float:left;position:relative;z-index:1;margin-left:-80px;background-color:#FFF}.el-upload-list--picture .el-upload-list__item-name{display:block;margin-top:20px}.el-upload-list--picture .el-upload-list__item-name i{font-size:70px;line-height:1;position:absolute;left:9px;top:10px}.el-upload-list--picture .el-upload-list__item-status-label{position:absolute;right:-17px;top:-7px;width:46px;height:26px;background:#13ce66;text-align:center;-webkit-transform:rotate(45deg);transform:rotate(45deg);-webkit-box-shadow:0 1px 1px #ccc;box-shadow:0 1px 1px #ccc}.el-upload-list--picture .el-upload-list__item-status-label i{font-size:12px;margin-top:12px;-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}.el-upload-list--picture .el-progress{position:relative;top:-7px}.el-upload-cover{position:absolute;left:0;top:0;width:100%;height:100%;overflow:hidden;z-index:10;cursor:default}.el-upload-cover::after{display:inline-block;height:100%;vertical-align:middle}.el-upload-cover img{display:block;width:100%;height:100%}.el-upload-cover__label{position:absolute;right:-15px;top:-6px;width:40px;height:24px;background:#13ce66;text-align:center;-webkit-transform:rotate(45deg);transform:rotate(45deg);-webkit-box-shadow:0 0 1pc 1px rgba(0,0,0,.2);box-shadow:0 0 1pc 1px rgba(0,0,0,.2)}.el-upload-cover__label i{font-size:12px;margin-top:11px;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);color:#fff}.el-upload-cover__progress{display:inline-block;vertical-align:middle;position:static;width:243px}.el-upload-cover__progress+.el-upload__inner{opacity:0}.el-upload-cover__content{position:absolute;top:0;left:0;width:100%;height:100%}.el-upload-cover__interact{position:absolute;bottom:0;left:0;width:100%;height:100%;background-color:rgba(0,0,0,.72);text-align:center}.el-upload-cover__interact .btn{display:inline-block;color:#FFF;font-size:14px;cursor:pointer;vertical-align:middle;-webkit-transition:opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);transition:opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);transition:transform .3s cubic-bezier(.23,1,.32,1),opacity .3s cubic-bezier(.23,1,.32,1);transition:transform .3s cubic-bezier(.23,1,.32,1),opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);margin-top:60px}.el-upload-cover__interact .btn span{opacity:0;-webkit-transition:opacity .15s linear;transition:opacity .15s linear}.el-upload-cover__interact .btn:not(:first-child){margin-left:35px}.el-upload-cover__interact .btn:hover{-webkit-transform:translateY(-13px);transform:translateY(-13px)}.el-upload-cover__interact .btn:hover span{opacity:1}.el-upload-cover__interact .btn i{color:#FFF;display:block;font-size:24px;line-height:inherit;margin:0 auto 5px}.el-upload-cover__title{position:absolute;bottom:0;left:0;background-color:#FFF;height:36px;width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:400;text-align:left;padding:0 10px;margin:0;line-height:36px;font-size:14px;color:#303133}.el-upload-cover+.el-upload__inner{opacity:0;position:relative;z-index:1}.el-progress{position:relative;line-height:1}.el-progress__text{font-size:14px;color:#606266;display:inline-block;vertical-align:middle;margin-left:10px;line-height:1}.el-progress__text i{vertical-align:middle;display:block}.el-progress--circle{display:inline-block}.el-progress--circle .el-progress__text{position:absolute;top:50%;left:0;width:100%;text-align:center;margin:0;-webkit-transform:translate(0,-50%);transform:translate(0,-50%)}.el-progress--circle .el-progress__text i{vertical-align:middle;display:inline-block}.el-progress--without-text .el-progress__text{display:none}.el-progress--without-text .el-progress-bar{padding-right:0;margin-right:0;display:block}.el-progress-bar,.el-progress-bar__inner::after,.el-progress-bar__innerText,.el-spinner{display:inline-block;vertical-align:middle}.el-progress--text-inside .el-progress-bar{padding-right:0;margin-right:0}.el-progress.is-success .el-progress-bar__inner{background-color:#67C23A}.el-progress.is-success .el-progress__text{color:#67C23A}.el-progress.is-exception .el-progress-bar__inner{background-color:#F56C6C}.el-progress.is-exception .el-progress__text{color:#F56C6C}.el-progress-bar{padding-right:50px;width:100%;margin-right:-55px;-webkit-box-sizing:border-box;box-sizing:border-box}.el-progress-bar__outer{height:6px;border-radius:100px;background-color:#EBEEF5;overflow:hidden;position:relative;vertical-align:middle}.el-progress-bar__inner{position:absolute;left:0;top:0;height:100%;background-color:#409EFF;text-align:right;border-radius:100px;line-height:1;white-space:nowrap;-webkit-transition:width .6s ease;transition:width .6s ease}.el-card,.el-message{border-radius:4px;overflow:hidden}.el-progress-bar__inner::after{height:100%}.el-progress-bar__innerText{color:#FFF;font-size:12px;margin:0 5px}@keyframes progress{0%{background-position:0 0}100%{background-position:32px 0}}.el-time-spinner{width:100%;white-space:nowrap}.el-spinner-inner{-webkit-animation:rotate 2s linear infinite;animation:rotate 2s linear infinite;width:50px;height:50px}.el-spinner-inner .path{stroke:#ececec;stroke-linecap:round;-webkit-animation:dash 1.5s ease-in-out infinite;animation:dash 1.5s ease-in-out infinite}@-webkit-keyframes rotate{100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes rotate{100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@-webkit-keyframes dash{0%{stroke-dasharray:1,150;stroke-dashoffset:0}50%{stroke-dasharray:90,150;stroke-dashoffset:-35}100%{stroke-dasharray:90,150;stroke-dashoffset:-124}}@keyframes dash{0%{stroke-dasharray:1,150;stroke-dashoffset:0}50%{stroke-dasharray:90,150;stroke-dashoffset:-35}100%{stroke-dasharray:90,150;stroke-dashoffset:-124}}.el-message{min-width:380px;-webkit-box-sizing:border-box;box-sizing:border-box;border-width:1px;border-style:solid;border-color:#EBEEF5;position:fixed;left:50%;top:20px;-webkit-transform:translateX(-50%);transform:translateX(-50%);background-color:#edf2fc;-webkit-transition:opacity .3s,-webkit-transform .4s;transition:opacity .3s,-webkit-transform .4s;transition:opacity .3s,transform .4s;transition:opacity .3s,transform .4s,-webkit-transform .4s;padding:15px 15px 15px 20px;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.el-message.is-center{-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.el-message.is-closable .el-message__content{padding-right:16px}.el-message p{margin:0}.el-message--info .el-message__content{color:#909399}.el-message--success{background-color:#f0f9eb;border-color:#e1f3d8}.el-message--success .el-message__content{color:#67C23A}.el-message--warning{background-color:#fdf6ec;border-color:#faecd8}.el-message--warning .el-message__content{color:#E6A23C}.el-message--error{background-color:#fef0f0;border-color:#fde2e2}.el-message--error .el-message__content{color:#F56C6C}.el-message__icon{margin-right:10px}.el-message__content{padding:0;font-size:14px;line-height:1}.el-message__closeBtn{position:absolute;top:50%;right:15px;-webkit-transform:translateY(-50%);transform:translateY(-50%);cursor:pointer;color:#C0C4CC;font-size:16px}.el-message__closeBtn:hover{color:#909399}.el-message .el-icon-success{color:#67C23A}.el-message .el-icon-error{color:#F56C6C}.el-message .el-icon-info{color:#909399}.el-message .el-icon-warning{color:#E6A23C}.el-message-fade-enter,.el-message-fade-leave-active{opacity:0;-webkit-transform:translate(-50%,-100%);transform:translate(-50%,-100%)}.el-badge{position:relative;vertical-align:middle;display:inline-block}.el-badge__content{background-color:#F56C6C;border-radius:10px;color:#FFF;display:inline-block;font-size:12px;height:18px;line-height:18px;padding:0 6px;text-align:center;white-space:nowrap;border:1px solid #FFF}.el-badge__content.is-fixed{position:absolute;top:0;right:10px;-webkit-transform:translateY(-50%) translateX(100%);transform:translateY(-50%) translateX(100%)}.el-rate__icon,.el-rate__item{position:relative;display:inline-block}.el-badge__content.is-fixed.is-dot{right:5px}.el-badge__content.is-dot{height:8px;width:8px;padding:0;right:0;border-radius:50%}.el-badge__content--primary{background-color:#409EFF}.el-badge__content--success{background-color:#67C23A}.el-badge__content--warning{background-color:#E6A23C}.el-badge__content--info{background-color:#909399}.el-badge__content--danger{background-color:#F56C6C}.el-card{border:1px solid #EBEEF5;background-color:#FFF;color:#303133;-webkit-transition:.3s;transition:.3s}.el-card.is-always-shadow,.el-card.is-hover-shadow:focus,.el-card.is-hover-shadow:hover{-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);box-shadow:0 2px 12px 0 rgba(0,0,0,.1)}.el-card__header{padding:18px 20px;border-bottom:1px solid #EBEEF5;-webkit-box-sizing:border-box;box-sizing:border-box}.el-card__body{padding:20px}.el-rate{height:20px;line-height:1}.el-rate__item{font-size:0;vertical-align:middle}.el-rate__icon{font-size:18px;margin-right:6px;color:#C0C4CC;-webkit-transition:.3s;transition:.3s}.el-rate__decimal,.el-rate__icon .path2{position:absolute;top:0;left:0}.el-rate__icon.hover{-webkit-transform:scale(1.15);transform:scale(1.15)}.el-rate__decimal{display:inline-block;overflow:hidden}.el-step.is-vertical,.el-steps{display:-webkit-box;display:-ms-flexbox}.el-rate__text{font-size:14px;vertical-align:middle}.el-steps{display:flex}.el-steps--simple{padding:13px 8%;border-radius:4px;background:#F5F7FA}.el-steps--horizontal{white-space:nowrap}.el-steps--vertical{height:100%;-webkit-box-orient:vertical;-ms-flex-flow:column;flex-flow:column}.el-step{position:relative;-ms-flex-negative:1;flex-shrink:1}.el-step:last-of-type .el-step__line{display:none}.el-step:last-of-type.is-flex{-ms-flex-preferred-size:auto!important;flex-basis:auto!important;-ms-flex-negative:0;flex-shrink:0;-webkit-box-flex:0;-ms-flex-positive:0;flex-grow:0}.el-step:last-of-type .el-step__description,.el-step:last-of-type .el-step__main{padding-right:0}.el-step__head{position:relative;width:100%}.el-step__head.is-process{color:#303133;border-color:#303133}.el-step__head.is-wait{color:#C0C4CC;border-color:#C0C4CC}.el-step__head.is-success{color:#67C23A;border-color:#67C23A}.el-step__head.is-error{color:#F56C6C;border-color:#F56C6C}.el-step__head.is-finish{color:#409EFF;border-color:#409EFF}.el-step__icon{position:relative;z-index:1;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;width:24px;height:24px;font-size:14px;-webkit-box-sizing:border-box;box-sizing:border-box;background:#FFF;-webkit-transition:.15s ease-out;transition:.15s ease-out}.el-step__icon.is-text{border-radius:50%;border:2px solid;border-color:inherit}.el-step__icon.is-icon{width:40px}.el-step__icon-inner{display:inline-block;-ms-user-select:none;user-select:none;text-align:center;font-weight:700;line-height:1;color:inherit}.el-step__icon-inner[class*=el-icon]:not(.is-status){font-size:25px;font-weight:400}.el-step__icon-inner.is-status{-webkit-transform:translateY(1px);transform:translateY(1px)}.el-step__line{position:absolute;border-color:inherit;background-color:#C0C4CC}.el-step__line-inner{display:block;border-width:1px;border-style:solid;border-color:inherit;-webkit-transition:.15s ease-out;transition:.15s ease-out;-webkit-box-sizing:border-box;box-sizing:border-box;width:0;height:0}.el-step__main{white-space:normal;text-align:left}.el-step__title{font-size:16px;line-height:38px}.el-step__title.is-process{font-weight:700;color:#303133}.el-step__title.is-wait{color:#C0C4CC}.el-step__title.is-success{color:#67C23A}.el-step__title.is-error{color:#F56C6C}.el-step__title.is-finish{color:#409EFF}.el-step__description{padding-right:10%;margin-top:-5px;font-size:12px;line-height:20px;font-weight:400}.el-step__description.is-process{color:#303133}.el-step__description.is-wait{color:#C0C4CC}.el-step__description.is-success{color:#67C23A}.el-step__description.is-error{color:#F56C6C}.el-step__description.is-finish{color:#409EFF}.el-step.is-horizontal{display:inline-block}.el-step.is-horizontal .el-step__line{height:2px;top:11px;left:0;right:0}.el-step.is-vertical{display:flex}.el-step.is-vertical .el-step__head{-webkit-box-flex:0;-ms-flex-positive:0;flex-grow:0;width:24px}.el-step.is-vertical .el-step__main{padding-left:10px;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1}.el-step.is-vertical .el-step__title{line-height:24px;padding-bottom:8px}.el-step.is-vertical .el-step__line{width:2px;top:0;bottom:0;left:11px}.el-step.is-vertical .el-step__icon.is-icon{width:24px}.el-step.is-center .el-step__head,.el-step.is-center .el-step__main{text-align:center}.el-step.is-center .el-step__description{padding-left:20%;padding-right:20%}.el-step.is-center .el-step__line{left:50%;right:-50%}.el-step.is-simple{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.el-step.is-simple .el-step__head{width:auto;font-size:0;padding-right:10px}.el-step.is-simple .el-step__icon{background:0 0;width:16px;height:16px;font-size:12px}.el-step.is-simple .el-step__icon-inner[class*=el-icon]:not(.is-status){font-size:18px}.el-step.is-simple .el-step__icon-inner.is-status{-webkit-transform:scale(.8) translateY(1px);transform:scale(.8) translateY(1px)}.el-step.is-simple .el-step__main{position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:stretch;-ms-flex-align:stretch;align-items:stretch;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1}.el-step.is-simple .el-step__title{font-size:16px;line-height:20px}.el-step.is-simple:not(:last-of-type) .el-step__title{max-width:50%;word-break:break-all}.el-step.is-simple .el-step__arrow{-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.el-step.is-simple .el-step__arrow::after,.el-step.is-simple .el-step__arrow::before{content:'';display:inline-block;position:absolute;height:15px;width:1px;background:#C0C4CC}.el-step.is-simple .el-step__arrow::before{-webkit-transform:rotate(-45deg) translateY(-4px);transform:rotate(-45deg) translateY(-4px);-webkit-transform-origin:0 0;transform-origin:0 0}.el-step.is-simple .el-step__arrow::after{-webkit-transform:rotate(45deg) translateY(4px);transform:rotate(45deg) translateY(4px);-webkit-transform-origin:100% 100%;transform-origin:100% 100%}.el-step.is-simple:last-of-type .el-step__arrow{display:none}.el-carousel{position:relative}.el-carousel--horizontal{overflow-x:hidden}.el-carousel--vertical{overflow-y:hidden}.el-carousel__container{position:relative;height:300px}.el-carousel__arrow{border:none;outline:0;padding:0;margin:0;height:36px;width:36px;cursor:pointer;-webkit-transition:.3s;transition:.3s;border-radius:50%;background-color:rgba(31,45,61,.11);color:#FFF;position:absolute;top:50%;z-index:10;-webkit-transform:translateY(-50%);transform:translateY(-50%);text-align:center;font-size:12px}.el-carousel__arrow--left{left:16px}.el-carousel__arrow--right{right:16px}.el-carousel__arrow:hover{background-color:rgba(31,45,61,.23)}.el-carousel__arrow i{cursor:pointer}.el-carousel__indicators{position:absolute;list-style:none;margin:0;padding:0;z-index:2}.el-carousel__indicators--horizontal{bottom:0;left:50%;-webkit-transform:translateX(-50%);transform:translateX(-50%)}.el-carousel__indicators--vertical{right:0;top:50%;-webkit-transform:translateY(-50%);transform:translateY(-50%)}.el-carousel__indicators--outside{bottom:26px;text-align:center;position:static;-webkit-transform:none;transform:none}.el-carousel__indicators--outside .el-carousel__indicator:hover button{opacity:.64}.el-carousel__indicators--outside button{background-color:#C0C4CC;opacity:.24}.el-carousel__indicators--labels{left:0;right:0;-webkit-transform:none;transform:none;text-align:center}.el-carousel__indicators--labels .el-carousel__button{height:auto;width:auto;padding:2px 18px;font-size:12px}.el-carousel__indicators--labels .el-carousel__indicator{padding:6px 4px}.el-carousel__indicator{background-color:transparent;cursor:pointer}.el-carousel__indicator:hover button{opacity:.72}.el-carousel__indicator--horizontal{display:inline-block;padding:12px 4px}.el-carousel__indicator--vertical{padding:4px 12px}.el-carousel__indicator--vertical .el-carousel__button{width:2px;height:15px}.el-carousel__indicator.is-active button{opacity:1}.el-carousel__button{display:block;opacity:.48;width:30px;height:2px;background-color:#FFF;border:none;outline:0;padding:0;margin:0;cursor:pointer;-webkit-transition:.3s;transition:.3s}.carousel-arrow-left-enter,.carousel-arrow-left-leave-active{-webkit-transform:translateY(-50%) translateX(-10px);transform:translateY(-50%) translateX(-10px);opacity:0}.carousel-arrow-right-enter,.carousel-arrow-right-leave-active{-webkit-transform:translateY(-50%) translateX(10px);transform:translateY(-50%) translateX(10px);opacity:0}.el-scrollbar{overflow:hidden;position:relative}.el-scrollbar:active>.el-scrollbar__bar,.el-scrollbar:focus>.el-scrollbar__bar,.el-scrollbar:hover>.el-scrollbar__bar{opacity:1;-webkit-transition:opacity 340ms ease-out;transition:opacity 340ms ease-out}.el-scrollbar__wrap{overflow:scroll;height:100%}.el-scrollbar__wrap--hidden-default::-webkit-scrollbar{width:0;height:0}.el-scrollbar__thumb{position:relative;display:block;width:0;height:0;cursor:pointer;border-radius:inherit;background-color:rgba(144,147,153,.3);-webkit-transition:.3s background-color;transition:.3s background-color}.el-scrollbar__thumb:hover{background-color:rgba(144,147,153,.5)}.el-scrollbar__bar{position:absolute;right:2px;bottom:2px;z-index:1;border-radius:4px;opacity:0;-webkit-transition:opacity 120ms ease-out;transition:opacity 120ms ease-out}.el-scrollbar__bar.is-vertical{width:6px;top:2px}.el-scrollbar__bar.is-vertical>div{width:100%}.el-scrollbar__bar.is-horizontal{height:6px;left:2px}.el-carousel__item,.el-carousel__mask{height:100%;top:0;left:0;position:absolute}.el-scrollbar__bar.is-horizontal>div{height:100%}.el-carousel__item{width:100%;display:inline-block;overflow:hidden;z-index:0}.el-carousel__item.is-active{z-index:2}.el-carousel__item.is-animating{-webkit-transition:-webkit-transform .4s ease-in-out;transition:-webkit-transform .4s ease-in-out;transition:transform .4s ease-in-out;transition:transform .4s ease-in-out,-webkit-transform .4s ease-in-out}.el-carousel__item--card{width:50%;-webkit-transition:-webkit-transform .4s ease-in-out;transition:-webkit-transform .4s ease-in-out;transition:transform .4s ease-in-out;transition:transform .4s ease-in-out,-webkit-transform .4s ease-in-out}.el-carousel__item--card.is-in-stage{cursor:pointer;z-index:1}.el-carousel__item--card.is-in-stage.is-hover .el-carousel__mask,.el-carousel__item--card.is-in-stage:hover .el-carousel__mask{opacity:.12}.el-carousel__item--card.is-active{z-index:2}.el-carousel__mask{width:100%;background-color:#FFF;opacity:.24;-webkit-transition:.2s;transition:.2s}.el-fade-in-enter,.el-fade-in-leave-active,.el-fade-in-linear-enter,.el-fade-in-linear-leave,.el-fade-in-linear-leave-active,.fade-in-linear-enter,.fade-in-linear-leave,.fade-in-linear-leave-active{opacity:0}.fade-in-linear-enter-active,.fade-in-linear-leave-active{-webkit-transition:opacity .2s linear;transition:opacity .2s linear}.el-fade-in-linear-enter-active,.el-fade-in-linear-leave-active{-webkit-transition:opacity .2s linear;transition:opacity .2s linear}.el-fade-in-enter-active,.el-fade-in-leave-active{-webkit-transition:all .3s cubic-bezier(.55,0,.1,1);transition:all .3s cubic-bezier(.55,0,.1,1)}.el-zoom-in-center-enter-active,.el-zoom-in-center-leave-active{-webkit-transition:all .3s cubic-bezier(.55,0,.1,1);transition:all .3s cubic-bezier(.55,0,.1,1)}.el-zoom-in-center-enter,.el-zoom-in-center-leave-active{opacity:0;-webkit-transform:scaleX(0);transform:scaleX(0)}.el-zoom-in-top-enter-active,.el-zoom-in-top-leave-active{opacity:1;-webkit-transform:scaleY(1);transform:scaleY(1);-webkit-transition:opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);transition:opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);transition:transform .3s cubic-bezier(.23,1,.32,1),opacity .3s cubic-bezier(.23,1,.32,1);transition:transform .3s cubic-bezier(.23,1,.32,1),opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);-webkit-transform-origin:center top;transform-origin:center top}.el-zoom-in-top-enter,.el-zoom-in-top-leave-active{opacity:0;-webkit-transform:scaleY(0);transform:scaleY(0)}.el-zoom-in-bottom-enter-active,.el-zoom-in-bottom-leave-active{opacity:1;-webkit-transform:scaleY(1);transform:scaleY(1);-webkit-transition:opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);transition:opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);transition:transform .3s cubic-bezier(.23,1,.32,1),opacity .3s cubic-bezier(.23,1,.32,1);transition:transform .3s cubic-bezier(.23,1,.32,1),opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);-webkit-transform-origin:center bottom;transform-origin:center bottom}.el-zoom-in-bottom-enter,.el-zoom-in-bottom-leave-active{opacity:0;-webkit-transform:scaleY(0);transform:scaleY(0)}.el-zoom-in-left-enter-active,.el-zoom-in-left-leave-active{opacity:1;-webkit-transform:scale(1,1);transform:scale(1,1);-webkit-transition:opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);transition:opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);transition:transform .3s cubic-bezier(.23,1,.32,1),opacity .3s cubic-bezier(.23,1,.32,1);transition:transform .3s cubic-bezier(.23,1,.32,1),opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);-webkit-transform-origin:top left;transform-origin:top left}.el-zoom-in-left-enter,.el-zoom-in-left-leave-active{opacity:0;-webkit-transform:scale(.45,.45);transform:scale(.45,.45)}.collapse-transition{-webkit-transition:.3s height ease-in-out,.3s padding-top ease-in-out,.3s padding-bottom ease-in-out;transition:.3s height ease-in-out,.3s padding-top ease-in-out,.3s padding-bottom ease-in-out}.horizontal-collapse-transition{-webkit-transition:.3s width ease-in-out,.3s padding-left ease-in-out,.3s padding-right ease-in-out;transition:.3s width ease-in-out,.3s padding-left ease-in-out,.3s padding-right ease-in-out}.el-list-enter-active,.el-list-leave-active{-webkit-transition:all 1s;transition:all 1s}.el-list-enter,.el-list-leave-active{opacity:0;-webkit-transform:translateY(-30px);transform:translateY(-30px)}.el-opacity-transition{-webkit-transition:opacity .3s cubic-bezier(.55,0,.1,1);transition:opacity .3s cubic-bezier(.55,0,.1,1)}.el-collapse{border-top:1px solid #EBEEF5;border-bottom:1px solid #EBEEF5}.el-collapse-item.is-disabled .el-collapse-item__header{color:#bbb;cursor:not-allowed}.el-collapse-item__header{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;height:48px;line-height:48px;background-color:#FFF;color:#303133;cursor:pointer;border-bottom:1px solid #EBEEF5;font-size:13px;font-weight:500;-webkit-transition:border-bottom-color .3s;transition:border-bottom-color .3s;outline:0}.el-collapse-item__arrow{margin:0 8px 0 auto;-webkit-transition:-webkit-transform .3s;transition:-webkit-transform .3s;transition:transform .3s;transition:transform .3s,-webkit-transform .3s;font-weight:300}.el-collapse-item__arrow.is-active{-webkit-transform:rotate(90deg);transform:rotate(90deg)}.el-collapse-item__header.focusing:focus:not(:hover){color:#409EFF}.el-collapse-item__header.is-active{border-bottom-color:transparent}.el-collapse-item__wrap{will-change:height;background-color:#FFF;overflow:hidden;-webkit-box-sizing:border-box;box-sizing:border-box;border-bottom:1px solid #EBEEF5}.el-collapse-item__content{padding-bottom:25px;font-size:13px;color:#303133;line-height:1.769230769230769}.el-collapse-item:last-child{margin-bottom:-1px}.el-popper .popper__arrow,.el-popper .popper__arrow::after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.el-popper .popper__arrow{border-width:6px;-webkit-filter:drop-shadow(0 2px 12px rgba(0, 0, 0, .03));filter:drop-shadow(0 2px 12px rgba(0, 0, 0, .03))}.el-popper .popper__arrow::after{content:" ";border-width:6px}.el-popper[x-placement^=top]{margin-bottom:12px}.el-popper[x-placement^=top] .popper__arrow{bottom:-6px;left:50%;margin-right:3px;border-top-color:#EBEEF5;border-bottom-width:0}.el-popper[x-placement^=top] .popper__arrow::after{bottom:1px;margin-left:-6px;border-top-color:#FFF;border-bottom-width:0}.el-popper[x-placement^=bottom]{margin-top:12px}.el-popper[x-placement^=bottom] .popper__arrow{top:-6px;left:50%;margin-right:3px;border-top-width:0;border-bottom-color:#EBEEF5}.el-popper[x-placement^=bottom] .popper__arrow::after{top:1px;margin-left:-6px;border-top-width:0;border-bottom-color:#FFF}.el-popper[x-placement^=right]{margin-left:12px}.el-popper[x-placement^=right] .popper__arrow{top:50%;left:-6px;margin-bottom:3px;border-right-color:#EBEEF5;border-left-width:0}.el-popper[x-placement^=right] .popper__arrow::after{bottom:-6px;left:1px;border-right-color:#FFF;border-left-width:0}.el-popper[x-placement^=left]{margin-right:12px}.el-popper[x-placement^=left] .popper__arrow{top:50%;right:-6px;margin-bottom:3px;border-right-width:0;border-left-color:#EBEEF5}.el-popper[x-placement^=left] .popper__arrow::after{right:1px;bottom:-6px;margin-left:-6px;border-right-width:0;border-left-color:#FFF}.el-cascader{display:inline-block;position:relative;font-size:14px;line-height:40px}.el-cascader .el-input,.el-cascader .el-input__inner{cursor:pointer}.el-cascader .el-input.is-focus .el-input__inner{border-color:#409EFF}.el-cascader .el-input__icon{-webkit-transition:none;transition:none}.el-cascader .el-icon-arrow-down{-webkit-transition:-webkit-transform .3s;transition:-webkit-transform .3s;transition:transform .3s;transition:transform .3s,-webkit-transform .3s;font-size:14px}.el-cascader .el-icon-arrow-down.is-reverse{-webkit-transform:rotateZ(180deg);transform:rotateZ(180deg)}.el-cascader .el-icon-circle-close{z-index:2;-webkit-transition:color .2s cubic-bezier(.645,.045,.355,1);transition:color .2s cubic-bezier(.645,.045,.355,1)}.el-cascader .el-icon-circle-close:hover{color:#909399}.el-cascader__clearIcon{z-index:2;position:relative}.el-cascader__label{position:absolute;left:0;top:0;height:100%;padding:0 25px 0 15px;color:#606266;width:100%;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;-webkit-box-sizing:border-box;box-sizing:border-box;cursor:pointer;text-align:left;font-size:inherit}.el-cascader__label span{color:#000}.el-cascader--medium{font-size:14px;line-height:36px}.el-cascader--small{font-size:13px;line-height:32px}.el-cascader--mini{font-size:12px;line-height:28px}.el-cascader.is-disabled .el-cascader__label{z-index:2;color:#C0C4CC}.el-cascader-menus{white-space:nowrap;background:#fff;position:absolute;margin:5px 0;z-index:2;border:1px solid #E4E7ED;border-radius:2px;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);box-shadow:0 2px 12px 0 rgba(0,0,0,.1)}.el-cascader-menu,.el-cascader-menu__item.is-disabled:hover{background-color:#FFF}.el-cascader-menu{display:inline-block;vertical-align:top;height:204px;overflow:auto;border-right:solid 1px #E4E7ED;-webkit-box-sizing:border-box;box-sizing:border-box;margin:0;padding:6px 0;min-width:160px}.el-cascader-menu:last-child{border-right:0}.el-cascader-menu__item{font-size:14px;padding:8px 20px;position:relative;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:#606266;height:34px;line-height:1.5;-webkit-box-sizing:border-box;box-sizing:border-box;cursor:pointer;outline:0}.el-cascader-menu__item span{padding-right:10px}.el-cascader-menu__item--extensible:after{font-family:element-icons;content:"\e6e0";font-size:14px;color:#bfcbd9;position:absolute;right:15px}.el-cascader-menu__item.is-disabled{color:#C0C4CC;background-color:#FFF;cursor:not-allowed}.el-cascader-menu__item.is-active{color:#409EFF}.el-cascader-menu__item:focus:not(:active),.el-cascader-menu__item:hover{background-color:#F5F7FA}.el-cascader-menu__item.selected{color:#FFF;background-color:#F5F7FA}.el-cascader-menu__item__keyword{font-weight:700}.el-cascader-menu--flexible{height:auto;max-height:180px;overflow:auto}.el-cascader-menu--flexible .el-cascader-menu__item{overflow:visible}.el-color-predefine{display:-webkit-box;display:-ms-flexbox;display:flex;font-size:12px;margin-top:8px;width:280px}.el-color-predefine__colors{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-flex:1;-ms-flex:1;flex:1;-ms-flex-wrap:wrap;flex-wrap:wrap}.el-color-predefine__color-selector{margin:0 0 8px 8px;width:20px;height:20px;border-radius:4px;cursor:pointer}.el-color-predefine__color-selector:nth-child(10n+1){margin-left:0}.el-color-predefine__color-selector.selected{-webkit-box-shadow:0 0 3px 2px #409EFF;box-shadow:0 0 3px 2px #409EFF}.el-color-predefine__color-selector>div{display:-webkit-box;display:-ms-flexbox;display:flex;height:100%;border-radius:3px}.el-color-predefine__color-selector.is-alpha{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==)}.el-color-hue-slider{position:relative;-webkit-box-sizing:border-box;box-sizing:border-box;width:280px;height:12px;background-color:red;padding:0 2px}.el-color-hue-slider__bar{position:relative;background:-webkit-gradient(linear,left top,right top,from(red),color-stop(17%,#ff0),color-stop(33%,#0f0),color-stop(50%,#0ff),color-stop(67%,#00f),color-stop(83%,#f0f),to(red));background:linear-gradient(to right,red 0,#ff0 17%,#0f0 33%,#0ff 50%,#00f 67%,#f0f 83%,red 100%);height:100%}.el-color-hue-slider__thumb{position:absolute;cursor:pointer;-webkit-box-sizing:border-box;box-sizing:border-box;left:0;top:0;width:4px;height:100%;border-radius:1px;background:#fff;border:1px solid #f0f0f0;-webkit-box-shadow:0 0 2px rgba(0,0,0,.6);box-shadow:0 0 2px rgba(0,0,0,.6);z-index:1}.el-color-hue-slider.is-vertical{width:12px;height:180px;padding:2px 0}.el-color-hue-slider.is-vertical .el-color-hue-slider__bar{background:-webkit-gradient(linear,left top,left bottom,from(red),color-stop(17%,#ff0),color-stop(33%,#0f0),color-stop(50%,#0ff),color-stop(67%,#00f),color-stop(83%,#f0f),to(red));background:linear-gradient(to bottom,red 0,#ff0 17%,#0f0 33%,#0ff 50%,#00f 67%,#f0f 83%,red 100%)}.el-color-hue-slider.is-vertical .el-color-hue-slider__thumb{left:0;top:0;width:100%;height:4px}.el-color-svpanel{position:relative;width:280px;height:180px}.el-color-svpanel__black,.el-color-svpanel__white{position:absolute;top:0;left:0;right:0;bottom:0}.el-color-svpanel__white{background:-webkit-gradient(linear,left top,right top,from(#fff),to(rgba(255,255,255,0)));background:linear-gradient(to right,#fff,rgba(255,255,255,0))}.el-color-svpanel__black{background:-webkit-gradient(linear,left bottom,left top,from(#000),to(rgba(0,0,0,0)));background:linear-gradient(to top,#000,rgba(0,0,0,0))}.el-color-svpanel__cursor{position:absolute}.el-color-svpanel__cursor>div{cursor:head;width:4px;height:4px;-webkit-box-shadow:0 0 0 1.5px #fff,inset 0 0 1px 1px rgba(0,0,0,.3),0 0 1px 2px rgba(0,0,0,.4);box-shadow:0 0 0 1.5px #fff,inset 0 0 1px 1px rgba(0,0,0,.3),0 0 1px 2px rgba(0,0,0,.4);border-radius:50%;-webkit-transform:translate(-2px,-2px);transform:translate(-2px,-2px)}.el-color-alpha-slider{position:relative;-webkit-box-sizing:border-box;box-sizing:border-box;width:280px;height:12px;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==)}.el-color-alpha-slider__bar{position:relative;background:-webkit-gradient(linear,left top,right top,from(rgba(255,255,255,0)),to(white));background:linear-gradient(to right,rgba(255,255,255,0) 0,#fff 100%);height:100%}.el-color-alpha-slider__thumb{position:absolute;cursor:pointer;-webkit-box-sizing:border-box;box-sizing:border-box;left:0;top:0;width:4px;height:100%;border-radius:1px;background:#fff;border:1px solid #f0f0f0;-webkit-box-shadow:0 0 2px rgba(0,0,0,.6);box-shadow:0 0 2px rgba(0,0,0,.6);z-index:1}.el-color-alpha-slider.is-vertical{width:20px;height:180px}.el-color-alpha-slider.is-vertical .el-color-alpha-slider__bar{background:-webkit-gradient(linear,left top,left bottom,from(rgba(255,255,255,0)),to(white));background:linear-gradient(to bottom,rgba(255,255,255,0) 0,#fff 100%)}.el-color-alpha-slider.is-vertical .el-color-alpha-slider__thumb{left:0;top:0;width:100%;height:4px}.el-color-dropdown{width:300px}.el-color-dropdown__main-wrapper{margin-bottom:6px}.el-color-dropdown__main-wrapper::after{content:"";display:table;clear:both}.el-color-dropdown__btns{margin-top:6px;text-align:right}.el-color-dropdown__value{float:left;line-height:26px;font-size:12px;color:#000;width:160px}.el-color-dropdown__btn{border:1px solid #dcdcdc;color:#333;line-height:24px;border-radius:2px;padding:0 20px;cursor:pointer;background-color:transparent;outline:0;font-size:12px}.el-color-dropdown__btn[disabled]{color:#ccc;cursor:not-allowed}.el-color-dropdown__btn:hover{color:#409EFF;border-color:#409EFF}.el-color-dropdown__link-btn{cursor:pointer;color:#409EFF;text-decoration:none;padding:15px;font-size:12px}.el-color-dropdown__link-btn:hover{color:tint(#409EFF,20%)}.el-color-picker{display:inline-block;position:relative;line-height:normal;height:40px}.el-color-picker.is-disabled .el-color-picker__trigger{cursor:not-allowed}.el-color-picker--medium{height:36px}.el-color-picker--medium .el-color-picker__trigger{height:36px;width:36px}.el-color-picker--medium .el-color-picker__mask{height:34px;width:34px}.el-color-picker--small{height:32px}.el-color-picker--small .el-color-picker__trigger{height:32px;width:32px}.el-color-picker--small .el-color-picker__mask{height:30px;width:30px}.el-color-picker--small .el-color-picker__empty,.el-color-picker--small .el-color-picker__icon{-webkit-transform:translate3d(-50%,-50%,0) scale(.8);transform:translate3d(-50%,-50%,0) scale(.8)}.el-color-picker--mini{height:28px}.el-color-picker--mini .el-color-picker__trigger{height:28px;width:28px}.el-color-picker--mini .el-color-picker__mask{height:26px;width:26px}.el-color-picker--mini .el-color-picker__empty,.el-color-picker--mini .el-color-picker__icon{-webkit-transform:translate3d(-50%,-50%,0) scale(.8);transform:translate3d(-50%,-50%,0) scale(.8)}.el-color-picker__mask{height:38px;width:38px;border-radius:4px;position:absolute;top:1px;left:1px;z-index:1;cursor:not-allowed;background-color:rgba(255,255,255,.7)}.el-color-picker__trigger{display:inline-block;-webkit-box-sizing:border-box;box-sizing:border-box;height:40px;width:40px;padding:4px;border:1px solid #e6e6e6;border-radius:4px;font-size:0;position:relative;cursor:pointer}.el-color-picker__color{position:relative;display:block;-webkit-box-sizing:border-box;box-sizing:border-box;border:1px solid #999;border-radius:2px;width:100%;height:100%;text-align:center}.el-color-picker__color.is-alpha{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==)}.el-color-picker__color-inner{position:absolute;left:0;top:0;right:0;bottom:0}.el-color-picker__empty,.el-color-picker__icon{top:50%;left:50%;font-size:12px;position:absolute}.el-color-picker__empty{color:#999;-webkit-transform:translate3d(-50%,-50%,0);transform:translate3d(-50%,-50%,0)}.el-color-picker__icon{display:inline-block;width:100%;-webkit-transform:translate3d(-50%,-50%,0);transform:translate3d(-50%,-50%,0);color:#FFF;text-align:center}.el-color-picker__panel{position:absolute;z-index:10;padding:6px;-webkit-box-sizing:content-box;box-sizing:content-box;background-color:#FFF;border:1px solid #EBEEF5;border-radius:4px;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);box-shadow:0 2px 12px 0 rgba(0,0,0,.1)}.el-textarea{position:relative;display:inline-block;width:100%;vertical-align:bottom;font-size:14px}.el-textarea__inner{display:block;resize:vertical;padding:5px 15px;line-height:1.5;-webkit-box-sizing:border-box;box-sizing:border-box;width:100%;font-size:inherit;color:#606266;background-color:#FFF;background-image:none;border:1px solid #DCDFE6;border-radius:4px;-webkit-transition:border-color .2s cubic-bezier(.645,.045,.355,1);transition:border-color .2s cubic-bezier(.645,.045,.355,1)}.el-textarea__inner::-webkit-input-placeholder{color:#C0C4CC}.el-textarea__inner:-ms-input-placeholder{color:#C0C4CC}.el-textarea__inner::-ms-input-placeholder{color:#C0C4CC}.el-textarea__inner::placeholder{color:#C0C4CC}.el-textarea__inner:hover{border-color:#C0C4CC}.el-textarea__inner:focus{outline:0;border-color:#409EFF}.el-textarea .el-input__count{color:#909399;background:#FFF;position:absolute;font-size:12px;bottom:5px;right:10px}.el-textarea.is-disabled .el-textarea__inner{background-color:#F5F7FA;border-color:#E4E7ED;color:#C0C4CC;cursor:not-allowed}.el-textarea.is-disabled .el-textarea__inner::-webkit-input-placeholder{color:#C0C4CC}.el-textarea.is-disabled .el-textarea__inner:-ms-input-placeholder{color:#C0C4CC}.el-textarea.is-disabled .el-textarea__inner::-ms-input-placeholder{color:#C0C4CC}.el-textarea.is-disabled .el-textarea__inner::placeholder{color:#C0C4CC}.el-textarea.is-exceed .el-textarea__inner{border-color:#F56C6C}.el-textarea.is-exceed .el-input__count{color:#F56C6C}.el-input{position:relative;font-size:14px;display:inline-block;width:100%}.el-input::-webkit-scrollbar{z-index:11;width:6px}.el-button-group>.el-button.is-active,.el-button-group>.el-button.is-disabled,.el-button-group>.el-button:active,.el-button-group>.el-button:focus,.el-button-group>.el-button:hover{z-index:1}.el-input::-webkit-scrollbar:horizontal{height:6px}.el-input::-webkit-scrollbar-thumb{border-radius:5px;width:6px;background:#b4bccc}.el-input::-webkit-scrollbar-corner{background:#fff}.el-input::-webkit-scrollbar-track{background:#fff}.el-input::-webkit-scrollbar-track-piece{background:#fff;width:6px}.el-input .el-input__clear{color:#C0C4CC;font-size:14px;line-height:16px;cursor:pointer;-webkit-transition:color .2s cubic-bezier(.645,.045,.355,1);transition:color .2s cubic-bezier(.645,.045,.355,1)}.el-input .el-input__clear:hover{color:#909399}.el-input .el-input__count{height:100%;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;color:#909399;font-size:12px}.el-input .el-input__count .el-input__count-inner{background:#FFF;display:inline-block;padding:0 5px}.el-input__inner{-webkit-appearance:none;background-color:#FFF;background-image:none;border-radius:4px;border:1px solid #DCDFE6;-webkit-box-sizing:border-box;box-sizing:border-box;color:#606266;display:inline-block;font-size:inherit;height:40px;line-height:40px;outline:0;padding:0 15px;-webkit-transition:border-color .2s cubic-bezier(.645,.045,.355,1);transition:border-color .2s cubic-bezier(.645,.045,.355,1);width:100%}.el-input__prefix,.el-input__suffix{position:absolute;top:0;-webkit-transition:all .3s;height:100%;color:#C0C4CC;text-align:center}.el-input__inner::-webkit-input-placeholder{color:#C0C4CC}.el-input__inner:-ms-input-placeholder{color:#C0C4CC}.el-input__inner::-ms-input-placeholder{color:#C0C4CC}.el-input__inner::placeholder{color:#C0C4CC}.el-input__inner:hover{border-color:#C0C4CC}.el-input.is-active .el-input__inner,.el-input__inner:focus{border-color:#409EFF;outline:0}.el-input__suffix{right:5px;transition:all .3s}.el-input__suffix-inner{pointer-events:all}.el-input__prefix{left:5px;transition:all .3s}.el-input__icon{height:100%;width:25px;text-align:center;-webkit-transition:all .3s;transition:all .3s;line-height:40px}.el-input__icon:after{content:'';height:100%;width:0;display:inline-block;vertical-align:middle}.el-input__validateIcon{pointer-events:none}.el-input.is-disabled .el-input__inner{background-color:#F5F7FA;border-color:#E4E7ED;color:#C0C4CC;cursor:not-allowed}.el-input.is-disabled .el-input__inner::-webkit-input-placeholder{color:#C0C4CC}.el-input.is-disabled .el-input__inner:-ms-input-placeholder{color:#C0C4CC}.el-input.is-disabled .el-input__inner::-ms-input-placeholder{color:#C0C4CC}.el-input.is-disabled .el-input__inner::placeholder{color:#C0C4CC}.el-input.is-disabled .el-input__icon{cursor:not-allowed}.el-input.is-exceed .el-input__inner{border-color:#F56C6C}.el-input.is-exceed .el-input__suffix .el-input__count{color:#F56C6C}.el-input--suffix .el-input__inner{padding-right:30px}.el-input--prefix .el-input__inner{padding-left:30px}.el-input--medium{font-size:14px}.el-input--medium .el-input__inner{height:36px;line-height:36px}.el-input--medium .el-input__icon{line-height:36px}.el-input--small{font-size:13px}.el-input--small .el-input__inner{height:32px;line-height:32px}.el-input--small .el-input__icon{line-height:32px}.el-input--mini{font-size:12px}.el-input--mini .el-input__inner{height:28px;line-height:28px}.el-input--mini .el-input__icon{line-height:28px}.el-input-group{line-height:normal;display:inline-table;width:100%;border-collapse:separate;border-spacing:0}.el-input-group>.el-input__inner{vertical-align:middle;display:table-cell}.el-input-group__append,.el-input-group__prepend{background-color:#F5F7FA;color:#909399;vertical-align:middle;display:table-cell;position:relative;border:1px solid #DCDFE6;border-radius:4px;padding:0 20px;width:1px;white-space:nowrap}.el-input-group--prepend .el-input__inner,.el-input-group__append{border-top-left-radius:0;border-bottom-left-radius:0}.el-input-group--append .el-input__inner,.el-input-group__prepend{border-top-right-radius:0;border-bottom-right-radius:0}.el-input-group__append:focus,.el-input-group__prepend:focus{outline:0}.el-input-group__append .el-button,.el-input-group__append .el-select,.el-input-group__prepend .el-button,.el-input-group__prepend .el-select{display:inline-block;margin:-10px -20px}.el-input-group__append button.el-button,.el-input-group__append div.el-select .el-input__inner,.el-input-group__append div.el-select:hover .el-input__inner,.el-input-group__prepend button.el-button,.el-input-group__prepend div.el-select .el-input__inner,.el-input-group__prepend div.el-select:hover .el-input__inner{border-color:transparent;background-color:transparent;color:inherit;border-top:0;border-bottom:0}.el-input-group__append .el-button,.el-input-group__append .el-input,.el-input-group__prepend .el-button,.el-input-group__prepend .el-input{font-size:inherit}.el-input-group__prepend{border-right:0}.el-input-group__append{border-left:0}.el-input-group--append .el-select .el-input.is-focus .el-input__inner,.el-input-group--prepend .el-select .el-input.is-focus .el-input__inner{border-color:transparent}.el-input__inner::-ms-clear{display:none;width:0;height:0}.el-button{display:inline-block;line-height:1;white-space:nowrap;cursor:pointer;background:#FFF;border:1px solid #DCDFE6;color:#606266;-webkit-appearance:none;text-align:center;-webkit-box-sizing:border-box;box-sizing:border-box;outline:0;margin:0;-webkit-transition:.1s;transition:.1s;font-weight:500;-ms-user-select:none;padding:12px 20px;font-size:14px;border-radius:4px}.el-button+.el-button{margin-left:10px}.el-button:focus,.el-button:hover{color:#409EFF;border-color:#c6e2ff;background-color:#ecf5ff}.el-button:active{color:#3a8ee6;border-color:#3a8ee6;outline:0}.el-button::-moz-focus-inner{border:0}.el-button [class*=el-icon-]+span{margin-left:5px}.el-button.is-plain:focus,.el-button.is-plain:hover{background:#FFF;border-color:#409EFF;color:#409EFF}.el-button.is-active,.el-button.is-plain:active{color:#3a8ee6;border-color:#3a8ee6}.el-button.is-plain:active{background:#FFF;outline:0}.el-button.is-disabled,.el-button.is-disabled:focus,.el-button.is-disabled:hover{color:#C0C4CC;cursor:not-allowed;background-image:none;background-color:#FFF;border-color:#EBEEF5}.el-button.is-disabled.el-button--text{background-color:transparent}.el-button.is-disabled.is-plain,.el-button.is-disabled.is-plain:focus,.el-button.is-disabled.is-plain:hover{background-color:#FFF;border-color:#EBEEF5;color:#C0C4CC}.el-button.is-loading{position:relative;pointer-events:none}.el-button.is-loading:before{pointer-events:none;content:'';position:absolute;left:-1px;top:-1px;right:-1px;bottom:-1px;border-radius:inherit;background-color:rgba(255,255,255,.35)}.el-checkbox,.el-checkbox__input{position:relative;display:inline-block}.el-button.is-round{border-radius:20px;padding:12px 23px}.el-button.is-circle{border-radius:50%;padding:12px}.el-button--primary{color:#FFF;background-color:#409EFF;border-color:#409EFF}.el-button--primary:focus,.el-button--primary:hover{background:#66b1ff;border-color:#66b1ff;color:#FFF}.el-button--primary.is-active,.el-button--primary:active{background:#3a8ee6;border-color:#3a8ee6;color:#FFF}.el-button--primary:active{outline:0}.el-button--primary.is-disabled,.el-button--primary.is-disabled:active,.el-button--primary.is-disabled:focus,.el-button--primary.is-disabled:hover{color:#FFF;background-color:#a0cfff;border-color:#a0cfff}.el-button--primary.is-plain{color:#409EFF;background:#ecf5ff;border-color:#b3d8ff}.el-button--primary.is-plain:focus,.el-button--primary.is-plain:hover{background:#409EFF;border-color:#409EFF;color:#FFF}.el-button--primary.is-plain:active{background:#3a8ee6;border-color:#3a8ee6;color:#FFF;outline:0}.el-button--primary.is-plain.is-disabled,.el-button--primary.is-plain.is-disabled:active,.el-button--primary.is-plain.is-disabled:focus,.el-button--primary.is-plain.is-disabled:hover{color:#8cc5ff;background-color:#ecf5ff;border-color:#d9ecff}.el-button--success{color:#FFF;background-color:#67C23A;border-color:#67C23A}.el-button--success:focus,.el-button--success:hover{background:#85ce61;border-color:#85ce61;color:#FFF}.el-button--success.is-active,.el-button--success:active{background:#5daf34;border-color:#5daf34;color:#FFF}.el-button--success:active{outline:0}.el-button--success.is-disabled,.el-button--success.is-disabled:active,.el-button--success.is-disabled:focus,.el-button--success.is-disabled:hover{color:#FFF;background-color:#b3e19d;border-color:#b3e19d}.el-button--success.is-plain{color:#67C23A;background:#f0f9eb;border-color:#c2e7b0}.el-button--success.is-plain:focus,.el-button--success.is-plain:hover{background:#67C23A;border-color:#67C23A;color:#FFF}.el-button--success.is-plain:active{background:#5daf34;border-color:#5daf34;color:#FFF;outline:0}.el-button--success.is-plain.is-disabled,.el-button--success.is-plain.is-disabled:active,.el-button--success.is-plain.is-disabled:focus,.el-button--success.is-plain.is-disabled:hover{color:#a4da89;background-color:#f0f9eb;border-color:#e1f3d8}.el-button--warning{color:#FFF;background-color:#E6A23C;border-color:#E6A23C}.el-button--warning:focus,.el-button--warning:hover{background:#ebb563;border-color:#ebb563;color:#FFF}.el-button--warning.is-active,.el-button--warning:active{background:#cf9236;border-color:#cf9236;color:#FFF}.el-button--warning:active{outline:0}.el-button--warning.is-disabled,.el-button--warning.is-disabled:active,.el-button--warning.is-disabled:focus,.el-button--warning.is-disabled:hover{color:#FFF;background-color:#f3d19e;border-color:#f3d19e}.el-button--warning.is-plain{color:#E6A23C;background:#fdf6ec;border-color:#f5dab1}.el-button--warning.is-plain:focus,.el-button--warning.is-plain:hover{background:#E6A23C;border-color:#E6A23C;color:#FFF}.el-button--warning.is-plain:active{background:#cf9236;border-color:#cf9236;color:#FFF;outline:0}.el-button--warning.is-plain.is-disabled,.el-button--warning.is-plain.is-disabled:active,.el-button--warning.is-plain.is-disabled:focus,.el-button--warning.is-plain.is-disabled:hover{color:#f0c78a;background-color:#fdf6ec;border-color:#faecd8}.el-button--danger{color:#FFF;background-color:#F56C6C;border-color:#F56C6C}.el-button--danger:focus,.el-button--danger:hover{background:#f78989;border-color:#f78989;color:#FFF}.el-button--danger.is-active,.el-button--danger:active{background:#dd6161;border-color:#dd6161;color:#FFF}.el-button--danger:active{outline:0}.el-button--danger.is-disabled,.el-button--danger.is-disabled:active,.el-button--danger.is-disabled:focus,.el-button--danger.is-disabled:hover{color:#FFF;background-color:#fab6b6;border-color:#fab6b6}.el-button--danger.is-plain{color:#F56C6C;background:#fef0f0;border-color:#fbc4c4}.el-button--danger.is-plain:focus,.el-button--danger.is-plain:hover{background:#F56C6C;border-color:#F56C6C;color:#FFF}.el-button--danger.is-plain:active{background:#dd6161;border-color:#dd6161;color:#FFF;outline:0}.el-button--danger.is-plain.is-disabled,.el-button--danger.is-plain.is-disabled:active,.el-button--danger.is-plain.is-disabled:focus,.el-button--danger.is-plain.is-disabled:hover{color:#f9a7a7;background-color:#fef0f0;border-color:#fde2e2}.el-button--info{color:#FFF;background-color:#909399;border-color:#909399}.el-button--info:focus,.el-button--info:hover{background:#a6a9ad;border-color:#a6a9ad;color:#FFF}.el-button--info.is-active,.el-button--info:active{background:#82848a;border-color:#82848a;color:#FFF}.el-button--info:active{outline:0}.el-button--info.is-disabled,.el-button--info.is-disabled:active,.el-button--info.is-disabled:focus,.el-button--info.is-disabled:hover{color:#FFF;background-color:#c8c9cc;border-color:#c8c9cc}.el-button--info.is-plain{color:#909399;background:#f4f4f5;border-color:#d3d4d6}.el-button--info.is-plain:focus,.el-button--info.is-plain:hover{background:#909399;border-color:#909399;color:#FFF}.el-button--info.is-plain:active{background:#82848a;border-color:#82848a;color:#FFF;outline:0}.el-button--info.is-plain.is-disabled,.el-button--info.is-plain.is-disabled:active,.el-button--info.is-plain.is-disabled:focus,.el-button--info.is-plain.is-disabled:hover{color:#bcbec2;background-color:#f4f4f5;border-color:#e9e9eb}.el-button--text,.el-button--text.is-disabled,.el-button--text.is-disabled:focus,.el-button--text.is-disabled:hover,.el-button--text:active{border-color:transparent}.el-button--medium{padding:10px 20px;font-size:14px;border-radius:4px}.el-button--mini,.el-button--small{font-size:12px;border-radius:3px}.el-button--medium.is-round{padding:10px 20px}.el-button--medium.is-circle{padding:10px}.el-button--small,.el-button--small.is-round{padding:9px 15px}.el-button--small.is-circle{padding:9px}.el-button--mini,.el-button--mini.is-round{padding:7px 15px}.el-button--mini.is-circle{padding:7px}.el-button--text{color:#409EFF;background:0 0;padding-left:0;padding-right:0}.el-button--text:focus,.el-button--text:hover{color:#66b1ff;border-color:transparent;background-color:transparent}.el-button--text:active{color:#3a8ee6;background-color:transparent}.el-checkbox,.el-checkbox-button__inner{font-weight:500;color:#606266;-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;white-space:nowrap}.el-button-group{display:inline-block;vertical-align:middle}.el-button-group::after,.el-button-group::before{display:table;content:""}.el-button-group::after{clear:both}.el-button-group>.el-button{float:left;position:relative}.el-button-group>.el-button+.el-button{margin-left:0}.el-button-group>.el-button:first-child{border-top-right-radius:0;border-bottom-right-radius:0}.el-button-group>.el-button:last-child{border-top-left-radius:0;border-bottom-left-radius:0}.el-button-group>.el-button:first-child:last-child{border-radius:4px}.el-button-group>.el-button:first-child:last-child.is-round{border-radius:20px}.el-button-group>.el-button:first-child:last-child.is-circle{border-radius:50%}.el-button-group>.el-button:not(:first-child):not(:last-child){border-radius:0}.el-button-group>.el-button:not(:last-child){margin-right:-1px}.el-button-group>.el-dropdown>.el-button{border-top-left-radius:0;border-bottom-left-radius:0;border-left-color:rgba(255,255,255,.5)}.el-button-group .el-button--primary:first-child{border-right-color:rgba(255,255,255,.5)}.el-button-group .el-button--primary:last-child{border-left-color:rgba(255,255,255,.5)}.el-button-group .el-button--primary:not(:first-child):not(:last-child){border-left-color:rgba(255,255,255,.5);border-right-color:rgba(255,255,255,.5)}.el-button-group .el-button--success:first-child{border-right-color:rgba(255,255,255,.5)}.el-button-group .el-button--success:last-child{border-left-color:rgba(255,255,255,.5)}.el-button-group .el-button--success:not(:first-child):not(:last-child){border-left-color:rgba(255,255,255,.5);border-right-color:rgba(255,255,255,.5)}.el-button-group .el-button--warning:first-child{border-right-color:rgba(255,255,255,.5)}.el-button-group .el-button--warning:last-child{border-left-color:rgba(255,255,255,.5)}.el-button-group .el-button--warning:not(:first-child):not(:last-child){border-left-color:rgba(255,255,255,.5);border-right-color:rgba(255,255,255,.5)}.el-button-group .el-button--danger:first-child{border-right-color:rgba(255,255,255,.5)}.el-button-group .el-button--danger:last-child{border-left-color:rgba(255,255,255,.5)}.el-button-group .el-button--danger:not(:first-child):not(:last-child){border-left-color:rgba(255,255,255,.5);border-right-color:rgba(255,255,255,.5)}.el-button-group .el-button--info:first-child{border-right-color:rgba(255,255,255,.5)}.el-button-group .el-button--info:last-child{border-left-color:rgba(255,255,255,.5)}.el-button-group .el-button--info:not(:first-child):not(:last-child){border-left-color:rgba(255,255,255,.5);border-right-color:rgba(255,255,255,.5)}.el-checkbox{font-size:14px;cursor:pointer;user-select:none;margin-right:30px}.el-checkbox.is-bordered{padding:9px 20px 9px 10px;border-radius:4px;border:1px solid #DCDFE6;-webkit-box-sizing:border-box;box-sizing:border-box;line-height:normal;height:40px}.el-checkbox.is-bordered.is-checked{border-color:#409EFF}.el-checkbox.is-bordered.is-disabled{border-color:#EBEEF5;cursor:not-allowed}.el-checkbox.is-bordered+.el-checkbox.is-bordered{margin-left:10px}.el-checkbox.is-bordered.el-checkbox--medium{padding:7px 20px 7px 10px;border-radius:4px;height:36px}.el-checkbox.is-bordered.el-checkbox--medium .el-checkbox__label{line-height:17px;font-size:14px}.el-checkbox.is-bordered.el-checkbox--medium .el-checkbox__inner{height:14px;width:14px}.el-checkbox.is-bordered.el-checkbox--small{padding:5px 15px 5px 10px;border-radius:3px;height:32px}.el-checkbox.is-bordered.el-checkbox--small .el-checkbox__label{line-height:15px;font-size:12px}.el-checkbox.is-bordered.el-checkbox--small .el-checkbox__inner{height:12px;width:12px}.el-checkbox.is-bordered.el-checkbox--small .el-checkbox__inner::after{height:6px;width:2px}.el-checkbox.is-bordered.el-checkbox--mini{padding:3px 15px 3px 10px;border-radius:3px;height:28px}.el-checkbox.is-bordered.el-checkbox--mini .el-checkbox__label{line-height:12px;font-size:12px}.el-checkbox.is-bordered.el-checkbox--mini .el-checkbox__inner{height:12px;width:12px}.el-checkbox.is-bordered.el-checkbox--mini .el-checkbox__inner::after{height:6px;width:2px}.el-checkbox__input{white-space:nowrap;cursor:pointer;outline:0;line-height:1;vertical-align:middle}.el-checkbox__input.is-disabled .el-checkbox__inner{background-color:#edf2fc;border-color:#DCDFE6;cursor:not-allowed}.el-checkbox__input.is-disabled .el-checkbox__inner::after{cursor:not-allowed;border-color:#C0C4CC}.el-checkbox__input.is-disabled .el-checkbox__inner+.el-checkbox__label{cursor:not-allowed}.el-checkbox__input.is-disabled.is-checked .el-checkbox__inner{background-color:#F2F6FC;border-color:#DCDFE6}.el-checkbox__input.is-disabled.is-checked .el-checkbox__inner::after{border-color:#C0C4CC}.el-checkbox__input.is-disabled.is-indeterminate .el-checkbox__inner{background-color:#F2F6FC;border-color:#DCDFE6}.el-checkbox__input.is-disabled.is-indeterminate .el-checkbox__inner::before{background-color:#C0C4CC;border-color:#C0C4CC}.el-checkbox__input.is-checked .el-checkbox__inner,.el-checkbox__input.is-indeterminate .el-checkbox__inner{background-color:#409EFF;border-color:#409EFF}.el-checkbox__input.is-disabled+span.el-checkbox__label{color:#C0C4CC;cursor:not-allowed}.el-checkbox__input.is-checked .el-checkbox__inner::after{-webkit-transform:rotate(45deg) scaleY(1);transform:rotate(45deg) scaleY(1)}.el-checkbox__input.is-checked+.el-checkbox__label{color:#409EFF}.el-checkbox__input.is-focus .el-checkbox__inner{border-color:#409EFF}.el-checkbox__input.is-indeterminate .el-checkbox__inner::before{content:'';position:absolute;display:block;background-color:#FFF;height:2px;-webkit-transform:scale(.5);transform:scale(.5);left:0;right:0;top:5px}.el-checkbox__input.is-indeterminate .el-checkbox__inner::after{display:none}.el-checkbox__inner{display:inline-block;position:relative;border:1px solid #DCDFE6;border-radius:2px;-webkit-box-sizing:border-box;box-sizing:border-box;width:14px;height:14px;background-color:#FFF;z-index:1;-webkit-transition:border-color .25s cubic-bezier(.71,-.46,.29,1.46),background-color .25s cubic-bezier(.71,-.46,.29,1.46);transition:border-color .25s cubic-bezier(.71,-.46,.29,1.46),background-color .25s cubic-bezier(.71,-.46,.29,1.46)}.el-checkbox__inner:hover{border-color:#409EFF}.el-checkbox__inner::after{-webkit-box-sizing:content-box;box-sizing:content-box;content:"";border:1px solid #FFF;border-left:0;border-top:0;height:7px;left:4px;position:absolute;top:1px;-webkit-transform:rotate(45deg) scaleY(0);transform:rotate(45deg) scaleY(0);width:3px;-webkit-transition:-webkit-transform .15s ease-in .05s;transition:-webkit-transform .15s ease-in .05s;transition:transform .15s ease-in .05s;transition:transform .15s ease-in .05s,-webkit-transform .15s ease-in .05s;-webkit-transform-origin:center;transform-origin:center}.el-checkbox-button__inner,.el-transfer-panel{-webkit-box-sizing:border-box;vertical-align:middle}.el-checkbox__original{opacity:0;outline:0;position:absolute;margin:0;width:0;height:0;z-index:-1}.el-checkbox-button,.el-checkbox-button__inner{position:relative;display:inline-block}.el-checkbox__label{display:inline-block;padding-left:10px;line-height:19px;font-size:14px}.el-checkbox:last-child{margin-right:0}.el-checkbox-button__inner{line-height:1;cursor:pointer;background:#FFF;border:1px solid #DCDFE6;border-left:0;-webkit-appearance:none;text-align:center;box-sizing:border-box;outline:0;margin:0;-webkit-transition:all .3s cubic-bezier(.645,.045,.355,1);transition:all .3s cubic-bezier(.645,.045,.355,1);padding:12px 20px;font-size:14px;border-radius:0}.el-checkbox-button__inner.is-round{padding:12px 20px}.el-checkbox-button__inner:hover{color:#409EFF}.el-checkbox-button__inner [class*=el-icon-]{line-height:.9}.el-checkbox-button__inner [class*=el-icon-]+span{margin-left:5px}.el-checkbox-button__original{opacity:0;outline:0;position:absolute;margin:0;z-index:-1}.el-checkbox-button.is-checked .el-checkbox-button__inner{color:#FFF;background-color:#409EFF;border-color:#409EFF;-webkit-box-shadow:-1px 0 0 0 #8cc5ff;box-shadow:-1px 0 0 0 #8cc5ff}.el-checkbox-button.is-checked:first-child .el-checkbox-button__inner{border-left-color:#409EFF}.el-checkbox-button.is-disabled .el-checkbox-button__inner{color:#C0C4CC;cursor:not-allowed;background-image:none;background-color:#FFF;border-color:#EBEEF5;-webkit-box-shadow:none;box-shadow:none}.el-link,.el-transfer-panel__filter .el-icon-circle-close{cursor:pointer}.el-checkbox-button.is-disabled:first-child .el-checkbox-button__inner{border-left-color:#EBEEF5}.el-checkbox-button:first-child .el-checkbox-button__inner{border-left:1px solid #DCDFE6;border-radius:4px 0 0 4px;-webkit-box-shadow:none!important;box-shadow:none!important}.el-checkbox-button.is-focus .el-checkbox-button__inner{border-color:#409EFF}.el-checkbox-button:last-child .el-checkbox-button__inner{border-radius:0 4px 4px 0}.el-checkbox-button--medium .el-checkbox-button__inner{padding:10px 20px;font-size:14px;border-radius:0}.el-checkbox-button--medium .el-checkbox-button__inner.is-round{padding:10px 20px}.el-checkbox-button--small .el-checkbox-button__inner{padding:9px 15px;font-size:12px;border-radius:0}.el-checkbox-button--small .el-checkbox-button__inner.is-round{padding:9px 15px}.el-checkbox-button--mini .el-checkbox-button__inner{padding:7px 15px;font-size:12px;border-radius:0}.el-checkbox-button--mini .el-checkbox-button__inner.is-round{padding:7px 15px}.el-checkbox-group{font-size:0}.el-transfer{font-size:14px}.el-transfer__buttons{display:inline-block;vertical-align:middle;padding:0 30px}.el-transfer__button{display:block;margin:0 auto;padding:10px;border-radius:50%;color:#FFF;background-color:#409EFF;font-size:0}.el-transfer-panel__item+.el-transfer-panel__item,.el-transfer__button [class*=el-icon-]+span{margin-left:0}.el-transfer__button.is-with-texts{border-radius:4px}.el-transfer__button.is-disabled,.el-transfer__button.is-disabled:hover{border:1px solid #DCDFE6;background-color:#F5F7FA;color:#C0C4CC}.el-transfer__button:first-child{margin-bottom:10px}.el-transfer__button:nth-child(2){margin:0}.el-transfer__button i,.el-transfer__button span{font-size:14px}.el-transfer-panel{border:1px solid #EBEEF5;border-radius:4px;overflow:hidden;background:#FFF;display:inline-block;width:200px;max-height:100%;box-sizing:border-box;position:relative}.el-transfer-panel__body{height:246px}.el-transfer-panel__body.is-with-footer{padding-bottom:40px}.el-transfer-panel__list{margin:0;padding:6px 0;list-style:none;height:246px;overflow:auto;-webkit-box-sizing:border-box;box-sizing:border-box}.el-transfer-panel__list.is-filterable{height:194px;padding-top:0}.el-transfer-panel__item{height:30px;line-height:30px;padding-left:15px;display:block}.el-transfer-panel__item.el-checkbox{color:#606266}.el-transfer-panel__item:hover{color:#409EFF}.el-transfer-panel__item.el-checkbox .el-checkbox__label{width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:block;-webkit-box-sizing:border-box;box-sizing:border-box;padding-left:24px;line-height:30px}.el-transfer-panel__item .el-checkbox__input{position:absolute;top:8px}.el-transfer-panel__filter{text-align:center;margin:15px;-webkit-box-sizing:border-box;box-sizing:border-box;display:block;width:auto}.el-transfer-panel__filter .el-input__inner{height:32px;width:100%;font-size:12px;display:inline-block;-webkit-box-sizing:border-box;box-sizing:border-box;border-radius:16px;padding-right:10px;padding-left:30px}.el-transfer-panel__filter .el-input__icon{margin-left:5px}.el-transfer-panel .el-transfer-panel__header{height:40px;line-height:40px;background:#F5F7FA;margin:0;padding-left:15px;border-bottom:1px solid #EBEEF5;-webkit-box-sizing:border-box;box-sizing:border-box;color:#000}.el-transfer-panel .el-transfer-panel__header .el-checkbox{display:block;line-height:40px}.el-transfer-panel .el-transfer-panel__header .el-checkbox .el-checkbox__label{font-size:16px;color:#303133;font-weight:400}.el-transfer-panel .el-transfer-panel__header .el-checkbox .el-checkbox__label span{position:absolute;right:15px;color:#909399;font-size:12px;font-weight:400}.el-divider__text,.el-link{font-weight:500;font-size:14px}.el-transfer-panel .el-transfer-panel__footer{height:40px;background:#FFF;margin:0;padding:0;border-top:1px solid #EBEEF5;position:absolute;bottom:0;left:0;width:100%;z-index:1}.el-transfer-panel .el-transfer-panel__footer::after{display:inline-block;content:"";height:100%;vertical-align:middle}.el-container,.el-timeline-item__node{display:-webkit-box;display:-ms-flexbox}.el-transfer-panel .el-transfer-panel__footer .el-checkbox{padding-left:20px;color:#606266}.el-transfer-panel .el-transfer-panel__empty{margin:0;height:30px;line-height:30px;padding:6px 15px 0;color:#909399;text-align:center}.el-transfer-panel .el-checkbox__label{padding-left:8px}.el-transfer-panel .el-checkbox__inner{height:14px;width:14px;border-radius:3px}.el-transfer-panel .el-checkbox__inner::after{height:6px;width:3px;left:4px}.el-container{display:flex;-webkit-box-orient:horizontal;-ms-flex-direction:row;flex-direction:row;-webkit-box-flex:1;-ms-flex:1;flex:1;-ms-flex-preferred-size:auto;flex-basis:auto;-webkit-box-sizing:border-box;box-sizing:border-box;min-width:0}.el-aside,.el-header{-webkit-box-sizing:border-box}.el-container.is-vertical{-webkit-box-orient:vertical;-ms-flex-direction:column;flex-direction:column}.el-header{padding:0 20px;box-sizing:border-box;-ms-flex-negative:0;flex-shrink:0}.el-aside{overflow:auto;box-sizing:border-box;-ms-flex-negative:0;flex-shrink:0}.el-footer,.el-main{-webkit-box-sizing:border-box}.el-main{display:block;-webkit-box-flex:1;-ms-flex:1;flex:1;-ms-flex-preferred-size:auto;flex-basis:auto;overflow:auto;box-sizing:border-box;padding:20px}.el-footer{padding:0 20px;box-sizing:border-box;-ms-flex-negative:0;flex-shrink:0}.el-timeline{margin:0;font-size:14px;list-style:none}.el-timeline .el-timeline-item:last-child .el-timeline-item__tail{display:none}.el-timeline-item{position:relative;padding-bottom:20px}.el-timeline-item__wrapper{position:relative;padding-left:28px;top:-3px}.el-timeline-item__tail{position:absolute;left:4px;height:100%;border-left:2px solid #E4E7ED}.el-timeline-item__icon{color:#FFF;font-size:13px}.el-timeline-item__node{position:absolute;background-color:#E4E7ED;border-radius:50%;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.el-image__error,.el-timeline-item__dot{display:-webkit-box;display:-ms-flexbox}.el-timeline-item__node--normal{left:-1px;width:12px;height:12px}.el-timeline-item__node--large{left:-2px;width:14px;height:14px}.el-timeline-item__node--primary{background-color:#409EFF}.el-timeline-item__node--success{background-color:#67C23A}.el-timeline-item__node--warning{background-color:#E6A23C}.el-timeline-item__node--danger{background-color:#F56C6C}.el-timeline-item__node--info{background-color:#909399}.el-timeline-item__dot{position:absolute;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.el-timeline-item__content{color:#303133}.el-timeline-item__timestamp{color:#909399;line-height:1;font-size:13px}.el-timeline-item__timestamp.is-top{margin-bottom:8px;padding-top:4px}.el-timeline-item__timestamp.is-bottom{margin-top:8px}.el-link{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-orient:horizontal;-ms-flex-direction:row;flex-direction:row;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;vertical-align:middle;position:relative;text-decoration:none;outline:0;padding:0}.el-link.is-underline:hover:after{content:"";position:absolute;left:0;right:0;height:0;bottom:0;border-bottom:1px solid #409EFF}.el-link.el-link--default:after,.el-link.el-link--primary.is-underline:hover:after,.el-link.el-link--primary:after{border-color:#409EFF}.el-link.is-disabled{cursor:not-allowed}.el-link [class*=el-icon-]+span{margin-left:5px}.el-link.el-link--default{color:#606266}.el-link.el-link--default:hover{color:#409EFF}.el-link.el-link--default.is-disabled{color:#C0C4CC}.el-link.el-link--primary{color:#409EFF}.el-link.el-link--primary:hover{color:#66b1ff}.el-link.el-link--primary.is-disabled{color:#a0cfff}.el-link.el-link--danger.is-underline:hover:after,.el-link.el-link--danger:after{border-color:#F56C6C}.el-link.el-link--danger{color:#F56C6C}.el-link.el-link--danger:hover{color:#f78989}.el-link.el-link--danger.is-disabled{color:#fab6b6}.el-link.el-link--success.is-underline:hover:after,.el-link.el-link--success:after{border-color:#67C23A}.el-link.el-link--success{color:#67C23A}.el-link.el-link--success:hover{color:#85ce61}.el-link.el-link--success.is-disabled{color:#b3e19d}.el-link.el-link--warning.is-underline:hover:after,.el-link.el-link--warning:after{border-color:#E6A23C}.el-link.el-link--warning{color:#E6A23C}.el-link.el-link--warning:hover{color:#ebb563}.el-link.el-link--warning.is-disabled{color:#f3d19e}.el-link.el-link--info.is-underline:hover:after,.el-link.el-link--info:after{border-color:#909399}.el-link.el-link--info{color:#909399}.el-link.el-link--info:hover{color:#a6a9ad}.el-link.el-link--info.is-disabled{color:#c8c9cc}.el-divider{background-color:#DCDFE6;position:relative}.el-divider--horizontal{display:block;height:1px;width:100%;margin:24px 0}.el-divider--vertical{display:inline-block;width:1px;height:1em;margin:0 8px;vertical-align:middle;position:relative}.el-divider__text{position:absolute;background-color:#FFF;padding:0 20px;color:#303133}.el-image__error,.el-image__placeholder{background:#F5F7FA}.el-divider__text.is-left{left:20px;-webkit-transform:translateY(-50%);transform:translateY(-50%)}.el-divider__text.is-center{left:50%;-webkit-transform:translateX(-50%) translateY(-50%);transform:translateX(-50%) translateY(-50%)}.el-divider__text.is-right{right:20px;-webkit-transform:translateY(-50%);transform:translateY(-50%)}.el-image__error,.el-image__inner,.el-image__placeholder{width:100%;height:100%}.el-image{display:inline-block}.el-image__inner{vertical-align:top}.el-image__error{display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;font-size:14px;color:#C0C4CC;vertical-align:middle}.el-calendar{background-color:#fff}.el-calendar__header{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;padding:12px 20px;border-bottom:1px solid #EBEEF5}.el-calendar__title{color:#000;-ms-flex-item-align:center;align-self:center}.el-calendar__body{padding:12px 20px 35px}.el-calendar-table{table-layout:fixed;width:100%}.el-calendar-table thead th{padding:12px 0;color:#606266;font-weight:400}.el-calendar-table:not(.is-range) td.next,.el-calendar-table:not(.is-range) td.prev{color:#C0C4CC}.el-calendar-table td{border-bottom:1px solid #EBEEF5;border-right:1px solid #EBEEF5;vertical-align:top;-webkit-transition:background-color .2s ease;transition:background-color .2s ease}.el-calendar-table td.is-selected{background-color:#F2F8FE}.el-calendar-table td.is-today{color:#409EFF}.el-calendar-table tr:first-child td{border-top:1px solid #EBEEF5}.el-calendar-table tr td:first-child{border-left:1px solid #EBEEF5}.el-calendar-table tr.el-calendar-table__row--hide-border td{border-top:none}.el-calendar-table .el-calendar-day{-webkit-box-sizing:border-box;box-sizing:border-box;padding:8px;height:85px}.el-calendar-table .el-calendar-day:hover{cursor:pointer;background-color:#F2F8FE}
\ No newline at end of file
diff --git a/admin/src/main/resources/static/dist/index.min.js b/admin/src/main/resources/static/dist/index.min.js
new file mode 100644
index 0000000..6abe13b
--- /dev/null
+++ b/admin/src/main/resources/static/dist/index.min.js
@@ -0,0 +1 @@
+!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("vue")):"function"==typeof define&&define.amd?define("ELEMENT",["vue"],t):"object"==typeof exports?exports.ELEMENT=t(require("vue")):e.ELEMENT=t(e.Vue)}("undefined"!=typeof self?self:this,function(e){return function(e){var t={};function i(n){if(t[n])return t[n].exports;var r=t[n]={i:n,l:!1,exports:{}};return e[n].call(r.exports,r,r.exports,i),r.l=!0,r.exports}return i.m=e,i.c=t,i.d=function(e,t,n){i.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},i.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.t=function(e,t){if(1&t&&(e=i(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(i.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)i.d(n,r,function(t){return e[t]}.bind(null,r));return n},i.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return i.d(t,"a",t),t},i.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},i.p="/dist/",i(i.s=48)}([function(t,i){t.exports=e},function(e,t,i){var n=i(12);e.exports=function(e,t,i){return void 0===i?n(e,t,!1):n(e,i,!1!==t)}},function(e,t,i){var n;!function(r){"use strict";var s={},o=/d{1,4}|M{1,4}|yy(?:yy)?|S{1,3}|Do|ZZ|([HhMsDm])\1?|[aA]|"[^"]*"|'[^']*'/g,a=/\d\d?/,l=/[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i,u=function(){};function c(e,t){for(var i=[],n=0,r=e.length;n3?0:(e-e%10!=10)*e%10]}};var g={D:function(e){return e.getDay()},DD:function(e){return d(e.getDay())},Do:function(e,t){return t.DoFn(e.getDate())},d:function(e){return e.getDate()},dd:function(e){return d(e.getDate())},ddd:function(e,t){return t.dayNamesShort[e.getDay()]},dddd:function(e,t){return t.dayNames[e.getDay()]},M:function(e){return e.getMonth()+1},MM:function(e){return d(e.getMonth()+1)},MMM:function(e,t){return t.monthNamesShort[e.getMonth()]},MMMM:function(e,t){return t.monthNames[e.getMonth()]},yy:function(e){return String(e.getFullYear()).substr(2)},yyyy:function(e){return e.getFullYear()},h:function(e){return e.getHours()%12||12},hh:function(e){return d(e.getHours()%12||12)},H:function(e){return e.getHours()},HH:function(e){return d(e.getHours())},m:function(e){return e.getMinutes()},mm:function(e){return d(e.getMinutes())},s:function(e){return e.getSeconds()},ss:function(e){return d(e.getSeconds())},S:function(e){return Math.round(e.getMilliseconds()/100)},SS:function(e){return d(Math.round(e.getMilliseconds()/10),2)},SSS:function(e){return d(e.getMilliseconds(),3)},a:function(e,t){return e.getHours()<12?t.amPm[0]:t.amPm[1]},A:function(e,t){return e.getHours()<12?t.amPm[0].toUpperCase():t.amPm[1].toUpperCase()},ZZ:function(e){var t=e.getTimezoneOffset();return(t>0?"-":"+")+d(100*Math.floor(Math.abs(t)/60)+Math.abs(t)%60,4)}},b={d:[a,function(e,t){e.day=t}],M:[a,function(e,t){e.month=t-1}],yy:[a,function(e,t){var i=+(""+(new Date).getFullYear()).substr(0,2);e.year=""+(t>68?i-1:i)+t}],h:[a,function(e,t){e.hour=t}],m:[a,function(e,t){e.minute=t}],s:[a,function(e,t){e.second=t}],yyyy:[/\d{4}/,function(e,t){e.year=t}],S:[/\d/,function(e,t){e.millisecond=100*t}],SS:[/\d{2}/,function(e,t){e.millisecond=10*t}],SSS:[/\d{3}/,function(e,t){e.millisecond=t}],D:[a,u],ddd:[l,u],MMM:[l,h("monthNamesShort")],MMMM:[l,h("monthNames")],a:[l,function(e,t,i){var n=t.toLowerCase();n===i.amPm[0]?e.isPm=!1:n===i.amPm[1]&&(e.isPm=!0)}],ZZ:[/[\+\-]\d\d:?\d\d/,function(e,t){var i,n=(t+"").match(/([\+\-]|\d\d)/gi);n&&(i=60*n[1]+parseInt(n[2],10),e.timezoneOffset="+"===n[0]?i:-i)}]};b.DD=b.D,b.dddd=b.ddd,b.Do=b.dd=b.d,b.mm=b.m,b.hh=b.H=b.HH=b.h,b.MM=b.M,b.ss=b.s,b.A=b.a,s.masks={default:"ddd MMM dd yyyy HH:mm:ss",shortDate:"M/D/yy",mediumDate:"MMM d, yyyy",longDate:"MMMM d, yyyy",fullDate:"dddd, MMMM d, yyyy",shortTime:"HH:mm",mediumTime:"HH:mm:ss",longTime:"HH:mm:ss.SSS"},s.format=function(e,t,i){var n=i||s.i18n;if("number"==typeof e&&(e=new Date(e)),"[object Date]"!==Object.prototype.toString.call(e)||isNaN(e.getTime()))throw new Error("Invalid Date in fecha.format");return(t=s.masks[t]||t||s.masks.default).replace(o,function(t){return t in g?g[t](e,n):t.slice(1,t.length-1)})},s.parse=function(e,t,i){var n=i||s.i18n;if("string"!=typeof t)throw new Error("Invalid format in fecha.parse");if(t=s.masks[t]||t,e.length>1e3)return!1;var r=!0,a={};if(t.replace(o,function(t){if(b[t]){var i=b[t],s=e.search(i[0]);~s?e.replace(i[0],function(t){return i[1](a,t,n),e=e.substr(s+t.length),t}):r=!1}return b[t]?"":t.slice(1,t.length-1)}),!r)return!1;var l,u=new Date;return!0===a.isPm&&null!=a.hour&&12!=+a.hour?a.hour=+a.hour+12:!1===a.isPm&&12==+a.hour&&(a.hour=0),null!=a.timezoneOffset?(a.minute=+(a.minute||0)-+a.timezoneOffset,l=new Date(Date.UTC(a.year||u.getFullYear(),a.month||0,a.day||1,a.hour||0,a.minute||0,a.second||0,a.millisecond||0))):l=new Date(a.year||u.getFullYear(),a.month||0,a.day||1,a.hour||0,a.minute||0,a.second||0,a.millisecond||0),l},e.exports?e.exports=s:void 0===(n=function(){return s}.call(t,i,t,e))||(e.exports=n)}()},function(e,t,i){"use strict";t.__esModule=!0;var n=o(i(64)),r=o(i(76)),s="function"==typeof r.default&&"symbol"==typeof n.default?function(e){return typeof e}:function(e){return e&&"function"==typeof r.default&&e.constructor===r.default&&e!==r.default.prototype?"symbol":typeof e};function o(e){return e&&e.__esModule?e:{default:e}}t.default="function"==typeof r.default&&"symbol"===s(n.default)?function(e){return void 0===e?"undefined":s(e)}:function(e){return e&&"function"==typeof r.default&&e.constructor===r.default&&e!==r.default.prototype?"symbol":void 0===e?"undefined":s(e)}},function(e,t){var i=e.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=i)},function(e,t){var i={}.hasOwnProperty;e.exports=function(e,t){return i.call(e,t)}},function(e,t,i){"use strict";t.__esModule=!0;var n,r=i(55),s=(n=r)&&n.__esModule?n:{default:n};t.default=s.default||function(e){for(var t=1;te?u():!0!==t&&(r=setTimeout(n?function(){r=void 0}:u,void 0===n?e-a:e))}}},function(e,t){var i=e.exports={version:"2.6.2"};"number"==typeof __e&&(__e=i)},function(e,t){e.exports=function(e){return"object"==typeof e?null!==e:"function"==typeof e}},function(e,t){e.exports=function(e){try{return!!e()}catch(e){return!0}}},function(e,t){var i=/^(attrs|props|on|nativeOn|class|style|hook)$/;function n(e,t){return function(){e&&e.apply(this,arguments),t&&t.apply(this,arguments)}}e.exports=function(e){return e.reduce(function(e,t){var r,s,o,a,l;for(o in t)if(r=e[o],s=t[o],r&&i.test(o))if("class"===o&&("string"==typeof r&&(l=r,e[o]=r={},r[l]=!0),"string"==typeof s&&(l=s,t[o]=s={},s[l]=!0)),"on"===o||"nativeOn"===o||"hook"===o)for(a in s)r[a]=n(r[a],s[a]);else if(Array.isArray(r))e[o]=r.concat(s);else if(Array.isArray(s))e[o]=[r].concat(s);else for(a in s)r[a]=s[a];else e[o]=t[o];return e},{})}},function(e,t,i){var n=i(14);e.exports=function(e){if(!n(e))throw TypeError(e+" is not an object!");return e}},function(e,t){e.exports=function(e,t){return{enumerable:!(1&e),configurable:!(2&e),writable:!(4&e),value:t}}},function(e,t,i){var n=i(37),r=i(29);e.exports=Object.keys||function(e){return n(e,r)}},function(e,t){e.exports=!0},function(e,t){var i=0,n=Math.random();e.exports=function(e){return"Symbol(".concat(void 0===e?"":e,")_",(++i+n).toString(36))}},function(e,t){t.f={}.propertyIsEnumerable},function(e,t,i){var n=i(4),r=i(13),s=i(58),o=i(7),a=i(5),l=function(e,t,i){var u,c,h,d=e&l.F,p=e&l.G,f=e&l.S,m=e&l.P,v=e&l.B,g=e&l.W,b=p?r:r[t]||(r[t]={}),y=b.prototype,_=p?n:f?n[t]:(n[t]||{}).prototype;for(u in p&&(i=t),i)(c=!d&&_&&void 0!==_[u])&&a(b,u)||(h=c?_[u]:i[u],b[u]=p&&"function"!=typeof _[u]?i[u]:v&&c?s(h,n):g&&_[u]==h?function(e){var t=function(t,i,n){if(this instanceof e){switch(arguments.length){case 0:return new e;case 1:return new e(t);case 2:return new e(t,i)}return new e(t,i,n)}return e.apply(this,arguments)};return t.prototype=e.prototype,t}(h):m&&"function"==typeof h?s(Function.call,h):h,m&&((b.virtual||(b.virtual={}))[u]=h,e&l.R&&y&&!y[u]&&o(y,u,h)))};l.F=1,l.G=2,l.S=4,l.P=8,l.B=16,l.W=32,l.U=64,l.R=128,e.exports=l},function(e,t,i){var n=i(14);e.exports=function(e,t){if(!n(e))return e;var i,r;if(t&&"function"==typeof(i=e.toString)&&!n(r=i.call(e)))return r;if("function"==typeof(i=e.valueOf)&&!n(r=i.call(e)))return r;if(!t&&"function"==typeof(i=e.toString)&&!n(r=i.call(e)))return r;throw TypeError("Can't convert object to primitive value")}},function(e,t){e.exports=function(e){if(null==e)throw TypeError("Can't call method on "+e);return e}},function(e,t){var i=Math.ceil,n=Math.floor;e.exports=function(e){return isNaN(e=+e)?0:(e>0?n:i)(e)}},function(e,t,i){var n=i(28)("keys"),r=i(21);e.exports=function(e){return n[e]||(n[e]=r(e))}},function(e,t,i){var n=i(13),r=i(4),s=r["__core-js_shared__"]||(r["__core-js_shared__"]={});(e.exports=function(e,t){return s[e]||(s[e]=void 0!==t?t:{})})("versions",[]).push({version:n.version,mode:i(20)?"pure":"global",copyright:"© 2019 Denis Pushkarev (zloirock.ru)"})},function(e,t){e.exports="constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf".split(",")},function(e,t){t.f=Object.getOwnPropertySymbols},function(e,t){e.exports={}},function(e,t,i){var n=i(8).f,r=i(5),s=i(11)("toStringTag");e.exports=function(e,t,i){e&&!r(e=i?e:e.prototype,s)&&n(e,s,{configurable:!0,value:t})}},function(e,t,i){t.f=i(11)},function(e,t,i){var n=i(4),r=i(13),s=i(20),o=i(33),a=i(8).f;e.exports=function(e){var t=r.Symbol||(r.Symbol=s?{}:n.Symbol||{});"_"==e.charAt(0)||e in t||a(t,e,{value:o.f(e)})}},function(e,t,i){e.exports=!i(9)&&!i(15)(function(){return 7!=Object.defineProperty(i(36)("div"),"a",{get:function(){return 7}}).a})},function(e,t,i){var n=i(14),r=i(4).document,s=n(r)&&n(r.createElement);e.exports=function(e){return s?r.createElement(e):{}}},function(e,t,i){var n=i(5),r=i(10),s=i(61)(!1),o=i(27)("IE_PROTO");e.exports=function(e,t){var i,a=r(e),l=0,u=[];for(i in a)i!=o&&n(a,i)&&u.push(i);for(;t.length>l;)n(a,i=t[l++])&&(~s(u,i)||u.push(i));return u}},function(e,t,i){var n=i(39);e.exports=Object("z").propertyIsEnumerable(0)?Object:function(e){return"String"==n(e)?e.split(""):Object(e)}},function(e,t){var i={}.toString;e.exports=function(e){return i.call(e).slice(8,-1)}},function(e,t,i){var n=i(25);e.exports=function(e){return Object(n(e))}},function(e,t,i){"use strict";var n=i(20),r=i(23),s=i(42),o=i(7),a=i(31),l=i(68),u=i(32),c=i(71),h=i(11)("iterator"),d=!([].keys&&"next"in[].keys()),p=function(){return this};e.exports=function(e,t,i,f,m,v,g){l(i,t,f);var b,y,_,w=function(e){if(!d&&e in S)return S[e];switch(e){case"keys":case"values":return function(){return new i(this,e)}}return function(){return new i(this,e)}},x=t+" Iterator",C="values"==m,k=!1,S=e.prototype,D=S[h]||S["@@iterator"]||m&&S[m],$=D||w(m),E=m?C?w("entries"):$:void 0,T="Array"==t&&S.entries||D;if(T&&(_=c(T.call(new e)))!==Object.prototype&&_.next&&(u(_,x,!0),n||"function"==typeof _[h]||o(_,h,p)),C&&D&&"values"!==D.name&&(k=!0,$=function(){return D.call(this)}),n&&!g||!d&&!k&&S[h]||o(S,h,$),a[t]=$,a[x]=p,m)if(b={values:C?$:w("values"),keys:v?$:w("keys"),entries:E},g)for(y in b)y in S||s(S,y,b[y]);else r(r.P+r.F*(d||k),t,b);return b}},function(e,t,i){e.exports=i(7)},function(e,t,i){var n=i(17),r=i(69),s=i(29),o=i(27)("IE_PROTO"),a=function(){},l=function(){var e,t=i(36)("iframe"),n=s.length;for(t.style.display="none",i(70).appendChild(t),t.src="javascript:",(e=t.contentWindow.document).open(),e.write("
+
+
+
+
+
+
+
403
+
您没有足够的权限哦!
+
您正在试图访问一个没有事先授权的页面.或登录已失效。
+
5 秒后自动跳转登录页
+
立即跳转
+
+
+
+
+
\ No newline at end of file
diff --git a/admin/src/main/resources/templates/404.ftl b/admin/src/main/resources/templates/404.ftl
new file mode 100644
index 0000000..8de2c9e
--- /dev/null
+++ b/admin/src/main/resources/templates/404.ftl
@@ -0,0 +1,1696 @@
+
+
+
+
+ 404
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/admin/src/main/resources/templates/500.ftl b/admin/src/main/resources/templates/500.ftl
new file mode 100644
index 0000000..120de0f
--- /dev/null
+++ b/admin/src/main/resources/templates/500.ftl
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/admin/src/main/resources/templates/control/footer.ftl b/admin/src/main/resources/templates/control/footer.ftl
new file mode 100644
index 0000000..99ee1a7
--- /dev/null
+++ b/admin/src/main/resources/templates/control/footer.ftl
@@ -0,0 +1,5 @@
+
+
+ ------------------------------this is footer html------------------------------
+
+
diff --git a/admin/src/main/resources/templates/control/header.ftl b/admin/src/main/resources/templates/control/header.ftl
new file mode 100644
index 0000000..bf5115c
--- /dev/null
+++ b/admin/src/main/resources/templates/control/header.ftl
@@ -0,0 +1,119 @@
+
+
diff --git a/admin/src/main/resources/templates/control/macro.ftl b/admin/src/main/resources/templates/control/macro.ftl
new file mode 100644
index 0000000..2a92c3c
--- /dev/null
+++ b/admin/src/main/resources/templates/control/macro.ftl
@@ -0,0 +1,63 @@
+<#macro print items >
+<#nested>:
+ <#list items as item>
+ ${item}
+ #list>
+#macro>
+<#--
+ 参数说明:
+ pageNumber:当前的页码
+ pageSize:页码大小
+ totalCount:总数
+ showPages:显示的页码个数
+ callback:回调函数
+-->
+<#macro page pageNumber pageSize totalCount showPages callback>
+<#if totalCount gt 0>
+
+ <#assign totalPage = 0/>
+ <#assign totalPage = (totalCount/pageSize)?ceiling/>
+ <#if pageNumber==1>
+
首页
+
上一页
+ #if>
+ <#if pageNumber!=1>
+
首页
+
上一页
+ #if>
+ <#if pageNumber-showPages/2 gt 0>
+ <#assign start = pageNumber-(showPages-1)/2/>
+ <#if showPages gt totalPage>
+ <#assign start = 1/>
+ #if>
+ <#else>
+ <#assign start = 1/>
+ #if>
+ <#if totalPage gt showPages>
+ <#assign end = (start+showPages-1)/>
+ <#if end gt totalPage>
+ <#assign start = totalPage-showPages+1/>
+ <#assign end = totalPage/>
+ #if>
+ <#else>
+ <#assign end = totalPage/>
+ #if>
+ <#assign pages=start..end/>
+ <#list pages as page>
+ <#if page==pageNumber>
+
${page}
+ <#else>
+
${page}
+ #if>
+ #list>
+ <#if pageNumber==totalPage>
+
下一页
+
尾页
+ #if>
+ <#if pageNumber!=totalPage>
+
下一页
+
尾页
+ #if>
+
+#if>
+#macro>
\ No newline at end of file
diff --git a/admin/src/main/resources/templates/control/nav.ftl b/admin/src/main/resources/templates/control/nav.ftl
new file mode 100644
index 0000000..d157606
--- /dev/null
+++ b/admin/src/main/resources/templates/control/nav.ftl
@@ -0,0 +1,160 @@
+
\ No newline at end of file
diff --git a/admin/src/main/resources/templates/layout/app.ftl b/admin/src/main/resources/templates/layout/app.ftl
new file mode 100644
index 0000000..ee9c6be
--- /dev/null
+++ b/admin/src/main/resources/templates/layout/app.ftl
@@ -0,0 +1,217 @@
+
+
+
+
+
+
+ <#--baseJs-->
+
+ <#--移动端ui-->
+
+
+ <#--ajax接口-->
+
+
+
+
+<#include Layout.setControl("mint-ui-extend")/>
+
+
+
+
+
+
+
+
+
+
+ 返回
+
+
+
+
+ Hello world demo
+
+
+
+
+
+
+ 关闭
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 打印类容
+
+
+
+
+
+
+
diff --git a/admin/src/main/resources/templates/layout/default.ftl b/admin/src/main/resources/templates/layout/default.ftl
new file mode 100644
index 0000000..57da8ac
--- /dev/null
+++ b/admin/src/main/resources/templates/layout/default.ftl
@@ -0,0 +1,20 @@
+
+
+
+
+
+ <#--baseJs-->
+
+ <#--element-ui-->
+
+
+ <#--ajax接口-->
+
+
+
+
+<#include Layout.setControl("macro")/>
+<#include Layout.setControl("nav")/>
+<#include Layout.setScreen()/>
+
+
diff --git a/admin/src/main/resources/templates/layout/index.ftl b/admin/src/main/resources/templates/layout/index.ftl
new file mode 100644
index 0000000..f050748
--- /dev/null
+++ b/admin/src/main/resources/templates/layout/index.ftl
@@ -0,0 +1,15 @@
+
+
+
+
+
+ <#--baseJs-->
+
+ <#--element-ui-->
+
+
+
+
+<#include Layout.setScreen()/>
+
+
diff --git a/admin/src/main/resources/templates/screen/demo.ftl b/admin/src/main/resources/templates/screen/demo.ftl
new file mode 100644
index 0000000..ec9ad6a
--- /dev/null
+++ b/admin/src/main/resources/templates/screen/demo.ftl
@@ -0,0 +1,19 @@
+
+
+
+
+
diff --git a/admin/src/main/resources/templates/screen/home.ftl b/admin/src/main/resources/templates/screen/home.ftl
new file mode 100644
index 0000000..29c3c09
--- /dev/null
+++ b/admin/src/main/resources/templates/screen/home.ftl
@@ -0,0 +1,1121 @@
+
+
+
+
+
+ 主要颜色
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 中性色
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 主要框架
+
+
+
+ SpringBoot v2.1.2.RELEASE
+
+
+ Freemarker v2.1.2.RELEASE
+ Html模板引擎
+
+
+ pagehelper v1.2.5
+ 分页插件、提供便捷的分页功能
+
+
+ dozer v5.5.1
+ 对象复制拷贝
+
+
+ logback v1.2.3
+ 日志框架
+
+
+ jQuery v3.2.1
+ 前端JavaScript框架(保留),打包进base.min.js,但请尽量勿使用jQuery直接操作Dom
+
+
+ Vue v2.5.17
+ DOM渲染引擎
+
+
+ ElementUI v2.8.2
+ 前端UI框架,提供统一风格控件
+
+
+ Maven
+ 后端构建管理工具
+
+
+ JDK 8+
+ SpringBoot2.x开始不再支持JDK 7及以下,所以请将JDk升级到8+
+
+
+
+
+
+
+
+
+
+
+ 调用AJAX
+
+
+
+ ajax.example({}).then(function (response) {
+
+ if (response.errors.length > 0) {
+
+ nav.e(response.errors[0].message);
+
+ } else {
+
+ nav.i("Ajax调用成功!");
+
+ }
+
+ })
+
+
+
+
+
+ 点击上传
+ 只能上传jpg/png文件,且不超过500kb
+
+
+
+
+ ajax.fileUpload(req.file).then(function (response) {
+
+ if (response.errors.length > 0) {
+
+ req.onError();
+
+ nav.e(response.errors[0].message);
+
+ } else {
+
+ req.onSuccess();
+
+ nav.i("文件上传成功!");
+
+ }
+
+ })
+
+
+
+
+
+
+ 普通消息
+ 错误消息
+ 成功消息
+ 警告消息
+
+
+
+ 加载提示框
+ 关闭提示框
+
+
+
+ 加载提示条
+ 成功
+ 失败
+
+
+
+
+
+
+
+ 占位输出
+
+
+ 正常输出
+ ${r'${hello}'}
+
+
+ HTML输出
+ ${r"${'<a>a标签</a>'?html}"}
+
+
+ $表达式
+ ${r"${r'${hello}'}"}
+
+
+
+
+
+
+
+ 条件输出
+
+
+ ${'<#if status == 0>'}
+
+ status is 0
+
+ ${'<#elseif status ==1>'}
+
+ status = 1
+
+ ${'<#else>'}
+
+ status != 0 && status !=1
+
+ ${'</#if>'}
+
+
+
+
+
+
+
+ 遍历集合
+
+
+ ${'<#list citys as city>'}
+
+ ${r' ${city_index} --> ${city}'}
+
+ ${'</#list>'}
+
+
+
+
+
+
+
+
+
1、表单控件集合及验证
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 立即创建
+ 重置
+
+
+
+
+
+
+
2、表格数据
+
+
+
+
+
+
+ {{ scope.row.date }}
+
+
+
+
+
+
+
+ 编辑
+
+ 删除
+
+
+
+
+
+
+
+
+
+
3、分页
+
+
+
+
+
+
+
+
+
+
4、按钮
+
+
+
+ 默认按钮
+ 主要按钮
+ 成功按钮
+ 信息按钮
+ 警告按钮
+ 危险按钮
+
+
+
+ 朴素按钮
+ 主要按钮
+ 成功按钮
+ 信息按钮
+ 警告按钮
+ 危险按钮
+
+
+
+ 圆角按钮
+ 主要按钮
+ 成功按钮
+ 信息按钮
+ 警告按钮
+
+
+
+ 危险按钮
+ 加载中
+
+
+
+
+
+
+
+
+
+ 默认按钮
+ 主要按钮
+ 成功按钮
+ 信息按钮
+ 警告按钮
+ 危险按钮
+
+
+
+ 朴素按钮
+ 主要按钮
+ 成功按钮
+ 信息按钮
+ 警告按钮
+ 危险按钮
+
+
+ 文字按钮
+ 文字按钮
+
+
+
+
+
+ 搜索
+ 上传
+
+
+
+
+ 上一页
+ 下一页
+
+
+
+
+
+
+
+
+
+ 默认按钮
+ 中等按钮
+ 小型按钮
+ 超小按钮
+
+
+ 默认按钮
+ 中等按钮
+ 小型按钮
+ 超小按钮
+
+
+
+
+
+
5、Link 文字链接
+
+
+
+ 默认链接
+ 主要链接
+ 成功链接
+ 警告链接
+ 危险链接
+ 信息链接
+
+
+
+ 默认链接
+ 主要链接
+ 成功链接
+ 警告链接
+ 危险链接
+ 信息链接
+
+
+
+ 无下划线
+ 有下划线
+ 编辑
+ 查看
+
+
+
+
+
+
6、Tabs 标签页
+
+
+
+ 用户管理
+ 配置管理
+ 角色管理
+ 定时任务补偿
+
+
+
+ Tabs位置共有4个位置分别为:
+
+ top
+
+ right
+
+ bottom
+
+ left
+
+
+
+
+
+
7、弹框、对话框、通知
+
+
+
+
+ 消息
+
+
+ 通知
+
+
+ 消息Box
+
+
+ 消息确认Box
+
+
+
+ hover 激活
+
+
+
+
+ 对话框Dialog
+
+
+ 这是一段信息
+
+
+
+
+
+
+
+
+
+
6、其他小控件
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 标签一
+ 标签二
+ 标签三
+ 标签四
+ 标签五
+
+
+
+ 标签一
+ 标签二
+ 标签三
+ 标签四
+ 标签五
+
+
+
+ 默认标签
+ 中等标签
+ 小型标签
+ 超小标签
+
+
+
+
+ 评论
+
+
+ 回复
+
+
+ 评论
+
+
+ 回复
+
+
+ 数据查询
+
+
+
+
+
+
+
+ 评论(最大值)
+
+
+ 回复(最大值)
+
+
+
+ 评论
+
+
+ 回复
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 首页
+ 活动管理
+ 活动列表
+ 活动详情
+
+
+
+
+
+ 下拉菜单
+
+ 黄金糕
+ 狮子头
+ 螺蛳粉
+ 双皮奶
+ 蚵仔煎
+
+
+
+
+ 默认尺寸
+
+ 黄金糕
+ 狮子头
+ 螺蛳粉
+ 双皮奶
+ 蚵仔煎
+
+
+
+
+ 中等尺寸
+
+ 黄金糕
+ 狮子头
+ 螺蛳粉
+ 双皮奶
+ 蚵仔煎
+
+
+
+
+ 小型尺寸
+
+ 黄金糕
+ 狮子头
+ 螺蛳粉
+ 双皮奶
+ 蚵仔煎
+
+
+
+
+ 超小尺寸
+
+ 黄金糕
+ 狮子头
+ 螺蛳粉
+ 双皮奶
+ 蚵仔煎
+
+
+
+
+ 头上一片晴天,心中一个想念
+ 少年包青天
+ 饿了别叫妈, 叫饿了么
+
+ 为了无法计算的价值
+ 阿里云
+
+
+
+ 雨纷纷
+
+ 旧故里
+
+ 草木深
+
+
+
+
+
+
+
+
+
+
1、页面初始化前闪现源代码
+
+
+ ${''?html}
+
+
+ ${'
'?html}
+
+
${'...'?html}
+
+
${'
'?html}
+
+
+
+
+
2、为什么Long类型返回json字符串变为String
+
+
+ 因为Long可支持的长度比JavaScript中Number支持的位数更多,所以当Long数值很大时转为Json再转为Number就会丢失精度,造成难以发现的Bug,所以本系统默认处理了该问题。
+
+
+
+
+
3、Date类型格式化问题
+
+
+ 默认启用全局Date格式化
+ yyyy-MM-dd HH:mm:ss
+ ,需要关闭请在
+ application-*
+ 中关闭。
+
+
+ 对于个别返回结果的Date格式化可以通过注解方式
+ @JsonFormat(pattern = "yyyy-MM-dd")
+
+
+
+
+
+
+
4、权限问题
+
+
+ 1、本系统启用自定义Token来控制权限,任何访问都会有一个全局Token,任何一处都可以通过
+ LocalData.getToken()
+ 来获取
+ 当前访问对象的Token。其中Token充当着访问对象的通行证,其中包含访问对象的
+ 用户ID
+ 、
+ 用户名
+ 、
+ 可访问资源
+ 等信息。
+
+
+ 2、对于未登录对象会提供临时(访客)
+ LocalData.getTempToken()
+ (有限的权限)来提供访问系统。
+
+
+ 3、如果系统存在Task等定时任务时,是不存在访问对象,通过
+ LocalData.getSystemToken()
+ 来获取系统层的Token来操作系统。
+
+
+
+
+
+
+
5、Token配置
+
+
+ Springboot环境配置文件application-* 中配置了系统中需要验证权限和不需要验证的url。而需要验证权限的URl会在
+ SecurityConfig.getAuthorization()
+ 方法中通过Parameter或Cookies中获取当前访问对象的登录信息,从而为当前访问对象组装Token对象。
+
+
+
+
+
+
+
+
+
diff --git a/admin/src/main/resources/templates/screen/index.ftl b/admin/src/main/resources/templates/screen/index.ftl
new file mode 100644
index 0000000..d893aeb
--- /dev/null
+++ b/admin/src/main/resources/templates/screen/index.ftl
@@ -0,0 +1,342 @@
+
+
+
+
+
+
+ 系统设置
+
+ 用户管理
+ 机构管理
+ 角色管理
+
+
+
+
+ 日志管理
+
+ 登录日志
+
+
+
+
+
+
+
+
+
diff --git a/admin/src/main/resources/templates/screen/login.ftl b/admin/src/main/resources/templates/screen/login.ftl
new file mode 100644
index 0000000..4f04ae0
--- /dev/null
+++ b/admin/src/main/resources/templates/screen/login.ftl
@@ -0,0 +1,134 @@
+
+
+
+
系统登录
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 登录
+
+
+
+
+
系统登录
+
+
+
+
+
+
+
diff --git a/admin/src/test/java/com/example/UtilTest.java b/admin/src/test/java/com/example/UtilTest.java
new file mode 100644
index 0000000..7a425e0
--- /dev/null
+++ b/admin/src/test/java/com/example/UtilTest.java
@@ -0,0 +1,88 @@
+package com.example;
+
+import com.example.frame.utils.*;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.transaction.annotation.Transactional;
+
+/**
+ * UtilTest - - 测试用例
+ *
+ * @author wangbing
+ * @version 0.0.1
+ * @since 2017-01-01
+ */
+@RunWith(SpringRunner.class)
+@SpringBootTest
+@Transactional
+public class UtilTest {
+
+ @Test
+ public void testIDgenerator() {
+ for (int i = 0; i < 10; i++) {
+ long l = IDgenerator.nextId();
+ System.out.println(l);
+ }
+ }
+
+ @Test
+ public void testAESUtil() {
+ // 加密
+ String data = "我有一个苹果";
+ String secret = "1234567890123456";
+ System.out.println("加密后的Base64密文是:" + AESUtil.encrypt2Base64(data.getBytes(), secret));
+
+ // 解密
+ String encrypt2Base64 = AESUtil.encrypt2Base64(data.getBytes(), secret);
+ byte[] decrypt = AESUtil.decrypt(Base64Util.decode(encrypt2Base64), secret);
+ System.out.println("解密后的明文是:" + new String(decrypt));
+ }
+
+ @Test
+ public void testBase64Util() {
+ String s = Base64Util.encodeToString(("我搜搜").getBytes());
+ System.out.println(s);
+
+ byte[] decode = Base64Util.decode(s);
+ System.out.println(new String(decode));
+ }
+
+ @Test
+ public void testMD5Util() {
+ String encode = MD5Util.encode("123456");
+ System.out.println(encode);
+ }
+
+ @Test
+ public void testProcessUtil() {
+ ProcessUtil.execExe("D:\\example.exe");
+ ProcessUtil.execBat("D:\\example.bat");
+ }
+
+ @Test
+ public void testRSAUtil() {
+ {//创建秘钥对
+ RSAUtil.createKey();
+ }
+
+ {//加解密
+
+ //加密
+ String encrypt = RSAUtil.encrypt2Base64("我有一个苹果".getBytes());
+ System.out.println(encrypt);
+
+ //解密
+ String decrypt = RSAUtil.decrypt2String(encrypt);
+ System.out.println(decrypt);
+ }
+
+
+ String sign = RSAUtil.sign2Base64("我有一个苹果".getBytes());
+ System.out.println(sign);
+
+ boolean b = RSAUtil.doCheck("我有一个苹果".getBytes(), sign);
+ System.out.println(b);
+ }
+}
diff --git a/admin/src/test/java/com/example/config/TestConfig.java b/admin/src/test/java/com/example/config/TestConfig.java
new file mode 100644
index 0000000..f0b4e4c
--- /dev/null
+++ b/admin/src/test/java/com/example/config/TestConfig.java
@@ -0,0 +1,17 @@
+package com.example.config;
+
+import com.example.frame.base.Token;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+@Configuration
+public class TestConfig {
+
+ @Bean
+ public Token getTestToken() {
+ Token token = new Token();
+ token.setId(0);
+ token.setUserId(0);
+ token.setUserName("system");
+ return token;
+ }
+}
\ No newline at end of file
diff --git a/admin/src/test/resources/application.properties b/admin/src/test/resources/application.properties
new file mode 100644
index 0000000..56fc5aa
--- /dev/null
+++ b/admin/src/test/resources/application.properties
@@ -0,0 +1,63 @@
+# 测试环境
+server.port=8080
+server.servlet.context-path=/
+spring.mvc.static-path-pattern=/static/**
+spring.resources.static-locations=classpath:static/
+spring.application.name=SpringBoot
+spring.main.banner-mode=CONSOLE
+spring.devtools.restart.enabled=true
+# 编码配置
+spring.http.encoding.force=true
+spring.http.encoding.charset=UTF-8
+spring.http.encoding.enabled=true
+server.tomcat.uri-encoding=UTF-8
+# 根路径、欢迎页
+web.welcome.page=/index.htm
+# 需要验证授权, 既访问时组装Token
+web.url.auth.included=/**
+# 不需要验证授权, 或该请求有自己的验证机制
+web.url.auth.excluded=/favicon.ico,/static/**,/api,/login.htm
+# 日志配置
+logging.path=D://
+logging.levels=DEBUG
+logging.config=classpath:logback-config.xml
+# mysql
+spring.datasource.driver-class-name=com.mysql.jdbc.Driver
+spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf-8
+spring.datasource.username=test
+spring.datasource.password=123456
+# mybatis
+mybatis.mapper-locations=classpath:**/mpr/*.xml
+# pagehelper
+pagehelper.autoRuntimeDialect=true
+pagehelper.reasonable=true
+pagehelper.supportMethodsArguments=true
+pagehelper.params=count=countSql
+# jackson 相关配置
+spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
+spring.jackson.time-zone=GMT+8
+spring.jackson.default-property-inclusion=use_defaults
+spring.jackson.mapper.sort-properties-alphabetically=true
+spring.jackson.deserialization.fail-on-unknown-properties=false
+# freemarker
+spring.freemarker.enabled=true
+spring.freemarker.allow-request-override=false
+spring.freemarker.cache=true
+spring.freemarker.check-template-location=true
+spring.freemarker.charset=UTF-8
+spring.freemarker.content-type=text/html
+spring.freemarker.expose-request-attributes=false
+spring.freemarker.expose-session-attributes=false
+spring.freemarker.expose-spring-macro-helpers=false
+spring.freemarker.settings.template_update_delay=1
+spring.freemarker.settings.locale=zh_CN
+spring.freemarker.settings.datetime_format=yyyy-MM-dd
+spring.freemarker.settings.date_format=yyyy-MM-dd
+spring.freemarker.settings.number_format=#.##
+spring.freemarker.settings.classic_compatible=true
+spring.freemarker.settings.whitespace_stripping=true
+spring.freemarker.settings.url_escaping_charset=utf-8
+# 文件上传配置
+spring.servlet.multipart.resolveLazily=false
+spring.servlet.multipart.max-file-size=100MB
+spring.servlet.multipart.max-request-size=100MB
\ No newline at end of file
diff --git a/admin/src/test/resources/logback-config.xml b/admin/src/test/resources/logback-config.xml
new file mode 100644
index 0000000..5d80b9f
--- /dev/null
+++ b/admin/src/test/resources/logback-config.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+ debug级别及以上
+
+ DEBUG
+
+
+ %highlight(%d{yyyy-MM-dd HH:mm:ss.SSS} [%-4level] [%thread] [%logger{36}-%method] %ex %msg%n)
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..b561422
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,80 @@
+
+
+ 4.0.0
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.1.2.RELEASE
+
+
+
+ xyz.wbsite
+ nginx-admin
+ 1.0-SNAPSHOT
+
+
+ UTF-8
+ UTF-8
+ 1.8
+ true
+ 2.6
+ 1.2.5
+ 1.3.2
+ 1.1.0
+ 5.5.1
+ Greenwich.RC2
+ 1.0-SNAPSHOT
+
+
+
+
+
+
+ org.springframework.cloud
+ spring-cloud-dependencies
+ ${spring-cloud.version}
+ pom
+ import
+
+
+
+ com.github.pagehelper
+ pagehelper-spring-boot-starter
+ ${pagehelper-version}
+
+
+
+ org.mybatis.spring.boot
+ mybatis-spring-boot-starter
+ ${mybatis-version}
+
+
+
+ org.mybatis.caches
+ mybatis-ehcache
+ ${ehcache-version}
+
+
+
+ net.sf.dozer
+ dozer
+ ${dozer-version}
+
+
+
+ commons-io
+ commons-io
+ ${commons-io-version}
+
+
+
+ xyz.wbsite
+ wsqlite
+ ${wsqlite}
+
+
+
+
\ No newline at end of file
diff --git a/wsqlite/pom.xml b/wsqlite/pom.xml
new file mode 100644
index 0000000..559ebae
--- /dev/null
+++ b/wsqlite/pom.xml
@@ -0,0 +1,24 @@
+
+
+ 4.0.0
+
+
+ xyz.wbsite
+ nginx-admin
+ 1.0-SNAPSHOT
+
+
+ xyz.wbsite
+ wsqlite
+ 1.0-SNAPSHOT
+
+
+
+ org.xerial
+ sqlite-jdbc
+ 3.14.2.1
+
+
+
\ No newline at end of file
diff --git a/wsqlite/src/main/java/xyz/wbsite/wsqlite/Client.java b/wsqlite/src/main/java/xyz/wbsite/wsqlite/Client.java
new file mode 100644
index 0000000..1f98fb8
--- /dev/null
+++ b/wsqlite/src/main/java/xyz/wbsite/wsqlite/Client.java
@@ -0,0 +1,125 @@
+package xyz.wbsite.wsqlite;
+
+import java.io.File;
+import java.sql.*;
+
+/**
+ * xyz.wbsite.wsqlite.Client
+ *
+ * @author wangbing
+ */
+public class Client {
+
+ Connection connection;
+ Statement statement;
+ ResultSet resultSet;
+ String dbFilePath;
+
+ /**
+ * 构造函数
+ *
+ * @param dbFile 文件
+ * @throws ClassNotFoundException
+ * @throws SQLException
+ */
+ public Client(File dbFile) throws ClassNotFoundException, SQLException {
+ this.dbFilePath = dbFile.getAbsolutePath();
+ if (!dbFile.exists()) {
+ connection = getConnection();
+ }
+ }
+
+ /**
+ * 执行sql语句
+ *
+ * @param sql
+ * @throws SQLException
+ * @throws ClassNotFoundException
+ */
+ public void execute(String sql) throws SQLException, ClassNotFoundException {
+ try {
+ getStatement().execute(sql);
+ } finally {
+ destroyed();
+ }
+ }
+
+ /**
+ * 执行sql查询语句
+ *
+ * @param sql
+ * @throws SQLException
+ * @throws ClassNotFoundException
+ */
+ public ResultSet executeQuery(String sql) throws SQLException, ClassNotFoundException {
+ return getStatement().executeQuery(sql);
+ }
+
+ /**
+ * 执行sql更新语句
+ *
+ * @param sqls
+ * @throws SQLException
+ * @throws ClassNotFoundException
+ */
+ public int executeUpdate(String... sqls) throws SQLException, ClassNotFoundException {
+ int count = 0;
+ try {
+ for (String sql : sqls) {
+ count += getStatement().executeUpdate(sql);
+ }
+ } finally {
+ destroyed();
+ }
+ return count;
+ }
+
+ /**
+ * 获取数据库连接
+ *
+ * @return 数据库连接
+ * @throws ClassNotFoundException
+ * @throws SQLException
+ */
+ Connection getConnection() throws ClassNotFoundException, SQLException {
+ if (null == connection) {
+ Class.forName("org.sqlite.JDBC");
+ connection = DriverManager.getConnection("jdbc:sqlite:" + dbFilePath);
+ }
+ return connection;
+ }
+
+ /**
+ * 获取数据库Statement对象
+ */
+ Statement getStatement() throws SQLException, ClassNotFoundException {
+ if (null == statement) {
+ statement = getConnection().createStatement();
+ }
+ return statement;
+ }
+
+ /**
+ * 数据库资源关闭和释放
+ */
+ public void destroyed() {
+ try {
+ if (null != resultSet) {
+ resultSet.close();
+ resultSet = null;
+ }
+
+ if (null != statement) {
+ statement.close();
+ statement = null;
+ }
+ if (null != connection) {
+ connection.close();
+ connection = null;
+ }
+
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ }
+}
\ No newline at end of file
diff --git a/wsqlite/src/main/java/xyz/wbsite/wsqlite/ObjectClient.java b/wsqlite/src/main/java/xyz/wbsite/wsqlite/ObjectClient.java
new file mode 100644
index 0000000..eb3e7f0
--- /dev/null
+++ b/wsqlite/src/main/java/xyz/wbsite/wsqlite/ObjectClient.java
@@ -0,0 +1,307 @@
+package xyz.wbsite.wsqlite;
+
+import xyz.wbsite.wsqlite.anonation.TableField;
+
+import java.io.File;
+import java.lang.reflect.Field;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * xyz.wbsite.wsqlite.Client
+ *
+ * @author wangbing
+ */
+public class ObjectClient extends Client {
+
+ private Map classMap = new HashMap();
+
+ /**
+ * 构造函数
+ *
+ * @param dbFile 文件
+ * @param classList 注册对象
+ * @throws ClassNotFoundException
+ * @throws SQLException
+ */
+ public ObjectClient(File dbFile, List classList) throws ClassNotFoundException, SQLException {
+ super(dbFile);
+ for (Class aClass : classList) {
+ classMap.put(aClass.getName(), aClass);
+ }
+ for (String key : classMap.keySet()) {
+ Class object = classMap.get(key);
+ StringBuffer sql = new StringBuffer();
+ String name = object.getSimpleName();
+
+ sql.append("CREATE TABLE IF NOT EXISTS ");
+ sql.append(name);
+ sql.append(" (");
+
+ Field[] fields = object.getDeclaredFields();
+ for (Field f : fields) {
+ if (f.isAnnotationPresent(TableField.class)) {
+ TableField bind = f.getAnnotation(TableField.class);
+ int length = bind.value();
+
+ if (f.getType() == String.class) {
+ sql.append(f.getName().toUpperCase());
+ sql.append(" VARCHAR(" + length + "),");
+ } else if (f.getType() == Boolean.class || f.getType() == boolean.class) {
+ sql.append(f.getName().toUpperCase());
+ sql.append(" BOOLEAN,");
+ }
+ }
+ }
+
+ sql.replace(sql.length() - 1, sql.length(), "");
+ sql.append(")");
+ System.out.println("SQL ==> " + sql.toString());
+ execute(sql.toString());
+ }
+ }
+
+ public void insert(Class poClass, T po) throws SQLException, ClassNotFoundException {
+ try {
+ Class aClass = classMap.get(poClass.getName());
+ if (aClass == null) {
+ System.err.println(poClass.getName() + " not found.");
+ } else {
+ StringBuffer sql = new StringBuffer();
+ sql.append("INSERT INTO ");
+ sql.append(aClass.getSimpleName());
+ sql.append("(");
+
+ //获取字段列表
+ List fs = getFields(poClass);
+
+ StringBuffer fieldsSql = new StringBuffer();
+ StringBuffer valueSql = new StringBuffer();
+
+ for (int i = 0; i < fs.size(); i++) {
+ Field f = fs.get(i);
+ f.setAccessible(true);
+ fieldsSql.append(f.getName().toUpperCase());
+
+ Object value = f.get(po);
+ if (f.getType() == String.class) {
+ valueSql.append("'");
+ valueSql.append(value);
+ valueSql.append("'");
+ } else if (f.getType() == Boolean.class || f.getType() == boolean.class) {
+ valueSql.append("'");
+ valueSql.append(String.valueOf(value));
+ valueSql.append("'");
+ } else {
+ valueSql.append(value);
+ }
+ if (i != fs.size() - 1) {
+ fieldsSql.append(",");
+ valueSql.append(",");
+ }
+ }
+
+ sql.append(fieldsSql);
+ sql.append(") VALUES (");
+ sql.append(valueSql);
+ sql.append(")");
+ System.out.println("SQL ==> " + sql.toString());
+ executeUpdate(sql.toString());
+ }
+ } catch (IllegalAccessException e) {
+ e.printStackTrace();
+ } finally {
+ destroyed();
+ }
+ }
+
+ public int delete(Class poClass, String... wheres) throws SQLException, ClassNotFoundException {
+ try {
+ Class aClass = classMap.get(poClass.getName());
+ if (aClass == null) {
+ System.err.println(poClass.getName() + " not found.");
+ } else {
+ StringBuffer sql = new StringBuffer();
+ sql.append("DELETE FROM ");
+ sql.append(aClass.getSimpleName());
+
+ if (wheres.length > 0) {
+ sql.append(" WHERE ");
+ for (int i = 0; i < wheres.length; i++) {
+ String where = wheres[i];
+ sql.append(where);
+ sql.append(i != wheres.length - 1 ? " AND " : "");
+ }
+ }
+ return executeUpdate(sql.toString());
+ }
+ } finally {
+ destroyed();
+ }
+ return 0;
+ }
+
+ public int update(Class poClass, T po, String... wheres) throws SQLException, ClassNotFoundException {
+ try {
+ Class aClass = classMap.get(poClass.getName());
+ if (aClass == null) {
+ System.err.println(poClass.getName() + " not found.");
+ } else {
+ StringBuffer sql = new StringBuffer();
+ sql.append("UPDATE ");
+ sql.append(aClass.getSimpleName());
+ sql.append(" SET ");
+
+ //获取字段列表
+ List fs = getFields(poClass);
+
+ for (int i = 0; i < fs.size(); i++) {
+ Field f = fs.get(i);
+ f.setAccessible(true);
+ sql.append(f.getName());
+ sql.append(" = ");
+
+ Object value = f.get(po);
+ if (f.getType() == String.class) {
+ sql.append("'");
+ sql.append(value);
+ sql.append("'");
+ } else if (f.getType() == Boolean.class || f.getType() == boolean.class) {
+ sql.append("'");
+ sql.append(String.valueOf(value));
+ sql.append("'");
+ } else {
+ sql.append(value);
+ }
+ if (i != fs.size() - 1) {
+ sql.append(",");
+ }
+ }
+
+ if (wheres.length > 0) {
+ sql.append(" WHERE ");
+ for (int i = 0; i < wheres.length; i++) {
+ String where = wheres[i];
+ sql.append(where);
+ sql.append(i != wheres.length - 1 ? " AND " : "");
+ }
+ }
+
+ System.out.println("SQL ==> " + sql.toString());
+ return executeUpdate(sql.toString());
+ }
+ } catch (IllegalAccessException e) {
+ e.printStackTrace();
+ } finally {
+ destroyed();
+ }
+ return 0;
+ }
+
+ public List select(Class poClass, int pageNumber, int pageSize, String... wheres) throws SQLException, ClassNotFoundException {
+ ArrayList list = new ArrayList();
+ try {
+ Class aClass = classMap.get(poClass.getName());
+ if (aClass == null) {
+ System.err.println(poClass.getName() + " not found.");
+ } else {
+ StringBuffer sql = new StringBuffer();
+ sql.append("SELECT ");
+
+ //获取字段列表
+ List fs = getFields(poClass);
+
+ for (int i = 0; i < fs.size(); i++) {
+ Field f = fs.get(i);
+ sql.append(f.getName().toUpperCase());
+ if (i != fs.size() - 1) {
+ sql.append(",");
+ }
+ }
+
+ sql.append(" FROM ");
+ sql.append(aClass.getSimpleName());
+
+ //条件参数
+ if (wheres.length > 0) {
+ sql.append(" WHERE ");
+ for (int i = 0; i < wheres.length; i++) {
+ String where = wheres[i];
+ sql.append(where);
+ sql.append(i != wheres.length - 1 ? " AND " : "");
+ }
+ }
+
+ //分页参数
+ sql.append(" LIMIT " + (pageNumber - 1) + "," + pageSize);
+
+ System.out.println("SQL ==> " + sql.toString());
+ list.addAll(executeQuery(sql.toString(), poClass));
+ }
+ } finally {
+ destroyed();
+ }
+ return list;
+ }
+
+ /**
+ * 执行select查询,返回结果列表
+ *
+ * @param sql sql select 语句
+ * @param poClass 结果集的行数据处理类对象
+ * @return
+ * @throws SQLException
+ * @throws ClassNotFoundException
+ */
+ public List executeQuery(String sql, Class poClass) throws SQLException, ClassNotFoundException {
+ List rsList = new ArrayList();
+ try {
+ resultSet = executeQuery(sql);
+
+ //获取字段列表
+ List fs = getFields(poClass);
+
+ while (resultSet.next()) {
+ try {
+ T o = poClass.newInstance();
+ for (int i = 0; i < fs.size(); i++) {
+ Field f = fs.get(i);
+ f.setAccessible(true);
+
+ if (f.getType() == String.class) {
+ String string = resultSet.getString(f.getName());
+ f.set(o, string);
+ } else if (f.getType() == Boolean.class || f.getType() == boolean.class) {
+ boolean b = resultSet.getBoolean(f.getName());
+ f.set(o, b);
+ } else {
+ String string = resultSet.getString(f.getName());
+ f.set(o, string);
+ }
+ }
+ rsList.add(o);
+ } catch (InstantiationException e) {
+ e.printStackTrace();
+ } catch (IllegalAccessException e) {
+ e.printStackTrace();
+ }
+ }
+ } finally {
+ destroyed();
+ }
+ return rsList;
+ }
+
+ private List getFields(Class aClass) {
+ List fs = new ArrayList();
+ for (Field f : aClass.getDeclaredFields()) {
+ if (f.isAnnotationPresent(TableField.class)) {
+ fs.add(f);
+ }
+ }
+ return fs;
+ }
+}
\ No newline at end of file
diff --git a/wsqlite/src/main/java/xyz/wbsite/wsqlite/anonation/TableField.java b/wsqlite/src/main/java/xyz/wbsite/wsqlite/anonation/TableField.java
new file mode 100644
index 0000000..838c286
--- /dev/null
+++ b/wsqlite/src/main/java/xyz/wbsite/wsqlite/anonation/TableField.java
@@ -0,0 +1,13 @@
+package xyz.wbsite.wsqlite.anonation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface TableField {
+
+ int value() default 20;
+}
diff --git a/wsqlite/src/main/java/xyz/wbsite/wsqlite/entity/User.java b/wsqlite/src/main/java/xyz/wbsite/wsqlite/entity/User.java
new file mode 100644
index 0000000..97d27ce
--- /dev/null
+++ b/wsqlite/src/main/java/xyz/wbsite/wsqlite/entity/User.java
@@ -0,0 +1,37 @@
+package xyz.wbsite.wsqlite.entity;
+
+import xyz.wbsite.wsqlite.anonation.TableField;
+
+public class User {
+
+ @TableField(40)
+ private String name;
+ @TableField(40)
+ private String password;
+ @TableField
+ private boolean valid;
+
+ public boolean isValid() {
+ return valid;
+ }
+
+ public void setValid(boolean valid) {
+ this.valid = valid;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+}
diff --git a/wsqlite/src/test/java/SqliteTest.java b/wsqlite/src/test/java/SqliteTest.java
new file mode 100644
index 0000000..16d2368
--- /dev/null
+++ b/wsqlite/src/test/java/SqliteTest.java
@@ -0,0 +1,42 @@
+import xyz.wbsite.wsqlite.ObjectClient;
+import xyz.wbsite.wsqlite.entity.User;
+
+import java.io.File;
+import java.sql.*;
+import java.util.ArrayList;
+import java.util.List;
+
+public class SqliteTest {
+ public static void main(String[] args) {
+ try {
+ List arrayList = new ArrayList();
+ arrayList.add(User.class);
+ ObjectClient h = new ObjectClient(new File("D:\\test.db"),arrayList);
+
+ System.out.println("测试 insert");
+ User user = new User();
+ user.setName("wangbing");
+ user.setPassword("test");
+ h.insert(User.class, user);
+
+ System.out.println("测试 select");
+ List select = h.select(User.class,1,10);
+ System.out.println(select.size());
+
+ System.out.println("测试 update");
+ user.setName("==");
+ user.setPassword("==");
+ int update = h.update(User.class, user);
+ System.out.println(update);
+
+ System.out.println("测试 delete");
+ int delete = h.delete(User.class,"NAME = '=='");
+ System.out.println(delete);
+
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ }
+}
\ No newline at end of file