master
wangbing 4 years ago
parent fa4be5d125
commit 99688c474f

@ -4,14 +4,11 @@ import com.fasterxml.jackson.core.TreeNode;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
@ -23,35 +20,35 @@ import org.springframework.web.servlet.View;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver;
import xyz.wbsite.config.ActionConfig;
import xyz.wbsite.frame.auth.LocalData;
import xyz.wbsite.frame.base.LocalData;
import xyz.wbsite.frame.base.Token;
import xyz.wbsite.frame.base.VisitorEntity;
import xyz.wbsite.frame.base.BaseRequest;
import xyz.wbsite.frame.base.BaseResponse;
import xyz.wbsite.frame.base.ErrorType;
import xyz.wbsite.frame.base.Screen;
import xyz.wbsite.frame.auth.Token;
import xyz.wbsite.frame.listener.FrameListener;
import xyz.wbsite.frame.provider.TokenProvider;
import xyz.wbsite.frame.provider.VisitorProvider;
import xyz.wbsite.frame.sse.Sser;
import xyz.wbsite.frame.utils.AESUtil;
import xyz.wbsite.frame.utils.LogUtil;
import xyz.wbsite.frame.utils.MD5Util;
import xyz.wbsite.frame.utils.MapperUtil;
import xyz.wbsite.frame.utils.RequestUtil;
import xyz.wbsite.frame.utils.StringUtil;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.Locale;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* ControllerController
* htm{@link GlobalController#action(Model, HttpServletRequest, HttpServletResponse)}
* htm{@link GlobalController#page(Model, HttpServletRequest, HttpServletResponse)}
* ajax{@link GlobalController#ajax(String, String, String, HttpServletRequest, HttpServletResponse, String, MultipartFile)}
* {@link GlobalController#exceptionHandler(HttpServletRequest, HttpServletResponse, Model, Exception)}
* {@link GlobalController#sse(String)}
* <p>
* Request
@ -62,77 +59,17 @@ import java.util.regex.Pattern;
* @since 2017-01-01
*/
@Controller
@ControllerAdvice
public class GlobalController implements ErrorController {
public class GlobalController {
@Value("${server.servlet.context-path}")
private String context;
@Value("${web.home.page}")
@Value("${web.url.index}")
private String homePage;
@Value("${web.login.page}")
@Value("${web.url.login}")
private String loginPage;
@Autowired
private FreeMarkerViewResolver viewResolver;
/**
*
*
* @param request
* @param response
* @param exception
* @return
*/
@ExceptionHandler(Exception.class)
public String exceptionHandler(HttpServletRequest request, HttpServletResponse response, Model model, Exception exception) {
StringBuffer msg = new StringBuffer("");
if (exception != null) {
msg = new StringBuffer("");
String message = exception.toString();
int length = exception.getStackTrace().length;
if (length > 0) {
msg.append("<a>").append(message).append("</a><br>");
for (int i = 0; i < length; i++) {
msg.append("<a>").append(exception.getStackTrace()[i]).append("</a><br>");
}
} else {
msg.append(message);
}
}
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
model.addAttribute("msg", msg.toString());
return "500";
}
private final static String ERROR_PATH = "/error";
@Override
public String getErrorPath() {
return ERROR_PATH;
}
@RequestMapping(value = ERROR_PATH)
public String error(HttpServletRequest request, HttpServletResponse response) {
switch (response.getStatus()) {
case 404:
return "404";
case 403:
String errorUrl = RequestUtil.getErrorUrl(request);
errorUrl = errorUrl.replaceFirst(context, "");
if ((errorUrl.equals(homePage) || errorUrl.equals("/")) && LocalData.getToken() == null) {
try {
response.sendRedirect(context + loginPage);
} catch (IOException e) {
e.printStackTrace();
}
}
return "403";
case 500:
return "500";
default:
return "403";
}
}
@RequestMapping("/")
public String home() {
Token token = LocalData.getToken();
@ -151,31 +88,17 @@ public class GlobalController implements ErrorController {
* @param request
*/
@RequestMapping({"/**/*.htm"})
public String action(Model model, HttpServletRequest request, HttpServletResponse response) {
public String page(Model model, HttpServletRequest request, HttpServletResponse response) {
String servletPath = request.getServletPath();// /**/*.htm
String layout = "/layout/default";
String action = LocalData.getAction();// **/*
Pattern compile = Pattern.compile("^/(.+)\\.htm");
Matcher matcher = compile.matcher(servletPath);
if (matcher.find()) {
action = matcher.group(1);
LocalData.setAction(action);
}
String page = RequestUtil.getPage();
try {
LocaleResolver localeResolver = (LocaleResolver) request.getAttribute(DispatcherServlet.LOCALE_RESOLVER_ATTRIBUTE);
Locale locale = localeResolver.resolveLocale(request);
{//查询screen
String[] split = action.split("/");
StringBuilder sb = new StringBuilder("");
sb.append("screen");
for (int i = 0; i < split.length; i++) {
sb.append(File.separator);
sb.append(split[i]);
}
layout = sb.toString();
layout = "screen/" + page;
View view = viewResolver.resolveViewName(layout, locale);
if (view == null) {
response.sendError(HttpServletResponse.SC_NOT_FOUND, "");
@ -184,7 +107,7 @@ public class GlobalController implements ErrorController {
// 尝试执行Screen执行器(服务器渲染),并返回视图模板
try {
String beanClassName = (ActionConfig.SCREEN_PREFIX + action).toLowerCase();
String beanClassName = (ActionConfig.SCREEN_PREFIX + page).toLowerCase();
Screen screenExec = LocalData.getApplicationContext().getBean(beanClassName, Screen.class);
screenExec.exec(model, request, response);
@ -198,7 +121,7 @@ public class GlobalController implements ErrorController {
}
{//查找layout
String[] split = action.split("/");
String[] split = page.split("/");
int lt = split.length;
while (lt > 0) {
@ -230,11 +153,12 @@ public class GlobalController implements ErrorController {
}
}
} catch (Exception e) {
return exceptionHandler(request, response, model, e);
throw new RuntimeException(e);
}
// todo 可在此获取共性数据(也可以在全局拦截器GlobalHandlerInterceptor、拦截器作用域比此更高)
// todo 例如用户信息等。其他业务数据在页面渲染后通过Ajax请求
model.addAttribute("token", LocalData.getToken());
return layout;
}
@ -265,7 +189,7 @@ public class GlobalController implements ErrorController {
if (methodC == null) {
BaseResponse baseResponse = new BaseResponse();
baseResponse.addError(ErrorType.BUSINESS_ERROR, "未找到对应的方法!");
baseResponse.addError(ErrorType.BUSINESS_ERROR, "未实现的资源方法!");
return baseResponse;
}
@ -301,17 +225,16 @@ public class GlobalController implements ErrorController {
} catch (IllegalAccessException e) {
e.printStackTrace();
BaseResponse baseResponse = new BaseResponse();
baseResponse.addError(ErrorType.BUSINESS_ERROR, "方法执必须公开!");
baseResponse.addError(ErrorType.BUSINESS_ERROR, "私有的资源方法!");
return baseResponse;
} catch (InvocationTargetException e) {
e.getTargetException().printStackTrace();
BaseResponse baseResponse = new BaseResponse();
baseResponse.addError(ErrorType.BUSINESS_ERROR, "方法执行错误[" + e.getTargetException().getMessage() + "]");
baseResponse.addError(ErrorType.BUSINESS_ERROR, "资源方法执行错误[" + e.getTargetException().getMessage() + "]");
return baseResponse;
}
}
@RequestMapping(path = "/api/{module}/{target}/{method}", method = RequestMethod.POST)
@ResponseBody
public String api(
@ -337,34 +260,60 @@ public class GlobalController implements ErrorController {
return MapperUtil.toJson(response);
}
String data = null;
String appSecret = "1234567890123456";
String data;
VisitorProvider visitorProvider = LocalData.getBean(VisitorProvider.class);
if (visitorProvider == null) {
response.addError(ErrorType.BUSINESS_ERROR, "接入提供者不存在!");
return MapperUtil.toJson(response);
}
// 检索接入对象
VisitorEntity visitorEntity = visitorProvider.getVisitor(appKey);
if (visitorEntity == null) {
response.addError(ErrorType.BUSINESS_ERROR, "接入信息错误!");
return MapperUtil.toJson(response);
}
// 解码
try {
data = AESUtil.decrypt2String(encryptData, appSecret);
data = AESUtil.decrypt2String(encryptData, visitorEntity.getAppSecret());
} catch (Exception e) {
response.addError(ErrorType.BUSINESS_ERROR, "解码失败,请确认编码是否正确!");
return MapperUtil.toJson(response);
}
// 验证签名
String sign_ = MD5Util.encode(appSecret + data + timestamp);
String sign_ = MD5Util.encode(visitorEntity.getAppSecret() + data + timestamp);
if (!sign_.equals(sign)) {
response.addError(ErrorType.BUSINESS_ERROR, "签名验证失败!");
return AESUtil.encrypt2Base64(MapperUtil.toJson(response).getBytes(), appSecret);
return AESUtil.encrypt2Base64(MapperUtil.toJson(response).getBytes(), visitorEntity.getAppSecret());
}
// 时效性验证
long currentTime = System.currentTimeMillis();
if (currentTime - timestamp > 2 * 60 * 1000) {
response.addError(ErrorType.BUSINESS_ERROR, "请求过期, 或本地时间错误!");
return AESUtil.encrypt2Base64(MapperUtil.toJson(response).getBytes(), appSecret);
return AESUtil.encrypt2Base64(MapperUtil.toJson(response).getBytes(), visitorEntity.getAppSecret());
}
// 权限验证
if (StringUtil.isNotEmpty(token)) {
TokenProvider tokenProvider = LocalData.getBean(TokenProvider.class);
if (tokenProvider == null) {
LocalData.setToken(null);
} else {
Token build = tokenProvider.build(token);
LocalData.setToken(build);
}
if (!LocalData.getToken().hasRes(httpServletRequest.getServletPath())) {
response.addError(ErrorType.BUSINESS_ERROR, "[" + httpServletRequest.getServletPath() + "]未授权的资源!");
return AESUtil.encrypt2Base64(MapperUtil.toJson(response).getBytes(), appSecret);
return AESUtil.encrypt2Base64(MapperUtil.toJson(response).getBytes(), visitorEntity.getAppSecret());
}
} else {
String excluded = LocalData.getEnvironment().getProperty("web.url.auth.excluded", "") + ",/api/wsys/User/login";
if (!excluded.contains(excluded)) {
response.addError(ErrorType.BUSINESS_ERROR, "请通过登录接口获取Token!");
return AESUtil.encrypt2Base64(MapperUtil.toJson(response).getBytes(), visitorEntity.getAppSecret());
}
}
// 开始处理业务
@ -383,7 +332,7 @@ public class GlobalController implements ErrorController {
if (methodC == null) {
response.addError(ErrorType.BUSINESS_ERROR, "未找到对应的方法!");
return AESUtil.encrypt2Base64(MapperUtil.toJson(response).getBytes(), appSecret);
return AESUtil.encrypt2Base64(MapperUtil.toJson(response).getBytes(), visitorEntity.getAppSecret());
}
Parameter[] parameters = methodC.getParameters();
@ -413,42 +362,79 @@ public class GlobalController implements ErrorController {
e.printStackTrace();
response.addError(ErrorType.BUSINESS_ERROR, "方法执必须公开!");
} catch (InvocationTargetException e) {
LogUtil.dumpException(e.getTargetException());
e.getTargetException().printStackTrace();
FrameListener instance = FrameListener.getInstance();
instance.onError(e.getTargetException());
response.addError(ErrorType.BUSINESS_ERROR, "方法执行错误[" + e.getTargetException().getMessage() + "]");
}
return AESUtil.encrypt2Base64(MapperUtil.toJson(response).getBytes(), appSecret);
return AESUtil.encrypt2Base64(MapperUtil.toJson(response).getBytes(), visitorEntity.getAppSecret());
}
private static ConcurrentHashMap<String, SseEmitter> sseMap = new ConcurrentHashMap();
@RequestMapping(path = "/msvr/{module}/{target}/{method}", method = RequestMethod.POST)
@ResponseBody
public BaseResponse msvr(
@PathVariable String module,
@PathVariable String target,
@PathVariable String method,
@RequestBody String data,
@RequestHeader String token) {
BaseResponse response = new BaseResponse();
/**
* Ssejs
* Sse{@link GlobalController#sseMap}
* Sse{@link GlobalController#pushAll}
*/
@RequestMapping(value = "/sse/{userId}", produces = "text/event-stream;charset=UTF-8")
public SseEmitter sse(@PathVariable String userId) {
SseEmitter sseEmitter = new SseEmitter(10000000L);
if (sseMap.get(userId) != null) {
sseMap.remove(userId);
LocalData.setToken(MapperUtil.toJava(token, Token.class));
// 开始处理业务
try {
String beanClassName = (ActionConfig.MSVR_PREFIX + module + "/" + target).toLowerCase();
Object ajax = LocalData.getApplicationContext().getBean(beanClassName);
Class ajaxClass = ajax.getClass();
Method[] methods = ajaxClass.getDeclaredMethods();
Method methodC = null;
for (Method meth : methods) {
if (meth.getName().equals(method)) {
methodC = meth;
}
sseMap.put(userId, sseEmitter);
return sseEmitter;
}
/**
* Sse
*
* @param data
*/
public static void pushAll(Object data) {
for (String s : sseMap.keySet()) {
try {
sseMap.get(s).send(MapperUtil.toJson(data), MediaType.APPLICATION_JSON);
} catch (IOException e) {
sseMap.remove(s);
if (methodC == null) {
response.addError(ErrorType.BUSINESS_ERROR, "未找到对应的服务方法!");
return response;
}
Parameter[] parameters = methodC.getParameters();
Object[] arg = new Object[parameters.length];
for (int i = 0; i < parameters.length; i++) {
Parameter parameter = parameters[i];
if (BaseRequest.class.isAssignableFrom(parameter.getType())) {
arg[i] = MapperUtil.toJava(data, parameter.getType());
} else if (parameter.getType() == Token.class) {
arg[i] = LocalData.getToken();
} else {
arg[i] = null;
}
}
response = (BaseResponse) methodC.invoke(ajax, arg);
} catch (BeansException e) {
e.printStackTrace();
response.addError(ErrorType.BUSINESS_ERROR, "未找到对应的目标!");
} catch (IllegalAccessException e) {
e.printStackTrace();
response.addError(ErrorType.BUSINESS_ERROR, "方法执必须公开!");
} catch (InvocationTargetException e) {
FrameListener instance = FrameListener.getInstance();
instance.onError(e.getTargetException());
response.addError(ErrorType.BUSINESS_ERROR, "服务方法执行错误[" + e.getTargetException().getMessage() + "]");
}
return response;
}
/**
* Ssejs
* Sse{@link Sser#push(String, Object)}
* Sse{@link Sser#pushAll(Object)}
*/
@RequestMapping(value = "/sse/{userId}", produces = "text/event-stream;charset=UTF-8")
public SseEmitter sse(@PathVariable String userId) {
return Sser.register(userId, new SseEmitter(10000000L));
}
}

@ -0,0 +1,108 @@
package xyz.wbsite.action.ajax.admin;
import com.alibaba.excel.support.ExcelTypeEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.multipart.MultipartFile;
import xyz.wbsite.frame.base.Error;
import xyz.wbsite.frame.excel.WExcel;
import xyz.wbsite.frame.utils.LogUtil;
import xyz.wbsite.frame.base.LocalData;
import xyz.wbsite.frame.base.ErrorType;
import xyz.wbsite.frame.utils.MapperUtil;
import xyz.wbsite.frame.base.BaseResponse;
import xyz.wbsite.frame.utils.ResponseUtil;
import xyz.wbsite.frame.utils.ValidationUtil;
import xyz.wbsite.frame.excel.exception.TemplateNotMatchException;
import xyz.wbsite.module.admin.ent.Services;
import xyz.wbsite.module.admin.mgr.ServicesManager;
import xyz.wbsite.module.admin.req.ServicesCreateRequest;
import xyz.wbsite.module.admin.req.ServicesDeleteRequest;
import xyz.wbsite.module.admin.req.ServicesFindRequest;
import xyz.wbsite.module.admin.req.ServicesUpdateRequest;
import xyz.wbsite.module.admin.rsp.ServicesCreateResponse;
import xyz.wbsite.module.admin.rsp.ServicesDeleteResponse;
import xyz.wbsite.module.admin.rsp.ServicesFindResponse;
import xyz.wbsite.module.admin.rsp.ServicesUpdateResponse;
import java.io.IOException;
import java.util.List;
public class ServicesAjax{
@Autowired
private ServicesManager servicesManager;
public ServicesCreateResponse create(ServicesCreateRequest request) {
return servicesManager.create(request, LocalData.getToken());
}
public ServicesDeleteResponse delete(ServicesDeleteRequest request) {
return servicesManager.delete(request, LocalData.getToken());
}
public ServicesUpdateResponse update(ServicesUpdateRequest request) {
return servicesManager.update(request, LocalData.getToken());
}
public ServicesFindResponse find(ServicesFindRequest request) {
return servicesManager.find(request, LocalData.getToken());
}
public Object template(){
return ResponseUtil.apply(new WExcel<>(Services.class));
}
public Object exports(ServicesFindRequest request) {
ServicesFindResponse response = servicesManager.find(request, LocalData.getToken());
if (response.hasError()) {
return response;
} else if (response.getTotalCount() == 0) {
response.addError(ErrorType.BUSINESS_ERROR, "导出数据为空");
return response;
}
return ResponseUtil.apply(new WExcel<>(Services.class).addDatas(response.getResult()));
}
public Object imports(MultipartFile file) {
BaseResponse baseResponse = new BaseResponse();
try {
// 检查文件格式
String originalFilename = file.getOriginalFilename() != null ? file.getOriginalFilename() : "";
if (!originalFilename.matches(".+(.xlsx?|.XLSX?)$")) {
baseResponse.addError(ErrorType.BUSINESS_ERROR, "上传文件格式错误!");
return baseResponse;
}
// 兼容2003以前老版本.xls
ExcelTypeEnum excelTypeEnum = originalFilename.matches(".+(.xlsx|.XLSX)$") ? ExcelTypeEnum.XLSX : ExcelTypeEnum.XLS;
WExcel sheet = new WExcel<>(Services.class).read(file.getBytes(), excelTypeEnum, new WExcel.Processor<Services>() {
@Override
public List<String> exec(Services o, int index) {
ServicesCreateRequest request = MapperUtil.map(o, ServicesCreateRequest.class);
List<String> validate = ValidationUtil.validate(request);
if (validate == null || validate.size() == 0) {
ServicesCreateResponse servicesCreateResponse = servicesManager.create(request, LocalData.getToken());
if (servicesCreateResponse.hasError()) {
for (Error error : servicesCreateResponse.getErrors()) {
validate.add(error.getMessage());
}
}
}
return validate;
}
});
// 当导入出现错误时可以将存在标注错误的Excel返回给用户改正
if (sheet.hasError()) {
return ResponseUtil.apply(sheet.getBytes(), sheet.getName() + "-检查.xlsx");
} else {
return baseResponse;
}
} catch (IOException e) {
e.printStackTrace();
LogUtil.dumpException(e);
baseResponse.addError(ErrorType.BUSINESS_ERROR, "上传文件出错");
} catch (TemplateNotMatchException e) {
baseResponse.addError(ErrorType.BUSINESS_ERROR, e.getMessage());
}
return baseResponse;
}
}

@ -0,0 +1,124 @@
package xyz.wbsite.action.ajax.wframe;
import org.springframework.beans.factory.annotation.Autowired;
import xyz.wbsite.config.CacheConfig;
import xyz.wbsite.frame.base.ErrorType;
import xyz.wbsite.frame.base.LocalData;
import xyz.wbsite.frame.base.LoginRequest;
import xyz.wbsite.frame.base.LoginResponse;
import xyz.wbsite.frame.base.LogoutRequest;
import xyz.wbsite.frame.base.LogoutResponse;
import xyz.wbsite.frame.base.Token;
import xyz.wbsite.frame.base.UserEntity;
import xyz.wbsite.frame.base.VerifyCodeRequest;
import xyz.wbsite.frame.base.VerifyCodeResponse;
import xyz.wbsite.frame.provider.FrameProvider;
import xyz.wbsite.frame.provider.TokenProvider;
import xyz.wbsite.frame.provider.UserProvider;
import xyz.wbsite.frame.utils.CookieUtil;
import xyz.wbsite.frame.utils.IDgenerator;
import xyz.wbsite.frame.utils.MD5Util;
import xyz.wbsite.frame.utils.ValidationUtil;
import xyz.wbsite.frame.utils.VerifyCodeUtil;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
public class AuthAjax {
@Autowired
private CacheConfig cacheConfig;
public VerifyCodeResponse verifyCode(VerifyCodeRequest request) {
VerifyCodeResponse response = new VerifyCodeResponse();
VerifyCodeUtil.Builder builder = new VerifyCodeUtil.Builder().build();
response.setVerifyCodeId(IDgenerator.nextId());
response.setVerifyCodeBase64(builder.toBase64());
cacheConfig.put(response.getVerifyCodeId(), builder.toCode(), 3 * 60 * 1000);
return response;
}
public LoginResponse login(LoginRequest request, HttpServletResponse httpServletResponse) {
LoginResponse response = new LoginResponse();
ValidationUtil.validate(request, response);
if (response.hasError()) {
return response;
}
// 获取验证码
String o = cacheConfig.remove(request.getVerifyCodeId(), String.class);
if (o == null) {
response.addError(ErrorType.BUSINESS_ERROR, "验证码已过期!");
return response;
}
// 验证验证码
if (!request.getVerifyCodeCode().toLowerCase().equals(o.toLowerCase())) {
response.addError(ErrorType.BUSINESS_ERROR, "验证码错误!");
cacheConfig.remove(request.getVerifyCodeId());
return response;
}
// 获取用户提供者
UserProvider userProvider = FrameProvider.getInstance().getUserProvider();
if (userProvider == null) {
response.addError(ErrorType.BUSINESS_ERROR, "用户提供者未实现!");
return response;
}
// 获取用户信息
UserEntity userEntity = userProvider.getUser(request.getUsername());
if (userEntity == null) {
response.addError(ErrorType.BUSINESS_ERROR, "用户名或密码错误!");
return response;
}
// 验证密码
String generatePwd = MD5Util.generatePwd(request.getPassword());
if (!generatePwd.equals(userEntity.getPassword())) {
response.addError(ErrorType.BUSINESS_ERROR, "用户名或密码错误!");
return response;
}
// 获取通行证提供者
TokenProvider tokenProvider = FrameProvider.getInstance().getTokenProvider();
if (tokenProvider == null) {
response.addError(ErrorType.BUSINESS_ERROR, "通行证提供者未实现!");
return response;
}
// 构建通行证
Token token = tokenProvider.build(userEntity);
if (token == null) {
response.addError(ErrorType.BUSINESS_ERROR, "通行证构建失败!");
return response;
}
response.setToken(token.getToken());
Cookie cookie = CookieUtil.newCookie("token", response.getToken());
httpServletResponse.addCookie(cookie);
return response;
}
public LogoutResponse logout(LogoutRequest request) {
LogoutResponse response = new LogoutResponse();
Token token = LocalData.getToken();
if (token != null) {
cacheConfig.clear(token.getToken());
}
CookieUtil.clearCookie("token");
return response;
}
public LogoutResponse changePwd(LogoutRequest request) {
LogoutResponse response = new LogoutResponse();
Token token = LocalData.getToken();
if (token != null) {
cacheConfig.clear(token.getToken());
}
CookieUtil.clearCookie("token");
return response;
}
}

@ -0,0 +1,24 @@
package xyz.wbsite.action.page.control;
import xyz.wbsite.frame.base.Control;
import org.springframework.ui.Model;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* resources/templates/control/header.ftl<#include controlHolder("nav")/> 访
* <br>
* 访Screen
*
* @author author
* @version 0.0.1
* @since 2020-11-01
*/
public class Header extends Control {
@Override
public void exec(Model model, HttpServletRequest request, HttpServletResponse response) {
}
}

@ -25,6 +25,9 @@ import java.util.regex.Pattern;
* <p>
* Screen {@link ActionConfig#registryScreen}
* Control {@link ActionConfig#registryControl}
* Ajax {@link ActionConfig#registryAjax}
* Api {@link ActionConfig#registryApi}
* Wsvr {@link ActionConfig#registryWsvr}
*
* @author wangbing
* @version 0.0.1
@ -37,6 +40,7 @@ public class ActionConfig implements BeanDefinitionRegistryPostProcessor {
public static String CONTROL_PREFIX = "/control/";
public static String AJAX_PREFIX = "/ajax/";
public static String API_PREFIX = "/api/";
public static String MSVR_PREFIX = "/wsvr/";
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
@ -44,11 +48,12 @@ public class ActionConfig implements BeanDefinitionRegistryPostProcessor {
Pattern compile = Pattern.compile("(.*)\\.config");
Matcher matcher = compile.matcher(aPackage);
if (matcher.find()) {
String basePackage = matcher.group(1);
registryScreen(basePackage + ".action.screen", beanDefinitionRegistry);
registryControl(basePackage + ".action.control", beanDefinitionRegistry);
registryAjax(basePackage + ".action.ajax", beanDefinitionRegistry);
registryApi(basePackage + ".action.api", beanDefinitionRegistry);
String domain = matcher.group(1);
registryScreen(domain + ".action.page.screen", beanDefinitionRegistry);
registryControl(domain + ".action.page.control", beanDefinitionRegistry);
registryAjax(domain + ".action.ajax", beanDefinitionRegistry);
registryApi(domain + ".action.api", beanDefinitionRegistry);
registryWsvr(domain + ".action.msvr", beanDefinitionRegistry);
}
}
@ -57,7 +62,7 @@ public class ActionConfig implements BeanDefinitionRegistryPostProcessor {
}
private int registryScreen(String basePackage, BeanDefinitionRegistry beanDefinitionRegistry) {
private int registryScreen(String domain, BeanDefinitionRegistry beanDefinitionRegistry) {
ClassPathBeanDefinitionScanner classPathBeanDefinitionScanner = new ClassPathBeanDefinitionScanner(beanDefinitionRegistry);
classPathBeanDefinitionScanner.resetFilters(false);
classPathBeanDefinitionScanner.addIncludeFilter(new AssignableTypeFilter(Screen.class));
@ -65,15 +70,15 @@ public class ActionConfig implements BeanDefinitionRegistryPostProcessor {
@Override
public String generateBeanName(BeanDefinition beanDefinition, BeanDefinitionRegistry beanDefinitionRegistry) {
String beanClassName = beanDefinition.getBeanClassName();
String beamName = beanClassName.replaceAll(basePackage + ".", SCREEN_PREFIX).replaceAll("\\.","/").toLowerCase();
String beamName = beanClassName.replaceAll(domain + ".", SCREEN_PREFIX).replaceAll("\\.","/").toLowerCase();
LogUtil.i("registry screen " + beamName);
return beamName;
}
});
return classPathBeanDefinitionScanner.scan(basePackage);
return classPathBeanDefinitionScanner.scan(domain);
}
private int registryControl(String basePackage, BeanDefinitionRegistry beanDefinitionRegistry) {
private int registryControl(String domain, BeanDefinitionRegistry beanDefinitionRegistry) {
ClassPathBeanDefinitionScanner classPathBeanDefinitionScanner = new ClassPathBeanDefinitionScanner(beanDefinitionRegistry);
classPathBeanDefinitionScanner.resetFilters(false);
classPathBeanDefinitionScanner.addIncludeFilter(new AssignableTypeFilter(Control.class));
@ -81,15 +86,15 @@ public class ActionConfig implements BeanDefinitionRegistryPostProcessor {
@Override
public String generateBeanName(BeanDefinition beanDefinition, BeanDefinitionRegistry beanDefinitionRegistry) {
String beanClassName = beanDefinition.getBeanClassName();
String beamName = beanClassName.replaceAll(basePackage + ".", CONTROL_PREFIX).replaceAll("\\.","/").toLowerCase();
String beamName = beanClassName.replaceAll(domain + ".", CONTROL_PREFIX).replaceAll("\\.","/").toLowerCase();
LogUtil.i("registry control " + beamName);
return beamName;
}
});
return classPathBeanDefinitionScanner.scan(basePackage);
return classPathBeanDefinitionScanner.scan(domain);
}
private int registryAjax(String basePackage, BeanDefinitionRegistry beanDefinitionRegistry) {
private int registryAjax(String domain, BeanDefinitionRegistry beanDefinitionRegistry) {
ClassPathBeanDefinitionScanner classPathBeanDefinitionScanner = new ClassPathBeanDefinitionScanner(beanDefinitionRegistry);
classPathBeanDefinitionScanner.resetFilters(false);
classPathBeanDefinitionScanner.addIncludeFilter(new TypeFilter() {
@ -103,17 +108,17 @@ public class ActionConfig implements BeanDefinitionRegistryPostProcessor {
public String generateBeanName(BeanDefinition beanDefinition, BeanDefinitionRegistry beanDefinitionRegistry) {
String beanClassName = beanDefinition.getBeanClassName();
if (beanClassName != null && beanClassName.endsWith("Ajax")) {
beanClassName = beanClassName.substring(0, beanClassName.length() - 4);
beanClassName = beanClassName.substring(0, beanClassName.lastIndexOf("Ajax"));
}
String beamName = beanClassName.replaceAll(basePackage + ".", AJAX_PREFIX).replaceAll("\\.","/").toLowerCase();
String beamName = beanClassName.replaceAll(domain + ".", AJAX_PREFIX).replaceAll("\\.","/").toLowerCase();
LogUtil.i("registry ajax " + beamName);
return beamName;
}
});
return classPathBeanDefinitionScanner.scan(basePackage);
return classPathBeanDefinitionScanner.scan(domain);
}
private int registryApi(String basePackage, BeanDefinitionRegistry beanDefinitionRegistry) {
private int registryApi(String domain, BeanDefinitionRegistry beanDefinitionRegistry) {
ClassPathBeanDefinitionScanner classPathBeanDefinitionScanner = new ClassPathBeanDefinitionScanner(beanDefinitionRegistry);
classPathBeanDefinitionScanner.addIncludeFilter(new TypeFilter() {
@Override
@ -126,13 +131,36 @@ public class ActionConfig implements BeanDefinitionRegistryPostProcessor {
public String generateBeanName(BeanDefinition beanDefinition, BeanDefinitionRegistry beanDefinitionRegistry) {
String beanClassName = beanDefinition.getBeanClassName();
if (beanClassName != null && beanClassName.endsWith("Api")) {
beanClassName = beanClassName.substring(0, beanClassName.length() - 3);
beanClassName = beanClassName.substring(0, beanClassName.lastIndexOf("Api"));
}
String beamName = beanClassName.replaceAll(basePackage + ".", API_PREFIX).replaceAll("\\.","/").toLowerCase();
String beamName = beanClassName.replaceAll(domain + ".", API_PREFIX).replaceAll("\\.","/").toLowerCase();
LogUtil.i("registry api " + beamName);
return beamName;
}
});
return classPathBeanDefinitionScanner.scan(basePackage);
return classPathBeanDefinitionScanner.scan(domain);
}
private int registryWsvr(String domain, BeanDefinitionRegistry beanDefinitionRegistry) {
ClassPathBeanDefinitionScanner classPathBeanDefinitionScanner = new ClassPathBeanDefinitionScanner(beanDefinitionRegistry);
classPathBeanDefinitionScanner.addIncludeFilter(new TypeFilter() {
@Override
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
return true;
}
});
classPathBeanDefinitionScanner.setBeanNameGenerator(new BeanNameGenerator() {
@Override
public String generateBeanName(BeanDefinition beanDefinition, BeanDefinitionRegistry beanDefinitionRegistry) {
String beanClassName = beanDefinition.getBeanClassName();
if (beanClassName != null && beanClassName.endsWith("Msvr")) {
beanClassName = beanClassName.substring(0, beanClassName.lastIndexOf("Msvr"));
}
String beamName = beanClassName.replaceAll(domain + ".", MSVR_PREFIX).replaceAll("\\.","/").toLowerCase();
LogUtil.i("registry wsvr " + beamName);
return beamName;
}
});
return classPathBeanDefinitionScanner.scan(domain);
}
}

@ -0,0 +1,90 @@
package xyz.wbsite.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
/**
* CacheRedisCacheEhCacheCacheConcurrentMapCache
* CacheManager(Cache)
*
* @EnableCaching
* @Cacheable condition:使 unless:
* @CacheEvict
* @CachePut
* <p>
* keyGenerator key
* serialize value
*/
@Configuration
@EnableCaching
@EnableScheduling
public class CacheConfig {
@Autowired
private CacheConfig cacheConfig;
private Map<Object, Long> expireMap = new HashMap<>();
public static final String DEFAULT_CACHE_NAME = "default_cache_name";
public <T> T put(Object key, T value) {
return cacheConfig.put(key, value, 0);
}
@Cacheable(value = DEFAULT_CACHE_NAME, key = "#key", unless = "#result==null")
public <T> T put(Object key, T value, long expire) {
if (value != null && expire > 0) {
expireMap.put(key, System.currentTimeMillis() + expire);
}
return value;
}
@CacheEvict(cacheNames = DEFAULT_CACHE_NAME, key = "#key")
public void clear(Object key) {
}
public Object get(Object key) {
return cacheConfig.get(key, Object.class);
}
public <T> T get(Object key, Class<T> tClass) {
return cacheConfig.put(key, null);
}
public Object remove(Object key) {
return remove(key, Object.class);
}
public <T> T remove(Object key, Class<T> tClass) {
T t = cacheConfig.get(key, tClass);
cacheConfig.clear(key);
return t;
}
@Scheduled(fixedDelay = 1000)
public void expireTask() {
Iterator<Object> iterator = expireMap.keySet().iterator();
while (iterator.hasNext()) {
Object next = iterator.next();
Long aLong = expireMap.get(next);
if (aLong == null) {
cacheConfig.remove(next);
iterator.remove();
}
if (aLong < System.currentTimeMillis()) {
cacheConfig.remove(next);
iterator.remove();
}
}
}
}

@ -1,5 +1,9 @@
package xyz.wbsite.config;
import xyz.wbsite.frame.base.LocalData;
import xyz.wbsite.frame.base.Control;
import xyz.wbsite.frame.utils.RequestUtil;
import xyz.wbsite.frame.utils.UrlUtil;
import freemarker.template.SimpleScalar;
import freemarker.template.TemplateMethodModelEx;
import freemarker.template.TemplateModelException;
@ -14,9 +18,6 @@ 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 xyz.wbsite.frame.auth.LocalData;
import xyz.wbsite.frame.base.Control;
import xyz.wbsite.frame.utils.UrlUtil;
import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
@ -55,28 +56,15 @@ public class FreeMarkerConfig {
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);
}
}
String page = RequestUtil.getPage();
Locale locale = localeResolver.resolveLocale(request);
String viewName = "screen" + File.separator + sb.toString();
String viewName = "screen/" + page;
View view = viewResolver.resolveViewName(viewName, locale);
//无法找到对应screen
if (view == null) {
return "";
} else {
return SCREEN_PREFIX + servletPath + suffix;
return SCREEN_PREFIX + page + suffix;
}
} catch (Exception e) {
e.printStackTrace();

@ -6,6 +6,7 @@ import org.springframework.context.annotation.Configuration;
import javax.annotation.PostConstruct;
import java.io.File;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -17,7 +18,8 @@ public class SQLiteConfig {
@PostConstruct
public void generateDB() {
Pattern compile = Pattern.compile("jdbc:sqlite:(.*.db).*");
try {
Pattern compile = Pattern.compile("jdbc:sqlite:(.*.db3).*");
Matcher matcher = compile.matcher(url);
if (matcher.find()) {
String group = matcher.group(1);
@ -25,8 +27,12 @@ public class SQLiteConfig {
if (!file.exists()) {
File path = file.getAbsoluteFile().getParentFile();
if (!path.exists()) path.mkdirs();
ResourceUtil.copyResource2File("nginx-admin.db", file);
if (!file.exists()) file.createNewFile();
ResourceUtil.copyToFile("nginx-admin.db3", file);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

@ -1,91 +0,0 @@
package xyz.wbsite.config;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.core.type.filter.AssignableTypeFilter;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.stereotype.Component;
import xyz.wbsite.frame.schedule.RunTask;
import xyz.wbsite.frame.utils.LogUtil;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ScheduledFuture;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* ,
* :@Profile("dev") ()
*/
@Configuration
@Component
public class ScheduleConfig extends ThreadPoolTaskScheduler implements BeanDefinitionRegistryPostProcessor {
private Map<String, Class<RunTask>> classMap;
private Map<String, ScheduledFuture<?>> futureMap;
public ScheduleConfig() {
classMap = new HashMap<>();
futureMap = new HashMap<>();
setPoolSize(4);
initialize();
}
public boolean createOrRepeat(RunTask task) {
if (futureMap.containsKey(task.taskId())) {
ScheduledFuture<?> scheduledFuture = futureMap.get(task.taskId());
scheduledFuture.cancel(false);
}
classMap.put(task.taskId(), (Class<RunTask>) task.getClass());
futureMap.put(task.taskId(), task.schedule(this));
return true;
}
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
String aPackage = this.getClass().getPackage().getName();
Pattern compile = Pattern.compile("(.*)\\.config");
Matcher matcher = compile.matcher(aPackage);
if (matcher.find()) {
String basePackage = matcher.group(1);
registryTask(basePackage, beanDefinitionRegistry);
}
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
}
private int registryTask(String basePackage, BeanDefinitionRegistry beanDefinitionRegistry) {
ClassPathBeanDefinitionScanner classPathBeanDefinitionScanner = new ClassPathBeanDefinitionScanner(beanDefinitionRegistry);
classPathBeanDefinitionScanner.resetFilters(false);
classPathBeanDefinitionScanner.addIncludeFilter(new AssignableTypeFilter(RunTask.class));
classPathBeanDefinitionScanner.setBeanNameGenerator(new BeanNameGenerator() {
@Override
public String generateBeanName(BeanDefinition beanDefinition, BeanDefinitionRegistry beanDefinitionRegistry) {
String beanClassName = beanDefinition.getBeanClassName();
try {
Class<?> aClass = Class.forName(beanClassName);
Object instance = aClass.newInstance();
RunTask task = (RunTask) instance;
ScheduleConfig.this.createOrRepeat(task);
} catch (Exception e) {
e.printStackTrace();
}
LogUtil.i("registry task " + beanClassName);
return beanClassName;
}
});
return classPathBeanDefinitionScanner.scan(basePackage);
}
}

@ -7,14 +7,16 @@ import org.springframework.security.access.AccessDeniedException;
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 org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
import xyz.wbsite.frame.auth.LocalData;
import xyz.wbsite.frame.auth.Token;
import xyz.wbsite.frame.base.LocalData;
import xyz.wbsite.frame.base.Token;
import xyz.wbsite.frame.provider.FrameProvider;
import xyz.wbsite.frame.provider.TokenProvider;
import xyz.wbsite.frame.utils.CookieUtil;
import xyz.wbsite.frame.utils.RequestUtil;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
@ -24,8 +26,6 @@ import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@Configuration
@EnableGlobalMethodSecurity(securedEnabled = true)
@ -35,16 +35,9 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
private String[] included;
@Value("${web.url.auth.excluded}")
private String[] excluded;
@Value("${spring.mvc.static-path-pattern}")
private String[] staticPath;
@Value("${web.login.page}")
@Value("${web.url.login}")
private String loginPage;
@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)
@ -77,24 +70,28 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
// 1优先获取参数中的token
String token = request.getParameter("token");
// 2其次获取Cookie中的token
if (token == null || token.isEmpty()) {
token = CookieUtil.getCookieValue(request.getCookies(), "token");
}
// 3其次获取Header中的token
if (token == null || token.isEmpty()) {
token = RequestUtil.getHeader(request, "token");
}
// 组装Token ~ 这边根据实际的业务组装Token
if (token != null) {
LocalData.setToken( LocalData.getSysToken());
} else {
TokenProvider tokenProvider = FrameProvider.getInstance().getTokenProvider();
if (tokenProvider == null) {
LocalData.setToken(null);
} else {
Token build = tokenProvider.build(token);
LocalData.setToken(build);
}
// Action
String servletPath = request.getServletPath().toLowerCase();
Pattern compile = Pattern.compile("^/(.+)\\.htm");
Matcher matcher = compile.matcher(servletPath);
if (matcher.find()) {
LocalData.setAction(matcher.group(1));
} else {
LocalData.setToken(null);
}
try {
@ -126,5 +123,4 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
}
};
}
}

@ -0,0 +1,63 @@
package xyz.wbsite.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.type.filter.AssignableTypeFilter;
import xyz.wbsite.frame.schedule.RunTask;
import xyz.wbsite.frame.schedule.Scheduler;
import xyz.wbsite.frame.utils.LogUtil;
import javax.annotation.PostConstruct;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@Configuration
public class TaskConfig {
@Autowired
private Scheduler scheduler;
@Bean
public Scheduler registerScheduler() {
return new Scheduler();
}
@PostConstruct
public void registryTask() {
{// 扫描类任务
String aPackage = this.getClass().getPackage().getName();
Pattern compile = Pattern.compile("(.*)\\.config");
Matcher matcher = compile.matcher(aPackage);
if (matcher.find()) {
DefaultListableBeanFactory simpleBeanDefinitionRegistry = new DefaultListableBeanFactory();
ClassPathBeanDefinitionScanner classPathBeanDefinitionScanner = new ClassPathBeanDefinitionScanner(simpleBeanDefinitionRegistry);
classPathBeanDefinitionScanner.resetFilters(false);
classPathBeanDefinitionScanner.addIncludeFilter(new AssignableTypeFilter(RunTask.class));
classPathBeanDefinitionScanner.setBeanNameGenerator(new BeanNameGenerator() {
@Override
public String generateBeanName(BeanDefinition beanDefinition, BeanDefinitionRegistry beanDefinitionRegistry) {
String beanClassName = beanDefinition.getBeanClassName();
try {
Class<?> aClass = Class.forName(beanClassName);
Object instance = aClass.newInstance();
RunTask task = (RunTask) instance;
scheduler.createOrRepeat(task);
} catch (Exception e) {
e.printStackTrace();
}
LogUtil.i("registry task " + beanClassName);
return beanClassName;
}
});
classPathBeanDefinitionScanner.scan(matcher.group(1));
}
}
}
}

@ -1,56 +0,0 @@
package xyz.wbsite.config;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.Configuration;
import org.springframework.lang.Nullable;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.lang.reflect.Method;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
@Configuration
@EnableAsync
public class ThreadPoolConfig implements AsyncConfigurer {
private ThreadPoolTaskExecutor executor;
private int corePoolSize = 10;//线程池维护线程的最少数量
private int maxPoolSize = 30;//线程池维护线程的最大数量
private int queueCapacity = 8; //缓存队列
private int keepAlive = 60;//允许的空闲时间
@Nullable
@Override
public Executor getAsyncExecutor() {
executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(corePoolSize);
executor.setMaxPoolSize(maxPoolSize);
executor.setQueueCapacity(queueCapacity);
executor.setThreadNamePrefix("mqExecutor-");
// rejection-policy当pool已经达到max size的时候如何处理新任务
// CALLER_RUNS不在新线程中执行任务而是由调用者所在的线程来执行
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); //对拒绝task的处理策略
executor.setKeepAliveSeconds(keepAlive);
executor.initialize();
return executor;
}
@Nullable
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return new AsyncUncaughtExceptionHandler() {
@Override
public void handleUncaughtException(Throwable throwable, Method method, Object... objects) {
System.out.println("-------------》》》捕获线程异常信息");
}
};
}
}

@ -1,55 +1,72 @@
package xyz.wbsite.config;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import xyz.wbsite.frame.utils.LogUtil;
import xyz.wbsite.frame.provider.SimpleTokenProvider;
import xyz.wbsite.frame.provider.SimpleUserProvider;
import xyz.wbsite.frame.provider.TokenProvider;
import xyz.wbsite.frame.provider.UserProvider;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Value("${web.home.page}")
@Value("${web.url.index}")
private String homePage;
@Value("${spring.mvc.static-path-pattern}")
private String[] staticPath;
/**
*
*
*
* @param registry
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 全局异常收集拦截器
// 全局拦截器
registry.addInterceptor(new HandlerInterceptorAdapter() {
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
super.afterCompletion(request, response, handler, ex);
if (ex != null) {
LogUtil.dumpException(ex);
}
}
}).addPathPatterns("/**").excludePathPatterns(staticPath);
}
/**
*
*
* @param registry
*/
// @Override
// public void addCorsMappings(CorsRegistry registry) {
// registry.addMapping("/**")
// .allowedOrigins("*")
// .allowCredentials(true)
// .allowedMethods("GET", "POST", "DELETE", "PUT")
// .maxAge(3600);
// }
/**
* Jackson
* <p>
* 1LonglongStringjavascriptNumber
*
* @param converters
*/
@ -59,64 +76,60 @@ public class WebMvcConfig implements WebMvcConfigurer {
if (converter instanceof MappingJackson2HttpMessageConverter) {
ObjectMapper objectMapper = ((MappingJackson2HttpMessageConverter) converter).getObjectMapper();
SimpleModule simpleModule = new SimpleModule();
{// 序列化时Long或long类型在转String防止出现javascript中Number精度丢失的情况。
simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);
}
{// 反序列化时Boolean和boolean可以识别0和1数字
simpleModule.addDeserializer(Boolean.class, new JsonDeserializer<Boolean>() {
@Override
public Boolean deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
String text = jsonParser.getText();
if (text == null || "".equals(text)) {
return null;
} else {
return text.matches("1|true");
}
}
});
simpleModule.addDeserializer(Boolean.TYPE, new JsonDeserializer<Boolean>() {
@Override
public Boolean deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
String text = jsonParser.getText();
if (text == null || "".equals(text)) {
return false;
} else {
return text.matches("1|true");
}
}
});
objectMapper.registerModule(simpleModule);
}
objectMapper.registerModule(simpleModule);
}
}
}
// @Bean
// @Profile("prod")
// public ServletWebServerFactory servletContainer() {
// TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory();
//
// // 基本参数
// String keyStore = "1754557_www.wbsite.xyz.pfx";
// String keyStorePassword = "s98n7CLd";
// String keyStoreType = "PKCS12";
// int httpsPort = 443;
//
// File keystore = null;
// // 正常开发可以通过getFile()获取打包jar后无法直接获取File对象需将文件考出
// try {
// keystore = new ClassPathResource(keyStore).getFile();
// } catch (IOException ex) {
// try {
// ApplicationHome home = new ApplicationHome(getClass());
// // 当前运行jar文件
// File jarFile = home.getSource();
// //jar同目录
// keystore = new File(jarFile.getParent(), keyStore);
//
// InputStream inputStream = new ClassPathResource(keyStore).getInputStream();
// byte[] bytes = new byte[inputStream.available()];
//
// inputStream.read(bytes);
//
// inputStream.close();
//
// FileOutputStream fileOutputStream = new FileOutputStream(keystore);
// fileOutputStream.write(bytes);
// fileOutputStream.close();
// } catch (IOException e) {
// e.printStackTrace();
// }
// }
//
// // 创建Connector
// Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
// Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler();
// connector.setScheme("https");
// connector.setSecure(true);
// connector.setPort(httpsPort);
// protocol.setSSLEnabled(true);
// protocol.setKeystoreFile(keystore.getAbsolutePath());
// protocol.setKeystorePass(keyStorePassword);
// protocol.setKeystoreType(keyStoreType);
//
// // 添加
// tomcat.addAdditionalTomcatConnectors(connector);
// return tomcat;
// }
/**
*
*
* @return
*/
@Bean
@ConditionalOnMissingBean
public UserProvider userProviderImpl() {
return new SimpleUserProvider();
}
/**
*
*
* @return
*/
@Bean
@ConditionalOnMissingBean
public TokenProvider tokenProviderImpl() {
return new SimpleTokenProvider();
}
}

@ -1,6 +1,8 @@
package xyz.wbsite.frame.base;
import com.alibaba.excel.annotation.ExcelIgnore;
import com.fasterxml.jackson.annotation.JsonIgnore;
import java.io.Serializable;
import java.util.Date;
@ -16,40 +18,47 @@ public class BaseEntity implements Serializable {
/**
*
*/
@ExcelIgnore
private long id;
/**
*
*/
@ExcelIgnore
private long rowVersion;
/**
*
*/
@JsonIgnore
@ExcelIgnore
private long createBy;
/**
*
*/
@ExcelIgnore
private Date createTime;
/**
*
*/
@JsonIgnore
@ExcelIgnore
private long lastUpdateBy;
/**
*
*/
@JsonIgnore
@ExcelIgnore
private Date lastUpdateTime;
/**
*
*/
@JsonIgnore
@ExcelIgnore
private boolean isDeleted;
public long getRowVersion() {

@ -0,0 +1,17 @@
package xyz.wbsite.frame.base;
import javax.validation.constraints.NotEmpty;
public class DictLoadRequest extends BaseRequest{
@NotEmpty(message = "字典名称不能为空")
private String dictName;
public String getDictName() {
return dictName;
}
public void setDictName(String dictName) {
this.dictName = dictName;
}
}

@ -0,0 +1,14 @@
package xyz.wbsite.frame.base;
import xyz.wbsite.frame.base.BaseRequest;
/**
* LogoutRequest -
*
* @author wangbing
* @version 0.0.1
* @since 2017-01-01
*/
public class LogoutRequest extends BaseRequest {
}

@ -0,0 +1,55 @@
package xyz.wbsite.frame.base;
import java.util.HashSet;
import java.util.Set;
public class UserEntity extends BaseEntity {
private String userName;
private String userAlias;
private String password;
private Set<String> resSet = new HashSet<>();
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserAlias() {
return userAlias;
}
public void setUserAlias(String userAlias) {
this.userAlias = userAlias;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Set<String> getResSet() {
return resSet;
}
public void setResSet(Set<String> resSet) {
this.resSet = resSet;
}
public void putRes(String resource) {
resSet.add(resource);
}
public void putRes(Set<String> resourceSet) {
this.resSet.addAll(resourceSet);
}
}

@ -0,0 +1,39 @@
package xyz.wbsite.frame.base;
import xyz.wbsite.frame.base.BaseResponse;
/**
* VerifyCodeResponse -
*
* @author wangbing
* @version 0.0.1
* @since 2020-12-24
*/
public class VerifyCodeResponse extends BaseResponse {
/**
* ID
*/
private Long verifyCodeId;
/**
* base64
*/
private String verifyCodeBase64;
public Long getVerifyCodeId() {
return verifyCodeId;
}
public void setVerifyCodeId(Long verifyCodeId) {
this.verifyCodeId = verifyCodeId;
}
public String getVerifyCodeBase64() {
return verifyCodeBase64;
}
public void setVerifyCodeBase64(String verifyCodeBase64) {
this.verifyCodeBase64 = verifyCodeBase64;
}
}

@ -0,0 +1,76 @@
package xyz.wbsite.frame.base;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
public class VisitorEntity implements Serializable {
/**
* APP_NAME -
*/
private String appName;
/**
* APP_NOTE -
*/
private String appNote;
/**
* APP_KEY -
*/
private String appKey;
/**
* APP_SECRET -
*/
private String appSecret;
public String getAppName() {
return appName;
}
public void setAppName(String appName) {
this.appName = appName;
}
public String getAppNote() {
return appNote;
}
public void setAppNote(String appNote) {
this.appNote = appNote;
}
public String getAppKey() {
return appKey;
}
public void setAppKey(String appKey) {
this.appKey = appKey;
}
public String getAppSecret() {
return appSecret;
}
public void setAppSecret(String appSecret) {
this.appSecret = appSecret;
}
private Set<String> resSet = new HashSet<>();
public Set<String> getResSet() {
return resSet;
}
public void setResSet(Set<String> resSet) {
this.resSet = resSet;
}
public void putRes(String resource) {
resSet.add(resource);
}
public void putRes(Set<String> resourceSet) {
this.resSet.addAll(resourceSet);
}
}

@ -0,0 +1,151 @@
package xyz.wbsite.frame.excel;
import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.format.DateTimeFormat;
import com.alibaba.excel.annotation.format.NumberFormat;
import xyz.wbsite.frame.base.BaseEntity;
import xyz.wbsite.frame.excel.annotation.ExcelNote;
import xyz.wbsite.frame.excel.annotation.ExcelSelect;
import xyz.wbsite.frame.excel.annotation.ExcelSheet;
import java.util.Date;
@ExcelSheet("应用接入")
public class DemoData extends BaseEntity {
@ExcelProperty({"字符列", "普通字符列"})
@ExcelNote("字符列描述")
private String str1;
@ExcelProperty({"字符列", "可选字符列"})
@ExcelSelect({"选项一", "选项二"})
@ExcelNote("可选字符列(选项一,选项二)")
private String str2;
@ExcelNote("无ExcelProperty默认为字段名称")
private String str3;//无ExcelProperty默认为字段名称
@ExcelIgnore
private String str4;//忽略的字段
@ExcelProperty("短整数列")
@ExcelNote("短整数列")
private short sint;
@ExcelProperty("整数列")
@ExcelNote("整数列")
private int mint;
@ExcelProperty("长整数列")
@ExcelNote("长整数列")
private long lint;
@ExcelProperty("双精度列")
@NumberFormat("#.##")
@ExcelNote("双精度列,格式化#.##")
private double dbn;
@ExcelProperty("单精度列")
@NumberFormat("#.##")
@ExcelNote("单精度列,格式化#.##")
private float fln;
@ExcelProperty("时间列")
@DateTimeFormat("yyyy年MM月dd日 HH时mm分ss秒")
@ExcelNote("时间列格式化yyyy年MM月dd日 HH时mm分ss秒")
private Date date;
@ExcelProperty("是否有效")
@ExcelSelect({"是", "否"})
@ExcelNote("布尔值(是, 否)")
private boolean valid;
public String getStr1() {
return str1;
}
public void setStr1(String str1) {
this.str1 = str1;
}
public String getStr2() {
return str2;
}
public void setStr2(String str2) {
this.str2 = str2;
}
public String getStr3() {
return str3;
}
public void setStr3(String str3) {
this.str3 = str3;
}
public String getStr4() {
return str4;
}
public void setStr4(String str4) {
this.str4 = str4;
}
public short getSint() {
return sint;
}
public void setSint(short sint) {
this.sint = sint;
}
public int getMint() {
return mint;
}
public void setMint(int mint) {
this.mint = mint;
}
public long getLint() {
return lint;
}
public void setLint(long lint) {
this.lint = lint;
}
public double getDbn() {
return dbn;
}
public void setDbn(double dbn) {
this.dbn = dbn;
}
public float getFln() {
return fln;
}
public void setFln(float fln) {
this.fln = fln;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public boolean isValid() {
return valid;
}
public void setValid(boolean valid) {
this.valid = valid;
}
}

@ -1,681 +1,360 @@
package xyz.wbsite.frame.excel;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.exception.ExcelDataConvertException;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.DataValidation;
import org.apache.poi.ss.usermodel.DataValidationConstraint;
import org.apache.poi.ss.usermodel.DataValidationHelper;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
import org.apache.poi.xssf.usermodel.XSSFComment;
import org.apache.poi.xssf.usermodel.XSSFDataValidation;
import org.apache.poi.xssf.usermodel.XSSFDrawing;
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.ss.util.CellRangeAddressList;
import org.apache.poi.ss.util.NumberToTextConverter;
import xyz.wbsite.frame.excel.annotation.ColumnDescription;
import xyz.wbsite.frame.excel.annotation.ColumnList;
import xyz.wbsite.frame.excel.annotation.ColumnName;
import xyz.wbsite.frame.excel.annotation.Convert;
import xyz.wbsite.frame.excel.annotation.Ignore;
import xyz.wbsite.frame.excel.annotation.ParentFirst;
import xyz.wbsite.frame.excel.annotation.SheetName;
import xyz.wbsite.frame.excel.annotation.ExcelNote;
import xyz.wbsite.frame.excel.annotation.ExcelSelect;
import xyz.wbsite.frame.excel.annotation.ExcelSheet;
import xyz.wbsite.frame.excel.converter.BooleanConverter;
import xyz.wbsite.frame.excel.converter.ByteConverter;
import xyz.wbsite.frame.excel.converter.CharacterConverter;
import xyz.wbsite.frame.excel.converter.Converter;
import xyz.wbsite.frame.excel.converter.DateConverter;
import xyz.wbsite.frame.excel.converter.DoubleConverter;
import xyz.wbsite.frame.excel.converter.FloatConverter;
import xyz.wbsite.frame.excel.converter.IntegerConverter;
import xyz.wbsite.frame.excel.converter.LongConverter;
import xyz.wbsite.frame.excel.converter.ShortConverter;
import xyz.wbsite.frame.excel.converter.StringConverter;
import xyz.wbsite.frame.excel.exception.ReadErrorException;
import xyz.wbsite.frame.excel.exception.TemplateNotMatchException;
import xyz.wbsite.frame.excel.exception.ValueConverterException;
import xyz.wbsite.frame.excel.style.DataCellStyle;
import xyz.wbsite.frame.excel.style.ErrorCellStyle;
import xyz.wbsite.frame.excel.style.HeadCellStyle;
import xyz.wbsite.frame.excel.style.RedFont;
import xyz.wbsite.frame.excel.style.SuccessCellStyle;
import xyz.wbsite.frame.excel.handler.HeadWriteHandler;
import xyz.wbsite.frame.excel.handler.WCellWriteHandler;
import xyz.wbsite.frame.excel.handler.WRowWriteHandler;
import xyz.wbsite.frame.excel.handler.WSheetWriteHandler;
import xyz.wbsite.frame.excel.listener.WReadListener;
import xyz.wbsite.frame.utils.ClassUtil;
import xyz.wbsite.frame.utils.FileUtil;
import xyz.wbsite.frame.utils.LogUtil;
import xyz.wbsite.frame.utils.ValidationUtil;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
* WExcel - Excel
*
*
* new WExcel<Dept>(Dept.class).loadData(depts).toFile(file);<br>
*
*
* byte[] bytes = FileUtil.readFileToByteArray(new File("E:\\E.xlsx"));<br>
* WExcel check = new WExcel<Dept>(Dept.class).loadData(bytes);
*
* @author wangbing
* @version 0.0.1
* @since 2017-01-01
*/
public class WExcel<T> implements Serializable, Cloneable {
public class WExcel<T> {
/**
*
* 簿,{@link ExcelSelect}.
*/
private String name;
/**
*
*
*/
private boolean freezeFirst;
private Class<T> clazz;
/**
*
* {@link com.alibaba.excel.annotation.ExcelProperty}.
*/
private Class<T> templateClass;
private List<WHead> wHeads;
/**
*
*
*/
private List<WColumn> columnList = new ArrayList<>();
private List<T> data;
/**
*
* Map key:,String:
*/
private List<WRow> rowList = new ArrayList<>();
private Map<Integer, List<String>> errMap;
/**
*
* ,{@link WSheetWriteHandler#beforeSheetCreate}.
* <p>
* :styles[0]styles[1]
*/
public WExcel(Class<T> tClass) {
this.templateClass = tClass;
initColumns(tClass);
}
private CellStyle[] styles = new CellStyle[2];
/**
* DataTable
*
* @return WColumn
*
*/
private List<WColumn> initColumns(Class<?> clazz) {
public WExcel(Class<T> clazz) {
this.clazz = clazz;
this.wHeads = new ArrayList<>();
this.data = new ArrayList<>();
this.errMap = new LinkedHashMap<>();
//获取工作簿名称,没有则以类名为默认工作簿名称
if (clazz.isAnnotationPresent(SheetName.class)) {
SheetName sheetName = clazz.getAnnotation(SheetName.class);
this.setName(sheetName.value());
this.setFreezeFirst(sheetName.freezeFirst());
if (clazz.isAnnotationPresent(ExcelSheet.class)) {
ExcelSheet ExcelSheet = clazz.getAnnotation(ExcelSheet.class);
this.name = ExcelSheet.value();
} else {
this.setName(clazz.getSimpleName());
this.name = clazz.getSimpleName();
}
//是否关注父类属性
boolean parentFirst = clazz.isAnnotationPresent(ParentFirst.class) && clazz.getAnnotation(ParentFirst.class).value();
Field[] fields = ClassUtil.getFields(clazz, parentFirst);
// 获取实体所有字段
Field[] fields = ClassUtil.getFields(clazz, true);
Map<String, Field> fieldMap = new HashMap<>();
for (Field field : fields) {
if (field.isAnnotationPresent(Ignore.class) && field.getAnnotation(Ignore.class).value()) {
continue;
fieldMap.put(field.getName(), field);
}
WColumn WColumn = new WColumn();
WColumn.setField(field);
Method set = ClassUtil.setMethod(field.getName(), clazz, field.getType());
WColumn.setSetMethod(set);
Method get = ClassUtil.getMethod(field.getName(), clazz);
WColumn.setGetMethod(get);
//获取列名称
if (!field.isAnnotationPresent(ColumnName.class)) {
WColumn.setName(field.getName());
} else {
ColumnName columnColumnName = field.getAnnotation(ColumnName.class);
WColumn.setName(columnColumnName.value());
WColumn.setCellWidth(columnColumnName.width());
WColumn.setRequired(columnColumnName.required());
}
//获取列填写说明或描述
if (field.isAnnotationPresent(ColumnDescription.class)) {
WColumn.setDescription(field.getAnnotation(ColumnDescription.class).value());
Map<String, WHead> wHeadMap = new LinkedHashMap<>();
// 获取导出Head
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
EasyExcel.write(outputStream)
.head(this.clazz)
.useDefaultStyle(false)
.registerConverter(new BooleanConverter())
.registerWriteHandler(new HeadWriteHandler() {
@Override
protected void handlerHead(Head head) {
WHead wHead = new WHead(head);
Field field = fieldMap.get(wHead.getHead().getFieldName());
// 获取HeadName
wHead.setName(head.getHeadNameList().get(head.getHeadNameList().size() - 1));
// 获取注释
if (field.isAnnotationPresent(ExcelNote.class)) {
wHead.setNote(field.getAnnotation(ExcelNote.class).value());
}
// 获取下拉列表
if (field.isAnnotationPresent(ColumnList.class)) {
WColumn.setCellList(field.getAnnotation(ColumnList.class).value());
}
//获取列类型
if (field.isAnnotationPresent(Convert.class)) {
Convert converter = field.getAnnotation(Convert.class);
Class target = converter.target();
try {
WColumn.setConverter((Converter) target.newInstance());
} catch (InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
} else {
if (field.getType() == boolean.class || field.getType() == Boolean.class) {
WColumn.setConverter(new BooleanConverter());
WColumn.setCellType(Cell.CELL_TYPE_BOOLEAN);
} else if (field.getType() == byte.class || field.getType() == Byte.class) {
WColumn.setConverter(new ByteConverter());
WColumn.setCellType(Cell.CELL_TYPE_NUMERIC);
} else if (field.getType() == char.class || field.getType() == Character.class) {
WColumn.setConverter(new CharacterConverter());
WColumn.setCellType(Cell.CELL_TYPE_STRING);
} else if (field.getType() == short.class || field.getType() == Short.class) {
WColumn.setConverter(new ShortConverter());
WColumn.setCellType(Cell.CELL_TYPE_NUMERIC);
} else if (field.getType() == int.class || field.getType() == Integer.class) {
WColumn.setConverter(new IntegerConverter());
WColumn.setCellType(Cell.CELL_TYPE_NUMERIC);
} else if (field.getType() == long.class || field.getType() == Long.class) {
WColumn.setConverter(new LongConverter());
WColumn.setCellType(Cell.CELL_TYPE_NUMERIC);
} else if (field.getType() == float.class || field.getType() == Float.class) {
WColumn.setConverter(new FloatConverter());
WColumn.setCellType(Cell.CELL_TYPE_NUMERIC);
} else if (field.getType() == double.class || field.getType() == Double.class) {
WColumn.setConverter(new DoubleConverter());
WColumn.setCellType(Cell.CELL_TYPE_NUMERIC);
} else if (field.getType() == Date.class) {
WColumn.setConverter(new DateConverter());
WColumn.setCellType(Cell.CELL_TYPE_NUMERIC);
} else if (field.getType() == String.class) {
WColumn.setConverter(new StringConverter());
WColumn.setCellType(Cell.CELL_TYPE_STRING);
} else {
throw new RuntimeException("Can not find Converter");
}
if (field.isAnnotationPresent(ExcelSelect.class)) {
wHead.setSelectList(field.getAnnotation(ExcelSelect.class).value());
}
columnList.add(WColumn);
wHeadMap.put(head.getFieldName(), wHead);
}
return columnList;
})
.sheet(this.name).doWrite(Collections.EMPTY_LIST);
wHeads.addAll(wHeadMap.values());
}
public WExcel loadData(List<T> list) {
return loadData(list, null);
/**
*
*
* @param os
* @return WExcel
*/
public WExcel addDatas(List<T> os) {
return addDatas(os, null);
}
/**
* <br/>
*
*
*
* @param list
* @param os
* @param processor
* @return WExcel
*/
public WExcel loadData(List<T> list, Processor<T> processor) {
if (list.size() > 0) {
for (T t : list) {
WRow row = new WRow();
for (WColumn column : columnList) {
if (column == null) {
continue;
}
Method method = column.getGetMethod();
try {
Object value = method.invoke(t);
if (null == value) {
row.put(column.getName(), new WCell());
} else {
String string = column.getConverter().string(value);
row.put(column.getName(), new WCell(string));
}
} catch (IllegalAccessException e) {
LogUtil.w("can not invoke get method!");
} catch (InvocationTargetException e) {
LogUtil.w(method.getName() + " unexpected exception!");
}
// <2层检查>检查模板注解验证是否通过
row.addErrors(ValidationUtil.validate(t));
// <3层检查>如果没有错误,则可以执行处理器进行业务处理
if (!row.hasError() && processor != null) {
List<String> exec = processor.exec(t);
row.addErrors(exec != null ? exec : Collections.EMPTY_LIST);
}
}
this.rowList.add(row);
}
public WExcel addDatas(List<T> os, Processor<T> processor) {
for (T o : os) {
addData(o, processor);
}
return this;
}
public WExcel loadData(File file) throws TemplateNotMatchException, ReadErrorException, IOException {
return loadData(FileUtil.readFileToByteArray(file), null);
}
public WExcel loadData(File file, Processor<T> processor) throws TemplateNotMatchException, ReadErrorException, IOException {
return loadData(FileUtil.readFileToByteArray(file), processor);
}
public WExcel loadData(byte[] bytes) throws TemplateNotMatchException, ReadErrorException {
return loadData(bytes, null);
}
/**
* Excel<br/>
* <br/>
*
*
* @param o
* @return WExcel
*/
public WExcel loadData(byte[] bytes, Processor<T> processor) throws TemplateNotMatchException, ReadErrorException {
Workbook workbook = null;
InputStream is = null;
boolean flag;
try {
flag = true;
is = new ByteArrayInputStream(bytes); //读取文件流
workbook = new HSSFWorkbook(is);
} catch (Exception e) {
flag = false;
}
if (!flag) {
try {
flag = true;
is = new ByteArrayInputStream(bytes); //读取文件流
workbook = new XSSFWorkbook(is);
} catch (Exception e) {
flag = false;
}
}
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (!flag) {
throw new ReadErrorException("读取Excel文件错误");
}
//第一张Sheet表
Sheet sheet = workbook.getSheetAt(0);
//获取Sheet名称
if (templateClass.isAnnotationPresent(SheetName.class)) {//如果模板存在注解则使用注解名称
SheetName sheetName = templateClass.getAnnotation(SheetName.class);
this.setName(sheetName.value());
} else {//将类名设为表名如果类名不存在将Excel表名设为表名
this.setName(sheet.getSheetName());
}
//读取表头
Row headRow = sheet.getRow(0);
//获取Excel列的总数
int columnSum = headRow.getPhysicalNumberOfCells();
//检查列数量
if (columnList.size() != columnSum) {
throw new TemplateNotMatchException("与模板列数量不同。");
} else {
for (int i = 0; i < columnList.size(); i++) {
WColumn wColumn = columnList.get(i);
Cell cell = headRow.getCell(i);
String headValue = getValue(cell);
headValue = headValue.replace("*", "");
headValue = headValue.replace(" ", "");
if (!wColumn.getName().equals(headValue)) {
throw new TemplateNotMatchException("第" + (i + 1) + "项,不匹配的列名," + wColumn.getName() + "和" + headValue);
}
}
}
//Excel文件的总行数
int maxRowNumber = sheet.getLastRowNum();
// 逐行读取导入文件的数据
for (int i = 0; i < maxRowNumber; i++) {
//Excel中的一行数据第0行为表头所以要加1
Row inputRow = sheet.getRow(i + 1);
WRow row = new WRow();
rowList.add(row);
if (null != inputRow) {
for (int j = 0; j < columnList.size(); j++) {
WColumn wcolumn = columnList.get(j);
/* 取得当前格子的值 */
Cell excelCell = inputRow.getCell(j);
WCell WCell = new WCell();
row.put(wcolumn.getName(), WCell);
String value = "";
if (null != excelCell) {
value = getValue(excelCell);
public WExcel addData(T o) {
return addData(o, null);
}
value = value.trim();
WCell.setValue(value);
}
}
try {
T t = templateClass.newInstance();
// <1层检查>检查数据格式是否正确
row.addErrors(transferMap(row, t));
// <2层检查>检查模板注解验证是否通过
row.addErrors(ValidationUtil.validate(t));
// <3层检查>如果没有错误,则可以执行处理器进行业务处理
if (!row.hasError() && processor != null) {
List<String> exec = processor.exec(t);
row.addErrors(exec != null ? exec : Collections.EMPTY_LIST);
}
} catch (InstantiationException | IllegalAccessException e) {
row.addError("模板对象默认构造函数错误");
}
}
/**
*
*
* @param o
* @param processor
* @return WExcel
*/
public WExcel addData(T o, Processor<T> processor) {
// 注解检查验证
List<String> validate = ValidationUtil.validate(o);
// 处理器执行
if ((validate == null || validate.isEmpty()) && processor != null) {
List<String> exec = processor.exec(o, this.data.size());
if (exec != null && exec.size() > 0) {
errMap.computeIfAbsent(data.size(), k -> new ArrayList<>());
List<String> errs = errMap.get(data.size());
errs.addAll(exec);
}
}
this.data.add(o);
return this;
}
/**
*
*
* @param row
* @param target
* @return
* @return
*/
public List<String> transferMap(WRow row, T target) {
List<String> err = new ArrayList<>();
for (String key : row.keySet()) {
for (WColumn column : columnList) {
String name = column.getName();
Method setMethod = column.getSetMethod();
if (key.equals(name)) {
WCell WCell = row.get(column.getName());
if (null != WCell) {
String value = WCell.getValue();
//获取转换器
Converter converter = column.getConverter();
try {
setMethod.invoke(target, converter.convert(value));
} catch (ValueConverterException e) {
e.printStackTrace();
err.add(e.getMessage());
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
err.add("[" + setMethod.getName() + "]执行错误");
}
}
break;
}
}
}
return err;
public List<T> getDatas() {
return this.data;
}
/**
*
*
* @return
* @return Excel
*/
public String getName() {
return name;
public byte[] getBytes() {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
EasyExcel.write(outputStream)
.head(this.clazz)
.useDefaultStyle(false)
.registerConverter(new BooleanConverter())
.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
.registerWriteHandler(new WSheetWriteHandler(wHeads, styles))
.registerWriteHandler(new WRowWriteHandler(wHeads, errMap))
.registerWriteHandler(new WCellWriteHandler(wHeads, styles, errMap))
.sheet(this.name).doWrite(data);
return outputStream.toByteArray();
}
/**
*
* Excel
*
* @param name
* @param file
*/
public void setName(String name) {
this.name = name;
public void toFile(File file) {
byte[] aByte = getBytes();
FileUtil.writeBytesToFile(aByte, file);
}
public boolean getFreezeFirst() {
return freezeFirst;
/**
* @param file
* @param processor
* @return WExcel
* @throws TemplateNotMatchException
* @throws IOException
*/
public WExcel<T> read(File file, Processor<T> processor) throws TemplateNotMatchException, IOException {
ExcelTypeEnum et;
if (file.getName().endsWith(".xls")) {
et = ExcelTypeEnum.XLS;
} else if (file.getName().endsWith(".xlsx")) {
et = ExcelTypeEnum.XLSX;
} else {
throw new RuntimeException("The file is not an excel file!");
}
public void setFreezeFirst(boolean freezeFirst) {
this.freezeFirst = freezeFirst;
byte[] bytes = FileUtil.readFileToByteArray(file);
return read(bytes, et, processor);
}
public final String toCSV() {
StringBuilder sb = new StringBuilder();
for (WColumn WColumn : this.columnList) {
if (WColumn != null) {
sb.append(WColumn.getName()).append(",");
}
/**
* @param bytes
* @return WExcel
* @throws TemplateNotMatchException
* @throws IOException
*/
public WExcel<T> read(byte[] bytes) throws TemplateNotMatchException, IOException {
return read(bytes, ExcelTypeEnum.XLSX, null);
}
sb.append("\n");
for (int i = 0; i < this.rowList.size(); i++) {
for (int j = 0; j < this.columnList.size(); j++) {
WColumn wColumn = this.columnList.get(j);
WCell wCell = this.rowList.get(i).get(wColumn.getName());
sb.append(wCell.getValue()).append(",");
}
sb.append("\n");
/**
* @param bytes
* @param processor
* @return WExcel
* @throws TemplateNotMatchException
* @throws IOException
*/
public WExcel<T> read(byte[] bytes, Processor<T> processor) throws TemplateNotMatchException, IOException {
return read(bytes, ExcelTypeEnum.XLSX, processor);
}
return sb.toString();
/**
* @param bytes
* @param et Excel
* @param processor
* @return WExcel
* @throws TemplateNotMatchException
* @throws IOException
*/
public WExcel<T> read(byte[] bytes, ExcelTypeEnum et, Processor<T> processor) throws TemplateNotMatchException, IOException {
ByteArrayInputStream stream = new ByteArrayInputStream(bytes);
return read(stream, et, processor);
}
/**
* DataTable
*
* @return .
* @param in
* @return WExcel
* @throws TemplateNotMatchException
* @throws IOException
*/
public final boolean hasError() {
for (WRow wRow : rowList) {
if (wRow.hasError()) {
return true;
}
}
return false;
public WExcel<T> read(InputStream in) throws TemplateNotMatchException {
return read(in, ExcelTypeEnum.XLSX, null);
}
public byte[] getBytes() {
XSSFWorkbook workbook = getExcel();
if (workbook != null) {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
try {
workbook.write(outputStream);
} catch (IOException e) {
return null;
}
return outputStream.toByteArray();
}
return null;
}
public XSSFWorkbook getExcel() {
XSSFWorkbook workbook = new XSSFWorkbook();
//创建一个Sheet表
XSSFSheet sheet = workbook.createSheet(name);
sheet.setDefaultRowHeightInPoints(18);
Row firstRow = sheet.createRow(0); // 下标为0的行开始
XSSFDrawing drawing = sheet.createDrawingPatriarch();
int offset = 0;
// 添加结果和错误说明列
if (hasError()) {
offset++;
{// 第一栏结果栏
Cell firstCell = firstRow.createCell(0);
firstCell.setCellStyle(new HeadCellStyle(workbook).getStyle());
firstCell.setCellValue(new XSSFRichTextString("执行结果"));
XSSFClientAnchor anchor = new XSSFClientAnchor(0, 0, 0, 0, (short) 3, 3, (short) 5, 6);
XSSFComment comment = drawing.createCellComment(anchor);
comment.setString("此列为检查结果,导入时请处理完错误,并删除该列!");
firstCell.setCellComment(comment);
}
offset++;
{// 第二栏错误信息栏
Cell secondCell = firstRow.createCell(1);
secondCell.setCellStyle(new HeadCellStyle(workbook).getStyle());
secondCell.setCellValue(new XSSFRichTextString("结果说明"));
sheet.setColumnWidth(1, 18 * 256);
XSSFClientAnchor anchor = new XSSFClientAnchor(0, 0, 0, 0, (short) 3, 3, (short) 5, 6);
XSSFComment comment = drawing.createCellComment(anchor);
comment.setString("此列为检查结果信息列,导入时请处理完错误,并删除该列!");
secondCell.setCellComment(comment);
}
}
for (int j = 0; j < this.columnList.size(); j++) {
WColumn column = this.columnList.get(j);
Cell firstCell = firstRow.createCell(j + offset);
String columnName = column.getName();
XSSFRichTextString textString;
if (column.isRequired()) {
textString = new XSSFRichTextString("*" + columnName);
textString.applyFont(0, 1, new RedFont(workbook).getFont());
textString.applyFont(1, textString.length(), workbook.createFont());
} else {
textString = new XSSFRichTextString(columnName);
textString.applyFont(workbook.createFont());
}
StringBuilder sb = new StringBuilder();
sb.append(column.getDescription()).append("\n");
// 如果填写了注释信息
if (sb.length() > 1) {
XSSFClientAnchor anchor = new XSSFClientAnchor(0, 0, 0, 0, (short) 3, 3, (short) 5, 6);
XSSFComment comment = drawing.createCellComment(anchor);
comment.setString(sb.toString());
firstCell.setCellComment(comment);
}
firstCell.setCellValue(textString);
firstCell.setCellStyle(new HeadCellStyle(workbook).getStyle());
sheet.setColumnWidth(j + offset, (4 + column.getCellWidth()) * 256);
if (column.getCellList() != null){
CellRangeAddressList cellRangeAddressList = new CellRangeAddressList(1, 65535, j+offset, j+offset);
DataValidationHelper helper = sheet.getDataValidationHelper();
DataValidationConstraint constraint = helper.createExplicitListConstraint(column.getCellList());
DataValidation dataValidation = helper.createValidation(constraint, cellRangeAddressList);
//处理Excel兼容性问题
if (dataValidation instanceof XSSFDataValidation) {
dataValidation.setSuppressDropDownArrow(true);
dataValidation.setShowErrorBox(true);
} else {
dataValidation.setSuppressDropDownArrow(false);
/**
* @param in
* @param processor
* @return WExcel
* @throws TemplateNotMatchException
* @throws IOException
*/
public WExcel<T> read(InputStream in, Processor<T> processor) throws TemplateNotMatchException {
return read(in, ExcelTypeEnum.XLSX, processor);
}
dataValidation.setEmptyCellAllowed(true);
dataValidation.setShowPromptBox(true);
dataValidation.createPromptBox("规则", "请选择下拉框里面的数据");
sheet.addValidationData(dataValidation);
/**
* @param in
* @param processor
* @param et Excel
* @return WExcel
* @throws TemplateNotMatchException
* @throws IOException
*/
public WExcel<T> read(InputStream in, ExcelTypeEnum et, Processor<T> processor) throws TemplateNotMatchException {
final TemplateNotMatchException[] e = new TemplateNotMatchException[1];
// 读取Head 验证模板是否符合情况
EasyExcel.read(in)
.excelType(et)
.head(this.clazz)
.registerConverter(new BooleanConverter())
.registerReadListener(new WReadListener<T>(wHeads, e) {
@Override
public void onException(Exception exception, AnalysisContext context) throws Exception {
if (exception instanceof ExcelDataConvertException) {
ExcelDataConvertException convertException = (ExcelDataConvertException) exception;
errMap.computeIfAbsent(data.size(), k -> new ArrayList<>());
List<String> errs = errMap.get(data.size());
errs.add(convertException.getCause().getMessage());
}else {
super.onException(exception, context);
}
}
// 冻结第一行
if (freezeFirst) {
sheet.createFreezePane(255, 1);
@Override
public void invoke(T o) {
if (processor != null) {
List<String> exec = processor.exec(o, data.size());
if (exec != null && exec.size() > 0) {
errMap.computeIfAbsent(data.size(), k -> new ArrayList<>());
List<String> errs = errMap.get(data.size());
errs.addAll(exec);
}
// 填充数据
for (int i = 0; i < this.rowList.size(); i++) {
WRow wRow = this.rowList.get(i);
Row row = sheet.createRow(i + 1);
if (offset > 0) {
if (this.rowList.get(i).hasError()) {
// 添加结果
List<String> errorList = wRow.getErrorList();
Cell resultCell = row.createCell(0);
resultCell.setCellStyle(new ErrorCellStyle(workbook).getStyle());
resultCell.setCellValue("错误");
// 添加错误信息详细说明
Cell errsCell = row.createCell(1);
errsCell.setCellStyle(new ErrorCellStyle(workbook).getStyle());
String join = String.join(";\n", errorList);
errsCell.setCellValue(new XSSFRichTextString(join));
} else {
// 添加结果
Cell resultCell = row.createCell(0);
resultCell.setCellStyle(new SuccessCellStyle(workbook).getStyle());
resultCell.setCellValue("成功");
// 添加错误信息详细说明
Cell errsCell = row.createCell(1);
errsCell.setCellStyle(new SuccessCellStyle(workbook).getStyle());
errsCell.setCellValue("");
}
data.add(o);
}
for (int j = 0; j < this.columnList.size(); j++) {
WColumn column = this.columnList.get(j);
Cell xssfCell = row.createCell(j + offset);
WCell WCell = this.rowList.get(i).get(column.getName());
if (null == WCell) {
continue;
})
.sheet().doRead();
if (e[0] != null) {
throw e[0];
}
String value = WCell.getValue();
xssfCell.setCellType(column.getCellType());
if (column.getCellType() == Cell.CELL_TYPE_NUMERIC || column.getCellType() == Cell.CELL_TYPE_BOOLEAN) {
xssfCell.setCellStyle(new DataCellStyle(workbook, CellStyle.ALIGN_RIGHT, wRow.hasError()).getStyle());
} else {
xssfCell.setCellStyle(new DataCellStyle(workbook, CellStyle.ALIGN_LEFT, wRow.hasError()).getStyle());
return this;
}
xssfCell.setCellValue(value);
}
}
return workbook;
public interface Processor<T> {
List<String> exec(T t, int index);
}
/**
*
*
* @param cell
* @return
* @return
*/
public static String getValue(Cell cell) {
if (cell == null) {
return "";
}
switch (cell.getCellType()) {
case Cell.CELL_TYPE_STRING:
return cell.getStringCellValue();
case Cell.CELL_TYPE_BOOLEAN:
return String.valueOf(cell.getBooleanCellValue());
case Cell.CELL_TYPE_NUMERIC:
if (HSSFDateUtil.isCellDateFormatted(cell)) {
Date value = cell.getDateCellValue();
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(value);
} else {
return NumberToTextConverter.toText(cell.getNumericCellValue());
}
default:
return cell.getStringCellValue();
}
}
public interface Processor<T> {
List<String> exec(T t);
public boolean hasError() {
return !errMap.isEmpty();
}
public void toFile(File file) throws IOException {
File parentFile = file.getParentFile();
if (!parentFile.exists() && !parentFile.mkdirs()) {
throw new RuntimeException("路径创建失败");
}
if (!file.exists() && !file.createNewFile()) {
throw new RuntimeException("文件创建失败");
}
FileOutputStream fileOutputStream = new FileOutputStream(file);
fileOutputStream.write(getBytes());
fileOutputStream.close();
/**
* @return
*/
public String getName() {
return name;
}
}

@ -0,0 +1,65 @@
package xyz.wbsite.frame.excel;
import com.alibaba.excel.metadata.Head;
/**
* WHead - Excel()
*
* @author wangbing
* @version 0.0.1
* @since 2017-01-01
*/
public class WHead {
public WHead(Head head) {
this.head = head;
}
/**
*
*/
private Head head;
/**
*
*/
private String name = "";
/**
*
*/
private String note = "";
/**
*
*/
private String[] selectList;
public Head getHead() {
return head;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note;
}
public String[] getSelectList() {
return selectList;
}
public void setSelectList(String[] selectList) {
this.selectList = selectList;
}
}

@ -1,21 +0,0 @@
package xyz.wbsite.frame.excel.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Converter - Excel
*
* @author wangbing
* @version 0.0.1
* @since 2017-01-01
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Convert {
Class target();
}

@ -7,7 +7,7 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* ColumnDescription - Excel
* ExcelNote - Excel
*
* @author wangbing
* @version 0.0.1
@ -16,7 +16,7 @@ import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ColumnDescription {
public @interface ExcelNote {
String value() default "";
}

@ -1,21 +0,0 @@
package xyz.wbsite.frame.excel.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* ParentFirst -
*
* @author wangbing
* @version 0.0.1
* @since 2017-01-01
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ParentFirst {
boolean value() default true;
}

@ -1,23 +0,0 @@
package xyz.wbsite.frame.excel.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* SheetName - Excel使Class
*
* @author wangbing
* @version 0.0.1
* @since 2017-01-01
*/
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SheetName {
String value();
boolean freezeFirst() default false;
}

@ -1,28 +0,0 @@
package xyz.wbsite.frame.excel.converter;
/**
* ByteConverter - ByteStringString
*
* @author wangbing
* @version 0.0.1
* @since 2017-01-01
*/
public class ByteConverter implements Converter<Byte> {
@Override
public Byte convert(String var) {
try {
return Byte.parseByte(var);
} catch (Exception e) {
return 0;
}
}
@Override
public String string(Byte var) {
if (var == null) {
return "";
}
return String.valueOf(var);
}
}

@ -1,17 +0,0 @@
package xyz.wbsite.frame.excel.converter;
import xyz.wbsite.frame.excel.exception.ValueConverterException;
/**
* Converter -
*
* @author wangbing
* @version 0.0.1
* @since 2017-01-01
*/
public interface Converter<T> {
T convert(String var) throws ValueConverterException;
String string(T var);
}

@ -1,28 +0,0 @@
package xyz.wbsite.frame.excel.converter;
/**
* IntegerConverter - IntegerStringString
*
* @author wangbing
* @version 0.0.1
* @since 2017-01-01
*/
public class IntegerConverter implements Converter<Integer> {
@Override
public Integer convert(String var) {
try {
return Integer.parseInt(var);
} catch (Exception e) {
return 0;
}
}
@Override
public String string(Integer var) {
if (var == null) {
return "";
}
return String.valueOf(var);
}
}

@ -1,40 +0,0 @@
package xyz.wbsite.frame.excel.converter;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* LongConverter - LongStringString
*
* @author wangbing
* @version 0.0.1
* @since 2017-01-01
*/
public class LongConverter implements Converter<Long> {
@Override
public Long convert(String var) {
try {
//增加对1.0一类的的兼容性
if (var.matches("(\\d+)\\.(\\d*)")) {
Pattern compile = Pattern.compile("(\\d+)\\.(\\d*)");
Matcher matcher = compile.matcher(var);
if (matcher.find()) {
var = matcher.group(1);
}
}
return Long.parseLong(var);
} catch (Exception e) {
return 0L;
}
}
@Override
public String string(Long var) {
if (var == null) {
return "";
}
return String.valueOf(var);
}
}

@ -1,24 +0,0 @@
package xyz.wbsite.frame.excel.converter;
/**
* StringConverter - StringStringString
*
* @author wangbing
* @version 0.0.1
* @since 2017-01-01
*/
public class StringConverter implements Converter<String> {
@Override
public String convert(String var) {
return var != null ? var.trim() : null;
}
@Override
public String string(String var) {
if (var == null) {
return "";
}
return String.valueOf(var);
}
}

@ -0,0 +1,87 @@
package xyz.wbsite.frame.excel.handler;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.write.handler.RowWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Comment;
import org.apache.poi.ss.usermodel.Drawing;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
import xyz.wbsite.frame.excel.WHead;
import xyz.wbsite.frame.utils.StringUtil;
import java.util.List;
import java.util.Map;
public class WRowWriteHandler implements RowWriteHandler {
private List<WHead> wHeads;
private Map<Integer, List<String>> errMap;
public WRowWriteHandler(List<WHead> wHeads, Map<Integer, List<String>> errMap) {
this.wHeads = wHeads;
this.errMap = errMap;
}
@Override
public void beforeRowCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Integer integer, Integer integer1, Boolean isHead) {
}
@Override
public void afterRowCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Integer integer, Boolean isHead) {
}
@Override
public void afterRowDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Integer rowIndex, Boolean isHead) {
if (isHead && getHeadMaxRow() == rowIndex) {
for (int i = 0; i < wHeads.size(); i++) {
WHead wHead = wHeads.get(i);
if (StringUtil.isNotEmpty(wHead.getNote())) {
Drawing<?> drawingPatriarch = writeSheetHolder.getSheet().createDrawingPatriarch();
// 创建一个批注
int headRow = getHeadRow(wHead.getHead());
Comment comment = drawingPatriarch.createCellComment(new XSSFClientAnchor(0, 0, 0, 0, (short) i, headRow, (short) i + 1, headRow + 3));
// 输入批注信息
comment.setString(new XSSFRichTextString(wHead.getNote()));
// 将批注添加到标题对象中
writeSheetHolder.getSheet().getRow(headRow).getCell(i).setCellComment(comment);
}
}
}
if (!isHead && errMap.get(rowIndex) != null) {
Cell cell = row.createCell(wHeads.size());
cell.getCellStyle().setWrapText(true);
List<String> errs = errMap.get(rowIndex);
cell.setCellValue(String.join("\r\n", errs));
}
}
public int getHeadMaxRow() {
int r = 0;
for (WHead wHead : wHeads) {
if (wHead.getHead().getHeadNameList().size() - 1 > r) r = wHead.getHead().getHeadNameList().size() - 1;
}
return r;
}
public int getHeadRow(Head head) {
List<String> nameList = head.getHeadNameList();
if (nameList.size() == 1) {
return 0;
}
int r = nameList.size() - 1;
String last = nameList.get(r);
for (int i = nameList.size() - 2; i >= 0; i--) {
String s = nameList.get(i);
if (s.equals(last)) {
r--;
}
}
return r;
}
}

@ -0,0 +1,68 @@
package xyz.wbsite.frame.excel.handler;
import com.alibaba.excel.write.handler.SheetWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.DataValidation;
import org.apache.poi.ss.usermodel.DataValidationConstraint;
import org.apache.poi.ss.usermodel.DataValidationHelper;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.util.CellRangeAddressList;
import xyz.wbsite.frame.excel.WHead;
import java.util.List;
public class WSheetWriteHandler implements SheetWriteHandler {
private List<WHead> wHeads;
private CellStyle[] styles;
public WSheetWriteHandler(List<WHead> wHeads, CellStyle[] styles) {
this.wHeads = wHeads;
this.styles = styles;
}
@Override
public void beforeSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
{
styles[1] = writeWorkbookHolder.getWorkbook().createCellStyle();
styles[1].setFillForegroundColor(IndexedColors.RED.getIndex());
styles[1].setFillPattern(FillPatternType.SOLID_FOREGROUND);
}
{
styles[0] = writeWorkbookHolder.getWorkbook().createCellStyle();
styles[0].setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
styles[0].setFillPattern(FillPatternType.SOLID_FOREGROUND);
styles[0].setBorderBottom(BorderStyle.THIN);
styles[0].setBorderLeft(BorderStyle.THIN);
styles[0].setBorderRight(BorderStyle.THIN);
styles[0].setBorderTop(BorderStyle.THIN);
styles[0].setAlignment(HorizontalAlignment.CENTER);
Font font = writeWorkbookHolder.getWorkbook().createFont();
font.setColor(IndexedColors.BLACK.getIndex());
font.setFontHeightInPoints((short) 12);
font.setBold(true);
styles[0].setFont(font);
}
}
@Override
public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
for (int i = 0; i < wHeads.size(); i++) {
WHead col = wHeads.get(i);
if (col.getSelectList() != null && col.getSelectList().length > 0) {
CellRangeAddressList cellRangeAddressList = new CellRangeAddressList(0, 500, i, i);
DataValidationHelper helper = writeSheetHolder.getSheet().getDataValidationHelper();
DataValidationConstraint constraint = helper.createExplicitListConstraint(col.getSelectList());
DataValidation dataValidation = helper.createValidation(constraint, cellRangeAddressList);
writeSheetHolder.getSheet().addValidationData(dataValidation);
}
}
}
}

@ -0,0 +1,64 @@
package xyz.wbsite.frame.excel.listener;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import xyz.wbsite.frame.excel.WHead;
import xyz.wbsite.frame.excel.exception.TemplateNotMatchException;
import java.util.List;
import java.util.Map;
public abstract class WReadListener<T> extends AnalysisEventListener<T> {
private List<WHead> wHeads;
private TemplateNotMatchException[] es;
private boolean isHead;
public WReadListener(List<WHead> wHeads, TemplateNotMatchException[] es) {
this.wHeads = wHeads;
this.es = es;
this.isHead = true;
}
@Override
public void invokeHeadMap(Map headMap, AnalysisContext context) {
if (wHeads.size() != headMap.size()) {
es[0] = new TemplateNotMatchException("文件列数量与模板不一致!");
return;
}
es[0] = null;
for (int i = 0; i < wHeads.size(); i++) {
WHead wCol = wHeads.get(i);
String cellValue = headMap.get(i).toString();
if (!wCol.getName().equals(cellValue)) {
es[0] = new TemplateNotMatchException(String.format("第 %d 列应为[ %s ]", i + 1, wCol.getName()));
break;
}
}
}
@Override
public void invoke(T o, AnalysisContext analysisContext) {
isHead = false;
invoke(o);
}
public abstract void invoke(T o);
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
}
@Override
public boolean hasNext(AnalysisContext context) {
// 请求head
if (isHead) {//多级表头,头部未结束
return true;
}
if (!isHead && es[0] == null) {
return true;
}
return false;
}
}

@ -1,29 +0,0 @@
package xyz.wbsite.frame.excel.style;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Workbook;
public class DataCellStyle extends BaseCellStyle {
public DataCellStyle(Workbook workbook, short align, boolean error) {
super(workbook);
style.setAlignment(align);
if (error) {
style.setFillForegroundColor(HSSFColor.RED.index); //背景颜色红色
style.setFillPattern(CellStyle.SOLID_FOREGROUND); //设置单元格填充样式
}
}
public DataCellStyle(Workbook workbook, short align) {
this(workbook, align, false);
}
public DataCellStyle(Workbook workbook, boolean error) {
this(workbook, CellStyle.ALIGN_LEFT, error);
}
public DataCellStyle(Workbook workbook) {
this(workbook, CellStyle.ALIGN_LEFT, false);
}
}

@ -1,22 +0,0 @@
package xyz.wbsite.frame.excel.style;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Workbook;
public class ErrorCellStyle extends BaseCellStyle {
public ErrorCellStyle(Workbook workbook) {
super(workbook);
style.setFillForegroundColor(HSSFColor.RED.index); //背景颜色红色
style.setFillPattern(CellStyle.SOLID_FOREGROUND); //设置单元格填充样式
}
public CellStyle getStyle() {
return style;
}
public void setStyle(CellStyle style) {
this.style = style;
}
}

@ -1,15 +0,0 @@
package xyz.wbsite.frame.excel.style;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Workbook;
public class HeadCellStyle extends BaseCellStyle {
public HeadCellStyle(Workbook workbook) {
super(workbook);
style.setFillForegroundColor(HSSFColor.GREY_25_PERCENT.index); //背景颜色-灰色
style.setFillPattern(CellStyle.SOLID_FOREGROUND); // 设置单元格填充样式
style.setAlignment(CellStyle.ALIGN_CENTER); // 居中
style.setVerticalAlignment(CellStyle.VERTICAL_CENTER);//上下居中
}
}

@ -1,18 +0,0 @@
package xyz.wbsite.frame.excel.style;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.Workbook;
/**
* .
* Created on 2015/1/29.
*
* @author
* @since 2.0.0
*/
public class RedFont extends BaseFont {
public RedFont(Workbook workbook) {
super(workbook);
font.setColor(HSSFColor.RED.index); //字体颜色-黑色
}
}

@ -0,0 +1,9 @@
package xyz.wbsite.frame.listener;
/**
*
*/
public interface IResListener {
void onRes(String res);
}

@ -0,0 +1,9 @@
package xyz.wbsite.frame.listener;
/**
*
*/
public interface ITaskErrorListener {
void error(Throwable error);
}

@ -0,0 +1,40 @@
package xyz.wbsite.frame.provider;
public interface ProfileProvider {
/**
*
*
* @param key
* @param defaultValue
* @return
*/
String getString(String key, String defaultValue);
/**
*
*
* @param key
* @param defaultValue
* @return
*/
int getInt(String key, int defaultValue);
/**
*
*
* @param key
* @param defaultValue
* @return
*/
long getLong(String key, long defaultValue);
/**
*
*
* @param key
* @param defaultValue
* @return
*/
boolean getBoolean(String key, boolean defaultValue);
}

@ -6,9 +6,16 @@ import org.springframework.util.Assert;
import java.util.concurrent.ScheduledFuture;
/**
* Cron
*
* @author wangbing
* @version 0.0.1
* @since 2020-01-01
*/
public abstract class RunCronTask extends RunTask {
abstract String cron();
public abstract String cron();
@Override
public ScheduledFuture<?> schedule(ThreadPoolTaskScheduler poolTaskScheduler) {

@ -0,0 +1,146 @@
package xyz.wbsite.frame.schedule;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.util.ErrorHandler;
import xyz.wbsite.frame.listener.FrameListener;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ScheduledFuture;
/**
*
*
* @author wangbing
* @version 0.0.1
* @since 2020-01-01
*/
public class Scheduler extends ThreadPoolTaskScheduler implements ErrorHandler {
private Map<String, TaskWrapper> taskMap = new HashMap<>();
public Scheduler() {
setErrorHandler(this);
setPoolSize(4);
initialize();
}
public boolean createOrRepeat(RunTask task) {
if (taskMap.containsKey(task.taskId())) {
ScheduledFuture<?> scheduledFuture = taskMap.get(task.taskId()).future;
scheduledFuture.cancel(false);
}
taskMap.put(task.taskId(), new TaskWrapper(task));
return true;
}
public boolean remove(String taskId) {
if (taskMap.containsKey(taskId)) {
ScheduledFuture<?> scheduledFuture = taskMap.get(taskId).future;
scheduledFuture.cancel(false);
taskMap.remove(taskId);
}
return true;
}
public boolean start(String taskId) {
if (taskMap.containsKey(taskId)) {
taskMap.get(taskId).run = true;
taskMap.get(taskId).future = taskMap.get(taskId).target.schedule(this);
return true;
}
return false;
}
public boolean stop(String taskId) {
if (taskMap.containsKey(taskId)) {
taskMap.get(taskId).run = false;
ScheduledFuture<?> scheduledFuture = taskMap.get(taskId).future;
scheduledFuture.cancel(false);
return true;
}
return false;
}
public List<Schedule> taskList() {
List<Schedule> result = new ArrayList<>();
for (TaskWrapper taskWrapper : taskMap.values()) {
Schedule schedule = new Schedule();
schedule.setId(taskWrapper.taskId);
schedule.setName(taskWrapper.taskName);
schedule.setNote(taskWrapper.taskNote);
schedule.setRun(taskWrapper.run);
result.add(schedule);
}
return result;
}
/**
* 线
* @param throwable
*/
@Override
public void handleError(Throwable throwable) {
FrameListener instance = FrameListener.getInstance();
instance.onTaskError(throwable);
}
class TaskWrapper {
RunTask target;
String taskId;
String taskName;
String taskNote;
boolean run;
ScheduledFuture<?> future;
public TaskWrapper(RunTask runTask) {
this.target = runTask;
this.taskId = runTask.taskId();
this.taskName = runTask.taskName();
this.taskNote = runTask.taskNote();
this.future = runTask.schedule(Scheduler.this);
this.run = true;
}
}
public static class Schedule {
private String id;
private String name;
private String note;
private boolean run;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note;
}
public boolean isRun() {
return run;
}
public void setRun(boolean run) {
this.run = run;
}
}
}

@ -3,7 +3,9 @@ package xyz.wbsite.frame.utils;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
@ -21,6 +23,27 @@ public class AESUtil {
private static final String ALGORITHM = "AES";
private static final String ALGORITHM_STR = "AES/ECB/PKCS5Padding";
/**
*
*
* @return
*/
public static String generateDesKey() {
try {
//实例化
KeyGenerator kgen = null;
kgen = KeyGenerator.getInstance("AES");
//设置密钥长度
kgen.init(128);
//生成密钥
SecretKey skey = kgen.generateKey();
//返回密钥的二进制编码
return BytesUtil.bytes2Hex(skey.getEncoded());
} catch (NoSuchAlgorithmException e) {
return "";
}
}
/**
*
*
@ -30,10 +53,10 @@ public class AESUtil {
*/
public static byte[] encrypt(byte[] data, String secret) {
try {
if (secret.length() != 16) {
throw new IllegalArgumentException("secret's length is not 16");
if (secret.length() != 32) {
throw new IllegalArgumentException("Hex secret's length must be 32");
}
SecretKeySpec key = new SecretKeySpec(secret.getBytes(), ALGORITHM);
SecretKeySpec key = new SecretKeySpec(BytesUtil.hex2Bytes(secret), ALGORITHM);
Cipher cipher = Cipher.getInstance(ALGORITHM_STR); // 创建密码器
cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化
return cipher.doFinal(data);// 加密
@ -72,10 +95,10 @@ public class AESUtil {
*/
public static byte[] decrypt(byte[] data, String secret) {
try {
if (secret.length() != 16) {
throw new IllegalArgumentException("secret's length is not 16");
if (secret.length() != 32) {
throw new IllegalArgumentException("Hex secret's length must be 32");
}
SecretKeySpec key = new SecretKeySpec(secret.getBytes(), ALGORITHM);
SecretKeySpec key = new SecretKeySpec(BytesUtil.hex2Bytes(secret), ALGORITHM);
Cipher cipher = Cipher.getInstance(ALGORITHM_STR);
cipher.init(Cipher.DECRYPT_MODE, key);
return cipher.doFinal(data);

@ -0,0 +1,56 @@
package xyz.wbsite.frame.utils;
import java.lang.reflect.Array;
/**
* ArrayUtil -
*
* @author wangbing
* @version 0.0.1
* @since 2017-01-01
*/
public class ArrayUtil {
/**
*
*
* @param array
* @param <T>
* @return
*/
public static <T> T[] clone(T[] array) {
return array == null ? null : array.clone();
}
/**
*
*
* @param array1 1
* @param array2 2
* @param <T>
* @return
*/
public static <T> T[] merge(T[] array1, T... array2) {
if (array1 == null) {
return clone(array2);
} else if (array2 == null) {
return clone(array1);
} else {
Class<?> type1 = array1.getClass().getComponentType();
T[] joinedArray = (T[]) Array.newInstance(type1, array1.length + array2.length);
System.arraycopy(array1, 0, joinedArray, 0, array1.length);
try {
System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
return joinedArray;
} catch (ArrayStoreException var6) {
Class<?> type2 = array2.getClass().getComponentType();
if (!type1.isAssignableFrom(type2)) {
throw new IllegalArgumentException("Cannot store " + type2.getName() + " in an array of " + type1.getName(), var6);
} else {
throw var6;
}
}
}
}
}

@ -0,0 +1,54 @@
package xyz.wbsite.frame.utils;
/**
* BytesUtil -
*
* @author wangbing
* @version 0.0.1
* @since 2017-01-01
*/
public class BytesUtil {
private static final char[] HEXES = {
'0', '1', '2', '3',
'4', '5', '6', '7',
'8', '9', 'a', 'b',
'c', 'd', 'e', 'f'
};
/**
* byte16
*/
public static String bytes2Hex(byte[] bytes) {
if (bytes == null || bytes.length == 0) {
return null;
}
StringBuilder hex = new StringBuilder();
for (byte b : bytes) {
hex.append(HEXES[(b >> 4) & 0x0F]);
hex.append(HEXES[b & 0x0F]);
}
return hex.toString();
}
/**
* 16byte
*/
public static byte[] hex2Bytes(String hex) {
if (hex == null || hex.length() == 0) {
return null;
}
char[] hexChars = hex.toCharArray();
byte[] bytes = new byte[hexChars.length / 2];
for (int i = 0; i < bytes.length; i++) {
bytes[i] = (byte) Integer.parseInt("" + hexChars[i * 2] + hexChars[i * 2 + 1], 16);
}
return bytes;
}
}

@ -1,5 +1,6 @@
package xyz.wbsite.frame.utils;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
@ -10,12 +11,19 @@ import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
public class FileUtil {
public static List<String> readFile2Lines(String fileName) {
public static List<String> readFileToLines(File filePath) {
return readFileToLines(filePath.getAbsolutePath());
}
public static List<String> readFileToLines(String fileName) {
List<String> returnString = new ArrayList<String>();
File file = new File(fileName);
BufferedReader reader = null;
@ -77,6 +85,63 @@ public class FileUtil {
return var5;
}
public static void writeBytesToFile(byte[] buffer, final File file) {
OutputStream output = null;
BufferedOutputStream bufferedOutput = null;
try {
output = new FileOutputStream(file);
bufferedOutput = new BufferedOutputStream(output);
bufferedOutput.write(buffer);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (null != bufferedOutput) {
try {
bufferedOutput.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (null != output) {
try {
output.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public static boolean writeStringToFile(String data, File file, boolean isNewLine, boolean isAppend) {
PrintWriter printWriter = null;
try {
printWriter = openPrintWriter(file);
if (isNewLine && isAppend) {// 换行追加
printWriter.println();
printWriter.append(data);
} else if (!isNewLine && isAppend) {// 不换行追加
printWriter.append(data);
} else {// 直接写入
printWriter.print(data);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
} finally {
if (printWriter != null) printWriter.close();
}
}
public static PrintWriter openPrintWriter(File file) {
try {
return new PrintWriter(new FileOutputStream(file));
} catch (FileNotFoundException e) {
e.printStackTrace();
return null;
}
}
public static FileInputStream openInputStream(File file) throws IOException {
if (file.exists()) {
if (file.isDirectory()) {
@ -91,6 +156,37 @@ public class FileUtil {
}
}
public static FileOutputStream openOutputStream(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 FileOutputStream(file);
}
} else {
throw new FileNotFoundException("File '" + file + "' does not exist");
}
}
/**
* @param fileLocation
* @return URL
*/
public static URL getURL(String fileLocation) {
try {
return new URL(fileLocation);
} catch (MalformedURLException var6) {
try {
return (new File(fileLocation)).toURI().toURL();
} catch (MalformedURLException var5) {
var5.printStackTrace();
}
}
return null;
}
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);

@ -0,0 +1,222 @@
package xyz.wbsite.frame.utils;
import xyz.wbsite.frame.base.LocalData;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
public class FreeMarkerUtil {
/**
* Configuration
*
* @return
*/
public static Configuration getDefaultConfiguration() {
return LocalData.getBean(Configuration.class);
}
/**
* Configuration
*
*
* @return
*/
public static FreeMarkerConfigurer getDefaultConfigurer() {
return LocalData.getBean(FreeMarkerConfigurer.class);
}
/**
*
*
* @param basePackagePath
* @return
*/
public static Configuration getNewConfiguration(String basePackagePath) {
Configuration newConfiguration = getNewConfiguration();
newConfiguration.setClassForTemplateLoading(FreeMarkerUtil.class, basePackagePath);
return newConfiguration;
}
/**
*
*
* @return
*/
public static Configuration getNewConfiguration() {
Configuration configuration;
try {
configuration = getDefaultConfigurer().createConfiguration();
} catch (IOException | TemplateException e) {
configuration = new Configuration(Configuration.VERSION_2_3_28);
}
return configuration;
}
/**
*
*
* @param template
* @param model
* @param writer
*/
public static boolean render(Template template, Object model, Writer writer) {
try {
// 渲染
template.process(model, writer);
// 关闭流
writer.close();
return true;
} catch (IOException | TemplateException e) {
e.printStackTrace();
return false;
}
}
/**
*
*
* @param defaultConfiguration 使
* @param resources
* @param model
* @param writer
*/
public static boolean renderByResources(boolean defaultConfiguration, String resources, Object model, Writer writer) {
Configuration newConfiguration = defaultConfiguration ? getDefaultConfiguration() : getNewConfiguration();
try {
// 构建模板
Template template = newConfiguration.getTemplate(resources);
// 渲染模板
return render(template, model, writer);
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
/**
*
*
* @param defaultConfiguration 使
* @param resources
* @param model
* @return
*/
public static String renderByResources(boolean defaultConfiguration, String resources, Object model) {
StringWriter writer = new StringWriter();
boolean b = renderByResources(defaultConfiguration, resources, model, writer);
if (!b) return "";
return writer.toString();
}
/**
*
*
* @param resources
* @param model
* @param writer
*/
public static boolean renderByResources(String resources, Object model, Writer writer) {
return renderByResources(true, resources, model, writer);
}
/**
*
*
* @param resources
* @param model
* @return
*/
public static String renderByResources(String resources, Object model) {
StringWriter writer = new StringWriter();
boolean b = renderByResources(true, resources, model, writer);
if (!b) return "";
return writer.toString();
}
/**
*
*
* @param file
* @param model
* @param writer
*/
public static boolean renderByFile(File file, Object model, Writer writer) {
try {
// 模板名称
String name = MD5Util.encode(file.getAbsolutePath());
// 获取缓存模板
Template template = (Template) getDefaultConfiguration().getCacheStorage().get(name);
if (template == null) {
// 构建模板,此处构建的模板需手动缓存
template = new Template(file.getName(), FileUtil.readFileToString(file), getDefaultConfiguration());
getDefaultConfiguration().getCacheStorage().put(name, template);
}
// 渲染模板
return render(template, model, writer);
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
/**
*
*
* @param file
* @param model
* @return
*/
public static String renderByFile(File file, Object model) {
StringWriter writer = new StringWriter();
boolean b = renderByFile(file, model, writer);
if (!b) return "";
return writer.toString();
}
/**
*
*
* @param source
* @param model
* @param writer
*/
public static boolean renderByString(String source, Object model, Writer writer) {
try {
// 模板名称
String name = MD5Util.encode(source);
// 获取缓存模板
Template template = (Template) getDefaultConfiguration().getCacheStorage().get(name);
if (template == null) {
// 构建模板,此处构建的模板需手动缓存
template = new Template(name, source, getDefaultConfiguration());
getDefaultConfiguration().getCacheStorage().put(name, template);
}
// 渲染模板
return render(template, model, writer);
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
/**
*
*
* @param source
* @param model
* @return
*/
public static String renderByString(String source, Object model) {
StringWriter writer = new StringWriter();
boolean b = renderByString(source, model, writer);
if (!b) return "";
return writer.toString();
}
}

@ -51,6 +51,20 @@ public class LogUtil {
*
*/
public static void dumpException(Throwable e){
logger.error(getTrace(e));
}
/**
*
*/
public static void dumpException(String e){
logger.error(e);
}
/**
*
*/
public static String getTrace(Throwable e){
StringBuffer msg = new StringBuffer("null");
if (e != null) {
msg = new StringBuffer("");
@ -65,6 +79,6 @@ public class LogUtil {
msg.append(message);
}
}
logger.error(msg.toString());
return msg.toString();
}
}

@ -7,7 +7,7 @@ import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.*;
import org.dozer.DozerBeanMapper;
import org.dozer.Mapper;
import xyz.wbsite.frame.auth.LocalData;
import xyz.wbsite.frame.base.LocalData;
import java.io.IOException;
import java.io.InputStream;

@ -8,13 +8,12 @@ package xyz.wbsite.frame.utils;
* @since 2017-01-01
*/
public class Message {
public static final String ERROR_500 = "服务器走了下神,稍后再试一次";
public static final String NOT_EXIST_METHOD = "调用的方法不存在";
public static String CREATE_FAILURE = "创建失败,请刷新后重新尝试";
public static String DELETE_FAILURE = "删除失败,请刷新后重新尝试";
public static String UPDATE_FAILURE = "更新失败,请刷新后重新尝试";
public static String FIND_FAILURE = "查询失败,请刷新后重新尝试";
public static String GET_FAILURE = "未获取相应内容";
public static String INSERT_DUPLICATE = "已经存在相同数据,返回列表页面确认";
public static String CREATE_FAILURE = "创建失败,请刷新后重新尝试!";
public static String DELETE_FAILURE = "删除失败,请刷新后重新尝试!";
public static String UPDATE_FAILURE = "更新失败,请刷新后重新尝试!";
public static String FIND_FAILURE = "查询失败,请刷新后重新尝试!";
public static String GET_FAILURE = "对象不存在!";
public static String INSERT_DUPLICATE = "已经存在相同数据,返回列表页面确认!";
public static String SERVICE_FAILURE = "服务调用失败!";
}

@ -0,0 +1,54 @@
package xyz.wbsite.frame.utils;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
/**
*
*
* @author wangbing
* @version 0.0.1
* @since 2020-11-10
*/
public class PropertiesUtil {
/**
*
*/
private static Map<String, Properties> propertiesMap = new HashMap<>();
/**
* @param name
* @param key
* @param defaultValue
* @return
*/
public static String getProp(String name, String key, String defaultValue) {
Properties properties = propertiesMap.get(name);
if (properties == null) {
try {
properties = new Properties();
properties.load(ResourceUtil.getInput(name));
propertiesMap.put(name, properties);
} catch (IOException ignored) {
}
}
if (properties == null) {
return "";
}
return properties.getProperty(key, defaultValue);
}
public static String getProp(String name, String key) {
return getProp(name, key);
}
public static int getPropInt(String name, String key, int defaultValue) {
String prop = getProp(name, key, String.valueOf(defaultValue));
// 这边对值不做容错处理预防因为容错出现难以查找的BUG
return Integer.parseInt(prop);
}
}

@ -4,7 +4,6 @@ import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import xyz.wbsite.frame.excel.WExcel;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
@ -36,7 +35,7 @@ public class ResponseUtil {
}
}
public static ResponseEntity<byte[]> apply(WExcel sheet) {
public static ResponseEntity<byte[]> apply(xyz.wbsite.frame.excel.WExcel sheet) {
return apply(sheet.getBytes(), sheet.getName() + ".xlsx");
}
}

@ -0,0 +1,23 @@
package xyz.wbsite.frame.validation;
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = DictValidator.class)
@Inherited
public @interface Dict {
String message() default "字典验证错误";
String name() default "";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}

@ -0,0 +1,80 @@
package xyz.wbsite.frame.validation;
import xyz.wbsite.frame.provider.DictProvider;
import xyz.wbsite.frame.provider.FrameProvider;
import xyz.wbsite.frame.utils.StringUtil;
import org.hibernate.validator.internal.engine.constraintvalidation.ConstraintValidatorContextImpl;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.Locale;
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) {
String fieldName = "";
// 获取注解的字段名称,用于快速定位排查
if (constraintValidatorContext instanceof ConstraintValidatorContextImpl) {
ConstraintValidatorContextImpl validatorContext = (ConstraintValidatorContextImpl) constraintValidatorContext;
if (validatorContext.getConstraintViolationCreationContexts() != null
&& validatorContext.getConstraintViolationCreationContexts().size() > 0
&& validatorContext.getConstraintViolationCreationContexts().get(0).getPath() != null) {
fieldName = validatorContext.getConstraintViolationCreationContexts().get(0).getPath().asString();
}
}
if (StringUtil.isEmpty(o)) {// 当值为空字符时,认为值有效
return true;
} else if (name == null) {// 当字典名称为空时,说明未指定字典,提示错误
// 禁用默认错误信息,防止错误信息与自定义信息乱串
constraintValidatorContext.disableDefaultConstraintViolation();
String message = String.format(Locale.CHINESE, "[ %s ] 未指定字典名称!", fieldName);
constraintValidatorContext.buildConstraintViolationWithTemplate(message).addConstraintViolation();
return false;
} else {// 加载字典,并验证提交值是否包含在内
DictProvider dictProvider = FrameProvider.getInstance().getDictProvider();
// 如果加载字典出现错误,返回验证错误
if (dictProvider == null) {
// 禁用默认错误信息,防止错误信息与自定义信息乱串
constraintValidatorContext.disableDefaultConstraintViolation();
String message = String.format(Locale.CHINESE, "[ %s ] 验证字典 [ %s ] 未实现字典验证接口", fieldName, name);
constraintValidatorContext.buildConstraintViolationWithTemplate(message).addConstraintViolation();
return false;
}
// 确认字典是否存在
boolean isExist = dictProvider.isExist(name);
if (!isExist) {
// 禁用默认错误信息,防止错误信息与自定义信息乱串
constraintValidatorContext.disableDefaultConstraintViolation();
String message = String.format(Locale.CHINESE, "[ %s ] 指定的字典 [ %s ] 未找到!", fieldName, name, o);
constraintValidatorContext.buildConstraintViolationWithTemplate(message).addConstraintViolation();
return false;
}
// 确认字典项是否存在
boolean isExistValue = dictProvider.isExistValue(name, o);
// 当未找到字典项值时,认为值无效,返回验证错误
if (!isExistValue) {
// 禁用默认错误信息,防止错误信息与自定义信息乱串
constraintValidatorContext.disableDefaultConstraintViolation();
String message = String.format(Locale.CHINESE, "[ %s ] 指定的字典 [ %s ] 中,未找到字典属值(%s)", fieldName, name, o);
constraintValidatorContext.buildConstraintViolationWithTemplate(message).addConstraintViolation();
return false;
} else {
return true;
}
}
}
}

@ -0,0 +1,25 @@
package xyz.wbsite.frame.validation;
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = NumberValidator.class)
@Inherited
public @interface Number {
String message() default "字段长度不符合";
int min() default 0;
int max() default 2147483647;
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}

@ -0,0 +1,48 @@
package xyz.wbsite.frame.validation;
import org.hibernate.validator.internal.engine.constraintvalidation.ConstraintValidatorContextImpl;
import xyz.wbsite.frame.utils.StringUtil;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.Locale;
public class NumberValidator implements ConstraintValidator<Number, Integer> {
private int min;
private int max;
private String defaultMessage;
@Override
public void initialize(Number constraint) {
min = constraint.min();
max = constraint.max();
}
@Override
public boolean isValid(Integer o, ConstraintValidatorContext constraintValidatorContext) {
String fieldName = "";
if (constraintValidatorContext instanceof ConstraintValidatorContextImpl) {
ConstraintValidatorContextImpl validatorContext = (ConstraintValidatorContextImpl) constraintValidatorContext;
if (validatorContext.getConstraintViolationCreationContexts() != null
&& validatorContext.getConstraintViolationCreationContexts().size() > 0
&& validatorContext.getConstraintViolationCreationContexts().get(0).getPath() != null) {
fieldName = validatorContext.getConstraintViolationCreationContexts().get(0).getPath().asString();
}
}
if (o < min) {
constraintValidatorContext.disableDefaultConstraintViolation();
String message = StringUtil.isNotEmpty(defaultMessage) ? defaultMessage : String.format(Locale.CHINESE, "[ %s ] 最小值为%d", fieldName, min);
constraintValidatorContext.buildConstraintViolationWithTemplate(message).addConstraintViolation();
return false;
} else if (o > max) {
constraintValidatorContext.disableDefaultConstraintViolation();
String message = StringUtil.isNotEmpty(defaultMessage) ? defaultMessage : String.format(Locale.CHINESE, "[ %s ] 最大值为%d", fieldName, max);
constraintValidatorContext.buildConstraintViolationWithTemplate(message).addConstraintViolation();
return false;
} else {
return true;
}
}
}

@ -0,0 +1,23 @@
package xyz.wbsite.frame.validation;
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = SelectValidator.class)
@Inherited
public @interface Select {
String message() default "选项验证错误";
String[] value() default {};
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}

@ -0,0 +1,55 @@
package xyz.wbsite.frame.validation;
import org.hibernate.validator.internal.engine.constraintvalidation.ConstraintValidatorContextImpl;
import xyz.wbsite.frame.utils.StringUtil;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.Locale;
public class SelectValidator implements ConstraintValidator<Select, String> {
private String[] values;
@Override
public void initialize(Select constraintAnnotation) {
values = constraintAnnotation.value();
}
@Override
public boolean isValid(String o, ConstraintValidatorContext constraintValidatorContext) {
String fieldName = "";
if (constraintValidatorContext instanceof ConstraintValidatorContextImpl) {
ConstraintValidatorContextImpl validatorContext = (ConstraintValidatorContextImpl) constraintValidatorContext;
if (validatorContext.getConstraintViolationCreationContexts() != null
&& validatorContext.getConstraintViolationCreationContexts().size() > 0
&& validatorContext.getConstraintViolationCreationContexts().get(0).getPath() != null) {
fieldName = validatorContext.getConstraintViolationCreationContexts().get(0).getPath().asString();
}
}
if (StringUtil.isEmpty(o)) {
return true;
} else {
if (values.length == 0) {
String message = String.format(Locale.CHINESE, "%s 指定枚举为空!", fieldName);
constraintValidatorContext.buildConstraintViolationWithTemplate(message).addConstraintViolation();
return false;
}
int i = 0;
for (; i < values.length; i++) {
if (o.equals(values[i])) {
break;
}
}
if (i < values.length) {
return true;
} else {
String message = String.format(Locale.CHINESE, "%s 指定枚举组 [ %s ] 中,未找到枚举值(%s)", fieldName, String.join(",", values), o);
constraintValidatorContext.buildConstraintViolationWithTemplate(message).addConstraintViolation();
return false;
}
}
}
}

@ -0,0 +1,75 @@
package xyz.wbsite.module.admin.ent;
import xyz.wbsite.frame.excel.annotation.ExcelNote;
import xyz.wbsite.frame.excel.annotation.ExcelSelect;
import com.alibaba.excel.annotation.ExcelProperty;
import xyz.wbsite.frame.excel.annotation.ExcelSheet;
import xyz.wbsite.frame.base.BaseEntity;
/**
* CONFIG -
*
* @author wangbing
* @version 0.0.1
* @since 2021-02-07
*/
@ExcelSheet("配置预设")
public class Config extends BaseEntity {
/**
* CONF_NAME -
*/
@ExcelProperty("配置名称")
@ExcelNote("")
private String confName;
/**
* CONF_TYPE -
*/
@ExcelProperty("配置类型")
@ExcelNote("")
private String confType;
/**
* CONF_VALUE -
*/
@ExcelProperty("配置属值")
@ExcelNote("")
private String confValue;
/**
* CONF_NOTE -
*/
@ExcelProperty("配置备注")
@ExcelNote("")
private String confNote;
public String getConfName() {
return this.confName;
}
public void setConfName(String confName) {
this.confName = confName;
}
public String getConfType() {
return this.confType;
}
public void setConfType(String confType) {
this.confType = confType;
}
public String getConfValue() {
return this.confValue;
}
public void setConfValue(String confValue) {
this.confValue = confValue;
}
public String getConfNote() {
return this.confNote;
}
public void setConfNote(String confNote) {
this.confNote = confNote;
}
}

@ -0,0 +1,74 @@
package xyz.wbsite.module.admin.ent;
import xyz.wbsite.frame.base.BaseEntity;
/**
* CONFIG_DATA -
*
* @author wangbing
* @version 0.0.1
* @since 2021-02-07
*/
public class ConfigData extends BaseEntity {
/**
* TARGET_ID -
*/
private Long targetId;
/**
* CONF_NAME -
*/
private String confName;
/**
* CONF_TYPE -
*/
private String confType;
/**
* CONF_VALUE -
*/
private String confValue;
/**
* CONF_NOTE -
*/
private String confNote;
public Long getTargetId() {
return this.targetId;
}
public void setTargetId(Long targetId) {
this.targetId = targetId;
}
public String getConfName() {
return this.confName;
}
public void setConfName(String confName) {
this.confName = confName;
}
public String getConfType() {
return this.confType;
}
public void setConfType(String confType) {
this.confType = confType;
}
public String getConfValue() {
return this.confValue;
}
public void setConfValue(String confValue) {
this.confValue = confValue;
}
public String getConfNote() {
return this.confNote;
}
public void setConfNote(String confNote) {
this.confNote = confNote;
}
}

@ -0,0 +1,119 @@
package xyz.wbsite.module.admin.ent;
import xyz.wbsite.frame.excel.annotation.ExcelNote;
import xyz.wbsite.frame.excel.annotation.ExcelSelect;
import com.alibaba.excel.annotation.ExcelProperty;
import xyz.wbsite.frame.excel.annotation.ExcelSheet;
import xyz.wbsite.frame.base.BaseEntity;
/**
* LOCATIONS -
*
* @author wangbing
* @version 0.0.1
* @since 2021-02-07
*/
@ExcelSheet("路径配置")
public class Locations extends BaseEntity {
/**
* SERVICE_ID -
*/
@ExcelProperty("服务主键")
@ExcelNote("")
private Long serviceId;
/**
* LOCAL_TITLE -
*/
@ExcelProperty("配置标题")
@ExcelNote("")
private String localTitle;
/**
* LOCAL_NOTE -
*/
@ExcelProperty("配置备注")
@ExcelNote("")
private String localNote;
/**
* LOCAL_PATH -
*/
@ExcelProperty("配置路径")
@ExcelNote("")
private String localPath;
/**
* LOCAL_VALID -
*/
@ExcelProperty("是否启用")
@ExcelNote("")
@ExcelSelect({"是","否"})
private Boolean localValid;
/**
* FILTER -
*/
@ExcelProperty("启用过滤")
@ExcelNote("")
@ExcelSelect({"是","否"})
private Boolean filter;
/**
* FILTER_CONF -
*/
@ExcelProperty("过滤配置")
@ExcelNote("")
private String filterConf;
public Long getServiceId() {
return this.serviceId;
}
public void setServiceId(Long serviceId) {
this.serviceId = serviceId;
}
public String getLocalTitle() {
return this.localTitle;
}
public void setLocalTitle(String localTitle) {
this.localTitle = localTitle;
}
public String getLocalNote() {
return this.localNote;
}
public void setLocalNote(String localNote) {
this.localNote = localNote;
}
public String getLocalPath() {
return this.localPath;
}
public void setLocalPath(String localPath) {
this.localPath = localPath;
}
public Boolean getLocalValid() {
return this.localValid;
}
public void setLocalValid(Boolean localValid) {
this.localValid = localValid;
}
public Boolean getFilter() {
return this.filter;
}
public void setFilter(Boolean filter) {
this.filter = filter;
}
public String getFilterConf() {
return this.filterConf;
}
public void setFilterConf(String filterConf) {
this.filterConf = filterConf;
}
}

@ -0,0 +1,57 @@
package xyz.wbsite.module.admin.mgr;
import xyz.wbsite.module.admin.req.ConfigDataCreateRequest;
import xyz.wbsite.module.admin.req.ConfigDataDeleteRequest;
import xyz.wbsite.module.admin.req.ConfigDataFindRequest;
import xyz.wbsite.module.admin.req.ConfigDataUpdateRequest;
import xyz.wbsite.module.admin.rsp.ConfigDataCreateResponse;
import xyz.wbsite.module.admin.rsp.ConfigDataDeleteResponse;
import xyz.wbsite.module.admin.rsp.ConfigDataFindResponse;
import xyz.wbsite.module.admin.rsp.ConfigDataUpdateResponse;
import xyz.wbsite.frame.base.Token;
/**
*
*
* @author wangbing
* @version 0.0.1
* @since 2021-02-07
*/
public interface ConfigDataManager {
/**
*
*
* @param request
* @param token
* @return
*/
ConfigDataCreateResponse create(ConfigDataCreateRequest request, Token token);
/**
*
*
* @param request
* @param token
* @return
*/
ConfigDataDeleteResponse delete(ConfigDataDeleteRequest request, Token token);
/**
*
*
* @param request
* @param token
* @return
*/
ConfigDataUpdateResponse update(ConfigDataUpdateRequest request, Token token);
/**
*
*
* @param request
* @param token
* @return
*/
ConfigDataFindResponse find(ConfigDataFindRequest request, Token token);
}

@ -0,0 +1,57 @@
package xyz.wbsite.module.admin.mgr;
import xyz.wbsite.module.admin.req.ServicesCreateRequest;
import xyz.wbsite.module.admin.req.ServicesDeleteRequest;
import xyz.wbsite.module.admin.req.ServicesFindRequest;
import xyz.wbsite.module.admin.req.ServicesUpdateRequest;
import xyz.wbsite.module.admin.rsp.ServicesCreateResponse;
import xyz.wbsite.module.admin.rsp.ServicesDeleteResponse;
import xyz.wbsite.module.admin.rsp.ServicesFindResponse;
import xyz.wbsite.module.admin.rsp.ServicesUpdateResponse;
import xyz.wbsite.frame.base.Token;
/**
*
*
* @author wangbing
* @version 0.0.1
* @since 2021-02-07
*/
public interface ServicesManager {
/**
*
*
* @param request
* @param token
* @return
*/
ServicesCreateResponse create(ServicesCreateRequest request, Token token);
/**
*
*
* @param request
* @param token
* @return
*/
ServicesDeleteResponse delete(ServicesDeleteRequest request, Token token);
/**
*
*
* @param request
* @param token
* @return
*/
ServicesUpdateResponse update(ServicesUpdateRequest request, Token token);
/**
*
*
* @param request
* @param token
* @return
*/
ServicesFindResponse find(ServicesFindRequest request, Token token);
}

@ -0,0 +1,100 @@
package xyz.wbsite.module.admin.mpr;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import xyz.wbsite.frame.base.Token;
import xyz.wbsite.module.admin.ent.ConfigData;
import xyz.wbsite.module.admin.req.ConfigDataFindRequest;
import java.util.List;
/**
* CONFIG_DATA -
*
* @author wangbing
* @since 2021-02-07
*/
@Mapper
public interface ConfigDataMapper {
/**
*
*
* @param request
* @param token
* @return
*/
long insert(@Param("request") ConfigData request, @Param("token") Token token);
/**
*
*
* @param list
* @param token
* @return
*/
long insertBatch(@Param("list") List<ConfigData> list, @Param("token") Token token);
/**
*
*
* @param id
* @param token
* @return
*/
long delete(@Param("id") Long id, @Param("token") Token token);
/**
*
*
* @param list
* @param token
* @return
*/
long deleteBatch(@Param("list") List<Long> list, @Param("token") Token token);
/**
*
*
* @param request
* @param token
* @return
*/
long update(@Param("request") ConfigData request, @Param("token") Token token);
/**
*
*
* @param request
* @param token
* @return
*/
List<ConfigData> select(@Param("request") ConfigData request, @Param("token") Token token);
/**
*
*
* @param request
* @param token
* @return
*/
List<ConfigData> find(@Param("request") ConfigDataFindRequest request, @Param("token") Token token);
/**
*
*
* @param id
* @param token
* @return
*/
ConfigData getById(@Param("id") Long id, @Param("token") Token token);
/**
*
*
* @param ids
* @param token
* @return
*/
List<ConfigData> getByIds(@Param("ids") Long[] ids, @Param("token") Token token);
}

@ -0,0 +1,100 @@
package xyz.wbsite.module.admin.mpr;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import xyz.wbsite.frame.base.Token;
import xyz.wbsite.module.admin.ent.Config;
import xyz.wbsite.module.admin.req.ConfigFindRequest;
import java.util.List;
/**
* CONFIG -
*
* @author wangbing
* @since 2021-02-07
*/
@Mapper
public interface ConfigMapper {
/**
*
*
* @param request
* @param token
* @return
*/
long insert(@Param("request") Config request, @Param("token") Token token);
/**
*
*
* @param list
* @param token
* @return
*/
long insertBatch(@Param("list") List<Config> list, @Param("token") Token token);
/**
*
*
* @param id
* @param token
* @return
*/
long delete(@Param("id") Long id, @Param("token") Token token);
/**
*
*
* @param list
* @param token
* @return
*/
long deleteBatch(@Param("list") List<Long> list, @Param("token") Token token);
/**
*
*
* @param request
* @param token
* @return
*/
long update(@Param("request") Config request, @Param("token") Token token);
/**
*
*
* @param request
* @param token
* @return
*/
List<Config> select(@Param("request") Config request, @Param("token") Token token);
/**
*
*
* @param request
* @param token
* @return
*/
List<Config> find(@Param("request") ConfigFindRequest request, @Param("token") Token token);
/**
*
*
* @param id
* @param token
* @return
*/
Config getById(@Param("id") Long id, @Param("token") Token token);
/**
*
*
* @param ids
* @param token
* @return
*/
List<Config> getByIds(@Param("ids") Long[] ids, @Param("token") Token token);
}

@ -0,0 +1,207 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="xyz.wbsite.module.admin.mpr.LocationsMapper">
<sql id="table">"NA_LOCATIONS"</sql>
<sql id="entityColumnList">
"ID","SERVICE_ID","LOCAL_TITLE","LOCAL_NOTE","LOCAL_PATH","LOCAL_VALID","FILTER","FILTER_CONF","ROW_VERSION","IS_DELETED","CREATE_BY","CREATE_TIME","LAST_UPDATE_BY","LAST_UPDATE_TIME"
</sql>
<resultMap id="locations" type="xyz.wbsite.module.admin.ent.Locations">
<result column="ID" jdbcType="BIGINT" property="id"/>
<result column="SERVICE_ID" jdbcType="BIGINT" property="serviceId"/>
<result column="LOCAL_TITLE" jdbcType="VARCHAR" property="localTitle"/>
<result column="LOCAL_NOTE" jdbcType="VARCHAR" property="localNote"/>
<result column="LOCAL_PATH" jdbcType="VARCHAR" property="localPath"/>
<result column="LOCAL_VALID" jdbcType="BIT" property="localValid"/>
<result column="FILTER" jdbcType="BIT" property="filter"/>
<result column="FILTER_CONF" jdbcType="VARCHAR" property="filterConf"/>
<result column="ROW_VERSION" jdbcType="BIGINT" property="rowVersion"/>
<result column="IS_DELETED" jdbcType="BIT" property="isDeleted"/>
<result column="CREATE_BY" jdbcType="BIGINT" property="createBy"/>
<result column="CREATE_TIME" jdbcType="TIMESTAMP" property="createTime"/>
<result column="LAST_UPDATE_BY" jdbcType="BIGINT" property="lastUpdateBy"/>
<result column="LAST_UPDATE_TIME" jdbcType="TIMESTAMP" property="lastUpdateTime"/>
</resultMap>
<insert id="insert">
INSERT INTO
<include refid="table"/>
(
<include refid="entityColumnList"/>
)
VALUES
(
#{request.id},
#{request.serviceId,jdbcType=BIGINT},
#{request.localTitle,jdbcType=VARCHAR},
#{request.localNote,jdbcType=VARCHAR},
#{request.localPath,jdbcType=VARCHAR},
#{request.localValid,jdbcType=BIT},
#{request.filter,jdbcType=BIT},
#{request.filterConf,jdbcType=VARCHAR},
0,
0,
#{token.userId,jdbcType=NUMERIC},
datetime('now','localtime'),
NULL,
NULL
)
</insert>
<insert id="insertBatch">
INSERT INTO
<include refid="table"/>
(
<include refid="entityColumnList"/>
)
VALUES
<foreach collection="list" item="item" index="index" separator="," open="(" close=")">
#{item.id},
#{item.serviceId,jdbcType=BIGINT},
#{item.localTitle,jdbcType=VARCHAR},
#{item.localNote,jdbcType=VARCHAR},
#{item.localPath,jdbcType=VARCHAR},
#{item.localValid,jdbcType=BIT},
#{item.filter,jdbcType=BIT},
#{item.filterConf,jdbcType=VARCHAR},
0,
0,
#{token.userId,jdbcType=NUMERIC},
datetime('now','localtime'),
NULL,
NULL
</foreach >
</insert>
<update id="delete">
UPDATE
<include refid="table"/>
SET "IS_DELETED" = 1
WHERE "IS_DELETED" = 0
AND "ID" = #{id}
</update>
<update id="deleteBatch">
UPDATE
<include refid="table"/>
SET "IS_DELETED" = 1
WHERE "IS_DELETED" = 0
AND "ID" IN
<foreach collection="list" item="item" index="index" separator="," open="(" close=")">
#{item}
</foreach>
</update>
<update id="update">
UPDATE
<include refid="table"/>
SET
SERVICE_ID = #{request.serviceId,jdbcType=BIGINT},
LOCAL_TITLE = #{request.localTitle,jdbcType=VARCHAR},
LOCAL_NOTE = #{request.localNote,jdbcType=VARCHAR},
LOCAL_PATH = #{request.localPath,jdbcType=VARCHAR},
LOCAL_VALID = #{request.localValid,jdbcType=BIT},
FILTER = #{request.filter,jdbcType=BIT},
FILTER_CONF = #{request.filterConf,jdbcType=VARCHAR},
"ROW_VERSION" = "ROW_VERSION" + 1,
"LAST_UPDATE_BY" = #{token.userId},
"LAST_UPDATE_TIME" = datetime('now','localtime')
WHERE "IS_DELETED" = 0
AND "ID" = #{request.id}
AND "ROW_VERSION" = #{request.rowVersion}
</update>
<select id="select" resultMap="locations">
SELECT
<include refid="entityColumnList"/>
FROM
<include refid="table"/>
WHERE "IS_DELETED" = 0
<if test="request.serviceId != null">
AND "SERVICE_ID" = #{request.serviceId}
</if>
<if test="request.localTitle != null and request.localTitle != ''">
AND "LOCAL_TITLE" = #{request.localTitle}
</if>
<if test="request.localPath != null and request.localPath != ''">
AND "LOCAL_PATH" = #{request.localPath}
</if>
<if test="request.localValid != null">
AND "LOCAL_VALID" = #{request.localValid}
</if>
<if test="request.filter != null">
AND "FILTER" = #{request.filter}
</if>
</select>
<select id="find" resultMap="locations">
SELECT
<include refid="entityColumnList"/>
FROM
<include refid="table"/>
WHERE "IS_DELETED" = 0
<if test="request.serviceId != null">
AND "SERVICE_ID" = #{request.serviceId}
</if>
<if test="request.localTitle != null and request.localTitle != ''">
AND "LOCAL_TITLE" = #{request.localTitle}
</if>
<if test="request.localTitleLike != null and request.localTitleLike != ''">
AND "LOCAL_TITLE" LIKE '%'||#{request.localTitleLike}||'%'
</if>
<if test="request.localNoteLike != null and request.localNoteLike != ''">
AND "LOCAL_NOTE" LIKE '%'||#{request.localNoteLike}||'%'
</if>
<if test="request.localPath != null and request.localPath != ''">
AND "LOCAL_PATH" = #{request.localPath}
</if>
<if test="request.localPathLike != null and request.localPathLike != ''">
AND "LOCAL_PATH" LIKE '%'||#{request.localPathLike}||'%'
</if>
<if test="request.localValid != null">
AND "LOCAL_VALID" = #{request.localValid}
</if>
<if test="request.filter != null">
AND "FILTER" = #{request.filter}
</if>
<if test="request.startDate != null">
AND strftime('%s',"CREATE_TIME", 'utc')*1000 &gt;= #{request.startDate}
</if>
<if test="request.endDate != null">
AND strftime('%s',"CREATE_TIME", 'utc')*1000 &lt;= #{request.endDate}
</if>
</select>
<select id="search" resultMap="locations">
SELECT
<include refid="entityColumnList"/>
FROM
<include refid="table"/>
WHERE "IS_DELETED" = 0
</select>
<select id="getById" resultMap="locations">
SELECT
<include refid="entityColumnList"/>
FROM
<include refid="table"/>
WHERE "IS_DELETED" = 0
AND "ID" = #{id}
</select>
<select id="getByIds" resultMap="locations">
SELECT
<include refid="entityColumnList"/>
FROM
<include refid="table"/>
WHERE "IS_DELETED" = 0
AND "ID" IN
<foreach collection="ids" item="item" index="index" separator="," open="(" close=")">
#{item}
</foreach>
</select>
</mapper>

@ -0,0 +1,100 @@
package xyz.wbsite.module.admin.mpr;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import xyz.wbsite.frame.base.Token;
import xyz.wbsite.module.admin.ent.Services;
import xyz.wbsite.module.admin.req.ServicesFindRequest;
import java.util.List;
/**
* SERVICES -
*
* @author wangbing
* @since 2021-02-07
*/
@Mapper
public interface ServicesMapper {
/**
*
*
* @param request
* @param token
* @return
*/
long insert(@Param("request") Services request, @Param("token") Token token);
/**
*
*
* @param list
* @param token
* @return
*/
long insertBatch(@Param("list") List<Services> list, @Param("token") Token token);
/**
*
*
* @param id
* @param token
* @return
*/
long delete(@Param("id") Long id, @Param("token") Token token);
/**
*
*
* @param list
* @param token
* @return
*/
long deleteBatch(@Param("list") List<Long> list, @Param("token") Token token);
/**
*
*
* @param request
* @param token
* @return
*/
long update(@Param("request") Services request, @Param("token") Token token);
/**
*
*
* @param request
* @param token
* @return
*/
List<Services> select(@Param("request") Services request, @Param("token") Token token);
/**
*
*
* @param request
* @param token
* @return
*/
List<Services> find(@Param("request") ServicesFindRequest request, @Param("token") Token token);
/**
*
*
* @param id
* @param token
* @return
*/
Services getById(@Param("id") Long id, @Param("token") Token token);
/**
*
*
* @param ids
* @param token
* @return
*/
List<Services> getByIds(@Param("ids") Long[] ids, @Param("token") Token token);
}

@ -0,0 +1,78 @@
package xyz.wbsite.module.admin.req;
import xyz.wbsite.frame.base.BaseRequest;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.NotBlank;
import org.hibernate.validator.constraints.Length;
import xyz.wbsite.frame.validation.Select;
/**
* ConfigCreateRequest -
*
* @author wangbing
* @version 0.0.1
* @since 2021-02-07
*/
public class ConfigCreateRequest extends BaseRequest {
/**
* .
*/
@NotBlank(message = "[confName]配置名称不能为空")
@Length(min = 0, max = 50, message = "[confName]配置名称长度不合法(0-50)")
private String confName;
/**
* .
* HTTP:
* SERVER:
* LOCATION:
*/
@NotNull(message = "[confType]配置类型不能为NULL")
@Select({"HTTP", "SERVER", "LOCATION"})
private String confType;
/**
* .
*/
@Length(min = 0, max = 255, message = "[confValue]配置属值长度不合法(0-255)")
private String confValue;
/**
* .
*/
@Length(min = 0, max = 255, message = "[confNote]配置备注长度不合法(0-255)")
private String confNote;
public String getConfName() {
return this.confName;
}
public void setConfName(String confName) {
this.confName = confName;
}
public String getConfType() {
return this.confType;
}
public void setConfType(String confType) {
this.confType = confType;
}
public String getConfValue() {
return this.confValue;
}
public void setConfValue(String confValue) {
this.confValue = confValue;
}
public String getConfNote() {
return this.confNote;
}
public void setConfNote(String confNote) {
this.confNote = confNote;
}
}

@ -0,0 +1,30 @@
package xyz.wbsite.module.admin.req;
import xyz.wbsite.frame.base.BaseRequest;
import javax.validation.constraints.NotNull;
/**
* ConfigDataDeleteRequest -
*
* @author wangbing
* @version 0.0.1
* @since 2021-02-07
*/
public class ConfigDataDeleteRequest extends BaseRequest {
/**
* .
*/
@NotNull(message = "[id]主键不能为空")
private Long id;
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
}

@ -0,0 +1,108 @@
package xyz.wbsite.module.admin.req;
import xyz.wbsite.frame.base.BaseUpdateRequest;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.NotEmpty;
import xyz.wbsite.frame.validation.Select;
/**
* ConfigDataUpdateRequest -
*
* @author wangbing
* @version 0.0.1
* @since 2021-02-07
*/
public class ConfigDataUpdateRequest extends BaseUpdateRequest {
/**
* .
*/
@NotNull(message = "[id]主键不能为NULL")
private Long id;
/**
* .
*/
@NotNull(message = "[targetId]目标主键不能为NULL")
private Long targetId;
/**
* .
*/
@NotBlank(message = "[confName]配置名称不能为空")
@Length(min = 0, max = 50, message = "[confName]配置名称长度不合法(0-50)")
private String confName;
/**
* .
* HTTP:
* SERVER:
* LOCATION:
*/
@NotNull(message = "[confType]配置类型不能为NULL")
@Select({"HTTP", "SERVER", "LOCATION"})
private String confType;
/**
* .
*/
@NotBlank(message = "[confValue]配置属值不能为空")
@Length(min = 0, max = 255, message = "[confValue]配置属值长度不合法(0-255)")
private String confValue;
/**
* .
*/
@Length(min = 0, max = 255, message = "[confNote]配置备注长度不合法(0-255)")
private String confNote;
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
public Long getTargetId() {
return this.targetId;
}
public void setTargetId(Long targetId) {
this.targetId = targetId;
}
public String getConfName() {
return this.confName;
}
public void setConfName(String confName) {
this.confName = confName;
}
public String getConfType() {
return this.confType;
}
public void setConfType(String confType) {
this.confType = confType;
}
public String getConfValue() {
return this.confValue;
}
public void setConfValue(String confValue) {
this.confValue = confValue;
}
public String getConfNote() {
return this.confNote;
}
public void setConfNote(String confNote) {
this.confNote = confNote;
}
}

@ -1,28 +1,30 @@
package xyz.wbsite.module.conf.req;
package xyz.wbsite.module.admin.req;
import xyz.wbsite.frame.base.BaseRequest;
import javax.validation.constraints.NotNull;
/**
* MappingGetRequest -
* ConfigDeleteRequest -
*
* @author wangbing
* @version 0.0.1
* @since 2020-03-18
* @since 2021-02-07
*/
public class MappingGetRequest extends BaseRequest {
public class ConfigDeleteRequest extends BaseRequest {
/**
*
* .
*/
@NotNull(message = "[id]主键不能为空")
private long id;
private Long id;
public long getId() {
public Long getId() {
return this.id;
}
public void setId(long id) {
public void setId(Long id) {
this.id = id;
}
}

@ -0,0 +1,116 @@
package xyz.wbsite.module.admin.req;
import xyz.wbsite.frame.base.BaseRequest;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.NotBlank;
import org.hibernate.validator.constraints.Length;
/**
* LocationsCreateRequest -
*
* @author wangbing
* @version 0.0.1
* @since 2021-02-07
*/
public class LocationsCreateRequest extends BaseRequest {
/**
* .
*/
@NotNull(message = "[serviceId]服务主键不能为NULL")
private Long serviceId;
/**
* .
*/
@NotBlank(message = "[localTitle]配置标题不能为空")
@Length(min = 0, max = 50, message = "[localTitle]配置标题长度不合法(0-50)")
private String localTitle;
/**
* .
*/
@Length(min = 0, max = 255, message = "[localNote]配置备注长度不合法(0-255)")
private String localNote;
/**
* .
*/
@NotBlank(message = "[localPath]配置路径不能为空")
@Length(min = 0, max = 50, message = "[localPath]配置路径长度不合法(0-50)")
private String localPath;
/**
* .
*/
@NotNull(message = "[localValid]是否启用不能为NULL")
private Boolean localValid;
/**
* .
*/
@NotNull(message = "[filter]启用过滤不能为NULL")
private Boolean filter;
/**
* .
*/
@Length(min = 0, max = 500, message = "[filterConf]过滤配置长度不合法(0-500)")
private String filterConf;
public Long getServiceId() {
return this.serviceId;
}
public void setServiceId(Long serviceId) {
this.serviceId = serviceId;
}
public String getLocalTitle() {
return this.localTitle;
}
public void setLocalTitle(String localTitle) {
this.localTitle = localTitle;
}
public String getLocalNote() {
return this.localNote;
}
public void setLocalNote(String localNote) {
this.localNote = localNote;
}
public String getLocalPath() {
return this.localPath;
}
public void setLocalPath(String localPath) {
this.localPath = localPath;
}
public Boolean getLocalValid() {
return this.localValid;
}
public void setLocalValid(Boolean localValid) {
this.localValid = localValid;
}
public Boolean getFilter() {
return this.filter;
}
public void setFilter(Boolean filter) {
this.filter = filter;
}
public String getFilterConf() {
return this.filterConf;
}
public void setFilterConf(String filterConf) {
this.filterConf = filterConf;
}
}

@ -0,0 +1,131 @@
package xyz.wbsite.module.admin.req;
import xyz.wbsite.frame.base.BaseUpdateRequest;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.NotEmpty;
/**
* LocationsUpdateRequest -
*
* @author wangbing
* @version 0.0.1
* @since 2021-02-07
*/
public class LocationsUpdateRequest extends BaseUpdateRequest {
/**
* .
*/
@NotNull(message = "[id]主键不能为NULL")
private Long id;
/**
* .
*/
@NotNull(message = "[serviceId]服务主键不能为NULL")
private Long serviceId;
/**
* .
*/
@NotBlank(message = "[localTitle]配置标题不能为空")
@Length(min = 0, max = 50, message = "[localTitle]配置标题长度不合法(0-50)")
private String localTitle;
/**
* .
*/
@Length(min = 0, max = 255, message = "[localNote]配置备注长度不合法(0-255)")
private String localNote;
/**
* .
*/
@NotBlank(message = "[localPath]配置路径不能为空")
@Length(min = 0, max = 50, message = "[localPath]配置路径长度不合法(0-50)")
private String localPath;
/**
* .
*/
@NotNull(message = "[localValid]是否启用不能为NULL")
private Boolean localValid;
/**
* .
*/
@NotNull(message = "[filter]启用过滤不能为NULL")
private Boolean filter;
/**
* .
*/
@Length(min = 0, max = 500, message = "[filterConf]过滤配置长度不合法(0-500)")
private String filterConf;
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
public Long getServiceId() {
return this.serviceId;
}
public void setServiceId(Long serviceId) {
this.serviceId = serviceId;
}
public String getLocalTitle() {
return this.localTitle;
}
public void setLocalTitle(String localTitle) {
this.localTitle = localTitle;
}
public String getLocalNote() {
return this.localNote;
}
public void setLocalNote(String localNote) {
this.localNote = localNote;
}
public String getLocalPath() {
return this.localPath;
}
public void setLocalPath(String localPath) {
this.localPath = localPath;
}
public Boolean getLocalValid() {
return this.localValid;
}
public void setLocalValid(Boolean localValid) {
this.localValid = localValid;
}
public Boolean getFilter() {
return this.filter;
}
public void setFilter(Boolean filter) {
this.filter = filter;
}
public String getFilterConf() {
return this.filterConf;
}
public void setFilterConf(String filterConf) {
this.filterConf = filterConf;
}
}

@ -0,0 +1,30 @@
package xyz.wbsite.module.admin.req;
import xyz.wbsite.frame.base.BaseRequest;
import javax.validation.constraints.NotNull;
/**
* ServicesDeleteRequest -
*
* @author wangbing
* @version 0.0.1
* @since 2021-02-07
*/
public class ServicesDeleteRequest extends BaseRequest {
/**
* .
*/
@NotNull(message = "[id]主键不能为空")
private Long id;
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
}

@ -0,0 +1,138 @@
package xyz.wbsite.module.admin.req;
import xyz.wbsite.frame.base.BaseFindRequest;
import java.util.Date;
import xyz.wbsite.frame.validation.Select;
/**
* ServicesFindRequest -
*
* @author wangbing
* @version 0.0.1
* @since 2021-02-07
*/
public class ServicesFindRequest extends BaseFindRequest {
/**
* .
*/
private String title;
/**
* .
*/
private String titleLike;
/**
* .
*/
private String domain;
/**
* .
* :
* :
* :
* :
* :
*/
@Select({"反向代理", "负载均衡", "正向代理", "文件代理", "端口转发"})
private String type;
/**
* .
*/
private Integer port;
/**
* .
*/
private Boolean valid;
/**
* .
*/
private Boolean filter;
/**
* .
*/
private Date startDate;
/**
* .
*/
private Date endDate;
public String getTitle() {
return this.title;
}
public void setTitle(String title) {
this.title = title;
}
public String getTitleLike() {
return this.titleLike;
}
public void setTitleLike(String titleLike) {
this.titleLike = titleLike;
}
public String getDomain() {
return this.domain;
}
public void setDomain(String domain) {
this.domain = domain;
}
public String getType() {
return this.type;
}
public void setType(String type) {
this.type = type;
}
public Integer getPort() {
return this.port;
}
public void setPort(Integer port) {
this.port = port;
}
public Boolean getValid() {
return this.valid;
}
public void setValid(Boolean valid) {
this.valid = valid;
}
public Boolean getFilter() {
return this.filter;
}
public void setFilter(Boolean filter) {
this.filter = filter;
}
public Date getStartDate() {
return startDate;
}
public void setStartDate(Date startDate) {
this.startDate = startDate;
}
public Date getEndDate() {
return endDate;
}
public void setEndDate(Date endDate) {
this.endDate = endDate;
}
}

@ -1,15 +1,15 @@
package xyz.wbsite.module.conf.rsp;
package xyz.wbsite.module.admin.rsp;
import xyz.wbsite.frame.base.BaseResponse;
/**
* MappingCreateResponse -
* ConfigCreateResponse -
*
* @author wangbing
* @version 0.0.1
* @since 2020-03-18
* @since 2021-02-07
*/
public class MappingCreateResponse extends BaseResponse {
public class ConfigCreateResponse extends BaseResponse {
/**
*

@ -0,0 +1,26 @@
package xyz.wbsite.module.admin.rsp;
import xyz.wbsite.frame.base.BaseResponse;
/**
* ConfigDataCreateResponse -
*
* @author wangbing
* @version 0.0.1
* @since 2021-02-07
*/
public class ConfigDataCreateResponse extends BaseResponse {
/**
*
*/
private Long id;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}

@ -0,0 +1,14 @@
package xyz.wbsite.module.admin.rsp;
import xyz.wbsite.frame.base.BaseFindResponse;
import xyz.wbsite.module.admin.ent.ConfigData;
/**
* ConfigDataFindResponse -
*
* @author wangbing
* @version 0.0.1
* @since 2021-02-07
*/
public class ConfigDataFindResponse extends BaseFindResponse<ConfigData> {
}

@ -0,0 +1,26 @@
package xyz.wbsite.module.admin.rsp;
import xyz.wbsite.frame.base.BaseResponse;
/**
* ConfigDataUpdateResponse -
*
* @author wangbing
* @version 0.0.1
* @since 2021-02-07
*/
public class ConfigDataUpdateResponse extends BaseResponse {
/**
*
*/
private Long result;
public Long getResult() {
return this.result;
}
public void setResult(Long result) {
this.result = result;
}
}

@ -0,0 +1,26 @@
package xyz.wbsite.module.admin.rsp;
import xyz.wbsite.frame.base.BaseResponse;
/**
* ConfigDeleteResponse -
*
* @author wangbing
* @version 0.0.1
* @since 2021-02-07
*/
public class ConfigDeleteResponse extends BaseResponse {
/**
*
*/
private Long result;
public Long getResult() {
return this.result;
}
public void setResult(Long result) {
this.result = result;
}
}

@ -0,0 +1,14 @@
package xyz.wbsite.module.admin.rsp;
import xyz.wbsite.frame.base.BaseFindResponse;
import xyz.wbsite.module.admin.ent.Config;
/**
* ConfigFindResponse -
*
* @author wangbing
* @version 0.0.1
* @since 2021-02-07
*/
public class ConfigFindResponse extends BaseFindResponse<Config> {
}

@ -0,0 +1,26 @@
package xyz.wbsite.module.admin.rsp;
import xyz.wbsite.frame.base.BaseResponse;
/**
* ConfigUpdateResponse -
*
* @author wangbing
* @version 0.0.1
* @since 2021-02-07
*/
public class ConfigUpdateResponse extends BaseResponse {
/**
*
*/
private Long result;
public Long getResult() {
return this.result;
}
public void setResult(Long result) {
this.result = result;
}
}

@ -0,0 +1,26 @@
package xyz.wbsite.module.admin.rsp;
import xyz.wbsite.frame.base.BaseResponse;
/**
* LocationsDeleteResponse -
*
* @author wangbing
* @version 0.0.1
* @since 2021-02-07
*/
public class LocationsDeleteResponse extends BaseResponse {
/**
*
*/
private Long result;
public Long getResult() {
return this.result;
}
public void setResult(Long result) {
this.result = result;
}
}

@ -0,0 +1,14 @@
package xyz.wbsite.module.admin.rsp;
import xyz.wbsite.frame.base.BaseFindResponse;
import xyz.wbsite.module.admin.ent.Locations;
/**
* LocationsFindResponse -
*
* @author wangbing
* @version 0.0.1
* @since 2021-02-07
*/
public class LocationsFindResponse extends BaseFindResponse<Locations> {
}

@ -0,0 +1,26 @@
package xyz.wbsite.module.admin.rsp;
import xyz.wbsite.frame.base.BaseResponse;
/**
* LocationsUpdateResponse -
*
* @author wangbing
* @version 0.0.1
* @since 2021-02-07
*/
public class LocationsUpdateResponse extends BaseResponse {
/**
*
*/
private Long result;
public Long getResult() {
return this.result;
}
public void setResult(Long result) {
this.result = result;
}
}

@ -0,0 +1,26 @@
package xyz.wbsite.module.admin.rsp;
import xyz.wbsite.frame.base.BaseResponse;
/**
* ServicesUpdateResponse -
*
* @author wangbing
* @version 0.0.1
* @since 2021-02-07
*/
public class ServicesUpdateResponse extends BaseResponse {
/**
*
*/
private Long result;
public Long getResult() {
return this.result;
}
public void setResult(Long result) {
this.result = result;
}
}

@ -1,71 +0,0 @@
package xyz.wbsite.module.conf.ent;
import xyz.wbsite.frame.utils.ProcessUtil;
import java.io.File;
public class NginxCtrl {
private String startCmd = "start nginx";
private String stopCmd = "nginx.exe -s quit";
private String reloadCmd = "nginx.exe -s reload";
private String versionCmd = "nginx -v";
private File config = null;
public void doStart() {
ProcessUtil.exec(startCmd);
}
public void doStop() {
ProcessUtil.exec(stopCmd);
}
public void doReload() {
ProcessUtil.exec(reloadCmd);
}
public String getStartCmd() {
return startCmd;
}
public void setStartCmd(String startCmd) {
this.startCmd = startCmd;
}
public String getStopCmd() {
return stopCmd;
}
public void setStopCmd(String stopCmd) {
this.stopCmd = stopCmd;
}
public String getReloadCmd() {
return reloadCmd;
}
public void setReloadCmd(String reloadCmd) {
this.reloadCmd = reloadCmd;
}
public String getVersionCmd() {
return versionCmd;
}
public void setVersionCmd(String versionCmd) {
this.versionCmd = versionCmd;
}
public File getConfig() {
return config;
}
public void setConfig(File config) {
this.config = config;
}
public boolean isRunning() {
return ProcessUtil.findProcess("nginx.exe");
}
}

@ -1,68 +0,0 @@
package xyz.wbsite.module.conf.mgr;
import xyz.wbsite.module.conf.req.MappingCreateRequest;
import xyz.wbsite.module.conf.req.MappingDeleteRequest;
import xyz.wbsite.module.conf.req.MappingFindRequest;
import xyz.wbsite.module.conf.req.MappingGetRequest;
import xyz.wbsite.module.conf.req.MappingUpdateRequest;
import xyz.wbsite.module.conf.rsp.MappingCreateResponse;
import xyz.wbsite.module.conf.rsp.MappingDeleteResponse;
import xyz.wbsite.module.conf.rsp.MappingFindResponse;
import xyz.wbsite.module.conf.rsp.MappingGetResponse;
import xyz.wbsite.module.conf.rsp.MappingUpdateResponse;
import xyz.wbsite.frame.auth.Token;
/**
*
*
* @author wangbing
* @version 0.0.1
* @since 2020-03-18
*/
public interface MappingManager {
/**
*
*
* @param request
* @param token
* @return
*/
MappingCreateResponse create(MappingCreateRequest request, Token token);
/**
*
*
* @param request
* @param token
* @return
*/
MappingDeleteResponse delete(MappingDeleteRequest request, Token token);
/**
*
*
* @param request
* @param token
* @return
*/
MappingUpdateResponse update(MappingUpdateRequest request, Token token);
/**
*
*
* @param request
* @param token
* @return
*/
MappingFindResponse find(MappingFindRequest request, Token token);
/**
*
*
* @param request
* @param token
* @return
*/
MappingGetResponse get(MappingGetRequest request, Token token);
}

@ -1,78 +0,0 @@
package xyz.wbsite.module.conf.mpr;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
import xyz.wbsite.module.conf.ent.Mapping;
import xyz.wbsite.module.conf.req.MappingCreateRequest;
import xyz.wbsite.module.conf.req.MappingDeleteRequest;
import xyz.wbsite.module.conf.req.MappingFindRequest;
import xyz.wbsite.module.conf.req.MappingGetRequest;
import xyz.wbsite.module.conf.req.MappingUpdateRequest;
import xyz.wbsite.frame.auth.Token;
/**
* MAPPING -
*
* @author wangbing
* @date 2020-03-18
*/
@Mapper
public interface MappingMapper {
/**
*
*
* @param request
* @param token
* @return
*/
long insert(@Param("request") Mapping request, @Param("token") Token token);
/**
*
*
* @param request
* @param token
* @return
*/
long insertBatch(@Param("list") List<Mapping> request, @Param("token") Token token);
/**
*
*
* @param request
* @param token
* @return
*/
long delete(@Param("request") MappingDeleteRequest request, @Param("token") Token token);
/**
*
*
* @param request
* @param token
* @return
*/
long update(@Param("request") MappingUpdateRequest request, @Param("token") Token token);
/**
*
*
* @param request
* @param token
* @return
*/
List<Mapping> find(@Param("request") MappingFindRequest request, @Param("token") Token token);
/**
*
*
* @param request
* @param token
* @return
*/
Mapping get(@Param("request") MappingGetRequest request, @Param("token") Token token);
}

@ -1,151 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="xyz.wbsite.module.conf.mpr.MappingMapper">
<sql id="table">"CONF_MAPPING"</sql>
<sql id="entityColumnList">
"ID","NAME","PORT","PATH","TYPE","LOCATION","NOTE","ROW_VERSION","IS_DELETED","CREATE_BY","CREATE_TIME","LAST_UPDATE_BY","LAST_UPDATE_TIME"
</sql>
<resultMap id="mapping" type="xyz.wbsite.module.conf.ent.Mapping">
<result column="ID" jdbcType="BIGINT" property="id"/>
<result column="NAME" jdbcType="VARCHAR" property="name"/>
<result column="PORT" jdbcType="VARCHAR" property="port"/>
<result column="PATH" jdbcType="VARCHAR" property="path"/>
<result column="TYPE" jdbcType="VARCHAR" property="type"/>
<result column="LOCATION" jdbcType="VARCHAR" property="location"/>
<result column="NOTE" jdbcType="VARCHAR" property="note"/>
<result column="ROW_VERSION" jdbcType="BIGINT" property="rowVersion"/>
<result column="IS_DELETED" jdbcType="BIT" property="isDeleted"/>
<result column="CREATE_BY" jdbcType="BIGINT" property="createBy"/>
<result column="CREATE_TIME" jdbcType="TIMESTAMP" property="createTime"/>
<result column="LAST_UPDATE_BY" jdbcType="BIGINT" property="lastUpdateBy"/>
<result column="LAST_UPDATE_TIME" jdbcType="TIMESTAMP" property="lastUpdateTime"/>
</resultMap>
<select id="find" resultMap="mapping">
SELECT
<include refid="entityColumnList"/>
FROM
<include refid="table"/>
WHERE
"IS_DELETED" = 0
<if test="request.name != null and request.name != ''">
AND NAME = #{request.name}
</if>
<if test="request.port != null and request.port != ''">
AND PORT = #{request.port}
</if>
<if test="request.path != null and request.path != ''">
AND PATH = #{request.path}
</if>
<if test="request.type != null and request.type != ''">
AND TYPE = #{request.type}
</if>
<if test="request.location != null and request.location != ''">
AND LOCATION = #{request.location}
</if>
</select>
<select id="search" resultMap="mapping">
SELECT
<include refid="entityColumnList"/>
FROM
<include refid="table"/>
WHERE
"IS_DELETED" = 0
<if test="request.keyword != null and request.keyword != ''">
1 = 2
</if>
</select>
<insert id="insert">
INSERT INTO
<include refid="table"/>
(
<include refid="entityColumnList"/>
)
VALUES
(
#{request.id},
#{request.name,jdbcType=VARCHAR},
#{request.port,jdbcType=VARCHAR},
#{request.path,jdbcType=VARCHAR},
#{request.type,jdbcType=VARCHAR},
#{request.location,jdbcType=VARCHAR},
#{request.note,jdbcType=VARCHAR},
0,
0,
#{token.userId,jdbcType=NUMERIC},
datetime('now','localtime'),
NULL,
NULL
)
</insert>
<insert id="insertBatch">
INSERT INTO
<include refid="table"/>
(
<include refid="entityColumnList"/>
)
VALUES
<foreach collection="list" item= "item" index ="index" separator=",">
(
#{item.id},
#{item.name,jdbcType=VARCHAR},
#{item.port,jdbcType=VARCHAR},
#{item.path,jdbcType=VARCHAR},
#{item.type,jdbcType=VARCHAR},
#{item.location,jdbcType=VARCHAR},
#{item.note,jdbcType=VARCHAR},
0,
0,
#{token.userId,jdbcType=NUMERIC},
datetime('now','localtime'),
NULL,
NULL
)
</foreach >
</insert>
<update id="delete">
UPDATE
<include refid="table"/>
SET "IS_DELETED" = 1
WHERE "IS_DELETED" = 0
AND "ID" = #{request.id}
</update>
<update id="update">
UPDATE
<include refid="table"/>
SET
NAME = #{request.name,jdbcType=VARCHAR},
PORT = #{request.port,jdbcType=VARCHAR},
PATH = #{request.path,jdbcType=VARCHAR},
TYPE = #{request.type,jdbcType=VARCHAR},
LOCATION = #{request.location,jdbcType=VARCHAR},
NOTE = #{request.note,jdbcType=VARCHAR},
"ROW_VERSION" = "ROW_VERSION" + 1,
"LAST_UPDATE_BY" = #{token.userId},
"LAST_UPDATE_TIME" = datetime('now','localtime')
WHERE
"IS_DELETED" = 0
AND "ID" = #{request.id}
AND "ROW_VERSION" = #{request.rowVersion}
</update>
<select id="get" resultMap="mapping">
SELECT
<include refid="entityColumnList"/>
FROM
<include refid="table"/>
WHERE
IS_DELETED = 0
AND ID = #{request.id}
</select>
</mapper>

@ -1,105 +0,0 @@
package xyz.wbsite.module.conf.req;
import xyz.wbsite.frame.base.BaseRequest;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.NotBlank;
import org.hibernate.validator.constraints.Length;
/**
* MappingCreateRequest -
*
* @author wangbing
* @version 0.0.1
* @since 2020-03-18
*/
public class MappingCreateRequest extends BaseRequest {
/**
*
*/
@NotBlank(message = "[name]名称不能为空")
@Length(min = 0, max = 50, message = "[name]名称长度不合法(0-50)")
private String name;
/**
*
*/
@NotBlank(message = "[port]端口不能为空")
@Length(min = 0, max = 50, message = "[port]端口长度不合法(0-50)")
private String port;
/**
*
*/
@NotBlank(message = "[path]路径不能为空")
@Length(min = 0, max = 50, message = "[path]路径长度不合法(0-50)")
private String path;
/**
*
*/
@NotBlank(message = "[type]类型不能为空")
@Length(min = 0, max = 50, message = "[type]类型长度不合法(0-50)")
private String type;
/**
*
*/
@NotBlank(message = "[location]代理地址不能为空")
@Length(min = 0, max = 50, message = "[location]代理地址长度不合法(0-50)")
private String location;
/**
*
*/
@Length(min = 0, max = 50, message = "[note]备注长度不合法(0-50)")
private String note;
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public String getPort() {
return this.port;
}
public void setPort(String port) {
this.port = port;
}
public String getPath() {
return this.path;
}
public void setPath(String path) {
this.path = path;
}
public String getType() {
return this.type;
}
public void setType(String type) {
this.type = type;
}
public String getLocation() {
return this.location;
}
public void setLocation(String location) {
this.location = location;
}
public String getNote() {
return this.note;
}
public void setNote(String note) {
this.note = note;
}
}

@ -1,28 +0,0 @@
package xyz.wbsite.module.conf.req;
import xyz.wbsite.frame.base.BaseUpdateRequest;
import javax.validation.constraints.NotNull;
/**
* MappingDeleteRequest -
*
* @author wangbing
* @version 0.0.1
* @since 2020-03-18
*/
public class MappingDeleteRequest extends BaseUpdateRequest {
/**
*
*/
@NotNull(message = "[id]主键不能为空")
private long id;
public long getId() {
return this.id;
}
public void setId(long id) {
this.id = id;
}
}

@ -1,78 +0,0 @@
package xyz.wbsite.module.conf.req;
import xyz.wbsite.frame.base.BaseFindRequest;
/**
* MappingRequest -
*
* @author wangbing
* @version 0.0.1
* @since 2020-03-18
*/
public class MappingFindRequest extends BaseFindRequest {
/**
*
*/
private String name;
/**
*
*/
private String port;
/**
*
*/
private String path;
/**
*
*/
private String type;
/**
*
*/
private String location;
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public String getPort() {
return this.port;
}
public void setPort(String port) {
this.port = port;
}
public String getPath() {
return this.path;
}
public void setPath(String path) {
this.path = path;
}
public String getType() {
return this.type;
}
public void setType(String type) {
this.type = type;
}
public String getLocation() {
return this.location;
}
public void setLocation(String location) {
this.location = location;
}
}

@ -1,120 +0,0 @@
package xyz.wbsite.module.conf.req;
import xyz.wbsite.frame.base.BaseUpdateRequest;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.NotEmpty;
/**
* MappingUpdateRequest -
*
* @author wangbing
* @version 0.0.1
* @since 2020-03-18
*/
public class MappingUpdateRequest extends BaseUpdateRequest {
/**
*
*/
@NotNull(message = "[id]主键不能为NULL")
private Long id;
/**
*
*/
@NotBlank(message = "[name]名称不能为空")
@Length(min = 0, max = 50, message = "[name]名称长度不合法(0-50)")
private String name;
/**
*
*/
@NotBlank(message = "[port]端口不能为空")
@Length(min = 0, max = 50, message = "[port]端口长度不合法(0-50)")
private String port;
/**
*
*/
@NotBlank(message = "[path]路径不能为空")
@Length(min = 0, max = 50, message = "[path]路径长度不合法(0-50)")
private String path;
/**
*
*/
@NotBlank(message = "[type]类型不能为空")
@Length(min = 0, max = 50, message = "[type]类型长度不合法(0-50)")
private String type;
/**
*
*/
@NotBlank(message = "[location]代理地址不能为空")
@Length(min = 0, max = 50, message = "[location]代理地址长度不合法(0-50)")
private String location;
/**
*
*/
@Length(min = 0, max = 50, message = "[note]备注长度不合法(0-50)")
private String note;
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public String getPort() {
return this.port;
}
public void setPort(String port) {
this.port = port;
}
public String getPath() {
return this.path;
}
public void setPath(String path) {
this.path = path;
}
public String getType() {
return this.type;
}
public void setType(String type) {
this.type = type;
}
public String getLocation() {
return this.location;
}
public void setLocation(String location) {
this.location = location;
}
public String getNote() {
return this.note;
}
public void setNote(String note) {
this.note = note;
}
}

@ -1,7 +0,0 @@
package xyz.wbsite.module.conf.req;
import xyz.wbsite.frame.base.BaseRequest;
public class NginxReloadRequest extends BaseRequest {
}

@ -1,14 +0,0 @@
package xyz.wbsite.module.conf.rsp;
import xyz.wbsite.frame.base.BaseFindResponse;
import xyz.wbsite.module.conf.ent.Mapping;
/**
* MappingFindResponse -
*
* @author wangbing
* @version 0.0.1
* @since 2020-03-18
*/
public class MappingFindResponse extends BaseFindResponse<Mapping> {
}

@ -1,27 +0,0 @@
package xyz.wbsite.module.conf.rsp;
import xyz.wbsite.module.conf.ent.Mapping;
import xyz.wbsite.frame.base.BaseResponse;
/**
* MappingGetResponse -
*
* @author wangbing
* @version 0.0.1
* @since 2020-03-18
*/
public class MappingGetResponse extends BaseResponse {
/**
*
*/
private Mapping mapping;
public Mapping getMapping() {
return this.mapping;
}
public void setMapping(Mapping mapping) {
this.mapping = mapping;
}
}

@ -1,7 +0,0 @@
package xyz.wbsite.module.conf.rsp;
import xyz.wbsite.frame.base.BaseResponse;
public class NginxReloadResponse extends BaseResponse {
}

@ -1,7 +0,0 @@
package xyz.wbsite.module.conf.rsp;
import xyz.wbsite.frame.base.BaseResponse;
public class NginxStopResponse extends BaseResponse {
}

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

Loading…
Cancel
Save

Powered by TurnKey Linux.