parent
73edc94e0e
commit
a394852b42
@ -0,0 +1,25 @@
|
||||
package xyz.wbsite.dbtool.web.action.ajax.system;
|
||||
|
||||
import xyz.wbsite.dbtool.web.frame.auth.LocalData;
|
||||
import xyz.wbsite.dbtool.web.frame.base.BaseResponse;
|
||||
|
||||
import javax.servlet.http.Cookie;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
public class AuthAjax {
|
||||
|
||||
public BaseResponse login(String jsonParam) {
|
||||
BaseResponse baseResponse = new BaseResponse();
|
||||
|
||||
// todo 设置cookie
|
||||
HttpServletRequest request = LocalData.getRequest();
|
||||
HttpServletResponse response = LocalData.getResponse();
|
||||
Cookie token = new Cookie("token", "");
|
||||
token.setDomain(request.getServerName());
|
||||
token.setPath("/");
|
||||
response.addCookie(token);
|
||||
|
||||
return baseResponse;
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package xyz.wbsite.dbtool.web.action.control;
|
||||
|
||||
import xyz.wbsite.dbtool.web.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) {
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package xyz.wbsite.dbtool.web.action.screen;
|
||||
|
||||
import xyz.wbsite.dbtool.web.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<String> citys = new ArrayList<>();
|
||||
citys.add("北京");
|
||||
citys.add("上海");
|
||||
citys.add("深圳");
|
||||
model.addAttribute("citys", citys);
|
||||
}
|
||||
}
|
@ -0,0 +1,124 @@
|
||||
package xyz.wbsite.dbtool.web.config;
|
||||
|
||||
import xyz.wbsite.dbtool.web.frame.auth.LocalData;
|
||||
import xyz.wbsite.dbtool.web.frame.base.Control;
|
||||
import xyz.wbsite.dbtool.web.frame.utils.UrlUtil;
|
||||
import freemarker.template.SimpleScalar;
|
||||
import freemarker.template.TemplateMethodModelEx;
|
||||
import freemarker.template.TemplateModelException;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
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.annotation.PostConstruct;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import static xyz.wbsite.dbtool.web.config.ActionConfig.CONTROL_PREFIX;
|
||||
import static xyz.wbsite.dbtool.web.config.ActionConfig.SCREEN_PREFIX;
|
||||
|
||||
@Configuration
|
||||
public class FreeMarkerConfig {
|
||||
@Autowired
|
||||
private FreeMarkerViewResolver viewResolver;
|
||||
@Autowired
|
||||
private freemarker.template.Configuration configuration;
|
||||
@Value("${server.servlet.context-path}")
|
||||
private String context;
|
||||
|
||||
private String suffix = ".ftl";
|
||||
|
||||
@PostConstruct
|
||||
public void setSharedVariable() throws TemplateModelException {
|
||||
// 全局共享变量、函数
|
||||
configuration.setSharedVariable("context", context);
|
||||
configuration.setSharedVariable("screenHolder", new ScreenHolder());
|
||||
configuration.setSharedVariable("controlHolder", new ControlHolder());
|
||||
configuration.setSharedVariable("UrlUtil", new UrlUtil());
|
||||
}
|
||||
|
||||
private class ScreenHolder implements TemplateMethodModelEx {
|
||||
|
||||
@Override
|
||||
public Object exec(List list) throws TemplateModelException {
|
||||
try {
|
||||
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
|
||||
LocaleResolver localeResolver = (LocaleResolver) request.getAttribute(DispatcherServlet.LOCALE_RESOLVER_ATTRIBUTE);
|
||||
String servletPath = LocalData.getAction();
|
||||
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 SCREEN_PREFIX + servletPath + suffix;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
private class ControlHolder implements TemplateMethodModelEx {
|
||||
|
||||
@Override
|
||||
public Object exec(List list) throws TemplateModelException {
|
||||
String control = "";
|
||||
if (list.size() != 1) {
|
||||
return "";
|
||||
}
|
||||
Object o = list.get(0);
|
||||
if (o instanceof SimpleScalar) {
|
||||
control = ((SimpleScalar) o).getAsString();
|
||||
}
|
||||
|
||||
// 查找是否存在对应控制面板执行器
|
||||
Control controlExec = null;
|
||||
try {
|
||||
String beanClassName = (CONTROL_PREFIX + control).toLowerCase();
|
||||
controlExec = LocalData.getApplicationContext().getBean(beanClassName, 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 CONTROL_PREFIX + control + suffix;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,119 @@
|
||||
package xyz.wbsite.dbtool.web.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.builders.WebSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||
import org.springframework.security.config.http.SessionCreationPolicy;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import xyz.wbsite.dbtool.web.frame.base.Token;
|
||||
import xyz.wbsite.dbtool.web.frame.utils.CookieUtil;
|
||||
import xyz.wbsite.dbtool.web.frame.auth.LocalData;
|
||||
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
|
||||
|
||||
import javax.servlet.*;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.IOException;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@Configuration
|
||||
@EnableGlobalMethodSecurity(securedEnabled = true)
|
||||
public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
||||
|
||||
@Value("${web.url.auth.included}")
|
||||
private String[] included;
|
||||
@Value("${web.url.auth.excluded}")
|
||||
private String[] excluded;
|
||||
@Value("${spring.mvc.static-path-pattern}")
|
||||
private String[] staticPath;
|
||||
|
||||
@Override
|
||||
public void configure(WebSecurity web) throws Exception {
|
||||
web.ignoring().mvcMatchers(staticPath);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
|
||||
.and()
|
||||
.addFilterBefore(new TokenFilter(), FilterSecurityInterceptor.class)// 过滤器用于处理Token
|
||||
.authorizeRequests()
|
||||
.antMatchers(excluded).permitAll()// 放行排除的URL
|
||||
.antMatchers(included).access("@Authorization.hasPermission(request,authentication)")// 需要权限的URL
|
||||
.and().cors()
|
||||
.and().headers().frameOptions().disable()
|
||||
.and().csrf().disable();
|
||||
}
|
||||
|
||||
/**
|
||||
* 此方法不要删除 用于屏蔽默认用户密码生成
|
||||
* <p>
|
||||
* 例如 Using generated security password: f6b42a66-71b1-4c31-b6a8-942838c81408
|
||||
*
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
@Bean
|
||||
public AuthenticationManager authenticationManagerBean() throws Exception {
|
||||
return super.authenticationManagerBean();
|
||||
}
|
||||
|
||||
public static class TokenFilter implements Filter {
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
|
||||
HttpServletRequest request = (HttpServletRequest) servletRequest;
|
||||
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(".*");
|
||||
LocalData.setToken(token1);
|
||||
}
|
||||
|
||||
// Action
|
||||
String servletPath = request.getServletPath();
|
||||
Pattern compile = Pattern.compile("^/(.+)\\.htm");
|
||||
Matcher matcher = compile.matcher(servletPath);
|
||||
if (matcher.find()) {
|
||||
LocalData.setAction(matcher.group(1));
|
||||
}
|
||||
|
||||
filterChain.doFilter(servletRequest, servletResponse);
|
||||
}
|
||||
}
|
||||
|
||||
@Bean("Authorization")
|
||||
public Object getAuthorization() {
|
||||
return new Object() {
|
||||
public boolean hasPermission(HttpServletRequest request, Authentication authentication) {
|
||||
|
||||
// 授权
|
||||
Token token_ = LocalData.getToken();
|
||||
if (token_.hasResource(request.getServletPath())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package xyz.wbsite.dbtool.web.framework.config;
|
||||
package xyz.wbsite.dbtool.web.config;
|
||||
|
||||
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
|
||||
import org.springframework.context.annotation.Configuration;
|
@ -1,70 +0,0 @@
|
||||
package xyz.wbsite.dbtool.web.controller;
|
||||
|
||||
import xyz.wbsite.dbtool.web.framework.LocalData;
|
||||
import xyz.wbsite.dbtool.web.framework.Message;
|
||||
import xyz.wbsite.dbtool.web.framework.base.BaseResponse;
|
||||
import xyz.wbsite.dbtool.web.framework.base.Error;
|
||||
import xyz.wbsite.dbtool.web.framework.base.ErrorType;
|
||||
import xyz.wbsite.dbtool.web.framework.base.Token;
|
||||
import xyz.wbsite.dbtool.web.framework.utils.LogUtil;
|
||||
import xyz.wbsite.dbtool.web.framework.utils.MapperUtil;
|
||||
import com.fasterxml.jackson.core.TreeNode;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStreamReader;
|
||||
|
||||
public class AjaxController {
|
||||
|
||||
@RequestMapping("/ajax")
|
||||
public BaseResponse ajax(@RequestParam("method") String method, HttpServletRequest request, HttpServletResponse response) {
|
||||
|
||||
BaseResponse baseResponse = new BaseResponse();
|
||||
String line = null;
|
||||
TreeNode treeNode = null;
|
||||
try {
|
||||
if (method == null) {
|
||||
baseResponse.addError(new xyz.wbsite.dbtool.web.framework.base.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());
|
||||
BufferedReader in = new BufferedReader(isr);
|
||||
line = in.readLine();
|
||||
treeNode = MapperUtil.toTree(line);
|
||||
|
||||
switch (method) {
|
||||
// 创建注释
|
||||
case "ajax.example.user.create":
|
||||
// baseResponse = createUser(treeNode, 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 + ", 请求参数:" + line);
|
||||
LogUtil.e("返回结果包含异常" + MapperUtil.toJson(baseResponse));
|
||||
}
|
||||
}
|
||||
return baseResponse;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,84 @@
|
||||
package xyz.wbsite.dbtool.web.frame.auth;
|
||||
|
||||
import xyz.wbsite.dbtool.web.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("ajax.system.admin.login");
|
||||
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<String> actionHolder = new ThreadLocal();
|
||||
|
||||
public static String getAction() {
|
||||
return actionHolder.get();
|
||||
}
|
||||
|
||||
public static void setAction(String action) {
|
||||
actionHolder.set(action);
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前用户的通行证
|
||||
*/
|
||||
private static final ThreadLocal<Token> 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());
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package xyz.wbsite.dbtool.web.frame.auth;
|
||||
|
||||
import xyz.wbsite.dbtool.web.frame.validation.DictValidator;
|
||||
|
||||
import javax.validation.Constraint;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target({ElementType.METHOD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Constraint(validatedBy = DictValidator.class)
|
||||
public @interface Verification {
|
||||
String name() default "";
|
||||
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
package xyz.wbsite.dbtool.web.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;
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package xyz.wbsite.dbtool.web.framework.base;
|
||||
package xyz.wbsite.dbtool.web.frame.base;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -0,0 +1,32 @@
|
||||
package xyz.wbsite.dbtool.web.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;
|
||||
}
|
||||
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package xyz.wbsite.dbtool.web.framework.base;
|
||||
package xyz.wbsite.dbtool.web.frame.base;
|
||||
|
||||
/**
|
||||
* BaseRequest - 基类
|
@ -1,4 +1,4 @@
|
||||
package xyz.wbsite.dbtool.web.framework.base;
|
||||
package xyz.wbsite.dbtool.web.frame.base;
|
||||
|
||||
/**
|
||||
* BaseSearchRequest - 基类
|
@ -1,4 +1,4 @@
|
||||
package xyz.wbsite.dbtool.web.framework.base;
|
||||
package xyz.wbsite.dbtool.web.frame.base;
|
||||
|
||||
/**
|
||||
* BaseUpdateRequest - 基类
|
@ -0,0 +1,10 @@
|
||||
package xyz.wbsite.dbtool.web.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);
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package xyz.wbsite.dbtool.web.framework.base;
|
||||
package xyz.wbsite.dbtool.web.frame.base;
|
||||
|
||||
/**
|
||||
* ErrorType - 错误类型
|
@ -0,0 +1,34 @@
|
||||
package xyz.wbsite.dbtool.web.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;
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
package xyz.wbsite.dbtool.web.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);
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package xyz.wbsite.dbtool.web.framework.base;
|
||||
package xyz.wbsite.dbtool.web.frame.base;
|
||||
|
||||
/**
|
||||
* SortTypeEnum - 排序方式
|
@ -0,0 +1,110 @@
|
||||
package xyz.wbsite.dbtool.web.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;
|
||||
}
|
||||
}
|
@ -0,0 +1,110 @@
|
||||
package xyz.wbsite.dbtool.web.frame.utils;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
public class FileUtil {
|
||||
|
||||
public static byte[] readFileToByteArray(File file) throws IOException {
|
||||
InputStream in = openInputStream(file);
|
||||
Throwable var2 = null;
|
||||
|
||||
byte[] var5;
|
||||
try {
|
||||
long fileLength = file.length();
|
||||
var5 = fileLength > 0L ? toByteArray(in, fileLength) : toByteArray(in);
|
||||
} catch (Throwable var14) {
|
||||
var2 = var14;
|
||||
throw var14;
|
||||
} finally {
|
||||
if (in != null) {
|
||||
if (var2 != null) {
|
||||
try {
|
||||
in.close();
|
||||
} catch (Throwable var13) {
|
||||
var2.addSuppressed(var13);
|
||||
}
|
||||
} else {
|
||||
in.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return var5;
|
||||
}
|
||||
|
||||
public static FileInputStream openInputStream(File file) throws IOException {
|
||||
if (file.exists()) {
|
||||
if (file.isDirectory()) {
|
||||
throw new IOException("File '" + file + "' exists but is a directory");
|
||||
} else if (!file.canRead()) {
|
||||
throw new IOException("File '" + file + "' cannot be read");
|
||||
} else {
|
||||
return new FileInputStream(file);
|
||||
}
|
||||
} else {
|
||||
throw new FileNotFoundException("File '" + file + "' does not exist");
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] toByteArray(InputStream input, long size) throws IOException {
|
||||
if (size > 2147483647L) {
|
||||
throw new IllegalArgumentException("Size cannot be greater than Integer max value: " + size);
|
||||
} else {
|
||||
return toByteArray(input, (int) size);
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] toByteArray(InputStream input) throws IOException {
|
||||
ByteArrayOutputStream output = new ByteArrayOutputStream();
|
||||
Throwable var2 = null;
|
||||
|
||||
byte[] var3;
|
||||
try {
|
||||
copy((InputStream) input, (OutputStream) output);
|
||||
var3 = output.toByteArray();
|
||||
} catch (Throwable var12) {
|
||||
var2 = var12;
|
||||
throw var12;
|
||||
} finally {
|
||||
if (output != null) {
|
||||
if (var2 != null) {
|
||||
try {
|
||||
output.close();
|
||||
} catch (Throwable var11) {
|
||||
var2.addSuppressed(var11);
|
||||
}
|
||||
} else {
|
||||
output.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return var3;
|
||||
}
|
||||
|
||||
public static int copy(InputStream input, OutputStream output) throws IOException {
|
||||
long count = copyLarge(input, output);
|
||||
return count > 2147483647L ? -1 : (int) count;
|
||||
}
|
||||
|
||||
|
||||
public static long copyLarge(InputStream input, OutputStream output) throws IOException {
|
||||
return copy(input, output, 4096);
|
||||
}
|
||||
|
||||
public static long copy(InputStream input, OutputStream output, int bufferSize) throws IOException {
|
||||
return copyLarge(input, output, new byte[bufferSize]);
|
||||
}
|
||||
|
||||
public static long copyLarge(InputStream input, OutputStream output, byte[] buffer) throws IOException {
|
||||
long count;
|
||||
int n;
|
||||
for (count = 0L; -1 != (n = input.read(buffer)); count += (long) n) {
|
||||
output.write(buffer, 0, n);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package xyz.wbsite.dbtool.web.framework.utils;
|
||||
package xyz.wbsite.dbtool.web.frame.utils;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
@ -0,0 +1,58 @@
|
||||
package xyz.wbsite.dbtool.web.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();
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package xyz.wbsite.dbtool.web.framework;
|
||||
package xyz.wbsite.dbtool.web.frame.utils;
|
||||
|
||||
|
||||
/**
|
@ -0,0 +1,308 @@
|
||||
package xyz.wbsite.dbtool.web.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;
|
||||
}
|
||||
}
|
@ -1,34 +1,41 @@
|
||||
package xyz.wbsite.dbtool.web.framework.freemarker;
|
||||
package xyz.wbsite.dbtool.web.frame.utils;
|
||||
|
||||
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帮助类
|
||||
* Url工具类
|
||||
*
|
||||
* @author wangbing
|
||||
* @version 0.0.1
|
||||
* @since 2017-01-01
|
||||
*/
|
||||
@Component
|
||||
public class Url {
|
||||
public class UrlUtil {
|
||||
|
||||
public String setUrl(String url) throws TemplateModelException {
|
||||
public String getUrl(String url) {
|
||||
if (url == null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
if (!url.startsWith("/")) {
|
||||
return "/" + url;
|
||||
}
|
||||
|
||||
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
|
||||
// 协议
|
||||
String scheme = request.getScheme();
|
||||
// 域名
|
||||
String serverName = request.getServerName();
|
||||
// 端口
|
||||
int serverPort = request.getServerPort();
|
||||
// 上下文路径
|
||||
String contextPath = request.getContextPath();
|
||||
|
||||
if (url.startsWith("/")) {
|
||||
return contextPath + url;
|
||||
} else {
|
||||
return contextPath + "/" + url;
|
||||
}
|
||||
return String.format(Locale.CHINA, "%s://%s:%d%s%s", scheme, serverName, serverPort, contextPath, url);
|
||||
}
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
package xyz.wbsite.dbtool.web.frame.utils;
|
||||
|
||||
import xyz.wbsite.dbtool.web.frame.base.BaseRequest;
|
||||
import xyz.wbsite.dbtool.web.frame.base.BaseResponse;
|
||||
import xyz.wbsite.dbtool.web.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 extends BaseResponse> T validate(BaseRequest req, T response) {
|
||||
|
||||
if (req == null) {
|
||||
response.addError(ErrorType.EXPECTATION_NULL, "请求对象不能为空");
|
||||
return response;
|
||||
}
|
||||
|
||||
try {
|
||||
Validator validator = factory.getValidator();
|
||||
|
||||
Set<ConstraintViolation<BaseRequest>> constraintViolations = validator.validate(req);
|
||||
|
||||
if (constraintViolations.size() > 0) {
|
||||
for (ConstraintViolation<BaseRequest> 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;
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package xyz.wbsite.dbtool.web.framework.utils;
|
||||
package xyz.wbsite.dbtool.web.frame.utils;
|
||||
|
||||
import javax.net.ssl.*;
|
||||
import java.io.*;
|
@ -1,4 +1,4 @@
|
||||
package xyz.wbsite.dbtool.web.framework.utils;
|
||||
package xyz.wbsite.dbtool.web.frame.utils;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.Enumeration;
|
@ -0,0 +1,18 @@
|
||||
package xyz.wbsite.dbtool.web.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 {};
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
package xyz.wbsite.dbtool.web.frame.validation;
|
||||
|
||||
import javax.validation.ConstraintValidator;
|
||||
import javax.validation.ConstraintValidatorContext;
|
||||
import java.util.HashSet;
|
||||
|
||||
public class DictValidator implements ConstraintValidator<Dict, String> {
|
||||
|
||||
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<String> codeSet = new HashSet<>();
|
||||
if (codeSet.contains(o)) {
|
||||
return true;
|
||||
} else {
|
||||
constraintValidatorContext.disableDefaultConstraintViolation();
|
||||
constraintValidatorContext.buildConstraintViolationWithTemplate("非法的字典[" + name + "]值").addConstraintViolation();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
package xyz.wbsite.dbtool.web.framework;
|
||||
|
||||
|
||||
import xyz.wbsite.dbtool.web.framework.base.Token;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* LocalData - 本地数据存放类
|
||||
*
|
||||
* @author wangbing
|
||||
* @version 0.0.1
|
||||
* @since 2017-01-01
|
||||
*/
|
||||
public class LocalData implements Serializable{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private static Token temp = null;
|
||||
|
||||
static {
|
||||
temp = new Token();
|
||||
temp.setId(-1);
|
||||
temp.setUserId(-1);
|
||||
temp.setUserName("游客");
|
||||
temp.putResource("/");
|
||||
temp.putResource("/index");
|
||||
temp.putResource("/login");
|
||||
temp.putResource("/ajax");
|
||||
temp.putResource("ajax.example.example");
|
||||
}
|
||||
|
||||
public static Token getTempToken(){
|
||||
return temp;
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前用户的通行证
|
||||
*/
|
||||
private static final ThreadLocal<Token> tokenHolder = new ThreadLocal();
|
||||
|
||||
public static Token getToken() {
|
||||
return tokenHolder.get();
|
||||
}
|
||||
|
||||
public static void setToken(Token token) {
|
||||
tokenHolder.set(token);
|
||||
}
|
||||
}
|
@ -1,75 +0,0 @@
|
||||
package xyz.wbsite.dbtool.web.framework.base;
|
||||
|
||||
/**
|
||||
* BaseFindRequest - 基类
|
||||
*
|
||||
* @author wangbing
|
||||
* @version 0.0.1
|
||||
* @since 2017-01-01
|
||||
*/
|
||||
public class BaseFindRequest extends BaseRequest {
|
||||
private long pageNumber = 1L;
|
||||
private long pageSize = 10L;
|
||||
private long beginIndex = 0;
|
||||
private long endIndex = 10;
|
||||
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;
|
||||
}
|
||||
|
||||
public long getPageNumber() {
|
||||
return pageNumber;
|
||||
}
|
||||
|
||||
public void setPageNumber(long pageNumber) {
|
||||
this.pageNumber = pageNumber;
|
||||
}
|
||||
|
||||
public long getPageSize() {
|
||||
return pageSize;
|
||||
}
|
||||
|
||||
public void setPageSize(long pageSize) {
|
||||
this.pageSize = pageSize;
|
||||
}
|
||||
|
||||
public long getBeginIndex() {
|
||||
beginIndex = pageSize * (pageNumber - 1);
|
||||
return beginIndex;
|
||||
}
|
||||
|
||||
public void setBeginIndex(long beginIndex) {
|
||||
this.beginIndex = beginIndex;
|
||||
}
|
||||
|
||||
public long getEndIndex() {
|
||||
endIndex = pageSize * (pageNumber - 1) + pageSize;
|
||||
return endIndex;
|
||||
}
|
||||
|
||||
public void setEndIndex(long endIndex) {
|
||||
this.endIndex = endIndex;
|
||||
}
|
||||
|
||||
public void updatePageNumber(Long totalCount){
|
||||
long maxPage = totalCount / pageSize + (totalCount % pageSize > 0 ? 1 : 0);
|
||||
|
||||
if (pageNumber > maxPage){
|
||||
pageNumber = maxPage;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
package xyz.wbsite.dbtool.web.framework.config;
|
||||
|
||||
import xyz.wbsite.dbtool.web.framework.freemarker.FreemarkerViewNameTranslator;
|
||||
import xyz.wbsite.dbtool.web.framework.freemarker.Layout;
|
||||
import xyz.wbsite.dbtool.web.framework.freemarker.Url;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator;
|
||||
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
|
||||
import org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* FreemarkerViewName解析器
|
||||
*
|
||||
* @author wangbing
|
||||
* @version 0.0.1
|
||||
* @since 2017-01-01
|
||||
*/
|
||||
@Configuration
|
||||
public class FreeMarkerConfig {
|
||||
|
||||
@Autowired
|
||||
private Layout layout;
|
||||
|
||||
@Autowired
|
||||
private Url url;
|
||||
|
||||
@Autowired
|
||||
protected FreeMarkerViewResolver resolver;
|
||||
|
||||
@Autowired
|
||||
protected FreeMarkerConfigurer freeMarkerConfigurer;
|
||||
|
||||
@PostConstruct
|
||||
public void setSharedVariable() {
|
||||
//设置基本工具类
|
||||
Map<String, Object> attributesMap = resolver.getAttributesMap();
|
||||
attributesMap.put("Layout", layout);
|
||||
attributesMap.put("Url", url);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析器
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Bean(name = "viewNameTranslator")
|
||||
public DefaultRequestToViewNameTranslator getViewNameTranslator() {
|
||||
FreemarkerViewNameTranslator nameTranslator = new FreemarkerViewNameTranslator();
|
||||
nameTranslator.setViewResolver(resolver);
|
||||
return nameTranslator;
|
||||
}
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
package xyz.wbsite.dbtool.web.framework.config;
|
||||
|
||||
import xyz.wbsite.dbtool.web.framework.interceptor.GlobalInterceptor;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.filter.CharacterEncodingFilter;
|
||||
import org.springframework.web.servlet.config.annotation.*;
|
||||
|
||||
@Configuration
|
||||
public class WebMvcConfig implements WebMvcConfigurer {
|
||||
|
||||
@Autowired
|
||||
private CharacterEncodingFilter characterEncodingFilter;
|
||||
|
||||
@Override
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
//增加全局拦截器
|
||||
registry.addInterceptor(new GlobalInterceptor()).addPathPatterns("/*");
|
||||
}
|
||||
|
||||
@Bean
|
||||
public FilterRegistrationBean characterEncodingFilterRegistration() {
|
||||
FilterRegistrationBean registration = new FilterRegistrationBean();
|
||||
//注入过滤器
|
||||
registration.setFilter(characterEncodingFilter);
|
||||
//拦截规则
|
||||
registration.addUrlPatterns("/*");
|
||||
//过滤器名称
|
||||
registration.setName("CharacterEncodingFilter");
|
||||
//过滤器顺序
|
||||
registration.setOrder(1);
|
||||
return registration;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public CharacterEncodingFilter characterEncodingFilter() {
|
||||
CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
|
||||
characterEncodingFilter.setEncoding("UTF-8");
|
||||
characterEncodingFilter.setForceEncoding(true);
|
||||
return characterEncodingFilter;
|
||||
}
|
||||
}
|
@ -1,66 +0,0 @@
|
||||
package xyz.wbsite.dbtool.web.framework.freemarker;
|
||||
|
||||
import freemarker.template.TemplateModelException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.context.request.RequestAttributes;
|
||||
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 java.io.File;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* 布局帮助类
|
||||
*
|
||||
* @author wangbing
|
||||
* @version 0.0.1
|
||||
* @since 2017-01-01
|
||||
*/
|
||||
@Component
|
||||
public class Layout {
|
||||
|
||||
@Value("${web.welcome.page}")
|
||||
private String homePage;
|
||||
|
||||
@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 = request.getServletPath();
|
||||
if ("/".equals(servletPath)) {
|
||||
servletPath = this.homePage;
|
||||
}
|
||||
servletPath = servletPath.replaceAll("^/", "");
|
||||
Locale locale = localeResolver.resolveLocale(request);
|
||||
String viewName = "screen" + File.separator + servletPath;
|
||||
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) {
|
||||
return controlPrefix + control + suffix;
|
||||
}
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
package xyz.wbsite.dbtool.web.framework.interceptor;
|
||||
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.web.servlet.HandlerInterceptor;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
public class GlobalInterceptor implements HandlerInterceptor {
|
||||
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
||||
|
||||
// todo do something
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
|
||||
|
||||
}
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
package xyz.wbsite.dbtool.web.framework.springmvc;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.module.SimpleModule;
|
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||
|
||||
/**
|
||||
* SpringMVC 对象JSON化自定义转换器
|
||||
*
|
||||
* @author wangbing
|
||||
* @version 0.0.1
|
||||
* @since 2017-01-01
|
||||
*/
|
||||
public class GlobalObjectMapper extends ObjectMapper {
|
||||
|
||||
/**
|
||||
* 设置@ResponseBody 返回的JSON格式
|
||||
*/
|
||||
public GlobalObjectMapper() {
|
||||
super();
|
||||
// 将所有的Long变成String以兼容js
|
||||
SimpleModule simpleModule = new SimpleModule("LongModule");
|
||||
simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
|
||||
simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);
|
||||
registerModule(simpleModule);
|
||||
}
|
||||
}
|
@ -1,114 +0,0 @@
|
||||
package xyz.wbsite.dbtool.web.framework.utils;//package com.example.demo.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();
|
||||
}
|
||||
|
||||
/**
|
||||
* 对json数据排序并签名
|
||||
* @param appSecret
|
||||
* @param currentTime
|
||||
* @return
|
||||
*/
|
||||
public static String toSign(TreeNode treeNode, String appSecret, String currentTime) {
|
||||
String typesetting = sortAndJson(treeNode);
|
||||
System.out.println(typesetting);
|
||||
return MD5Util.encode(appSecret + typesetting + currentTime);
|
||||
}
|
||||
|
||||
private static String sortAndJson(TreeNode treeNode) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
Iterator<String> keyIterator = treeNode.fieldNames();
|
||||
while (keyIterator.hasNext()){
|
||||
String next = keyIterator.next();
|
||||
sb.append(next).append(treeNode.get(next));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
//
|
||||
// private static String sortAndJson(JSONObject jsonObject) {
|
||||
// List<String> data = new ArrayList(jsonObject.keySet());
|
||||
// Collections.sort(data);
|
||||
// StringBuffer sb = new StringBuffer();
|
||||
//
|
||||
// for (String s : data) {
|
||||
// sb.append(s);
|
||||
// Object o = jsonObject.get(s);
|
||||
// if (o == null) {
|
||||
// sb.append("");
|
||||
// } else if (o instanceof JSONArray) {
|
||||
// sb.append(sortAndJson((JSONArray) o));
|
||||
// } else if (o instanceof JSONObject) {
|
||||
// sb.append(sortAndJson((JSONObject) o));
|
||||
// } else {
|
||||
// sb.append(o.toString());
|
||||
// }
|
||||
// }
|
||||
// return sb.toString();
|
||||
// }
|
||||
|
||||
|
||||
/**
|
||||
* 测试实例
|
||||
*
|
||||
* @param args
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
${AnsiColor.BRIGHT_YELLOW}
|
||||
/////////////////////////////////////////////////////////
|
||||
// _ooOoo_ //
|
||||
// o8888888o //
|
||||
// 88" . "88 //
|
||||
// (| ^_^ |) //
|
||||
// O\ = /O //
|
||||
// ____/`---'\____ //
|
||||
// .' \\| |// `. //
|
||||
// / \\||| : |||// \ //
|
||||
// / _||||| -:- |||||- \ //
|
||||
// | | \\\ - /// | | //
|
||||
// | \_| ''\---/'' | | //
|
||||
// \ .-\__ `-` ___/-. / //
|
||||
// ___`. .' /--.--\ `. . ___ //
|
||||
// ."" '< `.___\_<|>_/___.' >'"". //
|
||||
// | | : `- \`.;`\ _ /`;.`/ - ` : | | //
|
||||
// \ \ `-. \_ __\ /__ _/ .-` / / //
|
||||
// ========`-.____`-.___\_____/___.-`____.-'======== //
|
||||
// `=---=' //
|
||||
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ //
|
||||
/////////////////////////////////////////////////////////
|
||||
|
||||
佛祖保佑 永无BUG
|
||||
:: Spring Boot :: ${spring-boot.formatted-version} (${spring.profiles.active})
|
||||
|
@ -0,0 +1,110 @@
|
||||
package ${basePackage}.frame.utils;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
public class FileUtil {
|
||||
|
||||
public static byte[] readFileToByteArray(File file) throws IOException {
|
||||
InputStream in = openInputStream(file);
|
||||
Throwable var2 = null;
|
||||
|
||||
byte[] var5;
|
||||
try {
|
||||
long fileLength = file.length();
|
||||
var5 = fileLength > 0L ? toByteArray(in, fileLength) : toByteArray(in);
|
||||
} catch (Throwable var14) {
|
||||
var2 = var14;
|
||||
throw var14;
|
||||
} finally {
|
||||
if (in != null) {
|
||||
if (var2 != null) {
|
||||
try {
|
||||
in.close();
|
||||
} catch (Throwable var13) {
|
||||
var2.addSuppressed(var13);
|
||||
}
|
||||
} else {
|
||||
in.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return var5;
|
||||
}
|
||||
|
||||
public static FileInputStream openInputStream(File file) throws IOException {
|
||||
if (file.exists()) {
|
||||
if (file.isDirectory()) {
|
||||
throw new IOException("File '" + file + "' exists but is a directory");
|
||||
} else if (!file.canRead()) {
|
||||
throw new IOException("File '" + file + "' cannot be read");
|
||||
} else {
|
||||
return new FileInputStream(file);
|
||||
}
|
||||
} else {
|
||||
throw new FileNotFoundException("File '" + file + "' does not exist");
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] toByteArray(InputStream input, long size) throws IOException {
|
||||
if (size > 2147483647L) {
|
||||
throw new IllegalArgumentException("Size cannot be greater than Integer max value: " + size);
|
||||
} else {
|
||||
return toByteArray(input, (int) size);
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] toByteArray(InputStream input) throws IOException {
|
||||
ByteArrayOutputStream output = new ByteArrayOutputStream();
|
||||
Throwable var2 = null;
|
||||
|
||||
byte[] var3;
|
||||
try {
|
||||
copy((InputStream) input, (OutputStream) output);
|
||||
var3 = output.toByteArray();
|
||||
} catch (Throwable var12) {
|
||||
var2 = var12;
|
||||
throw var12;
|
||||
} finally {
|
||||
if (output != null) {
|
||||
if (var2 != null) {
|
||||
try {
|
||||
output.close();
|
||||
} catch (Throwable var11) {
|
||||
var2.addSuppressed(var11);
|
||||
}
|
||||
} else {
|
||||
output.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return var3;
|
||||
}
|
||||
|
||||
public static int copy(InputStream input, OutputStream output) throws IOException {
|
||||
long count = copyLarge(input, output);
|
||||
return count > 2147483647L ? -1 : (int) count;
|
||||
}
|
||||
|
||||
|
||||
public static long copyLarge(InputStream input, OutputStream output) throws IOException {
|
||||
return copy(input, output, 4096);
|
||||
}
|
||||
|
||||
public static long copy(InputStream input, OutputStream output, int bufferSize) throws IOException {
|
||||
return copyLarge(input, output, new byte[bufferSize]);
|
||||
}
|
||||
|
||||
public static long copyLarge(InputStream input, OutputStream output, byte[] buffer) throws IOException {
|
||||
long count;
|
||||
int n;
|
||||
for (count = 0L; -1 != (n = input.read(buffer)); count += (long) n) {
|
||||
output.write(buffer, 0, n);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
}
|
@ -0,0 +1,110 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
||||
|
||||
<title>403-对不起!您访问的页面未授权</title>
|
||||
|
||||
<style type="text/css">
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: #dfdfdf;
|
||||
}
|
||||
|
||||
.box {
|
||||
margin: 50px auto;
|
||||
background-color: #ffffff;
|
||||
width: 920px;
|
||||
height: 320px;
|
||||
overflow: hidden;
|
||||
border: 10px solid #0000002b;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.box div.img {
|
||||
width: 300px;
|
||||
height: 300px;
|
||||
margin-top: 50px;
|
||||
margin-left: 50px;
|
||||
}
|
||||
|
||||
.box div.info {
|
||||
width: 600px;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 50px;
|
||||
height: 200px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.box div.info {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.control {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
margin-right: 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.control a {
|
||||
margin-top: 50px;
|
||||
text-decoration: none;
|
||||
background: #f2f2f2;
|
||||
cursor: pointer;
|
||||
border: 3px solid #0000002b;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.control a:hover {
|
||||
background: #e6e6e6;
|
||||
border: 3px solid #0000002b
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="box">
|
||||
<div class="img">
|
||||
<svg t="1571239589656" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="3448" width="200" height="200">
|
||||
<path d="M512 928C282.25 928 96 741.75 96 512S282.25 96 512 96s416 186.25 416 416-186.25 416-416 416zM288 448c-17.673 0-32 14.327-32 32v96h480c17.673 0 32-14.327 32-32v-96H288z"
|
||||
p-id="3449"></path>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<div class="info">
|
||||
<p>抱歉!您尚未登录或登录信息已失效,或尚未授权!</p>
|
||||
</div>
|
||||
|
||||
<div class="control">
|
||||
<a onclick="history.back()">返回上页</a> <a id="login" href="${context}/login.htm"">登录</a>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
window.onload = function () {
|
||||
var count = 3;
|
||||
|
||||
function go() {
|
||||
if (count > 0) {
|
||||
var e = document.getElementById("login");
|
||||
e.innerHTML = "登录(" + count + " 秒后自动跳转)"
|
||||
count--;
|
||||
} else {
|
||||
location.href = "${context}/login.htm";
|
||||
}
|
||||
}
|
||||
|
||||
setInterval(go, 1000);
|
||||
};
|
||||
</script>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,90 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
||||
|
||||
<title>404-对不起!您访问的页面不存在</title>
|
||||
|
||||
<style type="text/css">
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: #dfdfdf;
|
||||
}
|
||||
|
||||
.box {
|
||||
margin: 50px auto;
|
||||
background-color: #ffffff;
|
||||
width: 920px;
|
||||
height: 320px;
|
||||
overflow: hidden;
|
||||
border: 10px solid #0000002b;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.box div.img {
|
||||
width: 300px;
|
||||
height: 300px;
|
||||
margin-top: 50px;
|
||||
margin-left: 50px;
|
||||
}
|
||||
|
||||
.box div.info {
|
||||
width: 600px;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 50px;
|
||||
height: 200px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.box div.info {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.control {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
margin-right: 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.control a {
|
||||
margin-top: 50px;
|
||||
text-decoration: none;
|
||||
background: #f2f2f2;
|
||||
cursor: pointer;
|
||||
border: 3px solid #0000002b;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.control a:hover {
|
||||
background: #e6e6e6;
|
||||
border: 3px solid #0000002b
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="box">
|
||||
<div class="img">
|
||||
<svg t="1571230949474" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="793" width="200" height="200">
|
||||
<path d="M931.6 585.6v79c28.6-60.2 44.8-127.4 44.8-198.4C976.4 211 769.4 4 514.2 4S52 211 52 466.2c0 3.2 0.2 6.4 0.2 9.6l166-206h96.4L171.8 485.6h46.4v-54.8l99.2-154.6V668h-99.2v-82.4H67.6c43 161 170.6 287.4 332.4 328.6-10.4 26.2-40.6 89.4-90.8 100.6-62.2 14 168.8 3.4 333.6-104.6C769.4 873.6 873.6 784.4 930.2 668h-97.6v-82.4H666.4V476l166.2-206.2h94L786.2 485.6h46.4v-59l99.2-154v313zM366.2 608c-4.8-11.2-7.2-23.2-7.2-36V357.6c0-12.8 2.4-24.8 7.2-36 4.8-11.2 11.4-21 19.6-29.2 8.2-8.2 18-14.8 29.2-19.6 11.2-4.8 23.2-7.2 36-7.2h81.6c12.8 0 24.8 2.4 36 7.2 11 4.8 20.6 11.2 28.8 19.2l-88.6 129.4v-23c0-4.8-1.6-8.8-4.8-12-3.2-3.2-7.2-4.8-12-4.8s-8.8 1.6-12 4.8c-3.2 3.2-4.8 7.2-4.8 12v72L372.6 620c-2.4-3.8-4.6-7.8-6.4-12z m258.2-36c0 12.8-2.4 24.8-7.2 36-4.8 11.2-11.4 21-19.6 29.2-8.2 8.2-18 14.8-29.2 19.6-11.2 4.8-23.2 7.2-36 7.2h-81.6c-12.8 0-24.8-2.4-36-7.2-11.2-4.8-21-11.4-29.2-19.6-3.6-3.6-7-7.8-10-12l99.2-144.6v50.6c0 4.8 1.6 8.8 4.8 12 3.2 3.2 7.2 4.8 12 4.8s8.8-1.6 12-4.8c3.2-3.2 4.8-7.2 4.8-12v-99.6L601 296.4c6.6 7.4 12 15.8 16 25.2 4.8 11.2 7.2 23.2 7.2 36V572z"
|
||||
p-id="794"></path>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<div class="info">
|
||||
<p>抱歉,您所请求的页面不存在或暂时不可用、也可能已被永久移除!</p>
|
||||
</div>
|
||||
<div class="control">
|
||||
<a onclick="history.back()">返回上页</a> <a href="/">返回首页</a>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,94 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
||||
|
||||
<title>500-服务器走了下神!</title>
|
||||
|
||||
<style type="text/css">
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: #dfdfdf;
|
||||
}
|
||||
|
||||
.box {
|
||||
margin: 50px auto;
|
||||
background-color: #ffffff;
|
||||
width: 920px;
|
||||
height: 320px;
|
||||
overflow: hidden;
|
||||
border: 10px solid #0000002b;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.box div.img {
|
||||
width: 300px;
|
||||
height: 300px;
|
||||
margin-top: 50px;
|
||||
margin-left: 50px;
|
||||
}
|
||||
|
||||
.box div.info {
|
||||
width: 600px;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 50px;
|
||||
height: 200px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.box div.info {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.control {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
margin-right: 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.control a {
|
||||
margin-top: 50px;
|
||||
text-decoration: none;
|
||||
background: #f2f2f2;
|
||||
cursor: pointer;
|
||||
border: 3px solid #0000002b;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.control a:hover {
|
||||
background: #e6e6e6;
|
||||
border: 3px solid #0000002b
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="box">
|
||||
<div class="img">
|
||||
<svg t="1571230949474" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="793" width="200" height="200">
|
||||
<path d="M931.6 585.6v79c28.6-60.2 44.8-127.4 44.8-198.4C976.4 211 769.4 4 514.2 4S52 211 52 466.2c0 3.2 0.2 6.4 0.2 9.6l166-206h96.4L171.8 485.6h46.4v-54.8l99.2-154.6V668h-99.2v-82.4H67.6c43 161 170.6 287.4 332.4 328.6-10.4 26.2-40.6 89.4-90.8 100.6-62.2 14 168.8 3.4 333.6-104.6C769.4 873.6 873.6 784.4 930.2 668h-97.6v-82.4H666.4V476l166.2-206.2h94L786.2 485.6h46.4v-59l99.2-154v313zM366.2 608c-4.8-11.2-7.2-23.2-7.2-36V357.6c0-12.8 2.4-24.8 7.2-36 4.8-11.2 11.4-21 19.6-29.2 8.2-8.2 18-14.8 29.2-19.6 11.2-4.8 23.2-7.2 36-7.2h81.6c12.8 0 24.8 2.4 36 7.2 11 4.8 20.6 11.2 28.8 19.2l-88.6 129.4v-23c0-4.8-1.6-8.8-4.8-12-3.2-3.2-7.2-4.8-12-4.8s-8.8 1.6-12 4.8c-3.2 3.2-4.8 7.2-4.8 12v72L372.6 620c-2.4-3.8-4.6-7.8-6.4-12z m258.2-36c0 12.8-2.4 24.8-7.2 36-4.8 11.2-11.4 21-19.6 29.2-8.2 8.2-18 14.8-29.2 19.6-11.2 4.8-23.2 7.2-36 7.2h-81.6c-12.8 0-24.8-2.4-36-7.2-11.2-4.8-21-11.4-29.2-19.6-3.6-3.6-7-7.8-10-12l99.2-144.6v50.6c0 4.8 1.6 8.8 4.8 12 3.2 3.2 7.2 4.8 12 4.8s8.8-1.6 12-4.8c3.2-3.2 4.8-7.2 4.8-12v-99.6L601 296.4c6.6 7.4 12 15.8 16 25.2 4.8 11.2 7.2 23.2 7.2 36V572z"
|
||||
p-id="794"></path>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<div class="info">
|
||||
<p style="font-size: 18px;font-weight: bold">服务器内部错误,错误信息如下:</p>
|
||||
|
||||
<p style="color: red">${msg}</p>
|
||||
</div>
|
||||
<div class="control">
|
||||
<a onclick="history.back()">返回上页</a> <a href="/">返回首页</a>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
@ -0,0 +1,119 @@
|
||||
<div id="header">
|
||||
<div class="logo">
|
||||
<img @click="this.nav.toHome()" src="${context}/static/img/logo.png">
|
||||
</div>
|
||||
|
||||
<a class="home" href="${context}">Home</a>
|
||||
|
||||
<div class="menu">
|
||||
<ul>
|
||||
<li>
|
||||
<a href="${context}/1">首页</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="${context}/2">工作台</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="${context}/3">消息中心</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="${context}/4">关于我</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<style>
|
||||
#header {
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
line-height: 50px;
|
||||
overflow: hidden;
|
||||
background: #2a2a2a;
|
||||
box-shadow: 0px 2px 8px 0px;
|
||||
}
|
||||
|
||||
#header .logo {
|
||||
display: inline-block;
|
||||
height: 50px;
|
||||
width: 50px;
|
||||
margin-left: 10px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#header .logo img {
|
||||
width: 50%;
|
||||
height: 50%;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.home {
|
||||
display: inline-block;
|
||||
color: #ffffff;
|
||||
font-weight: bold;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.home:hover {
|
||||
color: #ffffff;
|
||||
transform: translate(2px);
|
||||
}
|
||||
|
||||
#header .menu {
|
||||
display: inline-block;
|
||||
float: right;
|
||||
}
|
||||
|
||||
#header .menu ul {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
#header .menu ul li {
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
#header .menu ul li a {
|
||||
color: #ffffff;
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
margin: 0px 15px;
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
#header .menu ul li a:after {
|
||||
content: "";
|
||||
display: inline-block;
|
||||
background: #ffffff;
|
||||
width: 0%;
|
||||
height: 2px;
|
||||
position: absolute;
|
||||
bottom: 2px;
|
||||
left: 50%;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
#header .menu ul li a img {
|
||||
margin-top: 8px;
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
#header .menu ul li a:hover:after {
|
||||
width: 100%;
|
||||
left: 0%;
|
||||
}
|
||||
|
||||
#header .tx {
|
||||
display: inline-block;
|
||||
float: right;
|
||||
height: 50px;
|
||||
width: 50px;
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
#header .tx img {
|
||||
width: 50%;
|
||||
height: 50%;
|
||||
vertical-align: middle;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,160 @@
|
||||
<script>
|
||||
window.nav = new Vue({
|
||||
data: {
|
||||
activeIndex: 'home',
|
||||
contextPath: '${contextPath?default("")}',
|
||||
homePath: '${homePath?default("")}',
|
||||
loadingTip: '',
|
||||
loadingBar: '',
|
||||
tip: {
|
||||
show: function (msg) {
|
||||
var message = "<i class='el-icon-loading'></i> 正在加载 ..."
|
||||
if (msg) {
|
||||
message = "<i class='el-icon-loading'></i> " + msg
|
||||
}
|
||||
if (!nav.loadingTip) {
|
||||
nav.loadingTip = nav.$message({
|
||||
type: '',
|
||||
duration: 0,
|
||||
dangerouslyUseHTMLString: true,
|
||||
message: message
|
||||
});
|
||||
} else {
|
||||
nav.loadingTip.message = message;
|
||||
}
|
||||
},
|
||||
close: function () {
|
||||
if (nav.loadingTip) {
|
||||
nav.loadingTip.close();
|
||||
nav.loadingTip = '';
|
||||
}
|
||||
}
|
||||
},
|
||||
bar: {
|
||||
show: function () {
|
||||
if (!nav.loadingBar) {
|
||||
nav.loadingBar = nav.$message({
|
||||
type: '',
|
||||
duration: 0,
|
||||
customClass: 'loading-bar',
|
||||
dangerouslyUseHTMLString: true,
|
||||
message: '<i class="bar" style="width: 90%"></i>'
|
||||
});
|
||||
} else {
|
||||
nav.loadingBar.message = '<i class="bar" style="width: 90%"></i>'
|
||||
}
|
||||
},
|
||||
finish: function () {
|
||||
if (nav.loadingBar) {
|
||||
nav.loadingBar.message = '<i class="bar" style="width: 100%"></i>'
|
||||
setTimeout(function(){
|
||||
if (nav.loadingBar) {
|
||||
nav.loadingBar.close();
|
||||
nav.loadingBar = '';
|
||||
}
|
||||
},500);
|
||||
}
|
||||
},
|
||||
error: function () {
|
||||
if (nav.loadingBar) {
|
||||
nav.loadingBar.message = '<i class="bar error" style="width: 100%"></i>'
|
||||
setTimeout(function(){
|
||||
if(nav.loadingBar){
|
||||
nav.loadingBar.close();
|
||||
nav.loadingBar = '';
|
||||
}
|
||||
},500);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
i: function (message, callback) {
|
||||
this.$message({
|
||||
type: "info",
|
||||
showClose: true,
|
||||
message: message,
|
||||
duration: 1500,
|
||||
onClose: callback
|
||||
});
|
||||
},
|
||||
e: function (message, callback) {
|
||||
this.$message({
|
||||
type: "error",
|
||||
showClose: true,
|
||||
message: message,
|
||||
duration: 1500,
|
||||
onClose: callback
|
||||
});
|
||||
},
|
||||
w: function (message, callback) {
|
||||
this.$message({
|
||||
type: "warning",
|
||||
showClose: true,
|
||||
message: message,
|
||||
duration: 1500,
|
||||
onClose: callback
|
||||
});
|
||||
},
|
||||
s: function (message, callback) {
|
||||
this.$message({
|
||||
type: "success",
|
||||
showClose: true,
|
||||
message: message,
|
||||
duration: 1500,
|
||||
onClose: callback
|
||||
});
|
||||
},
|
||||
toOpen: function (url) {
|
||||
nav.tip.show();
|
||||
var url = url.substring(0, 1) == "/" ? url.substring(1) : url;
|
||||
$("body").append($("<a id='wb-open' href='" + this.contextPath + "/" + url + "' target='_self' style='dispaly:none;'></a>"))
|
||||
document.getElementById("wb-open").click();
|
||||
$("#wb-open").remove();
|
||||
},
|
||||
toOpenNew: function (url) {
|
||||
var url = url.substring(0, 1) == "/" ? url.substring(1) : url;
|
||||
$("body").append($("<a id='wb-open' href='" + this.contextPath + "/" + url + "' target='_blank' style='dispaly:none;'></a>"))
|
||||
document.getElementById("wb-open").click();
|
||||
$("#wb-open").remove();
|
||||
},
|
||||
toHome: function () {
|
||||
nav.tip.show();
|
||||
location.href = this.contextPath + "/"
|
||||
},
|
||||
/**
|
||||
* 滚动屏蔽至顶部
|
||||
*/
|
||||
scrollToTop: function () {
|
||||
var distance = document.documentElement.scrollTop || document.body.scrollTop;
|
||||
var step = distance / 10;
|
||||
|
||||
(function jump() {
|
||||
if (distance > 0) {
|
||||
distance -= step;
|
||||
window.scrollTo(0, distance);
|
||||
setTimeout(jump, 10)
|
||||
}
|
||||
})();
|
||||
},
|
||||
/**
|
||||
* 控制任一目标滚动到顶部
|
||||
* select jquery对象
|
||||
*/
|
||||
scrollToTop: function (select) {
|
||||
var distance = $(select).scrollTop();
|
||||
var step = distance / 10;
|
||||
|
||||
(function jump() {
|
||||
if (distance > 0) {
|
||||
distance -= step;
|
||||
$(select).scrollTop(distance);
|
||||
setTimeout(jump, 10)
|
||||
} else {
|
||||
$(select).scrollTop(distance);
|
||||
}
|
||||
})();
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
@ -0,0 +1,16 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title></title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||
<script src="${context}/static/dist/lib.min.js" type="text/javascript"></script>
|
||||
<script src="${context}/static/dist/index.min.js" type="text/javascript"></script>
|
||||
<link href="${context}/static/dist/index.min.css" rel="stylesheet"/>
|
||||
<script src="${context}/static/js/ajax.js" type="text/javascript"></script>
|
||||
<link href="${context}/static/css/base.css" rel="stylesheet"/>
|
||||
</head>
|
||||
<body>
|
||||
<#include controlHolder("nav")/>
|
||||
<#include screenHolder()/>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,14 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>首页</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||
<link href="${context}/static/favicon.ico" rel="icon" type="image/x-icon"/>
|
||||
<script src="${context}/static/dist/lib.min.js" type="text/javascript"></script>
|
||||
<script src="${context}/static/dist/index.min.js" type="text/javascript"></script>
|
||||
<link href="${context}/static/dist/index.min.css" rel="stylesheet"/>
|
||||
</head>
|
||||
<body>
|
||||
<#include screenHolder()/>
|
||||
</body>
|
||||
</html>
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,337 @@
|
||||
<div id="index" v-cloak>
|
||||
<div id="aside">
|
||||
<el-menu
|
||||
:style="{width:(properties.isCollapse?'64px':'200px')}"
|
||||
:default-active="properties.defaultActive"
|
||||
@open="handleOpen"
|
||||
@close="handleClose"
|
||||
@select="handleSelect"
|
||||
:unique-opened="properties.uniqueOpened"
|
||||
:collapse="properties.isCollapse"
|
||||
:collapse-transition="properties.transition"
|
||||
background-color="#252a2f"
|
||||
text-color="#d6d6d6"
|
||||
active-text-color="#ffd04b">
|
||||
<el-submenu index="2bd1dc9b-9444-4923-a186-7b420497b9e8" >
|
||||
<template slot="title">
|
||||
<i class="el-icon-setting"></i>
|
||||
<span slot="title">系统设置</span>
|
||||
</template>
|
||||
<el-menu-item index="23975e43-cc83-4eb7-b0ec-7b4b5fa8e334" @click="addTab({title: '字典管理', name: 'dict', url: '${context}/system/dict.htm'})">字典管理</el-menu-item>
|
||||
</el-submenu>
|
||||
<el-submenu index="188f8373-c8f3-4ef8-85d8-19269609935b">
|
||||
<template slot="title">
|
||||
<i class="el-icon-time"></i>
|
||||
<span slot="title">用户系统</span>
|
||||
</template>
|
||||
<el-menu-item index="1101dd41-b05b-4589-a40b-64436e1c9836" @click="addTab({title: '用户1', name: 'USER1', url: '${context}/user/user1.htm'})">用户1</el-menu-item>
|
||||
</el-submenu>
|
||||
</el-menu>
|
||||
</div>
|
||||
|
||||
<div id="main">
|
||||
<div id="head">
|
||||
<div class="collapseSwitch" @click="collapseSwitch">
|
||||
<a :class="properties.isCollapse?'reversal':''"><i class="el-icon-s-grid"></i></a>
|
||||
</div>
|
||||
|
||||
<el-link :underline="false" @click="onHome" icon="el-icon-s-home">首页</el-link>
|
||||
|
||||
<div class="menu">
|
||||
<ul>
|
||||
<li>
|
||||
<el-input
|
||||
size="mini"
|
||||
placeholder="请输入搜索内容">
|
||||
<i slot="prefix" class="el-input__icon el-icon-search"></i>
|
||||
</el-input>
|
||||
</li>
|
||||
<li>
|
||||
<el-link :underline="false" @click="onHome" icon="el-icon-message-solid"><span
|
||||
style="line-height: 20px;"><el-badge is-dot class="item">消息</el-badge></span></el-link>
|
||||
</li>
|
||||
<li>
|
||||
<el-dropdown>
|
||||
<el-link :underline="false" @click="onHome" icon="el-icon-user-solid">账户信息</el-link>
|
||||
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item>个人信息</el-dropdown-item>
|
||||
<el-dropdown-item>修改密码</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</li>
|
||||
<li>
|
||||
<el-link :underline="false" @click="onHome" icon="el-icon-warning-outline">系统版本</el-link>
|
||||
</li>
|
||||
<li>
|
||||
<el-link :underline="false" icon="el-icon-switch-button"></el-link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div id="content">
|
||||
<el-tabs v-model="activeTabName" type="border-card" closable @tab-remove="removeTab">
|
||||
<el-tab-pane
|
||||
v-for="(item, index) in tabs"
|
||||
:key="item.name"
|
||||
:label="item.title"
|
||||
:name="item.name">
|
||||
<iframe :src="item.url" style="width: 100%;height: 100%;border: 0;"></iframe>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<style>
|
||||
* {
|
||||
-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, body, #index, #main, #content {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
body {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#index {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
#aside {
|
||||
background: #252a2f;
|
||||
}
|
||||
|
||||
#aside .el-menu {
|
||||
transition: all .5s;
|
||||
border-right: 0
|
||||
}
|
||||
|
||||
#aside .el-menu-item, .el-submenu__title {
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
}
|
||||
|
||||
#main {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
#head {
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
overflow: hidden;
|
||||
background: #252a2f;
|
||||
}
|
||||
|
||||
#head .collapseSwitch {
|
||||
display: inline-block;
|
||||
height: 40px;
|
||||
width: 40px;
|
||||
text-align: center;
|
||||
font-size: 24px;
|
||||
border-left: 1px solid #424242;
|
||||
border-right: 1px solid #424242;
|
||||
}
|
||||
|
||||
#head .collapseSwitch a {
|
||||
display: inline-block;
|
||||
transition: all 1s;
|
||||
}
|
||||
|
||||
#head .collapseSwitch a.reversal {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
|
||||
#head a {
|
||||
color: #d6d6d6;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
#head a:hover {
|
||||
color: #409EFF;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
#head .collapseSwitch:hover {
|
||||
background: #3b4146;
|
||||
}
|
||||
|
||||
#head .menu {
|
||||
display: inline-block;
|
||||
float: right;
|
||||
}
|
||||
|
||||
#head .menu ul {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
#head .menu ul li {
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
#head .menu ul li a {
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
margin: 0 10px;
|
||||
height: 40px;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
#head .menu ul li a:after {
|
||||
content: "";
|
||||
display: inline-block;
|
||||
background: #409EFF;
|
||||
width: 0;
|
||||
height: 2px;
|
||||
position: absolute;
|
||||
bottom: 2px;
|
||||
left: 50%;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
#head .menu ul li a:hover:after {
|
||||
width: 100%;
|
||||
left: 0%;
|
||||
}
|
||||
|
||||
#content {
|
||||
height: calc(100% - 35px);
|
||||
}
|
||||
|
||||
#content > div {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#content > div > .el-tabs__content {
|
||||
padding: 0;
|
||||
height: calc(100% - 43px);
|
||||
}
|
||||
|
||||
#content .el-tabs__item {
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
#content .el-tabs__nav {
|
||||
white-space: normal !important;
|
||||
}
|
||||
|
||||
#content > div > .el-tabs__content .el-tab-pane {
|
||||
height: 100%;
|
||||
background: #f0f2f5;
|
||||
}
|
||||
|
||||
</style>
|
||||
<script>
|
||||
window.index = new Vue({
|
||||
el: "#index",
|
||||
data: {
|
||||
tabs: [],//所有Tabs
|
||||
activeTabName: '',
|
||||
properties: {
|
||||
uniqueOpened: true,//是否保持一个子菜单展开
|
||||
isCollapse: false,//左侧菜单是否收缩
|
||||
transition:false,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onHome: function () {
|
||||
this.addTab({
|
||||
title: '首页',
|
||||
name: 'home',
|
||||
url: '${contextPath}/home.htm'
|
||||
})
|
||||
},
|
||||
collapseSwitch: function () {
|
||||
this.properties.isCollapse = !this.properties.isCollapse;
|
||||
},
|
||||
handleOpen: function () {
|
||||
|
||||
},
|
||||
handleClose: function () {
|
||||
|
||||
},
|
||||
handleSelect: function (index) {
|
||||
|
||||
},
|
||||
addTab: function (tab) {
|
||||
//查找是否存在该tab
|
||||
var tempTabs = this.tabs.filter(function (tab_) {
|
||||
return tab_.name === tab.name;
|
||||
})
|
||||
//不存在则添加
|
||||
if (tempTabs.length <= 0) {
|
||||
this.tabs.push(tab)
|
||||
}
|
||||
this.activeTabName = tab.name;
|
||||
},
|
||||
removeTab: function (tabName) {
|
||||
var activeName = this.activeTabName;
|
||||
var tempTabs = this.tabs;
|
||||
if (activeName === tabName) {
|
||||
tempTabs.forEach(function (tab, index) {
|
||||
if (tab.name === tabName) {
|
||||
var nextTab = tempTabs[index + 1] || tempTabs[index - 1];
|
||||
if (nextTab) {
|
||||
activeName = nextTab.name;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
this.activeTabName = activeName;
|
||||
this.tabs = tempTabs.filter(function (tab) {
|
||||
return tab.name !== tabName
|
||||
})
|
||||
}
|
||||
},
|
||||
created: function () {
|
||||
},
|
||||
mounted: function () {
|
||||
this.onHome();//页面初始好后打开首页
|
||||
},
|
||||
watch: {}
|
||||
})
|
||||
</script>
|
||||
|
@ -0,0 +1,139 @@
|
||||
<div id="app" v-cloak>
|
||||
<div class="frame">
|
||||
<div class="login-box">
|
||||
<div class="login-title">系统登录</div>
|
||||
|
||||
<el-form :model="form" :rules="rules" ref="form" class="form">
|
||||
<el-form-item prop="username">
|
||||
<el-input placeholder="用户名" v-model="form.username">
|
||||
<template slot="prepend"><i class="icon iconfont el-icon-user"></i></template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item prop="password">
|
||||
<el-input placeholder="密码" v-model="form.password" type="password">
|
||||
<template slot="prepend"><i class="icon iconfont el-icon-lock"></i></template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" style="width: 100%" :loading="isLogin" :disabled="isLogin"
|
||||
@click="submitForm('form')">登录
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<a class="tip">系统登录</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<style>
|
||||
#app {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
display: flex;
|
||||
background: #001d3a;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.frame {
|
||||
width: 600px;
|
||||
height: 500px;
|
||||
background: #42424263;
|
||||
border-radius: 10px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
box-shadow: 0 0 10px 0 #afafaf52;
|
||||
}
|
||||
|
||||
.login-box {
|
||||
display: inline-block;
|
||||
background: #fff;
|
||||
border-radius: 5px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.login-title {
|
||||
line-height: 50px;
|
||||
border-bottom: 1px solid #e8e8e8;
|
||||
font-weight: bold;
|
||||
text-align: left;
|
||||
padding-left: 20px;
|
||||
font-size: 15px;
|
||||
height: 50px;
|
||||
color: #757575;
|
||||
}
|
||||
|
||||
.form {
|
||||
width: 300px;
|
||||
margin-top: 20px;
|
||||
margin-left: 20px;
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.form .el-input-group__prepend {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.tip {
|
||||
padding: 5px;
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
color: #b7b7b7;
|
||||
width: 100%;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<script type="text/javascript">
|
||||
var app = new Vue({
|
||||
el: "#app",
|
||||
data: {
|
||||
form: {
|
||||
username: '',
|
||||
password: ''
|
||||
},
|
||||
rules: {
|
||||
username: [
|
||||
{required: true, message: '请输入用户名', trigger: 'blur'}
|
||||
],
|
||||
password: [
|
||||
{required: true, message: '请输入密码', trigger: 'change'}
|
||||
],
|
||||
},
|
||||
isLogin: false
|
||||
},
|
||||
mounted: function () {
|
||||
|
||||
},
|
||||
methods: {
|
||||
submitForm: function (formName) {
|
||||
this.$refs[formName].validate(function (valid) {
|
||||
if (valid) {
|
||||
this.isLogin = true;
|
||||
ajax.authLogin(this.form).then(function (response) {
|
||||
this.isLogin = false;
|
||||
if (response.errors.length > 0) {
|
||||
nav.e(response.errors[0].message);
|
||||
} else {
|
||||
nav.i("登录成功!", function () {
|
||||
location.href = "/index.htm"
|
||||
});
|
||||
}
|
||||
})
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}.bind(this));
|
||||
},
|
||||
resetForm: function (formName) {
|
||||
this.$refs[formName].resetFields();
|
||||
}
|
||||
},
|
||||
})
|
||||
</script>
|
@ -0,0 +1,343 @@
|
||||
<div id="app" v-cloak>
|
||||
<el-card class="box-card">
|
||||
<el-form :inline="true" :model="vm" ref="vm" label-width="90px">
|
||||
<el-form-item label="字典名称" prop="dictName">
|
||||
<el-input v-model="vm.dictName" clearable size="small" placeholder=""></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="字典代码" prop="dictCode">
|
||||
<el-input v-model="vm.dictCode" clearable size="small" placeholder=""></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="是否有效" prop="valid">
|
||||
<el-select v-model="vm.valid" size="small" placeholder="">
|
||||
<el-option label="所有" value=""></el-option>
|
||||
<el-option label="有效" value="true"></el-option>
|
||||
<el-option label="无效" value="false"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" size="small" icon="el-icon-search" @click="onSearch">搜索</el-button>
|
||||
<el-button type="warning" size="small" icon="el-icon-refresh-left" @click="onReset('vm')">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<el-card class="box-card">
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-button type="success" size="small" icon="el-icon-plus" @click="onAction(['create',''])">新增
|
||||
</el-button>
|
||||
<el-button type="warning" size="small" icon="el-icon-download">导出</el-button>
|
||||
|
||||
<el-dialog class="form" :title="form.title" :visible.sync="form.dialog">
|
||||
<el-form :model="form" :inline="true" :rules="formRules" ref="form" label-width="90px">
|
||||
<el-form-item label="字典名称" prop="dictName">
|
||||
<el-input size="small" v-model="form.dictName"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="字典代码" prop="dictCode">
|
||||
<el-input size="small" v-model="form.dictCode"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="字典版本" required>
|
||||
<el-date-picker size="small"
|
||||
v-model="form.version"
|
||||
type="datetime"
|
||||
value-format="yyyy-MM-dd HH:mm:ss"
|
||||
placeholder="选择日期时间"
|
||||
align="right">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="是否有效" prop="valid">
|
||||
<el-switch size="small" v-model="form.valid"></el-switch>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button size="small" @click="form.dialog = false">取 消</el-button>
|
||||
<el-button size="small" type="primary" @click="onAction(['save',''])">保存</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="12">
|
||||
<el-button-group style="float: right;">
|
||||
<el-button size="small" icon="el-icon-delete" @click="onBitchDelete"></el-button>
|
||||
<el-button size="small" icon="el-icon-refresh" @click="onFind"></el-button>
|
||||
</el-button-group>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-table
|
||||
style="margin-top: 10px"
|
||||
@selection-change="onSelectionChange"
|
||||
empty-text="无数据"
|
||||
:data="result"
|
||||
size="small"
|
||||
style="width: 100%">
|
||||
<el-table-column
|
||||
align="center"
|
||||
type="selection"
|
||||
width="50">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
prop="id"
|
||||
label="主键"
|
||||
width="140">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
width="80"
|
||||
label="是否有效">
|
||||
<template slot-scope="scope">
|
||||
<el-tag size="mini" v-if="scope.row.valid">有效</el-tag>
|
||||
<el-tag size="mini" type="danger" v-if="!scope.row.valid">无效</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
prop="dictName"
|
||||
label="字典名称">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
prop="dictCode"
|
||||
label="字典代码">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
prop="version"
|
||||
label="字典版本">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
prop="createTime"
|
||||
label="创建时间">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
fixed="right"
|
||||
width="120"
|
||||
label="操作">
|
||||
<template slot-scope="scope">
|
||||
<el-dropdown size="mini" split-button type="primary" @click="onAction(['view',scope.row])"
|
||||
@command="onAction">
|
||||
<i class="el-icon-tickets"></i>查看
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item :command="['edit',scope.row]" icon="el-icon-edit">编辑</el-dropdown-item>
|
||||
<el-dropdown-item :command="['delete',scope.row]" icon="el-icon-delete">删除
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<el-pagination
|
||||
style="margin-top: 10px"
|
||||
v-if="vm.totalCount > vm.pageSize"
|
||||
@current-change="onPage"
|
||||
:current-page="vm.pageNumber"
|
||||
:page-size="vm.pageSize"
|
||||
layout="total, prev, pager, next, jumper"
|
||||
:total="vm.totalCount">
|
||||
</el-pagination>
|
||||
</el-card>
|
||||
</div>
|
||||
<style>
|
||||
#app {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.box-card {
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
.form .el-dialog {
|
||||
width: 700px;
|
||||
}
|
||||
|
||||
.form .el-dialog .el-form-item__content {
|
||||
width: 220px;
|
||||
}
|
||||
|
||||
</style>
|
||||
<script>
|
||||
var app = new Vue({
|
||||
el: "#app",
|
||||
data: {
|
||||
vm: {
|
||||
id: '',
|
||||
dictName: '',
|
||||
dictCode: '',
|
||||
valid: "",
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
totalCount: 0
|
||||
},
|
||||
select: [],
|
||||
result: [],
|
||||
form: {
|
||||
title: "",
|
||||
dialog: false,
|
||||
id: '',
|
||||
dictName: '',
|
||||
dictCode: '',
|
||||
version: '',
|
||||
valid: false,
|
||||
rowVersion: '',
|
||||
},
|
||||
formRules: {
|
||||
dictName: [
|
||||
{required: true, message: '请输入字典名称', trigger: 'blur'},
|
||||
{min: 1, max: 50, message: '长度在 3 到 5 个字符', trigger: 'blur'}
|
||||
],
|
||||
dictCode: [
|
||||
{required: true, message: '请输入字典代码', trigger: 'blur'},
|
||||
{min: 1, max: 50, message: '长度在 1 到 50 个字符', trigger: 'blur'}
|
||||
],
|
||||
version: [
|
||||
{type: 'date', required: true, message: '字典版本不能为空', trigger: 'change'}
|
||||
],
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
onSearch: function () {
|
||||
this.vm.pageNumber = 1;
|
||||
this.onFind();
|
||||
},
|
||||
onReset: function (form) {
|
||||
this.$refs[form].resetFields();
|
||||
nav.w('重置成功');
|
||||
},
|
||||
onFind: function () {
|
||||
ajax.dictFind(this.vm).then(function (response) {
|
||||
if (response.errors.length > 0) {
|
||||
nav.e(response.errors[0].message);
|
||||
} else {
|
||||
this.result = response.result;
|
||||
this.vm.totalCount = Number(response.totalCount);
|
||||
}
|
||||
}.bind(this))
|
||||
},
|
||||
onPage: function (pageNumber) {
|
||||
this.vm.pageNumber = pageNumber;
|
||||
this.onFind();
|
||||
},
|
||||
onSelectionChange: function (select) {
|
||||
this.select = select;
|
||||
},
|
||||
onBitchDelete: function () {
|
||||
if (this.select.length == 0) {
|
||||
nav.w("至少选中一项");
|
||||
} else {
|
||||
this.$confirm('将删除已选择的项, 是否继续?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(function () {
|
||||
for (var i = 0; i < this.select.length; i++) {
|
||||
var obj = this.select[i];
|
||||
ajax.dictDelete({id: obj.id}).then(function (response) {
|
||||
if (response.errors.length > 0) {
|
||||
nav.e(response.errors[0].message);
|
||||
} else {
|
||||
for (var j = 0; j < this.select.length; j++) {
|
||||
if (this.select[j].id == obj.id) {
|
||||
this.select.splice(j, 1);
|
||||
}
|
||||
}
|
||||
if (this.select.length == 0) {
|
||||
nav.s("删除成功")
|
||||
this.onFind();
|
||||
}
|
||||
}
|
||||
}.bind(this))
|
||||
}
|
||||
}.bind(this)).catch(function (action) {
|
||||
|
||||
});
|
||||
}
|
||||
},
|
||||
onAction: function (arg) {
|
||||
const action = arg[0];
|
||||
const item = arg[1];
|
||||
switch (action) {
|
||||
case "create":
|
||||
this.form.title = '新增字典';
|
||||
this.form.id = '';
|
||||
this.form.dictName = '';
|
||||
this.form.dictCode = '';
|
||||
this.form.version = '';
|
||||
this.form.valid = true;
|
||||
this.form.dialog = true;
|
||||
break;
|
||||
case "save":
|
||||
this.$refs['form'].validate(function (valid) {
|
||||
if (valid) {
|
||||
if (this.form.id) {
|
||||
ajax.dictUpdate(this.form).then(function (response) {
|
||||
if (response.errors.length > 0) {
|
||||
nav.e(response.errors[0].message);
|
||||
} else {
|
||||
this.onFind();
|
||||
this.form.dialog = false;
|
||||
}
|
||||
}.bind(this))
|
||||
} else {
|
||||
ajax.dictCreate(this.form).then(function (response) {
|
||||
if (response.errors.length > 0) {
|
||||
nav.e(response.errors[0].message);
|
||||
} else {
|
||||
this.onFind();
|
||||
this.form.dialog = false;
|
||||
}
|
||||
}.bind(this))
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}.bind(this));
|
||||
break;
|
||||
case "view":
|
||||
parent.index.addTab({
|
||||
title: "字典项管理",
|
||||
name: "dictItem" + item.id,
|
||||
url: "${context}/system/dictItem.htm?dictId=" + item.id
|
||||
});
|
||||
break;
|
||||
case "edit":
|
||||
this.form.title = '编辑字典';
|
||||
this.form.id = item.id;
|
||||
this.form.dictName = item.dictName;
|
||||
this.form.dictCode = item.dictCode;
|
||||
this.form.version = item.version;
|
||||
this.form.valid = item.valid;
|
||||
this.form.rowVersion = item.rowVersion;
|
||||
this.form.dialog = true;
|
||||
break;
|
||||
case "delete":
|
||||
this.$confirm('将删除该项, 是否继续?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(function () {
|
||||
ajax.dictDelete({id: item.id}).then(function (response) {
|
||||
if (response.errors.length > 0) {
|
||||
nav.e(response.errors[0].message);
|
||||
} else {
|
||||
nav.s("删除成功");
|
||||
this.onFind();
|
||||
}
|
||||
}.bind(this));
|
||||
}.bind(this));
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
filters: {},
|
||||
created: function () {
|
||||
},
|
||||
mounted: function () {
|
||||
this.onFind();
|
||||
},
|
||||
watch: {}
|
||||
})
|
||||
</script>
|
@ -0,0 +1,339 @@
|
||||
<div id="app" v-cloak>
|
||||
<el-card class="box-card">
|
||||
<el-form :inline="true" :model="vm" ref="vm" label-width="90px">
|
||||
<el-form-item label="字典名称">
|
||||
<el-input disabled v-model="vm.dictName" clearable size="small"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="字典键" prop="key">
|
||||
<el-input v-model="vm.key" clearable size="small" placeholder=""></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="字典值" prop="value">
|
||||
<el-input v-model="vm.value" clearable size="small" placeholder=""></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="是否有效" prop="valid">
|
||||
<el-select v-model="vm.valid" size="small" placeholder="">
|
||||
<el-option label="所有" value=""></el-option>
|
||||
<el-option label="有效" value="true"></el-option>
|
||||
<el-option label="无效" value="false"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" size="small" icon="el-icon-search" @click="onSearch">搜索</el-button>
|
||||
<el-button type="warning" size="small" icon="el-icon-refresh-left" @click="onReset('vm')">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<el-card class="box-card">
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-button type="success" size="small" icon="el-icon-plus" @click="onAction(['create',''])">新增</el-button>
|
||||
<el-button type="warning" size="small" icon="el-icon-download">导出</el-button>
|
||||
|
||||
<el-dialog class="form" :title="form.title" :visible.sync="form.dialog">
|
||||
<el-form :model="form":inline="true" :rules="formRules" ref="form" label-width="90px">
|
||||
<el-form-item label="字典键" prop="dictName">
|
||||
<el-input size="small" v-model="form.key"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="字典值" prop="dictCode">
|
||||
<el-input size="small" v-model="form.value"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="排序值" prop="dictCode">
|
||||
<el-input-number size="small" v-model="form.sort" :min="0" :max="10000"
|
||||
label="描述文字"></el-input-number>
|
||||
</el-form-item>
|
||||
<el-form-item label="是否有效" prop="valid">
|
||||
<el-switch size="small" v-model="form.valid"></el-switch>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button size="small" @click="form.dialog = false">取消</el-button>
|
||||
<el-button size="small" type="primary" @click="onAction(['save',''])">保存</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="12">
|
||||
<el-button-group style="float: right;">
|
||||
<el-button size="small" icon="el-icon-delete" @click="onBitchDelete"></el-button>
|
||||
<el-button size="small" icon="el-icon-refresh" @click="onFind"></el-button>
|
||||
</el-button-group>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-table
|
||||
@selection-change="onSelectionChange"
|
||||
empty-text="无数据"
|
||||
:data="result"
|
||||
size="small"
|
||||
style="width: 100%">
|
||||
<el-table-column
|
||||
align="center"
|
||||
type="selection"
|
||||
width="50">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
prop="id"
|
||||
label="主键"
|
||||
width="140">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
width="80"
|
||||
label="是否有效">
|
||||
<template slot-scope="scope">
|
||||
<el-tag size="mini" v-if="scope.row.valid">有效</el-tag>
|
||||
<el-tag size="mini" type="danger" v-if="!scope.row.valid">无效</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
prop="key"
|
||||
label="字典键">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
prop="value"
|
||||
label="字典值">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
prop="sort"
|
||||
label="排序">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
prop="createTime"
|
||||
label="创建时间">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
fixed="right"
|
||||
width="120"
|
||||
label="操作">
|
||||
<template slot-scope="scope">
|
||||
<el-dropdown size="mini" split-button type="primary" @click="onAction(['edit',scope.row])"
|
||||
@command="onAction">
|
||||
<i class="el-icon-edit"></i>编辑
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item :command="['delete',scope.row]" icon="el-icon-delete">删除
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<el-pagination
|
||||
v-if="vm.totalCount > vm.pageSize"
|
||||
@current-change="onPage"
|
||||
:current-page="vm.pageNumber"
|
||||
:page-size="vm.pageSize"
|
||||
layout="total, prev, pager, next, jumper"
|
||||
:total="vm.totalCount">
|
||||
</el-pagination>
|
||||
</el-card>
|
||||
</div>
|
||||
<style>
|
||||
#app {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.box-card {
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
.form .el-dialog{
|
||||
width: 700px;
|
||||
}
|
||||
|
||||
.form .el-dialog .el-form-item__content {
|
||||
width: 220px;
|
||||
}
|
||||
|
||||
</style>
|
||||
<script>
|
||||
var app = new Vue({
|
||||
el: "#app",
|
||||
data: {
|
||||
vm: {
|
||||
id: '',
|
||||
dictId: location.getParam("dictId"),
|
||||
dictName: '',
|
||||
key: '',
|
||||
value: '',
|
||||
valid: '',
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
totalCount: 0
|
||||
},
|
||||
select: [],
|
||||
result: [],
|
||||
form: {
|
||||
title: "",
|
||||
dialog: false,
|
||||
id: '',
|
||||
dictId: location.getParam("dictId"),
|
||||
key: '',
|
||||
value: '',
|
||||
sort: 0,
|
||||
valid: true
|
||||
},
|
||||
formRules: {
|
||||
key: [
|
||||
{required: true, message: '请输入字典名称', trigger: 'blur'},
|
||||
{min: 1, max: 50, message: '长度在 3 到 5 个字符', trigger: 'blur'}
|
||||
],
|
||||
value: [
|
||||
{required: true, message: '请输入字典代码', trigger: 'blur'},
|
||||
{min: 1, max: 50, message: '长度在 1 到 50 个字符', trigger: 'blur'}
|
||||
],
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
onSearch: function () {
|
||||
this.vm.pageNumber = 1;
|
||||
this.onFind();
|
||||
},
|
||||
onReset: function (form) {
|
||||
this.$refs[form].resetFields();
|
||||
nav.w('重置成功');
|
||||
},
|
||||
onFind: function () {
|
||||
ajax.dictItemFind(this.vm).then(function (response) {
|
||||
if (response.errors.length > 0) {
|
||||
nav.e(response.errors[0].message);
|
||||
} else {
|
||||
this.result = response.result;
|
||||
this.vm.totalCount = Number(response.totalCount);
|
||||
}
|
||||
}.bind(this))
|
||||
},
|
||||
onPage: function (pageNumber) {
|
||||
this.vm.pageNumber = pageNumber;
|
||||
this.onFind();
|
||||
},
|
||||
onSelectionChange: function (select) {
|
||||
this.select = select;
|
||||
},
|
||||
onBitchDelete: function () {
|
||||
if (this.select.length == 0) {
|
||||
nav.w("至少选中一项");
|
||||
} else {
|
||||
this.$confirm('将删除已选择的项, 是否继续?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(function () {
|
||||
for (var i = 0; i < this.select.length; i++) {
|
||||
var obj = this.select[i];
|
||||
ajax.dictItemDelete({id: obj.id}).then(function (response) {
|
||||
if (response.errors.length > 0) {
|
||||
nav.e(response.errors[0].message);
|
||||
} else {
|
||||
for (var j = 0; j < this.select.length; j++) {
|
||||
if (this.select[j].id == obj.id) {
|
||||
this.select.splice(j, 1);
|
||||
}
|
||||
}
|
||||
if (this.select.length == 0) {
|
||||
nav.s("删除成功")
|
||||
this.onFind();
|
||||
}
|
||||
}
|
||||
}.bind(this))
|
||||
}
|
||||
}.bind(this)).catch(function (action) {
|
||||
|
||||
});
|
||||
}
|
||||
},
|
||||
getDict: function () {
|
||||
ajax.dictGet({id: location.getParam("dictId")}).then(function (response) {
|
||||
if (response.errors.length > 0) {
|
||||
nav.e(response.errors[0].message);
|
||||
} else {
|
||||
this.vm.dictName = response.dict.dictName;
|
||||
}
|
||||
}.bind(this))
|
||||
},
|
||||
onAction: function (arg) {
|
||||
const action = arg[0];
|
||||
const item = arg[1];
|
||||
switch (action) {
|
||||
case "create":
|
||||
this.form.title = '新增字典项';
|
||||
this.form.id = '';
|
||||
this.form.key = '';
|
||||
this.form.value = '';
|
||||
this.form.sort = this.vm.totalCount;
|
||||
this.form.valid = true;
|
||||
this.form.dialog = true;
|
||||
break;
|
||||
case "save":
|
||||
this.$refs['form'].validate(function (valid) {
|
||||
if (valid) {
|
||||
if (this.form.id) {
|
||||
ajax.dictItemUpdate(this.form).then(function (response) {
|
||||
if (response.errors.length > 0) {
|
||||
nav.e(response.errors[0].message);
|
||||
} else {
|
||||
this.onFind();
|
||||
this.form.dialog = false;
|
||||
}
|
||||
}.bind(this))
|
||||
} else {
|
||||
ajax.dictItemCreate(this.form).then(function (response) {
|
||||
if (response.errors.length > 0) {
|
||||
nav.e(response.errors[0].message);
|
||||
} else {
|
||||
this.onFind();
|
||||
this.form.dialog = false;
|
||||
}
|
||||
}.bind(this))
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}.bind(this));
|
||||
break;
|
||||
case "edit":
|
||||
this.form.title = '编辑字典项';
|
||||
this.form.id = item.id;
|
||||
this.form.key = item.key;
|
||||
this.form.value = item.value;
|
||||
this.form.valid = item.valid;
|
||||
this.form.sort = item.sort;
|
||||
this.form.rowVersion = item.rowVersion;
|
||||
this.form.dialog = true;
|
||||
break;
|
||||
case "delete":
|
||||
this.$confirm('将删除该项, 是否继续?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(function () {
|
||||
ajax.dictItemDelete({id: item.id}).then(function (response) {
|
||||
if (response.errors.length > 0) {
|
||||
nav.e(response.errors[0].message);
|
||||
} else {
|
||||
nav.s("删除成功")
|
||||
this.onFind();
|
||||
}
|
||||
}.bind(this));
|
||||
}.bind(this));
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
filters: {},
|
||||
created: function () {
|
||||
},
|
||||
mounted: function () {
|
||||
this.getDict();
|
||||
this.onFind();
|
||||
},
|
||||
watch: {}
|
||||
})
|
||||
</script>
|
@ -0,0 +1,381 @@
|
||||
<div id="app" v-cloak>
|
||||
<el-card class="box-card">
|
||||
<el-form :inline="true" :model="vm" ref="vm" label-width="90px">
|
||||
<el-form-item label="用户名" prop="name">
|
||||
<el-input v-model="vm.name" clearable size="small" placeholder="请输入用户名"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="年龄" prop="age">
|
||||
<el-input v-model="vm.age" clearable size="small" placeholder="请输入年龄"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="性别" prop="sex">
|
||||
<el-input v-model="vm.sex" clearable size="small" placeholder="请输入性别"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="头像" prop="tx">
|
||||
<el-input v-model="vm.tx" clearable size="small" placeholder="请输入头像"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="QQ" prop="qq">
|
||||
<el-input v-model="vm.qq" clearable size="small" placeholder="请输入QQ"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="微信、" prop="wx">
|
||||
<el-input v-model="vm.wx" clearable size="small" placeholder="请输入微信、"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="微博" prop="wb">
|
||||
<el-input v-model="vm.wb" clearable size="small" placeholder="请输入微博"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="个人主页" prop="personPage">
|
||||
<el-input v-model="vm.personPage" clearable size="small" placeholder="请输入个人主页"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" size="small" icon="el-icon-search" @click="onSearch">搜索</el-button>
|
||||
<el-button type="warning" size="small" icon="el-icon-refresh-left" @click="onReset('vm')">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<el-card class="box-card">
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-button type="success" size="small" icon="el-icon-plus" @click="onAction(['create',''])">新增
|
||||
</el-button>
|
||||
<el-button type="warning" size="small" icon="el-icon-download">导出</el-button>
|
||||
|
||||
<el-dialog class="form" :title="form.title" :visible.sync="form.dialog">
|
||||
<el-form :model="form" :inline="true" :rules="formRules" ref="form" label-width="90px">
|
||||
<el-form-item label="用户名" prop="name">
|
||||
<el-input v-model="form.name" clearable size="small" placeholder="请输入用户名"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="年龄" prop="age">
|
||||
<el-input v-model="form.age" clearable size="small" placeholder="请输入年龄"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="性别" prop="sex">
|
||||
<el-input v-model="form.sex" clearable size="small" placeholder="请输入性别"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="头像" prop="tx">
|
||||
<el-input v-model="form.tx" clearable size="small" placeholder="请输入头像"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="QQ" prop="qq">
|
||||
<el-input v-model="form.qq" clearable size="small" placeholder="请输入QQ"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="微信、" prop="wx">
|
||||
<el-input v-model="form.wx" clearable size="small" placeholder="请输入微信、"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="微博" prop="wb">
|
||||
<el-input v-model="form.wb" clearable size="small" placeholder="请输入微博"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="个人主页" prop="personPage">
|
||||
<el-input v-model="form.personPage" clearable size="small" placeholder="请输入个人主页"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button size="small" @click="form.dialog = false">取 消</el-button>
|
||||
<el-button size="small" type="primary" @click="onAction(['save',''])">保存</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="12">
|
||||
<el-button-group style="float: right;">
|
||||
<el-button size="small" icon="el-icon-delete" @click="onBitchDelete"></el-button>
|
||||
<el-button size="small" icon="el-icon-refresh" @click="onFind"></el-button>
|
||||
</el-button-group>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-table
|
||||
style="margin-top: 10px"
|
||||
@selection-change="onSelectionChange"
|
||||
empty-text="无数据"
|
||||
:data="result"
|
||||
size="mini"
|
||||
style="width: 100%">
|
||||
<el-table-column
|
||||
align="center"
|
||||
type="selection"
|
||||
width="40">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
prop="name"
|
||||
label="用户名">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
prop="age"
|
||||
label="年龄">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
prop="sex"
|
||||
label="性别">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
prop="tx"
|
||||
label="头像">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
prop="qq"
|
||||
label="QQ">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
prop="wx"
|
||||
label="微信、">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
prop="wb"
|
||||
label="微博">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
prop="personPage"
|
||||
label="个人主页">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
prop="createTime"
|
||||
width="140"
|
||||
label="创建时间">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
fixed="right"
|
||||
width="120"
|
||||
label="操作">
|
||||
<template slot-scope="scope">
|
||||
<el-dropdown size="mini" split-button type="primary" @click="onAction(['edit',scope.row])"
|
||||
@command="onAction">
|
||||
<i class="el-icon-edit"></i>编辑
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item :command="['delete',scope.row]" icon="el-icon-delete">删除
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<el-pagination
|
||||
style="margin-top: 10px"
|
||||
v-if="vm.totalCount > vm.pageSize"
|
||||
@current-change="onPage"
|
||||
:current-page="vm.pageNumber"
|
||||
:page-size="vm.pageSize"
|
||||
layout="total, prev, pager, next, jumper"
|
||||
:total="vm.totalCount">
|
||||
</el-pagination>
|
||||
</el-card>
|
||||
</div>
|
||||
<style>
|
||||
#app {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.box-card {
|
||||
margin: 10px;
|
||||
}
|
||||
.form .el-dialog{
|
||||
width: 700px;
|
||||
}
|
||||
|
||||
.form .el-dialog .el-form-item__content {
|
||||
width: 220px;
|
||||
}
|
||||
|
||||
</style>
|
||||
<script>
|
||||
var app = new Vue({
|
||||
el: "#app",
|
||||
data: {
|
||||
vm: {//条件及分页参数
|
||||
name: "",
|
||||
age: "",
|
||||
sex: "",
|
||||
tx: "",
|
||||
qq: "",
|
||||
wx: "",
|
||||
wb: "",
|
||||
personPage: "",
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
totalCount: 0
|
||||
},
|
||||
form: {//待提交表单
|
||||
title: "",
|
||||
dialog: false,
|
||||
id: '',
|
||||
name: "",
|
||||
age: "",
|
||||
sex: "",
|
||||
tx: "",
|
||||
qq: "",
|
||||
wx: "",
|
||||
wb: "",
|
||||
personPage: "",
|
||||
rowVersion: ""
|
||||
},
|
||||
formRules: {
|
||||
name: [
|
||||
{min: 1, max: 10, message: '用户名长度在 1 到 10 个字符', trigger: 'blur'}
|
||||
],
|
||||
age: [
|
||||
{min: 1, max: 50, message: '年龄长度在 1 到 50 个字符', trigger: 'blur'}
|
||||
],
|
||||
sex: [
|
||||
{min: 1, max: 50, message: '性别长度在 1 到 50 个字符', trigger: 'blur'}
|
||||
],
|
||||
tx: [
|
||||
{min: 1, max: 50, message: '头像长度在 1 到 50 个字符', trigger: 'blur'}
|
||||
],
|
||||
qq: [
|
||||
{min: 1, max: 50, message: 'QQ长度在 1 到 50 个字符', trigger: 'blur'}
|
||||
],
|
||||
wx: [
|
||||
{min: 1, max: 50, message: '微信、长度在 1 到 50 个字符', trigger: 'blur'}
|
||||
],
|
||||
wb: [
|
||||
{min: 1, max: 50, message: '微博长度在 1 到 50 个字符', trigger: 'blur'}
|
||||
],
|
||||
personPage: [
|
||||
{min: 1, max: 50, message: '个人主页长度在 1 到 50 个字符', trigger: 'blur'}
|
||||
],
|
||||
},
|
||||
select: [],
|
||||
result: [],
|
||||
},
|
||||
methods: {
|
||||
onSearch: function () {
|
||||
this.vm.pageNumber = 1;
|
||||
this.onFind();
|
||||
},
|
||||
onReset: function (form) {
|
||||
this.$refs[form].resetFields();
|
||||
nav.w('重置成功');
|
||||
},
|
||||
onFind: function () {
|
||||
ajax.user1Find(this.vm).then(function (response) {
|
||||
if (response.errors.length > 0) {
|
||||
nav.e(response.errors[0].message);
|
||||
} else {
|
||||
this.result = response.result;
|
||||
this.vm.totalCount = Number(response.totalCount);
|
||||
}
|
||||
}.bind(this))
|
||||
},
|
||||
onPage: function (pageNumber) {
|
||||
this.vm.pageNumber = pageNumber;
|
||||
this.onFind();
|
||||
},
|
||||
onBitchDelete: function () {
|
||||
if (this.select.length === 0) {
|
||||
nav.e("尚未选择数据列");
|
||||
return;
|
||||
}
|
||||
this.$confirm('将删除所有选中项, 是否继续?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(function () {
|
||||
this.select.forEach(function (item) {
|
||||
ajax.user1Delete({id: item.id}).then(function (response) {
|
||||
if (response.errors.length > 0) {
|
||||
nav.e(response.errors[0].message);
|
||||
} else {
|
||||
this.select.remove(item);
|
||||
if (this.select.length===0){
|
||||
nav.s("删除成功");
|
||||
this.onFind();
|
||||
}
|
||||
}
|
||||
}.bind(this))
|
||||
}.bind(this))
|
||||
}.bind(this)).catch(function (action) {
|
||||
|
||||
});
|
||||
},
|
||||
onSelectionChange: function (select) {
|
||||
this.select = select;
|
||||
},
|
||||
onAction: function (arg) {
|
||||
const action = arg[0];
|
||||
const item = arg[1];
|
||||
switch (action) {
|
||||
case "create":
|
||||
this.form.title = "用户1新增";
|
||||
this.form.dialog = true;
|
||||
this.form.id = "";
|
||||
this.form.name = "";
|
||||
this.form.age = "";
|
||||
this.form.sex = "";
|
||||
this.form.tx = "";
|
||||
this.form.qq = "";
|
||||
this.form.wx = "";
|
||||
this.form.wb = "";
|
||||
this.form.personPage = "";
|
||||
break;
|
||||
case "save":
|
||||
if (this.form.id) {
|
||||
ajax.user1Update(this.form).then(function (response) {
|
||||
if (response.errors.length > 0) {
|
||||
nav.e(response.errors[0].message);
|
||||
} else {
|
||||
this.onFind();
|
||||
this.form.dialog = false;
|
||||
}
|
||||
}.bind(this))
|
||||
} else {
|
||||
ajax.user1Create(this.form).then(function (response) {
|
||||
if (response.errors.length > 0) {
|
||||
nav.e(response.errors[0].message);
|
||||
} else {
|
||||
this.onFind();
|
||||
this.form.dialog = false;
|
||||
}
|
||||
}.bind(this))
|
||||
}
|
||||
break;
|
||||
case "edit":
|
||||
this.form.title = "用户1编辑";
|
||||
this.form.dialog = true;
|
||||
this.form.id = item.id;
|
||||
this.form.name = item.name;
|
||||
this.form.age = item.age;
|
||||
this.form.sex = item.sex;
|
||||
this.form.tx = item.tx;
|
||||
this.form.qq = item.qq;
|
||||
this.form.wx = item.wx;
|
||||
this.form.wb = item.wb;
|
||||
this.form.personPage = item.personPage;
|
||||
this.form.rowVersion = item.rowVersion;
|
||||
break;
|
||||
case "delete":
|
||||
this.$confirm('将删除该项, 是否继续?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(function () {
|
||||
ajax.user1Delete({id: item.id}).then(function (response) {
|
||||
if (response.errors.length > 0) {
|
||||
nav.e(response.errors[0].message);
|
||||
} else {
|
||||
nav.s("删除成功")
|
||||
this.onFind();
|
||||
}
|
||||
}.bind(this))
|
||||
}.bind(this)).catch(function (action) {
|
||||
|
||||
});
|
||||
break;
|
||||
}
|
||||
},
|
||||
},
|
||||
created: function () {
|
||||
},
|
||||
mounted: function () {
|
||||
this.onFind();
|
||||
},
|
||||
watch: {}
|
||||
})
|
||||
</script>
|
Loading…
Reference in new issue